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"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _MoveToHelper {
107 ModestMailOperation *mail_op;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
144 ModestMailOperationState *state,
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
150 gint num_of_uncached_msgs);
152 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
154 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
155 const TnyFolderStore *src_folder);
159 * This function checks whether a TnyFolderStore is a pop account
162 remote_folder_is_pop (const TnyFolderStore *folder)
164 const gchar *proto = NULL;
165 TnyAccount *account = NULL;
167 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
169 if (TNY_IS_ACCOUNT (folder)) {
170 account = TNY_ACCOUNT(folder);
171 g_object_ref(account);
172 } else if (TNY_IS_FOLDER (folder)) {
173 account = tny_folder_get_account(TNY_FOLDER(folder));
176 proto = tny_account_get_proto(account);
177 g_object_unref (account);
180 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
184 * This functions checks whether if a list of messages are already
185 * deleted from the server: that is, if the server is a POP account
186 * and all messages are already cached.
189 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
192 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
194 gboolean src_is_pop = remote_folder_is_pop (src_folder);
195 gint uncached_msgs = header_list_count_uncached_msgs (headers);
197 return (src_is_pop && !uncached_msgs);
200 /* Show the account creation wizard dialog.
201 * returns: TRUE if an account was created. FALSE if the user cancelled.
204 modest_run_account_setup_wizard (ModestWindow *win)
206 gboolean result = FALSE;
209 wizard = modest_window_mgr_get_easysetup_dialog
210 (modest_runtime_get_window_mgr());
212 /* old wizard is active already; present it and
213 * act as if the user cancelled the non-existing
216 printf ("wizard already active\n");
219 /* there is no such wizard yet */
220 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
221 modest_window_mgr_set_easysetup_dialog
222 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with to wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
232 /* make sure the mainwindow is visible */
233 gtk_widget_show_all (GTK_WIDGET(win));
234 gtk_window_present (GTK_WINDOW(win));
237 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
239 /* Don't make this a modal window, because secondary windows will then
240 * be unusable, freezing the UI: */
241 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
243 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
244 if (dialog_response == GTK_RESPONSE_CANCEL)
247 /* Check whether an account was created: */
248 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
251 gtk_widget_destroy (GTK_WIDGET (wizard));
253 /* clear it from the window mgr */
254 modest_window_mgr_set_easysetup_dialog
255 (modest_runtime_get_window_mgr(), NULL);
262 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
265 const gchar *authors[] = {
266 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
269 about = gtk_about_dialog_new ();
270 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
271 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
272 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
273 _("Copyright (c) 2006, Nokia Corporation\n"
274 "All rights reserved."));
275 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
276 _("a modest e-mail client\n\n"
277 "design and implementation: Dirk-Jan C. Binnema\n"
278 "contributions from the fine people at KC and Ig\n"
279 "uses the tinymail email framework written by Philip van Hoof"));
280 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
281 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
282 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
283 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
285 gtk_dialog_run (GTK_DIALOG (about));
286 gtk_widget_destroy(about);
290 * Gets the list of currently selected messages. If the win is the
291 * main window, then it returns a newly allocated list of the headers
292 * selected in the header view. If win is the msg view window, then
293 * the value returned is a list with just a single header.
295 * The caller of this funcion must free the list.
298 get_selected_headers (ModestWindow *win)
300 if (MODEST_IS_MAIN_WINDOW(win)) {
301 GtkWidget *header_view;
303 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
304 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
305 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
307 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
308 /* for MsgViewWindows, we simply return a list with one element */
310 TnyList *list = NULL;
312 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
313 if (header != NULL) {
314 list = tny_simple_list_new ();
315 tny_list_prepend (list, G_OBJECT(header));
316 g_object_unref (G_OBJECT(header));
326 headers_action_mark_as_read (TnyHeader *header,
330 TnyHeaderFlags flags;
332 g_return_if_fail (TNY_IS_HEADER(header));
334 flags = tny_header_get_flags (header);
335 if (flags & TNY_HEADER_FLAG_SEEN) return;
336 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
340 headers_action_mark_as_unread (TnyHeader *header,
344 TnyHeaderFlags flags;
346 g_return_if_fail (TNY_IS_HEADER(header));
348 flags = tny_header_get_flags (header);
349 if (flags & TNY_HEADER_FLAG_SEEN) {
350 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
354 /** A convenience method, because deleting a message is
355 * otherwise complicated, and it's best to change it in one place
358 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
360 ModestMailOperation *mail_op = NULL;
361 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
362 win ? G_OBJECT(win) : NULL);
363 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
366 /* Always delete. TODO: Move to trash still not supported */
367 modest_mail_operation_remove_msg (mail_op, header, FALSE);
368 g_object_unref (G_OBJECT (mail_op));
371 /** A convenience method, because deleting a message is
372 * otherwise complicated, and it's best to change it in one place
375 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
377 ModestMailOperation *mail_op = NULL;
378 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
379 win ? G_OBJECT(win) : NULL);
380 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
383 /* Always delete. TODO: Move to trash still not supported */
384 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
385 g_object_unref (G_OBJECT (mail_op));
389 /* headers_action_delete (TnyHeader *header, */
390 /* ModestWindow *win, */
391 /* gpointer user_data) */
393 /* modest_do_message_delete (header, win); */
397 /** After deleing a message that is currently visible in a window,
398 * show the next message from the list, or close the window if there are no more messages.
400 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
402 /* Close msg view window or select next */
403 if (modest_msg_view_window_last_message_selected (win) &&
404 modest_msg_view_window_first_message_selected (win)) {
405 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
407 if (!modest_msg_view_window_select_next_message (win)) {
409 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
415 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
417 TnyList *header_list = NULL;
418 TnyIterator *iter = NULL;
419 TnyHeader *header = NULL;
420 gchar *message = NULL;
423 ModestWindowMgr *mgr;
424 GtkWidget *header_view = NULL;
426 g_return_if_fail (MODEST_IS_WINDOW(win));
428 /* Check first if the header view has the focus */
429 if (MODEST_IS_MAIN_WINDOW (win)) {
431 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
432 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
433 if (!gtk_widget_is_focus (header_view))
437 /* Get the headers, either from the header view (if win is the main window),
438 * or from the message view window: */
439 header_list = get_selected_headers (win);
440 if (!header_list) return;
442 /* Check if any of the headers are already opened, or in the process of being opened */
443 if (MODEST_IS_MAIN_WINDOW (win)) {
445 iter = tny_list_create_iterator (header_list);
447 mgr = modest_runtime_get_window_mgr ();
448 while (!tny_iterator_is_done (iter) && !found) {
449 header = TNY_HEADER (tny_iterator_get_current (iter));
451 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
452 g_object_unref (header);
455 tny_iterator_next (iter);
457 g_object_unref (iter);
462 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
463 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
465 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
469 g_object_unref (header_list);
475 if (tny_list_get_length(header_list) == 1) {
476 iter = tny_list_create_iterator (header_list);
477 header = TNY_HEADER (tny_iterator_get_current (iter));
479 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
480 g_object_unref (header);
483 g_object_unref (iter);
485 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
486 tny_list_get_length(header_list)), desc);
488 /* Confirmation dialog */
489 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
493 if (response == GTK_RESPONSE_OK) {
494 ModestWindow *main_window = NULL;
495 ModestWindowMgr *mgr = NULL;
496 GtkTreeModel *model = NULL;
497 GtkTreeSelection *sel = NULL;
498 GList *sel_list = NULL, *tmp = NULL;
499 GtkTreeRowReference *next_row_reference = NULL;
500 GtkTreeRowReference *prev_row_reference = NULL;
501 GtkTreePath *next_path = NULL;
502 GtkTreePath *prev_path = NULL;
505 /* Find last selected row */
506 if (MODEST_IS_MAIN_WINDOW (win)) {
507 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
508 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
509 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
510 for (tmp=sel_list; tmp; tmp=tmp->next) {
511 if (tmp->next == NULL) {
512 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
513 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
515 gtk_tree_path_prev (prev_path);
516 gtk_tree_path_next (next_path);
518 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
519 next_row_reference = gtk_tree_row_reference_new (model, next_path);
524 /* Disable window dimming management */
525 modest_window_disable_dimming (MODEST_WINDOW(win));
527 /* Remove each header. If it's a view window header_view == NULL */
528 modest_do_messages_delete (header_list, win);
530 /* Enable window dimming management */
532 gtk_tree_selection_unselect_all (sel);
534 modest_window_enable_dimming (MODEST_WINDOW(win));
536 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
537 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
539 /* Get main window */
540 mgr = modest_runtime_get_window_mgr ();
541 main_window = modest_window_mgr_get_main_window (mgr);
544 /* Move cursor to next row */
547 /* Select next or previous row */
548 if (gtk_tree_row_reference_valid (next_row_reference)) {
549 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
550 gtk_tree_selection_select_path (sel, next_path);
552 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
553 gtk_tree_selection_select_path (sel, prev_path);
557 if (next_row_reference != NULL)
558 gtk_tree_row_reference_free (next_row_reference);
559 if (next_path != NULL)
560 gtk_tree_path_free (next_path);
561 if (prev_row_reference != NULL)
562 gtk_tree_row_reference_free (prev_row_reference);
563 if (prev_path != NULL)
564 gtk_tree_path_free (prev_path);
568 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
572 /* Update toolbar dimming state */
573 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
576 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
577 g_list_free (sel_list);
583 g_object_unref (header_list);
589 /* delete either message or folder, based on where we are */
591 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
593 g_return_if_fail (MODEST_IS_WINDOW(win));
595 /* Check first if the header view has the focus */
596 if (MODEST_IS_MAIN_WINDOW (win)) {
598 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
599 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
600 if (gtk_widget_is_focus (w)) {
601 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
605 modest_ui_actions_on_delete_message (action, win);
611 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
613 ModestWindowMgr *mgr = NULL;
615 #ifdef MODEST_PLATFORM_MAEMO
616 modest_osso_save_state();
617 #endif /* MODEST_PLATFORM_MAEMO */
619 g_debug ("closing down, clearing %d item(s) from operation queue",
620 modest_mail_operation_queue_num_elements
621 (modest_runtime_get_mail_operation_queue()));
623 /* cancel all outstanding operations */
624 modest_mail_operation_queue_cancel_all
625 (modest_runtime_get_mail_operation_queue());
627 g_debug ("queue has been cleared");
630 /* Check if there are opened editing windows */
631 mgr = modest_runtime_get_window_mgr ();
632 modest_window_mgr_close_all_windows (mgr);
634 /* note: when modest-tny-account-store is finalized,
635 it will automatically set all network connections
638 /* gtk_main_quit (); */
642 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
646 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
648 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
649 /* gtk_widget_destroy (GTK_WIDGET (win)); */
650 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
651 /* gboolean ret_value; */
652 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
653 /* } else if (MODEST_IS_WINDOW (win)) { */
654 /* gtk_widget_destroy (GTK_WIDGET (win)); */
656 /* g_return_if_reached (); */
661 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
663 GtkClipboard *clipboard = NULL;
664 gchar *selection = NULL;
666 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
667 selection = gtk_clipboard_wait_for_text (clipboard);
669 /* Question: why is the clipboard being used here?
670 * It doesn't really make a lot of sense. */
674 modest_address_book_add_address (selection);
680 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
682 /* This is currently only implemented for Maemo */
683 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
684 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
685 modest_run_account_setup_wizard (win);
688 /* Show the list of accounts: */
689 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
690 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
692 /* The accounts dialog must be modal */
693 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
694 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
697 GtkWidget *dialog, *label;
699 /* Create the widgets */
701 dialog = gtk_dialog_new_with_buttons ("Message",
703 GTK_DIALOG_DESTROY_WITH_PARENT,
707 label = gtk_label_new ("Hello World!");
709 /* Ensure that the dialog box is destroyed when the user responds. */
711 g_signal_connect_swapped (dialog, "response",
712 G_CALLBACK (gtk_widget_destroy),
715 /* Add the label, and show everything we've added to the dialog. */
717 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
719 gtk_widget_show_all (dialog);
720 #endif /* MODEST_PLATFORM_MAEMO */
724 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
726 /* Save any changes. */
727 modest_connection_specific_smtp_window_save_server_accounts (
728 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
729 gtk_widget_destroy (GTK_WIDGET (window));
735 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
737 /* This is currently only implemented for Maemo,
738 * because it requires an API (libconic) to detect different connection
741 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
743 /* Create the window if necessary: */
744 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
745 modest_connection_specific_smtp_window_fill_with_connections (
746 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
747 modest_runtime_get_account_mgr());
749 /* Show the window: */
750 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
751 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
752 gtk_widget_show (specific_window);
754 /* Save changes when the window is hidden: */
755 g_signal_connect (specific_window, "hide",
756 G_CALLBACK (on_smtp_servers_window_hide), win);
757 #endif /* MODEST_PLATFORM_MAEMO */
761 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
763 ModestWindow *msg_win = NULL;
765 TnyFolder *folder = NULL;
766 gchar *account_name = NULL;
767 gchar *from_str = NULL;
768 /* GError *err = NULL; */
769 TnyAccount *account = NULL;
770 ModestWindowMgr *mgr;
771 gchar *signature = NULL, *blank_and_signature = NULL;
773 /* if there are no accounts yet, just show the wizard */
774 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
775 const gboolean created = modest_run_account_setup_wizard (win);
780 account_name = g_strdup (modest_window_get_active_account (win));
782 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
784 g_printerr ("modest: no account found\n");
788 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
790 TNY_ACCOUNT_TYPE_STORE);
792 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
796 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
798 g_printerr ("modest: failed get from string for '%s'\n", account_name);
802 gboolean use_signature = FALSE;
803 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
806 blank_and_signature = g_strconcat ("\n", signature, NULL);
808 blank_and_signature = g_strdup ("");
813 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
815 g_printerr ("modest: failed to create new msg\n");
819 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
821 g_printerr ("modest: failed to find Drafts folder\n");
826 /* Create and register edit window */
827 /* This is destroyed by TODO. */
828 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
829 mgr = modest_runtime_get_window_mgr ();
830 modest_window_mgr_register_window (mgr, msg_win);
833 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
835 gtk_widget_show_all (GTK_WIDGET (msg_win));
838 g_free (account_name);
840 g_free (blank_and_signature);
842 g_object_unref (msg_win);
844 g_object_unref (G_OBJECT(account));
846 g_object_unref (G_OBJECT(msg));
848 g_object_unref (G_OBJECT(folder));
852 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
856 ModestMailOperationStatus status;
858 /* If there is no message or the operation was not successful */
859 status = modest_mail_operation_get_status (mail_op);
860 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
862 /* Remove the header from the preregistered uids */
863 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
873 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
875 ModestWindowMgr *mgr = NULL;
876 ModestWindow *parent_win = NULL;
877 ModestWindow *win = NULL;
878 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
879 gchar *account = NULL;
882 /* Do nothing if there was any problem with the mail
883 operation. The error will be shown by the error_handler of
884 the mail operation */
885 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
888 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
889 folder = tny_header_get_folder (header);
891 /* Mark header as read */
892 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
895 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
897 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
899 /* Gets folder type (OUTBOX headers will be opened in edit window */
900 if (modest_tny_folder_is_local_folder (folder))
901 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
903 /* If the header is in the drafts folder then open the editor,
904 else the message view window */
905 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
906 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
907 /* we cannot edit without a valid account... */
908 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
909 const gboolean created = modest_run_account_setup_wizard(parent_win);
913 win = modest_msg_edit_window_new (msg, account, TRUE);
917 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
920 gchar *uid = modest_tny_folder_get_header_unique_id (header);
922 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
923 GtkWidget *header_view;
924 GtkTreeSelection *sel;
925 GList *sel_list = NULL;
928 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
929 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
931 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
932 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
934 if (sel_list != NULL) {
935 GtkTreeRowReference *row_reference;
937 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
938 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
939 g_list_free (sel_list);
941 win = modest_msg_view_window_new_with_header_model (
942 msg, account, (const gchar*) uid,
943 model, row_reference);
944 gtk_tree_row_reference_free (row_reference);
946 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
949 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
954 /* Register and show new window */
956 mgr = modest_runtime_get_window_mgr ();
957 modest_window_mgr_register_window (mgr, win);
958 g_object_unref (win);
959 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
960 gtk_widget_show_all (GTK_WIDGET(win));
963 /* Update toolbar dimming state */
964 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
965 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
971 g_object_unref (parent_win);
972 g_object_unref (folder);
976 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
980 GObject *win = modest_mail_operation_get_source (mail_op);
982 error = modest_mail_operation_get_error (mail_op);
983 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
985 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
987 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
990 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
991 _("mail_ni_ui_folder_get_msg_folder_error"));
995 g_object_unref (win);
999 * This function is used by both modest_ui_actions_on_open and
1000 * modest_ui_actions_on_header_activated. This way we always do the
1001 * same when trying to open messages.
1004 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1006 ModestWindowMgr *mgr = NULL;
1007 TnyIterator *iter = NULL;
1008 ModestMailOperation *mail_op = NULL;
1009 TnyList *not_opened_headers = NULL;
1010 TnyHeaderFlags flags = 0;
1012 g_return_if_fail (headers != NULL);
1014 /* Check that only one message is selected for opening */
1015 if (tny_list_get_length (headers) != 1) {
1016 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1017 _("mcen_ib_select_one_message"));
1022 /* Look if we already have a message view for each header. If
1023 true, then remove the header from the list of headers to
1025 mgr = modest_runtime_get_window_mgr ();
1026 iter = tny_list_create_iterator (headers);
1027 not_opened_headers = tny_simple_list_new ();
1029 while (!tny_iterator_is_done (iter)) {
1031 ModestWindow *window = NULL;
1032 TnyHeader *header = NULL;
1033 gboolean found = FALSE;
1035 header = TNY_HEADER (tny_iterator_get_current (iter));
1037 flags = tny_header_get_flags (header);
1040 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1042 /* Do not open again the message and present the
1043 window to the user */
1046 gtk_window_present (GTK_WINDOW (window));
1048 /* the header has been registered already, we don't do
1049 * anything but wait for the window to come up*/
1050 g_debug ("header %p already registered, waiting for window", header);
1052 tny_list_append (not_opened_headers, G_OBJECT (header));
1056 g_object_unref (header);
1058 tny_iterator_next (iter);
1060 g_object_unref (iter);
1063 /* If some messages would have to be downloaded, ask the user to
1064 * make a connection. It's generally easier to do this here (in the mainloop)
1065 * than later in a thread:
1067 if (tny_list_get_length (not_opened_headers) > 0) {
1069 gboolean found = FALSE;
1071 iter = tny_list_create_iterator (not_opened_headers);
1072 while (!tny_iterator_is_done (iter) && !found) {
1073 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1074 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1077 tny_iterator_next (iter);
1079 g_object_unref (header);
1081 g_object_unref (iter);
1083 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1084 g_object_unref (not_opened_headers);
1089 /* Register the headers before actually creating the windows: */
1090 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1091 while (!tny_iterator_is_done (iter_not_opened)) {
1092 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1094 modest_window_mgr_register_header (mgr, header);
1095 g_object_unref (header);
1098 tny_iterator_next (iter_not_opened);
1100 g_object_unref (iter_not_opened);
1101 iter_not_opened = NULL;
1103 /* Open each message */
1104 if (tny_list_get_length (not_opened_headers) > 0) {
1105 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1107 modest_ui_actions_get_msgs_full_error_handler,
1109 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1110 if (tny_list_get_length (not_opened_headers) > 1) {
1111 modest_mail_operation_get_msgs_full (mail_op,
1117 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1118 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1119 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1120 g_object_unref (header);
1121 g_object_unref (iter);
1123 g_object_unref (mail_op);
1127 if (not_opened_headers != NULL)
1128 g_object_unref (not_opened_headers);
1132 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1137 headers = get_selected_headers (win);
1142 _modest_ui_actions_open (headers, win);
1144 g_object_unref(headers);
1149 free_reply_forward_helper (gpointer data)
1151 ReplyForwardHelper *helper;
1153 helper = (ReplyForwardHelper *) data;
1154 g_free (helper->account_name);
1155 g_slice_free (ReplyForwardHelper, helper);
1159 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1163 ReplyForwardHelper *rf_helper;
1164 ModestWindow *msg_win = NULL;
1165 ModestEditType edit_type;
1167 TnyAccount *account = NULL;
1168 ModestWindowMgr *mgr = NULL;
1169 gchar *signature = NULL;
1171 /* If there was any error. The mail operation could be NULL,
1172 this means that we already have the message downloaded and
1173 that we didn't do a mail operation to retrieve it */
1174 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1177 g_return_if_fail (user_data != NULL);
1178 rf_helper = (ReplyForwardHelper *) user_data;
1180 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1181 rf_helper->account_name);
1182 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1183 rf_helper->account_name,
1184 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1185 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1186 rf_helper->account_name,
1187 MODEST_ACCOUNT_SIGNATURE, FALSE);
1190 /* Create reply mail */
1191 switch (rf_helper->action) {
1194 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1195 rf_helper->reply_forward_type,
1196 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1198 case ACTION_REPLY_TO_ALL:
1200 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1201 MODEST_TNY_MSG_REPLY_MODE_ALL);
1202 edit_type = MODEST_EDIT_TYPE_REPLY;
1204 case ACTION_FORWARD:
1206 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1207 edit_type = MODEST_EDIT_TYPE_FORWARD;
1210 g_return_if_reached ();
1217 g_printerr ("modest: failed to create message\n");
1221 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1222 rf_helper->account_name,
1223 TNY_ACCOUNT_TYPE_STORE);
1225 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1229 /* Create and register the windows */
1230 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1231 mgr = modest_runtime_get_window_mgr ();
1232 modest_window_mgr_register_window (mgr, msg_win);
1234 if (rf_helper->parent_window != NULL) {
1235 gdouble parent_zoom;
1237 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1238 modest_window_set_zoom (msg_win, parent_zoom);
1241 /* Show edit window */
1242 gtk_widget_show_all (GTK_WIDGET (msg_win));
1246 g_object_unref (msg_win);
1248 g_object_unref (G_OBJECT (new_msg));
1250 g_object_unref (G_OBJECT (account));
1251 /* g_object_unref (msg); */
1252 free_reply_forward_helper (rf_helper);
1255 /* Checks a list of headers. If any of them are not currently
1256 * downloaded (CACHED) then returns TRUE else returns FALSE.
1259 header_list_count_uncached_msgs (TnyList *header_list)
1262 gint uncached_messages = 0;
1264 iter = tny_list_create_iterator (header_list);
1265 while (!tny_iterator_is_done (iter)) {
1268 header = TNY_HEADER (tny_iterator_get_current (iter));
1270 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1271 uncached_messages ++;
1272 g_object_unref (header);
1275 tny_iterator_next (iter);
1277 g_object_unref (iter);
1279 return uncached_messages;
1282 /* Returns FALSE if the user does not want to download the
1283 * messages. Returns TRUE if the user allowed the download.
1286 connect_to_get_msg (GtkWindow *win,
1287 gint num_of_uncached_msgs)
1289 /* Allways download if we are online. */
1290 if (tny_device_is_online (modest_runtime_get_device ()))
1293 /* If offline, then ask for user permission to download the messages */
1294 GtkResponseType response;
1295 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1296 ngettext("mcen_nc_get_msg",
1298 num_of_uncached_msgs));
1299 if (response == GTK_RESPONSE_CANCEL)
1302 return modest_platform_connect_and_wait(win, NULL);
1306 * Common code for the reply and forward actions
1309 reply_forward (ReplyForwardAction action, ModestWindow *win)
1311 ModestMailOperation *mail_op = NULL;
1312 TnyList *header_list = NULL;
1313 ReplyForwardHelper *rf_helper = NULL;
1314 guint reply_forward_type;
1315 gboolean continue_download = TRUE;
1316 gboolean do_retrieve = TRUE;
1318 g_return_if_fail (MODEST_IS_WINDOW(win));
1320 /* we need an account when editing */
1321 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1322 const gboolean created = modest_run_account_setup_wizard (win);
1327 header_list = get_selected_headers (win);
1331 reply_forward_type =
1332 modest_conf_get_int (modest_runtime_get_conf (),
1333 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1336 /* check if we need to download msg before asking about it */
1337 do_retrieve = (action == ACTION_FORWARD) ||
1338 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1341 gint num_of_unc_msgs;
1342 /* check that the messages have been previously downloaded */
1343 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1344 /* If there are any uncached message ask the user
1345 * whether he/she wants to download them. */
1346 if (num_of_unc_msgs)
1347 continue_download = connect_to_get_msg (
1352 if (!continue_download) {
1353 g_object_unref (header_list);
1357 /* We assume that we can only select messages of the
1358 same folder and that we reply all of them from the
1359 same account. In fact the interface currently only
1360 allows single selection */
1363 rf_helper = g_slice_new0 (ReplyForwardHelper);
1364 rf_helper->reply_forward_type = reply_forward_type;
1365 rf_helper->action = action;
1366 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1368 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1369 rf_helper->parent_window = GTK_WIDGET (win);
1370 if (!rf_helper->account_name)
1371 rf_helper->account_name =
1372 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1374 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1377 /* Get header and message. Do not free them here, the
1378 reply_forward_cb must do it */
1379 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1380 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1381 if (!msg || !header) {
1383 g_object_unref (msg);
1384 g_printerr ("modest: no message found\n");
1387 reply_forward_cb (NULL, header, msg, rf_helper);
1390 g_object_unref (header);
1395 /* Only reply/forward to one message */
1396 iter = tny_list_create_iterator (header_list);
1397 header = TNY_HEADER (tny_iterator_get_current (iter));
1398 g_object_unref (iter);
1401 /* Retrieve messages */
1403 mail_op = modest_mail_operation_new_with_error_handling (
1404 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1406 modest_ui_actions_get_msgs_full_error_handler,
1408 modest_mail_operation_queue_add (
1409 modest_runtime_get_mail_operation_queue (), mail_op);
1411 modest_mail_operation_get_msg (mail_op,
1416 g_object_unref(mail_op);
1418 /* we put a ref here to prevent double unref as the reply
1419 * forward callback unrefs the header at its end */
1420 reply_forward_cb (NULL, header, NULL, rf_helper);
1424 g_object_unref (header);
1430 g_object_unref (header_list);
1434 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1436 g_return_if_fail (MODEST_IS_WINDOW(win));
1438 reply_forward (ACTION_REPLY, win);
1442 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1444 g_return_if_fail (MODEST_IS_WINDOW(win));
1446 reply_forward (ACTION_FORWARD, win);
1450 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1452 g_return_if_fail (MODEST_IS_WINDOW(win));
1454 reply_forward (ACTION_REPLY_TO_ALL, win);
1458 modest_ui_actions_on_next (GtkAction *action,
1459 ModestWindow *window)
1461 if (MODEST_IS_MAIN_WINDOW (window)) {
1462 GtkWidget *header_view;
1464 header_view = modest_main_window_get_child_widget (
1465 MODEST_MAIN_WINDOW(window),
1466 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1470 modest_header_view_select_next (
1471 MODEST_HEADER_VIEW(header_view));
1472 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1473 modest_msg_view_window_select_next_message (
1474 MODEST_MSG_VIEW_WINDOW (window));
1476 g_return_if_reached ();
1481 modest_ui_actions_on_prev (GtkAction *action,
1482 ModestWindow *window)
1484 g_return_if_fail (MODEST_IS_WINDOW(window));
1486 if (MODEST_IS_MAIN_WINDOW (window)) {
1487 GtkWidget *header_view;
1488 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1489 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1493 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1494 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1495 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1497 g_return_if_reached ();
1502 modest_ui_actions_on_sort (GtkAction *action,
1503 ModestWindow *window)
1505 g_return_if_fail (MODEST_IS_WINDOW(window));
1507 if (MODEST_IS_MAIN_WINDOW (window)) {
1508 GtkWidget *header_view;
1509 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1510 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1512 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1517 /* Show sorting dialog */
1518 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1523 new_messages_arrived (ModestMailOperation *self,
1524 TnyList *new_headers,
1527 ModestMainWindow *win = NULL;
1528 GtkWidget *folder_view = NULL;
1529 TnyFolderStore *folder = NULL;
1530 gboolean folder_empty = FALSE;
1532 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1533 win = MODEST_MAIN_WINDOW (user_data);
1535 /* Don't do anything if there are not new headers, this could
1536 happen if there was any problem with the mail operation */
1540 /* Set contents style of headers view */
1541 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1542 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1543 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1544 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1547 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1550 modest_main_window_set_contents_style (win,
1551 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1554 /* Notify new messages have been downloaded */
1555 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1556 TnyIterator *iter = tny_list_create_iterator (new_headers);
1558 TnyHeader *header = NULL;
1560 header = TNY_HEADER (tny_iterator_get_current (iter));
1561 modest_platform_on_new_header_received (header);
1562 g_object_unref (header);
1564 tny_iterator_next (iter);
1565 } while (!tny_iterator_is_done (iter));
1566 g_object_unref (iter);
1571 * This function performs the send & receive required actions. The
1572 * window is used to create the mail operation. Typically it should
1573 * always be the main window, but we pass it as argument in order to
1577 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1579 gchar *acc_name = NULL;
1580 ModestMailOperation *mail_op;
1581 TnyAccount *store_account = NULL;
1583 /* If no account name was provided then get the current account, and if
1584 there is no current account then pick the default one: */
1585 if (!account_name) {
1586 acc_name = g_strdup (modest_window_get_active_account(win));
1588 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1590 g_printerr ("modest: cannot get default account\n");
1594 acc_name = g_strdup (account_name);
1598 /* Ensure that we have a connection available */
1600 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1602 TNY_ACCOUNT_TYPE_STORE);
1603 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1604 g_object_unref (store_account);
1607 g_object_unref (store_account);
1609 /* Set send/receive operation in progress */
1610 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1612 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1614 modest_ui_actions_send_receive_error_handler,
1617 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1618 G_CALLBACK (_on_send_receive_progress_changed),
1621 /* Send & receive. */
1622 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1623 /* Receive and then send. The operation is tagged initially as
1624 a receive operation because the account update performs a
1625 receive and then a send. The operation changes its type
1626 internally, so the progress objects will receive the proper
1627 progress information */
1628 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1629 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1630 g_object_unref (G_OBJECT (mail_op));
1638 modest_ui_actions_do_cancel_send (const gchar *account_name,
1641 TnyTransportAccount *transport_account;
1642 TnySendQueue *send_queue = NULL;
1643 GError *error = NULL;
1645 /* Get transport account */
1647 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1648 (modest_runtime_get_account_store(),
1650 TNY_ACCOUNT_TYPE_TRANSPORT));
1651 if (!transport_account) {
1652 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1657 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1658 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1659 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1660 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1661 "modest: could not find send queue for account\n");
1663 /* Keeep messages in outbox folder */
1664 tny_send_queue_cancel (send_queue, FALSE, &error);
1668 if (transport_account != NULL)
1669 g_object_unref (G_OBJECT (transport_account));
1673 modest_ui_actions_cancel_send_all (ModestWindow *win)
1675 GSList *account_names, *iter;
1677 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1680 iter = account_names;
1682 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1683 iter = g_slist_next (iter);
1686 modest_account_mgr_free_account_names (account_names);
1687 account_names = NULL;
1691 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1694 /* Check if accounts exist */
1695 gboolean accounts_exist =
1696 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1698 /* If not, allow the user to create an account before trying to send/receive. */
1699 if (!accounts_exist)
1700 modest_ui_actions_on_accounts (NULL, win);
1702 /* Cancel all sending operaitons */
1703 modest_ui_actions_cancel_send_all (win);
1707 * Refreshes all accounts. This function will be used by automatic
1711 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1713 GSList *account_names, *iter;
1715 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1718 iter = account_names;
1720 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1721 iter = g_slist_next (iter);
1724 modest_account_mgr_free_account_names (account_names);
1725 account_names = NULL;
1729 modest_do_refresh_current_folder(ModestWindow *win)
1731 /* Refresh currently selected folder. Note that if we only
1732 want to retreive the headers, then the refresh only will
1733 invoke a poke_status over all folders, i.e., only the
1734 total/unread count will be updated */
1735 if (MODEST_IS_MAIN_WINDOW (win)) {
1736 GtkWidget *header_view, *folder_view;
1737 TnyFolderStore *folder_store;
1739 /* Get folder and header view */
1741 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1742 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1746 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1748 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1750 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1751 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1753 /* We do not need to set the contents style
1754 because it hasn't changed. We also do not
1755 need to save the widget status. Just force
1757 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1758 TNY_FOLDER (folder_store),
1759 folder_refreshed_cb,
1760 MODEST_MAIN_WINDOW (win));
1764 g_object_unref (folder_store);
1770 * Handler of the click on Send&Receive button in the main toolbar
1773 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1775 /* Check if accounts exist */
1776 gboolean accounts_exist =
1777 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1779 /* If not, allow the user to create an account before trying to send/receive. */
1780 if (!accounts_exist)
1781 modest_ui_actions_on_accounts (NULL, win);
1783 modest_do_refresh_current_folder (win);
1785 /* Refresh the active account */
1786 modest_ui_actions_do_send_receive (NULL, win);
1791 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1794 GtkWidget *header_view;
1796 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1798 header_view = modest_main_window_get_child_widget (main_window,
1799 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1803 conf = modest_runtime_get_conf ();
1805 /* what is saved/restored is depending on the style; thus; we save with
1806 * old style, then update the style, and restore for this new style
1808 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1810 if (modest_header_view_get_style
1811 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1812 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1813 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1815 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1816 MODEST_HEADER_VIEW_STYLE_DETAILS);
1818 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1819 MODEST_CONF_HEADER_VIEW_KEY);
1824 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1826 ModestMainWindow *main_window)
1828 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1829 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1831 /* in the case the folder is empty, show the empty folder message and focus
1833 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1834 if (modest_header_view_is_empty (header_view)) {
1835 TnyFolder *folder = modest_header_view_get_folder (header_view);
1836 GtkWidget *folder_view =
1837 modest_main_window_get_child_widget (main_window,
1838 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1840 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1841 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1845 /* If no header has been selected then exit */
1850 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1851 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1853 /* Update toolbar dimming state */
1854 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1858 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1860 ModestMainWindow *main_window)
1864 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1870 /* headers = tny_simple_list_new (); */
1871 /* tny_list_prepend (headers, G_OBJECT (header)); */
1872 headers = modest_header_view_get_selected_headers (header_view);
1874 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1876 g_object_unref (headers);
1880 set_active_account_from_tny_account (TnyAccount *account,
1881 ModestWindow *window)
1883 const gchar *server_acc_name = tny_account_get_id (account);
1885 /* We need the TnyAccount provided by the
1886 account store because that is the one that
1887 knows the name of the Modest account */
1888 TnyAccount *modest_server_account = modest_server_account =
1889 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1890 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1892 if (!modest_server_account) {
1893 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1897 /* Update active account, but only if it's not a pseudo-account */
1898 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1899 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1900 const gchar *modest_acc_name =
1901 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1902 if (modest_acc_name)
1903 modest_window_set_active_account (window, modest_acc_name);
1906 g_object_unref (modest_server_account);
1911 folder_refreshed_cb (ModestMailOperation *mail_op,
1915 ModestMainWindow *win = NULL;
1916 GtkWidget *header_view;
1917 gboolean folder_empty = FALSE;
1918 gboolean all_marked_as_deleted = FALSE;
1920 g_return_if_fail (TNY_IS_FOLDER (folder));
1922 win = MODEST_MAIN_WINDOW (user_data);
1924 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1927 TnyFolder *current_folder;
1929 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1930 if (current_folder != NULL && folder != current_folder) {
1931 g_object_unref (current_folder);
1934 g_object_unref (current_folder);
1937 /* Check if folder is empty and set headers view contents style */
1938 folder_empty = (tny_folder_get_all_count (folder) == 0);
1939 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1940 if (folder_empty || all_marked_as_deleted)
1941 modest_main_window_set_contents_style (win,
1942 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1946 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1947 TnyFolderStore *folder_store,
1949 ModestMainWindow *main_window)
1952 GtkWidget *header_view;
1954 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1956 header_view = modest_main_window_get_child_widget(main_window,
1957 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1961 conf = modest_runtime_get_conf ();
1963 if (TNY_IS_ACCOUNT (folder_store)) {
1965 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1967 /* Show account details */
1968 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1971 if (TNY_IS_FOLDER (folder_store) && selected) {
1973 /* Update the active account */
1974 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1976 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1977 g_object_unref (account);
1981 /* Set the header style by default, it could
1982 be changed later by the refresh callback to
1984 modest_main_window_set_contents_style (main_window,
1985 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1987 /* Set folder on header view. This function
1988 will call tny_folder_refresh_async so we
1989 pass a callback that will be called when
1990 finished. We use that callback to set the
1991 empty view if there are no messages */
1992 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1993 TNY_FOLDER (folder_store),
1994 folder_refreshed_cb,
1997 /* Restore configuration. We need to do this
1998 *after* the set_folder because the widget
1999 memory asks the header view about its
2001 modest_widget_memory_restore (modest_runtime_get_conf (),
2002 G_OBJECT(header_view),
2003 MODEST_CONF_HEADER_VIEW_KEY);
2005 /* Update the active account */
2006 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2007 /* Save only if we're seeing headers */
2008 if (modest_main_window_get_contents_style (main_window) ==
2009 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2010 modest_widget_memory_save (conf, G_OBJECT (header_view),
2011 MODEST_CONF_HEADER_VIEW_KEY);
2012 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2016 /* Update toolbar dimming state */
2017 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2021 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2028 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2030 online = tny_device_is_online (modest_runtime_get_device());
2033 /* already online -- the item is simply not there... */
2034 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2036 GTK_MESSAGE_WARNING,
2038 _("The %s you selected cannot be found"),
2040 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2041 gtk_dialog_run (GTK_DIALOG(dialog));
2043 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2046 _("mcen_bd_dialog_cancel"),
2047 GTK_RESPONSE_REJECT,
2048 _("mcen_bd_dialog_ok"),
2049 GTK_RESPONSE_ACCEPT,
2051 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2052 "Do you want to get online?"), item);
2053 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2054 gtk_label_new (txt), FALSE, FALSE, 0);
2055 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2058 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2059 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2060 /* TODO: Comment about why is this commented out: */
2061 /* modest_platform_connect_and_wait (); */
2064 gtk_widget_destroy (dialog);
2068 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2071 /* g_message ("%s %s", __FUNCTION__, link); */
2076 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2079 modest_platform_activate_uri (link);
2083 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2086 modest_platform_show_uri_popup (link);
2090 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2093 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2097 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2098 const gchar *address,
2101 /* g_message ("%s %s", __FUNCTION__, address); */
2105 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2107 TnyTransportAccount *transport_account;
2108 ModestMailOperation *mail_operation;
2110 gchar *account_name, *from;
2111 ModestAccountMgr *account_mgr;
2112 gchar *info_text = NULL;
2114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2116 data = modest_msg_edit_window_get_msg_data (edit_window);
2118 account_mgr = modest_runtime_get_account_mgr();
2119 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2121 account_name = modest_account_mgr_get_default_account (account_mgr);
2122 if (!account_name) {
2123 g_printerr ("modest: no account found\n");
2124 modest_msg_edit_window_free_msg_data (edit_window, data);
2128 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2129 account_name = g_strdup (data->account_name);
2133 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2134 (modest_runtime_get_account_store(),
2136 TNY_ACCOUNT_TYPE_TRANSPORT));
2137 if (!transport_account) {
2138 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2139 g_free (account_name);
2140 modest_msg_edit_window_free_msg_data (edit_window, data);
2143 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2145 /* Create the mail operation */
2146 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2147 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2149 modest_mail_operation_save_to_drafts (mail_operation,
2161 data->priority_flags);
2164 g_free (account_name);
2165 g_object_unref (G_OBJECT (transport_account));
2166 g_object_unref (G_OBJECT (mail_operation));
2168 modest_msg_edit_window_free_msg_data (edit_window, data);
2170 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2171 modest_platform_information_banner (NULL, NULL, info_text);
2175 /* For instance, when clicking the Send toolbar button when editing a message: */
2177 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2181 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2184 /* Offer the connection dialog, if necessary: */
2185 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2188 /* FIXME: Code added just for testing. The final version will
2189 use the send queue provided by tinymail and some
2191 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2192 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2194 account_name = modest_account_mgr_get_default_account (account_mgr);
2196 if (!account_name) {
2197 /* Run account setup wizard */
2198 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2203 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2205 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2206 account_name = g_strdup (data->account_name);
2209 /* Get the currently-active transport account for this modest account: */
2210 TnyTransportAccount *transport_account =
2211 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2212 (modest_runtime_get_account_store(),
2214 if (!transport_account) {
2215 /* Run account setup wizard */
2216 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2221 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2223 /* Create the mail operation */
2224 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2227 modest_mail_operation_send_new_mail (mail_operation,
2238 data->priority_flags);
2242 g_free (account_name);
2243 g_object_unref (G_OBJECT (transport_account));
2244 g_object_unref (G_OBJECT (mail_operation));
2246 modest_msg_edit_window_free_msg_data (edit_window, data);
2247 modest_msg_edit_window_set_sent (edit_window, TRUE);
2249 /* Save settings and close the window: */
2250 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2254 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2255 ModestMsgEditWindow *window)
2257 ModestMsgEditFormatState *format_state = NULL;
2259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2260 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2262 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2265 format_state = modest_msg_edit_window_get_format_state (window);
2266 g_return_if_fail (format_state != NULL);
2268 format_state->bold = gtk_toggle_action_get_active (action);
2269 modest_msg_edit_window_set_format_state (window, format_state);
2270 g_free (format_state);
2275 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2276 ModestMsgEditWindow *window)
2278 ModestMsgEditFormatState *format_state = NULL;
2280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2283 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2286 format_state = modest_msg_edit_window_get_format_state (window);
2287 g_return_if_fail (format_state != NULL);
2289 format_state->italics = gtk_toggle_action_get_active (action);
2290 modest_msg_edit_window_set_format_state (window, format_state);
2291 g_free (format_state);
2296 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2297 ModestMsgEditWindow *window)
2299 ModestMsgEditFormatState *format_state = NULL;
2301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2302 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2304 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2307 format_state = modest_msg_edit_window_get_format_state (window);
2308 g_return_if_fail (format_state != NULL);
2310 format_state->bullet = gtk_toggle_action_get_active (action);
2311 modest_msg_edit_window_set_format_state (window, format_state);
2312 g_free (format_state);
2317 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2318 GtkRadioAction *selected,
2319 ModestMsgEditWindow *window)
2321 ModestMsgEditFormatState *format_state = NULL;
2322 GtkJustification value;
2324 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2326 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2329 value = gtk_radio_action_get_current_value (selected);
2331 format_state = modest_msg_edit_window_get_format_state (window);
2332 g_return_if_fail (format_state != NULL);
2334 format_state->justification = value;
2335 modest_msg_edit_window_set_format_state (window, format_state);
2336 g_free (format_state);
2340 modest_ui_actions_on_select_editor_color (GtkAction *action,
2341 ModestMsgEditWindow *window)
2343 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2344 g_return_if_fail (GTK_IS_ACTION (action));
2346 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2349 modest_msg_edit_window_select_color (window);
2353 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2354 ModestMsgEditWindow *window)
2356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2357 g_return_if_fail (GTK_IS_ACTION (action));
2359 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2362 modest_msg_edit_window_select_background_color (window);
2366 modest_ui_actions_on_insert_image (GtkAction *action,
2367 ModestMsgEditWindow *window)
2369 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2370 g_return_if_fail (GTK_IS_ACTION (action));
2372 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2375 modest_msg_edit_window_insert_image (window);
2379 modest_ui_actions_on_attach_file (GtkAction *action,
2380 ModestMsgEditWindow *window)
2382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2383 g_return_if_fail (GTK_IS_ACTION (action));
2385 modest_msg_edit_window_offer_attach_file (window);
2389 modest_ui_actions_on_remove_attachments (GtkAction *action,
2390 ModestMsgEditWindow *window)
2392 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2393 g_return_if_fail (GTK_IS_ACTION (action));
2395 modest_msg_edit_window_remove_attachments (window, NULL);
2399 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2402 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2403 const GError *error = modest_mail_operation_get_error (mail_op);
2407 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2408 modest_mail_operation_get_error (mail_op)->message);
2413 modest_ui_actions_create_folder(GtkWidget *parent_window,
2414 GtkWidget *folder_view)
2416 TnyFolderStore *parent_folder;
2418 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2420 if (parent_folder) {
2421 gboolean finished = FALSE;
2423 gchar *folder_name = NULL, *suggested_name = NULL;
2424 const gchar *proto_str = NULL;
2425 TnyAccount *account;
2427 if (TNY_IS_ACCOUNT (parent_folder))
2428 account = g_object_ref (parent_folder);
2430 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2431 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2433 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2434 MODEST_PROTOCOL_STORE_POP) {
2436 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2438 g_object_unref (account);
2440 /* Run the new folder dialog */
2442 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2447 g_free (suggested_name);
2448 suggested_name = NULL;
2450 if (result == GTK_RESPONSE_REJECT) {
2453 ModestMailOperation *mail_op;
2454 TnyFolder *new_folder = NULL;
2456 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2457 G_OBJECT(parent_window),
2458 modest_ui_actions_new_folder_error_handler,
2461 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2463 new_folder = modest_mail_operation_create_folder (mail_op,
2465 (const gchar *) folder_name);
2467 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2470 g_object_unref (new_folder);
2473 g_object_unref (mail_op);
2476 suggested_name = folder_name;
2480 g_object_unref (parent_folder);
2485 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2487 GtkWidget *folder_view;
2489 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2491 folder_view = modest_main_window_get_child_widget (main_window,
2492 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2496 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2500 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2503 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2504 const GError *error = NULL;
2505 const gchar *message = NULL;
2507 /* Get error message */
2508 error = modest_mail_operation_get_error (mail_op);
2510 g_return_if_reached ();
2512 switch (error->code) {
2513 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2514 message = _CS("ckdg_ib_folder_already_exists");
2517 g_return_if_reached ();
2520 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2524 modest_ui_actions_on_rename_folder (GtkAction *action,
2525 ModestMainWindow *main_window)
2527 TnyFolderStore *folder;
2528 GtkWidget *folder_view;
2529 GtkWidget *header_view;
2531 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2533 folder_view = modest_main_window_get_child_widget (main_window,
2534 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2538 header_view = modest_main_window_get_child_widget (main_window,
2539 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2544 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2549 if (TNY_IS_FOLDER (folder)) {
2552 const gchar *current_name;
2553 TnyFolderStore *parent;
2554 gboolean do_rename = TRUE;
2556 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2557 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2558 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2559 parent, current_name,
2561 g_object_unref (parent);
2563 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2565 } else if (modest_platform_is_network_folderstore(folder) &&
2566 !tny_device_is_online (modest_runtime_get_device())) {
2567 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2568 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2569 g_object_unref(account);
2573 ModestMailOperation *mail_op;
2574 GtkTreeSelection *sel = NULL;
2577 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2578 G_OBJECT(main_window),
2579 modest_ui_actions_rename_folder_error_handler,
2582 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2585 /* Clear the headers view */
2586 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2587 gtk_tree_selection_unselect_all (sel);
2589 /* Select *after* the changes */
2590 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2591 TNY_FOLDER(folder), TRUE);
2593 /* Actually rename the folder */
2594 modest_mail_operation_rename_folder (mail_op,
2595 TNY_FOLDER (folder),
2596 (const gchar *) folder_name);
2598 g_object_unref (mail_op);
2599 g_free (folder_name);
2602 g_object_unref (folder);
2606 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2609 GObject *win = modest_mail_operation_get_source (mail_op);
2611 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2612 _("mail_in_ui_folder_delete_error"));
2613 g_object_unref (win);
2617 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2619 TnyFolderStore *folder;
2620 GtkWidget *folder_view;
2623 gboolean do_delete = TRUE;
2625 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2627 folder_view = modest_main_window_get_child_widget (main_window,
2628 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2632 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2634 /* Show an error if it's an account */
2635 if (!TNY_IS_FOLDER (folder)) {
2636 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2637 _("mail_in_ui_folder_delete_error"));
2638 g_object_unref (G_OBJECT (folder));
2643 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2644 tny_folder_get_name (TNY_FOLDER (folder)));
2645 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2646 (const gchar *) message);
2649 if (response != GTK_RESPONSE_OK) {
2651 } else if (modest_platform_is_network_folderstore(folder) &&
2652 !tny_device_is_online (modest_runtime_get_device())) {
2653 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2654 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2655 g_object_unref(account);
2659 ModestMailOperation *mail_op;
2660 GtkTreeSelection *sel;
2662 /* Unselect the folder before deleting it to free the headers */
2663 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2664 gtk_tree_selection_unselect_all (sel);
2666 /* Create the mail operation */
2668 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2669 G_OBJECT(main_window),
2670 modest_ui_actions_delete_folder_error_handler,
2673 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2675 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2676 g_object_unref (G_OBJECT (mail_op));
2679 g_object_unref (G_OBJECT (folder));
2683 modest_ui_actions_on_delete_folder (GtkAction *action,
2684 ModestMainWindow *main_window)
2686 GtkWidget *folder_view;
2687 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2689 delete_folder (main_window, FALSE);
2690 folder_view = modest_main_window_get_child_widget (main_window,
2691 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2694 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2698 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2700 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2702 delete_folder (main_window, TRUE);
2707 show_error (GtkWidget *parent_widget, const gchar* text)
2709 hildon_banner_show_information(parent_widget, NULL, text);
2712 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2714 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2721 gtk_dialog_run (dialog);
2722 gtk_widget_destroy (GTK_WIDGET (dialog));
2727 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2728 const gchar* server_account_name,
2733 ModestMainWindow *main_window)
2735 g_return_if_fail(server_account_name);
2736 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2738 /* Initalize output parameters: */
2745 #ifdef MODEST_PLATFORM_MAEMO
2746 /* Maemo uses a different (awkward) button order,
2747 * It should probably just use gtk_alternative_dialog_button_order ().
2749 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2752 _("mcen_bd_dialog_ok"),
2753 GTK_RESPONSE_ACCEPT,
2754 _("mcen_bd_dialog_cancel"),
2755 GTK_RESPONSE_REJECT,
2758 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2762 GTK_RESPONSE_REJECT,
2764 GTK_RESPONSE_ACCEPT,
2766 #endif /* MODEST_PLATFORM_MAEMO */
2768 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2770 gchar *server_name = modest_server_account_get_hostname (
2771 modest_runtime_get_account_mgr(), server_account_name);
2772 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2773 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2778 /* This causes a warning because the logical ID has no %s in it,
2779 * though the translation does, but there is not much we can do about that: */
2780 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2781 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2784 g_free (server_name);
2788 gchar *initial_username = modest_server_account_get_username (
2789 modest_runtime_get_account_mgr(), server_account_name);
2791 GtkWidget *entry_username = gtk_entry_new ();
2792 if (initial_username)
2793 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2794 /* Dim this if a connection has ever succeeded with this username,
2795 * as per the UI spec: */
2796 const gboolean username_known =
2797 modest_server_account_get_username_has_succeeded(
2798 modest_runtime_get_account_mgr(), server_account_name);
2799 gtk_widget_set_sensitive (entry_username, !username_known);
2801 #ifdef MODEST_PLATFORM_MAEMO
2802 /* Auto-capitalization is the default, so let's turn it off: */
2803 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2805 /* Create a size group to be used by all captions.
2806 * Note that HildonCaption does not create a default size group if we do not specify one.
2807 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2808 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2810 GtkWidget *caption = hildon_caption_new (sizegroup,
2811 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2812 gtk_widget_show (entry_username);
2813 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2814 FALSE, FALSE, MODEST_MARGIN_HALF);
2815 gtk_widget_show (caption);
2817 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2819 #endif /* MODEST_PLATFORM_MAEMO */
2822 GtkWidget *entry_password = gtk_entry_new ();
2823 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2824 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2826 #ifdef MODEST_PLATFORM_MAEMO
2827 /* Auto-capitalization is the default, so let's turn it off: */
2828 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2829 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2831 caption = hildon_caption_new (sizegroup,
2832 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2833 gtk_widget_show (entry_password);
2834 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2835 FALSE, FALSE, MODEST_MARGIN_HALF);
2836 gtk_widget_show (caption);
2837 g_object_unref (sizegroup);
2839 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2841 #endif /* MODEST_PLATFORM_MAEMO */
2843 /* This is not in the Maemo UI spec:
2844 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2845 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2849 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2851 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2853 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2855 modest_server_account_set_username (
2856 modest_runtime_get_account_mgr(), server_account_name,
2859 const gboolean username_was_changed =
2860 (strcmp (*username, initial_username) != 0);
2861 if (username_was_changed) {
2862 g_warning ("%s: tinymail does not yet support changing the "
2863 "username in the get_password() callback.\n", __FUNCTION__);
2868 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2870 /* We do not save the password in the configuration,
2871 * because this function is only called for passwords that should
2872 * not be remembered:
2873 modest_server_account_set_password (
2874 modest_runtime_get_account_mgr(), server_account_name,
2883 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2895 /* This is not in the Maemo UI spec:
2896 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2902 gtk_widget_destroy (dialog);
2904 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2908 modest_ui_actions_on_cut (GtkAction *action,
2909 ModestWindow *window)
2911 GtkWidget *focused_widget;
2912 GtkClipboard *clipboard;
2914 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2915 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2916 if (GTK_IS_EDITABLE (focused_widget)) {
2917 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2918 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2919 gtk_clipboard_store (clipboard);
2920 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2921 GtkTextBuffer *buffer;
2923 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2924 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2925 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2926 gtk_clipboard_store (clipboard);
2927 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2928 TnyList *header_list = modest_header_view_get_selected_headers (
2929 MODEST_HEADER_VIEW (focused_widget));
2930 gboolean continue_download = FALSE;
2931 gint num_of_unc_msgs;
2933 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2935 if (num_of_unc_msgs)
2936 continue_download = connect_to_get_msg(
2937 GTK_WINDOW (window),
2940 if (num_of_unc_msgs == 0 || continue_download) {
2941 /* modest_platform_information_banner (
2942 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2943 modest_header_view_cut_selection (
2944 MODEST_HEADER_VIEW (focused_widget));
2947 g_object_unref (header_list);
2948 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2949 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2954 modest_ui_actions_on_copy (GtkAction *action,
2955 ModestWindow *window)
2957 GtkClipboard *clipboard;
2958 GtkWidget *focused_widget;
2959 gboolean copied = TRUE;
2961 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2962 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2964 if (GTK_IS_LABEL (focused_widget)) {
2965 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2966 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2967 gtk_clipboard_store (clipboard);
2968 } else if (GTK_IS_EDITABLE (focused_widget)) {
2969 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2970 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2971 gtk_clipboard_store (clipboard);
2972 } else if (GTK_IS_HTML (focused_widget)) {
2973 gtk_html_copy (GTK_HTML (focused_widget));
2974 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2975 gtk_clipboard_store (clipboard);
2976 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2977 GtkTextBuffer *buffer;
2978 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2979 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2980 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2981 gtk_clipboard_store (clipboard);
2982 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2983 TnyList *header_list = modest_header_view_get_selected_headers (
2984 MODEST_HEADER_VIEW (focused_widget));
2985 gboolean continue_download = FALSE;
2986 gint num_of_unc_msgs;
2988 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2990 if (num_of_unc_msgs)
2991 continue_download = connect_to_get_msg(
2992 GTK_WINDOW (window),
2995 if (num_of_unc_msgs == 0 || continue_download) {
2996 modest_platform_information_banner (
2997 NULL, NULL, _CS("mcen_ib_getting_items"));
2998 modest_header_view_copy_selection (
2999 MODEST_HEADER_VIEW (focused_widget));
3003 g_object_unref (header_list);
3005 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3006 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3009 /* Show information banner if there was a copy to clipboard */
3011 modest_platform_information_banner (
3012 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3016 modest_ui_actions_on_undo (GtkAction *action,
3017 ModestWindow *window)
3019 ModestEmailClipboard *clipboard = NULL;
3021 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3022 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3023 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3024 /* Clear clipboard source */
3025 clipboard = modest_runtime_get_email_clipboard ();
3026 modest_email_clipboard_clear (clipboard);
3029 g_return_if_reached ();
3034 modest_ui_actions_on_redo (GtkAction *action,
3035 ModestWindow *window)
3037 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3038 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3041 g_return_if_reached ();
3047 paste_msgs_cb (const GObject *object, gpointer user_data)
3049 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
3050 g_return_if_fail (GTK_IS_WIDGET (user_data));
3052 /* destroy information note */
3053 gtk_widget_destroy (GTK_WIDGET(user_data));
3058 paste_as_attachment_free (gpointer data)
3060 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3062 gtk_widget_destroy (helper->banner);
3063 g_object_unref (helper->banner);
3068 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3073 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3079 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3084 modest_ui_actions_on_paste (GtkAction *action,
3085 ModestWindow *window)
3087 GtkWidget *focused_widget = NULL;
3088 GtkWidget *inf_note = NULL;
3089 ModestMailOperation *mail_op = NULL;
3091 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3092 if (GTK_IS_EDITABLE (focused_widget)) {
3093 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3094 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3095 ModestEmailClipboard *e_clipboard = NULL;
3096 e_clipboard = modest_runtime_get_email_clipboard ();
3097 if (modest_email_clipboard_cleared (e_clipboard)) {
3098 GtkTextBuffer *buffer;
3099 GtkClipboard *clipboard;
3101 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3102 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3103 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3104 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3105 ModestMailOperation *mail_op;
3106 TnyFolder *src_folder;
3109 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3110 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3111 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3112 _CS("ckct_nw_pasting"));
3113 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3114 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3116 if (helper->banner != NULL) {
3117 g_object_ref (G_OBJECT (helper->banner));
3118 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3119 gtk_widget_show (GTK_WIDGET (helper->banner));
3123 modest_mail_operation_get_msgs_full (mail_op,
3125 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3127 paste_as_attachment_free);
3130 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3131 ModestEmailClipboard *clipboard = NULL;
3132 TnyFolder *src_folder = NULL;
3133 TnyFolderStore *folder_store = NULL;
3134 TnyList *data = NULL;
3135 gboolean delete = FALSE;
3137 /* Check clipboard source */
3138 clipboard = modest_runtime_get_email_clipboard ();
3139 if (modest_email_clipboard_cleared (clipboard))
3142 /* Get elements to paste */
3143 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3145 /* Create a new mail operation */
3146 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3148 /* Get destination folder */
3149 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3151 /* transfer messages */
3155 /* Ask for user confirmation */
3156 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3157 TNY_FOLDER (folder_store),
3161 if (response == GTK_RESPONSE_OK) {
3162 /* Launch notification */
3163 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3164 _CS("ckct_nw_pasting"));
3165 if (inf_note != NULL) {
3166 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3167 gtk_widget_show (GTK_WIDGET(inf_note));
3170 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3171 modest_mail_operation_xfer_msgs (mail_op,
3173 TNY_FOLDER (folder_store),
3178 g_object_unref (mail_op);
3181 } else if (src_folder != NULL) {
3182 /* Launch notification */
3183 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3184 _CS("ckct_nw_pasting"));
3185 if (inf_note != NULL) {
3186 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3187 gtk_widget_show (GTK_WIDGET(inf_note));
3190 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3191 modest_mail_operation_xfer_folder (mail_op,
3201 g_object_unref (data);
3202 if (src_folder != NULL)
3203 g_object_unref (src_folder);
3204 if (folder_store != NULL)
3205 g_object_unref (folder_store);
3211 modest_ui_actions_on_select_all (GtkAction *action,
3212 ModestWindow *window)
3214 GtkWidget *focused_widget;
3216 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3217 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3218 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3219 } else if (GTK_IS_LABEL (focused_widget)) {
3220 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3221 } else if (GTK_IS_EDITABLE (focused_widget)) {
3222 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3223 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3224 GtkTextBuffer *buffer;
3225 GtkTextIter start, end;
3227 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3228 gtk_text_buffer_get_start_iter (buffer, &start);
3229 gtk_text_buffer_get_end_iter (buffer, &end);
3230 gtk_text_buffer_select_range (buffer, &start, &end);
3231 } else if (GTK_IS_HTML (focused_widget)) {
3232 gtk_html_select_all (GTK_HTML (focused_widget));
3233 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3234 GtkWidget *header_view = focused_widget;
3235 GtkTreeSelection *selection = NULL;
3237 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3238 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3239 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3242 /* Disable window dimming management */
3243 modest_window_disable_dimming (MODEST_WINDOW(window));
3245 /* Select all messages */
3246 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3247 gtk_tree_selection_select_all (selection);
3249 /* Set focuse on header view */
3250 gtk_widget_grab_focus (header_view);
3253 /* Enable window dimming management */
3254 modest_window_enable_dimming (MODEST_WINDOW(window));
3255 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3261 modest_ui_actions_on_mark_as_read (GtkAction *action,
3262 ModestWindow *window)
3264 g_return_if_fail (MODEST_IS_WINDOW(window));
3266 /* Mark each header as read */
3267 do_headers_action (window, headers_action_mark_as_read, NULL);
3271 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3272 ModestWindow *window)
3274 g_return_if_fail (MODEST_IS_WINDOW(window));
3276 /* Mark each header as read */
3277 do_headers_action (window, headers_action_mark_as_unread, NULL);
3281 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3282 GtkRadioAction *selected,
3283 ModestWindow *window)
3287 value = gtk_radio_action_get_current_value (selected);
3288 if (MODEST_IS_WINDOW (window)) {
3289 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3294 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3295 GtkRadioAction *selected,
3296 ModestWindow *window)
3298 TnyHeaderFlags flags;
3299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3301 flags = gtk_radio_action_get_current_value (selected);
3302 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3306 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3307 GtkRadioAction *selected,
3308 ModestWindow *window)
3312 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3314 file_format = gtk_radio_action_get_current_value (selected);
3315 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3320 modest_ui_actions_on_zoom_plus (GtkAction *action,
3321 ModestWindow *window)
3323 g_return_if_fail (MODEST_IS_WINDOW (window));
3325 modest_window_zoom_plus (MODEST_WINDOW (window));
3329 modest_ui_actions_on_zoom_minus (GtkAction *action,
3330 ModestWindow *window)
3332 g_return_if_fail (MODEST_IS_WINDOW (window));
3334 modest_window_zoom_minus (MODEST_WINDOW (window));
3338 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3339 ModestWindow *window)
3341 ModestWindowMgr *mgr;
3342 gboolean fullscreen, active;
3343 g_return_if_fail (MODEST_IS_WINDOW (window));
3345 mgr = modest_runtime_get_window_mgr ();
3347 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3348 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3350 if (active != fullscreen) {
3351 modest_window_mgr_set_fullscreen_mode (mgr, active);
3352 gtk_window_present (GTK_WINDOW (window));
3357 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3358 ModestWindow *window)
3360 ModestWindowMgr *mgr;
3361 gboolean fullscreen;
3363 g_return_if_fail (MODEST_IS_WINDOW (window));
3365 mgr = modest_runtime_get_window_mgr ();
3366 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3367 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3369 gtk_window_present (GTK_WINDOW (window));
3373 * Used by modest_ui_actions_on_details to call do_headers_action
3376 headers_action_show_details (TnyHeader *header,
3377 ModestWindow *window,
3384 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3387 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3388 gtk_widget_show_all (dialog);
3389 gtk_dialog_run (GTK_DIALOG (dialog));
3391 gtk_widget_destroy (dialog);
3395 * Show the folder details in a ModestDetailsDialog widget
3398 show_folder_details (TnyFolder *folder,
3404 dialog = modest_details_dialog_new_with_folder (window, folder);
3407 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3408 gtk_widget_show_all (dialog);
3409 gtk_dialog_run (GTK_DIALOG (dialog));
3411 gtk_widget_destroy (dialog);
3415 * Show the header details in a ModestDetailsDialog widget
3418 modest_ui_actions_on_details (GtkAction *action,
3421 TnyList * headers_list;
3425 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3428 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3431 g_object_unref (msg);
3433 headers_list = get_selected_headers (win);
3437 iter = tny_list_create_iterator (headers_list);
3439 header = TNY_HEADER (tny_iterator_get_current (iter));
3441 headers_action_show_details (header, win, NULL);
3442 g_object_unref (header);
3445 g_object_unref (iter);
3446 g_object_unref (headers_list);
3448 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3449 GtkWidget *folder_view, *header_view;
3451 /* Check which widget has the focus */
3452 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3453 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3454 if (gtk_widget_is_focus (folder_view)) {
3455 TnyFolderStore *folder_store
3456 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3457 if (!folder_store) {
3458 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3461 /* Show only when it's a folder */
3462 /* This function should not be called for account items,
3463 * because we dim the menu item for them. */
3464 if (TNY_IS_FOLDER (folder_store)) {
3465 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3468 g_object_unref (folder_store);
3471 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3472 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3473 /* Show details of each header */
3474 do_headers_action (win, headers_action_show_details, header_view);
3480 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3481 ModestMsgEditWindow *window)
3483 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3485 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3489 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3490 ModestMsgEditWindow *window)
3492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3494 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3498 modest_ui_actions_toggle_folders_view (GtkAction *action,
3499 ModestMainWindow *main_window)
3501 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3503 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3504 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3506 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3510 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3511 ModestWindow *window)
3513 gboolean active, fullscreen = FALSE;
3514 ModestWindowMgr *mgr;
3516 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3518 /* Check if we want to toggle the toolbar vuew in fullscreen
3520 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3521 "ViewShowToolbarFullScreen")) {
3525 /* Toggle toolbar */
3526 mgr = modest_runtime_get_window_mgr ();
3527 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3531 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3532 ModestMsgEditWindow *window)
3534 modest_msg_edit_window_select_font (window);
3538 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3539 const gchar *display_name,
3542 /* Do not change the application name if the widget has not
3543 the focus. This callback could be called even if the folder
3544 view has not the focus, because the handled signal could be
3545 emitted when the folder view is redrawn */
3546 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3548 gtk_window_set_title (window, display_name);
3550 gtk_window_set_title (window, " ");
3555 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3557 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3558 modest_msg_edit_window_select_contacts (window);
3562 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3564 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3565 modest_msg_edit_window_check_names (window, FALSE);
3569 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3571 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3572 GTK_WIDGET (user_data));
3576 * This function is used to track changes in the selection of the
3577 * folder view that is inside the "move to" dialog to enable/disable
3578 * the OK button because we do not want the user to select a disallowed
3579 * destination for a folder.
3580 * The user also not desired to be able to use NEW button on items where
3581 * folder creation is not possibel.
3584 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3585 TnyFolderStore *folder_store,
3589 GtkWidget *dialog = NULL;
3590 GtkWidget *ok_button = NULL, *new_button = NULL;
3591 GList *children = NULL;
3592 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3593 gboolean moving_folder = FALSE;
3594 gboolean is_local_account = TRUE;
3595 GtkWidget *folder_view = NULL;
3596 ModestTnyFolderRules rules;
3601 /* Get the OK button */
3602 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3606 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3607 ok_button = GTK_WIDGET (children->next->next->data);
3608 new_button = GTK_WIDGET (children->next->data);
3609 g_list_free (children);
3611 /* check if folder_store is an remote account */
3612 if (TNY_IS_ACCOUNT (folder_store)) {
3613 TnyAccount *local_account = NULL;
3614 ModestTnyAccountStore *account_store = NULL;
3616 account_store = modest_runtime_get_account_store ();
3617 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3619 if ((gpointer) local_account != (gpointer) folder_store) {
3620 is_local_account = FALSE;
3621 /* New button should be dimmed on remote
3623 new_sensitive = FALSE;
3625 g_object_unref (local_account);
3628 /* Check the target folder rules */
3629 if (TNY_IS_FOLDER (folder_store)) {
3630 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3631 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3632 ok_sensitive = FALSE;
3633 new_sensitive = FALSE;
3638 /* Check if we're moving a folder */
3639 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3640 /* Get the widgets */
3641 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3642 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3643 if (gtk_widget_is_focus (folder_view))
3644 moving_folder = TRUE;
3647 if (moving_folder) {
3648 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3650 /* Get the folder to move */
3651 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3653 /* Check that we're not moving to the same folder */
3654 if (TNY_IS_FOLDER (moved_folder)) {
3655 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3656 if (parent == folder_store)
3657 ok_sensitive = FALSE;
3658 g_object_unref (parent);
3661 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3662 /* Do not allow to move to an account unless it's the
3663 local folders account */
3664 if (!is_local_account)
3665 ok_sensitive = FALSE;
3668 if (ok_sensitive && (moved_folder == folder_store)) {
3669 /* Do not allow to move to itself */
3670 ok_sensitive = FALSE;
3672 g_object_unref (moved_folder);
3674 TnyHeader *header = NULL;
3675 TnyFolder *src_folder = NULL;
3677 /* Moving a message */
3678 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3679 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3680 src_folder = tny_header_get_folder (header);
3681 g_object_unref (header);
3684 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3687 /* Do not allow to move the msg to the same folder */
3688 /* Do not allow to move the msg to an account */
3689 if ((gpointer) src_folder == (gpointer) folder_store ||
3690 TNY_IS_ACCOUNT (folder_store))
3691 ok_sensitive = FALSE;
3692 g_object_unref (src_folder);
3696 /* Set sensitivity of the OK button */
3697 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3698 /* Set sensitivity of the NEW button */
3699 gtk_widget_set_sensitive (new_button, new_sensitive);
3703 create_move_to_dialog (GtkWindow *win,
3704 GtkWidget *folder_view,
3705 GtkWidget **tree_view)
3707 GtkWidget *dialog, *scroll;
3708 GtkWidget *new_button;
3710 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3712 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3715 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3716 /* We do this manually so GTK+ does not associate a response ID for
3718 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3719 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3720 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3722 /* Create scrolled window */
3723 scroll = gtk_scrolled_window_new (NULL, NULL);
3724 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3725 GTK_POLICY_AUTOMATIC,
3726 GTK_POLICY_AUTOMATIC);
3728 /* Create folder view */
3729 *tree_view = modest_platform_create_folder_view (NULL);
3731 /* Track changes in the selection to
3732 * disable the OK button whenever "Move to" is not possible
3733 * disbale NEW button whenever New is not possible */
3734 g_signal_connect (*tree_view,
3735 "folder_selection_changed",
3736 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3739 /* Listen to clicks on New button */
3740 g_signal_connect (G_OBJECT (new_button),
3742 G_CALLBACK(create_move_to_dialog_on_new_folder),
3745 /* It could happen that we're trying to move a message from a
3746 window (msg window for example) after the main window was
3747 closed, so we can not just get the model of the folder
3749 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3750 const gchar *visible_id = NULL;
3752 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3753 MODEST_FOLDER_VIEW(*tree_view));
3756 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3758 /* Show the same account than the one that is shown in the main window */
3759 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3762 const gchar *active_account_name = NULL;
3763 ModestAccountMgr *mgr = NULL;
3764 ModestAccountData *acc_data = NULL;
3766 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3767 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3769 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3770 mgr = modest_runtime_get_account_mgr ();
3771 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3773 /* Set the new visible & active account */
3774 if (acc_data && acc_data->store_account) {
3775 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3776 acc_data->store_account->account_name);
3777 modest_account_mgr_free_account_data (mgr, acc_data);
3781 /* Hide special folders */
3782 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3784 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3786 /* Add scroll to dialog */
3787 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3788 scroll, TRUE, TRUE, 0);
3790 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3791 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3797 * Returns TRUE if at least one of the headers of the list belongs to
3798 * a message that has been fully retrieved.
3800 #if 0 /* no longer in use. delete in 2007.10 */
3802 has_retrieved_msgs (TnyList *list)
3805 gboolean found = FALSE;
3807 iter = tny_list_create_iterator (list);
3808 while (!tny_iterator_is_done (iter) && !found) {
3810 TnyHeaderFlags flags = 0;
3812 header = TNY_HEADER (tny_iterator_get_current (iter));
3814 flags = tny_header_get_flags (header);
3815 if (flags & TNY_HEADER_FLAG_CACHED)
3816 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3819 g_object_unref (header);
3823 tny_iterator_next (iter);
3825 g_object_unref (iter);
3833 * Shows a confirmation dialog to the user when we're moving messages
3834 * from a remote server to the local storage. Returns the dialog
3835 * response. If it's other kind of movement then it always returns
3838 * This one is used by the next functions:
3839 * modest_ui_actions_on_paste - commented out
3840 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3843 msgs_move_to_confirmation (GtkWindow *win,
3844 TnyFolder *dest_folder,
3848 gint response = GTK_RESPONSE_OK;
3850 /* return with OK if the destination is a remote folder */
3851 if (modest_tny_folder_is_remote_folder (dest_folder))
3852 return GTK_RESPONSE_OK;
3854 TnyFolder *src_folder = NULL;
3855 TnyIterator *iter = NULL;
3856 TnyHeader *header = NULL;
3858 /* Get source folder */
3859 iter = tny_list_create_iterator (headers);
3860 header = TNY_HEADER (tny_iterator_get_current (iter));
3862 src_folder = tny_header_get_folder (header);
3863 g_object_unref (header);
3865 g_object_unref (iter);
3867 /* if no src_folder, message may be an attahcment */
3868 if (src_folder == NULL)
3869 return GTK_RESPONSE_CANCEL;
3871 /* If the source is a local or MMC folder */
3872 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3873 g_object_unref (src_folder);
3874 return GTK_RESPONSE_OK;
3876 g_object_unref (src_folder);
3878 /* now if offline we ask the user */
3879 if(connect_to_get_msg( GTK_WINDOW (win),
3880 tny_list_get_length (headers)))
3881 response = GTK_RESPONSE_OK;
3883 response = GTK_RESPONSE_CANCEL;
3891 move_to_cb (const GObject *object, gpointer user_data)
3893 ModestMsgViewWindow *self = NULL;
3894 g_return_if_fail (GTK_IS_WIDGET (user_data));
3895 g_return_if_fail (MODEST_IS_WINDOW (object));
3897 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3898 self = MODEST_MSG_VIEW_WINDOW (object);
3900 if (!modest_msg_view_window_select_next_message (self))
3901 if (!modest_msg_view_window_select_previous_message (self))
3902 /* No more messages to view, so close this window */
3903 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3905 gtk_widget_destroy (GTK_WIDGET(user_data));
3909 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3912 ModestMainWindow *main_window = NULL;
3913 GtkWidget *folder_view = NULL;
3914 GObject *win = modest_mail_operation_get_source (mail_op);
3915 const GError *error = NULL;
3916 const gchar *message = NULL;
3918 /* Get error message */
3919 error = modest_mail_operation_get_error (mail_op);
3920 if (error != NULL && error->message != NULL) {
3921 message = error->message;
3923 message = _("mail_in_ui_folder_move_target_error");
3926 /* Disable next automatic folder selection */
3927 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3928 main_window = MODEST_MAIN_WINDOW(user_data);
3929 folder_view = modest_main_window_get_child_widget (main_window,
3930 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3931 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3934 /* Show notification dialog */
3935 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3936 g_object_unref (win);
3940 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3943 GObject *win = modest_mail_operation_get_source (mail_op);
3944 const GError *error = modest_mail_operation_get_error (mail_op);
3946 g_return_if_fail (error != NULL);
3947 if (error->message != NULL)
3948 g_printerr ("modest: %s\n", error->message);
3950 g_printerr ("modest: unkonw error on send&receive operation");
3952 /* Show error message */
3953 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3954 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3955 /* _CS("sfil_ib_unable_to_receive")); */
3957 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3958 /* _CS("sfil_ib_unable_to_send")); */
3959 g_object_unref (win);
3963 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3970 gint pending_purges = 0;
3971 gboolean some_purged = FALSE;
3972 ModestWindow *win = MODEST_WINDOW (user_data);
3973 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3975 /* If there was any error */
3976 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3977 modest_window_mgr_unregister_header (mgr, header);
3981 /* Once the message has been retrieved for purging, we check if
3982 * it's all ok for purging */
3984 parts = tny_simple_list_new ();
3985 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3986 iter = tny_list_create_iterator (parts);
3988 while (!tny_iterator_is_done (iter)) {
3990 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3991 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3992 if (tny_mime_part_is_purged (part))
3999 g_object_unref (part);
4001 tny_iterator_next (iter);
4004 if (pending_purges>0) {
4006 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4008 if (response == GTK_RESPONSE_OK) {
4009 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4010 tny_iterator_first (iter);
4011 while (!tny_iterator_is_done (iter)) {
4014 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4015 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4016 tny_mime_part_set_purged (part);
4019 g_object_unref (part);
4021 tny_iterator_next (iter);
4024 tny_msg_rewrite_cache (msg);
4027 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4030 /* remove attachments */
4031 tny_iterator_first (iter);
4032 while (!tny_iterator_is_done (iter)) {
4035 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4037 /* One for the reference given by tny_iterator_get_current(): */
4038 g_object_unref (part);
4040 /* TODO: Is this meant to remove the attachment by doing another unref()?
4041 * Otherwise, this seems useless. */
4044 tny_iterator_next (iter);
4046 modest_window_mgr_unregister_header (mgr, header);
4048 g_object_unref (iter);
4049 g_object_unref (parts);
4053 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4054 ModestMainWindow *win)
4056 GtkWidget *header_view;
4057 TnyList *header_list;
4060 TnyHeaderFlags flags;
4061 ModestWindow *msg_view_window = NULL;
4064 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4066 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4067 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4069 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4071 if (tny_list_get_length (header_list) == 1) {
4072 iter = tny_list_create_iterator (header_list);
4073 header = TNY_HEADER (tny_iterator_get_current (iter));
4074 g_object_unref (iter);
4079 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4080 header, &msg_view_window);
4081 flags = tny_header_get_flags (header);
4082 if (!(flags & TNY_HEADER_FLAG_CACHED))
4085 if (msg_view_window != NULL)
4086 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4088 /* do nothing; uid was registered before, so window is probably on it's way */
4089 g_warning ("debug: header %p has already been registered", header);
4092 ModestMailOperation *mail_op = NULL;
4093 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4094 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4096 modest_ui_actions_get_msgs_full_error_handler,
4098 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4099 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4101 g_object_unref (mail_op);
4104 g_object_unref (header);
4106 g_object_unref (header_list);
4110 * Utility function that transfer messages from both the main window
4111 * and the msg view window when using the "Move to" dialog
4114 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4117 TnyList *headers = NULL;
4118 TnyAccount *dst_account = NULL;
4119 const gchar *proto_str = NULL;
4120 gboolean dst_is_pop = FALSE;
4122 if (!TNY_IS_FOLDER (dst_folder)) {
4123 modest_platform_information_banner (GTK_WIDGET (win),
4125 _CS("ckdg_ib_unable_to_move_to_current_location"));
4129 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4130 proto_str = tny_account_get_proto (dst_account);
4132 /* tinymail will return NULL for local folders it seems */
4133 dst_is_pop = proto_str &&
4134 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4135 MODEST_PROTOCOL_STORE_POP);
4137 g_object_unref (dst_account);
4139 /* Get selected headers */
4140 headers = get_selected_headers (MODEST_WINDOW (win));
4143 modest_platform_information_banner (GTK_WIDGET (win),
4145 ngettext("mail_in_ui_folder_move_target_error",
4146 "mail_in_ui_folder_move_targets_error",
4147 tny_list_get_length (headers)));
4148 g_object_unref (headers);
4152 GtkWidget *inf_note;
4153 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4154 _CS("ckct_nw_pasting"));
4155 if (inf_note != NULL) {
4156 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4157 gtk_widget_show (GTK_WIDGET(inf_note));
4160 ModestMailOperation *mail_op =
4161 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4163 modest_ui_actions_move_folder_error_handler,
4165 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4168 modest_mail_operation_xfer_msgs (mail_op,
4170 TNY_FOLDER (dst_folder),
4175 g_object_unref (G_OBJECT (mail_op));
4176 g_object_unref (headers);
4180 * UI handler for the "Move to" action when invoked from the
4184 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4185 GtkWidget *folder_view,
4186 TnyFolderStore *dst_folder,
4187 ModestMainWindow *win)
4189 ModestHeaderView *header_view = NULL;
4190 ModestMailOperation *mail_op = NULL;
4191 TnyFolderStore *src_folder;
4192 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4194 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4196 /* Get the source folder */
4197 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4199 /* Get header view */
4200 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4202 /* Get folder or messages to transfer */
4203 if (gtk_widget_is_focus (folder_view)) {
4204 GtkTreeSelection *sel;
4205 gboolean do_xfer = TRUE;
4207 /* Allow only to transfer folders to the local root folder */
4208 if (TNY_IS_ACCOUNT (dst_folder) &&
4209 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4211 } else if (!TNY_IS_FOLDER (src_folder)) {
4212 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4214 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4215 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4216 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4222 GtkWidget *inf_note;
4223 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4224 _CS("ckct_nw_pasting"));
4225 if (inf_note != NULL) {
4226 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4227 gtk_widget_show (GTK_WIDGET(inf_note));
4229 /* Clean folder on header view before moving it */
4230 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4231 gtk_tree_selection_unselect_all (sel);
4234 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4236 modest_ui_actions_move_folder_error_handler,
4238 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4241 /* Select *after* the changes */
4242 /* TODO: this function hangs UI after transfer */
4243 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4244 /* TNY_FOLDER (src_folder), TRUE); */
4246 modest_mail_operation_xfer_folder (mail_op,
4247 TNY_FOLDER (src_folder),
4249 TRUE, move_to_cb, inf_note);
4250 /* Unref mail operation */
4251 g_object_unref (G_OBJECT (mail_op));
4253 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4254 gboolean do_xfer = TRUE;
4255 /* Ask for confirmation if the source folder is remote and we're not connected */
4256 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4257 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4258 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4259 guint num_headers = tny_list_get_length(headers);
4260 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4264 g_object_unref(headers);
4266 if (do_xfer) /* Transfer messages */
4267 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4271 g_object_unref (src_folder);
4276 * UI handler for the "Move to" action when invoked from the
4277 * ModestMsgViewWindow
4280 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4281 TnyFolderStore *dst_folder,
4282 ModestMsgViewWindow *win)
4284 TnyHeader *header = NULL;
4285 TnyFolderStore *src_folder;
4287 /* Create header list */
4288 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4289 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4290 g_object_unref (header);
4292 /* Transfer the message if online or confirmed by the user */
4293 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4294 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4295 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4298 g_object_unref (src_folder);
4302 modest_ui_actions_on_move_to (GtkAction *action,
4305 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4307 TnyFolderStore *dst_folder = NULL;
4308 ModestMainWindow *main_window;
4310 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4311 MODEST_IS_MSG_VIEW_WINDOW (win));
4313 /* Get the main window if exists */
4314 if (MODEST_IS_MAIN_WINDOW (win))
4315 main_window = MODEST_MAIN_WINDOW (win);
4318 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4320 /* Get the folder view widget if exists */
4322 folder_view = modest_main_window_get_child_widget (main_window,
4323 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4327 /* Create and run the dialog */
4328 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4329 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4330 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4331 result = gtk_dialog_run (GTK_DIALOG(dialog));
4332 g_object_ref (tree_view);
4333 gtk_widget_destroy (dialog);
4335 if (result != GTK_RESPONSE_ACCEPT)
4338 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4339 /* Do window specific stuff */
4340 if (MODEST_IS_MAIN_WINDOW (win)) {
4341 modest_ui_actions_on_main_window_move_to (action,
4344 MODEST_MAIN_WINDOW (win));
4346 modest_ui_actions_on_msg_view_window_move_to (action,
4348 MODEST_MSG_VIEW_WINDOW (win));
4352 g_object_unref (dst_folder);
4356 * Calls #HeadersFunc for each header already selected in the main
4357 * window or the message currently being shown in the msg view window
4360 do_headers_action (ModestWindow *win,
4364 TnyList *headers_list = NULL;
4365 TnyIterator *iter = NULL;
4366 TnyHeader *header = NULL;
4367 TnyFolder *folder = NULL;
4370 headers_list = get_selected_headers (win);
4374 /* Get the folder */
4375 iter = tny_list_create_iterator (headers_list);
4376 header = TNY_HEADER (tny_iterator_get_current (iter));
4378 folder = tny_header_get_folder (header);
4379 g_object_unref (header);
4382 /* Call the function for each header */
4383 while (!tny_iterator_is_done (iter)) {
4384 header = TNY_HEADER (tny_iterator_get_current (iter));
4385 func (header, win, user_data);
4386 g_object_unref (header);
4387 tny_iterator_next (iter);
4390 /* Trick: do a poke status in order to speed up the signaling
4392 tny_folder_poke_status (folder);
4395 g_object_unref (folder);
4396 g_object_unref (iter);
4397 g_object_unref (headers_list);
4401 modest_ui_actions_view_attachment (GtkAction *action,
4402 ModestWindow *window)
4404 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4405 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4407 /* not supported window for this action */
4408 g_return_if_reached ();
4413 modest_ui_actions_save_attachments (GtkAction *action,
4414 ModestWindow *window)
4416 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4417 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4419 /* not supported window for this action */
4420 g_return_if_reached ();
4425 modest_ui_actions_remove_attachments (GtkAction *action,
4426 ModestWindow *window)
4428 if (MODEST_IS_MAIN_WINDOW (window)) {
4429 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4430 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4431 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4433 /* not supported window for this action */
4434 g_return_if_reached ();
4439 modest_ui_actions_on_settings (GtkAction *action,
4444 dialog = modest_platform_get_global_settings_dialog ();
4445 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4446 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4447 gtk_widget_show_all (dialog);
4449 gtk_dialog_run (GTK_DIALOG (dialog));
4451 gtk_widget_destroy (dialog);
4455 modest_ui_actions_on_help (GtkAction *action,
4458 const gchar *help_id = NULL;
4460 if (MODEST_IS_MAIN_WINDOW (win)) {
4461 GtkWidget *folder_view;
4462 TnyFolderStore *folder_store;
4464 /* Get selected folder */
4465 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4466 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4467 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4469 /* Switch help_id */
4470 if (TNY_IS_FOLDER (folder_store)) {
4471 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4472 case TNY_FOLDER_TYPE_NORMAL:
4473 help_id = "applications_email_managefolders";
4475 case TNY_FOLDER_TYPE_INBOX:
4476 help_id = "applications_email_inbox";
4478 case TNY_FOLDER_TYPE_OUTBOX:
4479 help_id = "applications_email_outbox";
4481 case TNY_FOLDER_TYPE_SENT:
4482 help_id = "applications_email_sent";
4484 case TNY_FOLDER_TYPE_DRAFTS:
4485 help_id = "applications_email_drafts";
4487 case TNY_FOLDER_TYPE_ARCHIVE:
4488 help_id = "applications_email_managefolders";
4491 help_id = "applications_email_managefolders";
4494 help_id = "applications_email_mainview";
4496 g_object_unref (folder_store);
4497 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4498 help_id = "applications_email_viewer";
4499 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4500 help_id = "applications_email_editor";
4502 modest_platform_show_help (GTK_WINDOW (win), help_id);
4506 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4507 ModestWindow *window)
4509 ModestMailOperation *mail_op;
4513 headers = get_selected_headers (window);
4517 /* Create mail operation */
4518 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4520 modest_ui_actions_get_msgs_full_error_handler,
4522 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4523 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4526 g_object_unref (headers);
4527 g_object_unref (mail_op);
4531 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4532 ModestWindow *window)
4534 g_return_if_fail (MODEST_IS_WINDOW (window));
4537 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4541 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4542 ModestWindow *window)
4544 g_return_if_fail (MODEST_IS_WINDOW (window));
4547 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4551 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4552 ModestWindow *window)
4554 g_return_if_fail (MODEST_IS_WINDOW (window));
4557 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4561 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4562 ModestWindow *window)
4564 g_return_if_fail (MODEST_IS_WINDOW (window));
4567 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4571 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4572 ModestWindow *window)
4574 g_return_if_fail (MODEST_IS_WINDOW (window));
4577 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4581 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4582 ModestWindow *window)
4584 g_return_if_fail (MODEST_IS_WINDOW (window));
4587 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4591 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4592 ModestWindow *window)
4594 g_return_if_fail (MODEST_IS_WINDOW (window));
4597 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4601 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4602 ModestWindow *window)
4604 g_return_if_fail (MODEST_IS_WINDOW (window));
4607 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4611 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4612 ModestWindow *window)
4614 g_return_if_fail (MODEST_IS_WINDOW (window));
4617 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4621 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4623 g_return_if_fail (MODEST_IS_WINDOW (window));
4626 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4630 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4632 g_return_if_fail (MODEST_IS_WINDOW (window));
4634 modest_platform_show_search_messages (GTK_WINDOW (window));
4638 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4640 g_return_if_fail (MODEST_IS_WINDOW (win));
4641 modest_platform_show_addressbook (GTK_WINDOW (win));
4646 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4647 ModestWindow *window)
4649 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4651 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4655 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4656 ModestMailOperationState *state,
4659 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4661 /* Set send/receive operation finished */
4662 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4663 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4669 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4675 const gchar* server_name = NULL;
4676 TnyTransportAccount *server_account;
4677 gchar *message = NULL;
4679 /* Don't show anything if the user cancelled something */
4680 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4683 /* Get the server name: */
4685 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4686 if (server_account) {
4687 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4689 g_object_unref (server_account);
4690 server_account = NULL;
4693 g_return_if_fail (server_name);
4695 /* Show the appropriate message text for the GError: */
4696 switch (err->code) {
4697 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4698 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4700 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4701 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4703 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4704 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4706 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4707 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4710 g_return_if_reached ();
4713 /* TODO if the username or the password where not defined we
4714 should show the Accounts Settings dialog or the Connection
4715 specific SMTP server window */
4717 modest_platform_run_information_dialog (NULL, message);
4722 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4727 ModestMainWindow *main_window = NULL;
4728 ModestWindowMgr *mgr = NULL;
4729 GtkWidget *folder_view = NULL, *header_view = NULL;
4730 TnyFolderStore *selected_folder = NULL;
4731 TnyFolderType folder_type;
4733 mgr = modest_runtime_get_window_mgr ();
4734 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4739 /* Check if selected folder is OUTBOX */
4740 folder_view = modest_main_window_get_child_widget (main_window,
4741 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4742 header_view = modest_main_window_get_child_widget (main_window,
4743 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4745 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4746 if (!TNY_IS_FOLDER (selected_folder))
4749 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4750 #if GTK_CHECK_VERSION(2, 8, 0)
4751 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4752 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4753 GtkTreeViewColumn *tree_column;
4755 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4756 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4757 gtk_tree_view_column_queue_resize (tree_column);
4760 gtk_widget_queue_draw (header_view);
4765 if (selected_folder != NULL)
4766 g_object_unref (selected_folder);