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));
388 /** After deleing a message that is currently visible in a window,
389 * show the next message from the list, or close the window if there are no more messages.
392 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
394 /* Close msg view window or select next */
395 if (modest_msg_view_window_last_message_selected (win) &&
396 modest_msg_view_window_first_message_selected (win)) {
397 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
398 } else if (!modest_msg_view_window_select_next_message (win)) {
400 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
405 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
407 TnyList *header_list = NULL;
408 TnyIterator *iter = NULL;
409 TnyHeader *header = NULL;
410 gchar *message = NULL;
413 ModestWindowMgr *mgr;
414 GtkWidget *header_view = NULL;
416 g_return_if_fail (MODEST_IS_WINDOW(win));
418 /* Check first if the header view has the focus */
419 if (MODEST_IS_MAIN_WINDOW (win)) {
421 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
422 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
423 if (!gtk_widget_is_focus (header_view))
427 /* Get the headers, either from the header view (if win is the main window),
428 * or from the message view window: */
429 header_list = get_selected_headers (win);
430 if (!header_list) return;
432 /* Check if any of the headers are already opened, or in the process of being opened */
433 if (MODEST_IS_MAIN_WINDOW (win)) {
434 gint opened_headers = 0;
436 iter = tny_list_create_iterator (header_list);
437 mgr = modest_runtime_get_window_mgr ();
438 while (!tny_iterator_is_done (iter)) {
439 header = TNY_HEADER (tny_iterator_get_current (iter));
441 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
443 g_object_unref (header);
445 tny_iterator_next (iter);
447 g_object_unref (iter);
449 if (opened_headers > 0) {
452 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
455 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
458 g_object_unref (header_list);
464 if (tny_list_get_length(header_list) == 1) {
465 iter = tny_list_create_iterator (header_list);
466 header = TNY_HEADER (tny_iterator_get_current (iter));
468 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
469 g_object_unref (header);
472 g_object_unref (iter);
474 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
475 tny_list_get_length(header_list)), desc);
477 /* Confirmation dialog */
478 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
482 if (response == GTK_RESPONSE_OK) {
483 ModestWindow *main_window = NULL;
484 ModestWindowMgr *mgr = NULL;
485 GtkTreeModel *model = NULL;
486 GtkTreeSelection *sel = NULL;
487 GList *sel_list = NULL, *tmp = NULL;
488 GtkTreeRowReference *next_row_reference = NULL;
489 GtkTreeRowReference *prev_row_reference = NULL;
490 GtkTreePath *next_path = NULL;
491 GtkTreePath *prev_path = NULL;
494 /* Find last selected row */
495 if (MODEST_IS_MAIN_WINDOW (win)) {
496 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
497 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
498 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
499 for (tmp=sel_list; tmp; tmp=tmp->next) {
500 if (tmp->next == NULL) {
501 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
502 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
504 gtk_tree_path_prev (prev_path);
505 gtk_tree_path_next (next_path);
507 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
508 next_row_reference = gtk_tree_row_reference_new (model, next_path);
513 /* Disable window dimming management */
514 modest_window_disable_dimming (MODEST_WINDOW(win));
516 /* Remove each header. If it's a view window header_view == NULL */
517 modest_do_messages_delete (header_list, win);
519 /* Enable window dimming management */
521 gtk_tree_selection_unselect_all (sel);
523 modest_window_enable_dimming (MODEST_WINDOW(win));
525 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
526 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
528 /* Get main window */
529 mgr = modest_runtime_get_window_mgr ();
530 main_window = modest_window_mgr_get_main_window (mgr);
533 /* Move cursor to next row */
536 /* Select next or previous row */
537 if (gtk_tree_row_reference_valid (next_row_reference)) {
538 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
539 gtk_tree_selection_select_path (sel, next_path);
541 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
542 gtk_tree_selection_select_path (sel, prev_path);
546 if (next_row_reference != NULL)
547 gtk_tree_row_reference_free (next_row_reference);
548 if (next_path != NULL)
549 gtk_tree_path_free (next_path);
550 if (prev_row_reference != NULL)
551 gtk_tree_row_reference_free (prev_row_reference);
552 if (prev_path != NULL)
553 gtk_tree_path_free (prev_path);
557 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
561 /* Update toolbar dimming state */
562 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
565 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
566 g_list_free (sel_list);
572 g_object_unref (header_list);
578 /* delete either message or folder, based on where we are */
580 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
582 g_return_if_fail (MODEST_IS_WINDOW(win));
584 /* Check first if the header view has the focus */
585 if (MODEST_IS_MAIN_WINDOW (win)) {
587 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
588 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
589 if (gtk_widget_is_focus (w)) {
590 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
594 modest_ui_actions_on_delete_message (action, win);
600 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
602 ModestWindowMgr *mgr = NULL;
604 #ifdef MODEST_PLATFORM_MAEMO
605 modest_osso_save_state();
606 #endif /* MODEST_PLATFORM_MAEMO */
608 g_debug ("closing down, clearing %d item(s) from operation queue",
609 modest_mail_operation_queue_num_elements
610 (modest_runtime_get_mail_operation_queue()));
612 /* cancel all outstanding operations */
613 modest_mail_operation_queue_cancel_all
614 (modest_runtime_get_mail_operation_queue());
616 g_debug ("queue has been cleared");
619 /* Check if there are opened editing windows */
620 mgr = modest_runtime_get_window_mgr ();
621 modest_window_mgr_close_all_windows (mgr);
623 /* note: when modest-tny-account-store is finalized,
624 it will automatically set all network connections
627 /* gtk_main_quit (); */
631 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
635 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
637 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
638 /* gtk_widget_destroy (GTK_WIDGET (win)); */
639 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
640 /* gboolean ret_value; */
641 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
642 /* } else if (MODEST_IS_WINDOW (win)) { */
643 /* gtk_widget_destroy (GTK_WIDGET (win)); */
645 /* g_return_if_reached (); */
650 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
652 GtkClipboard *clipboard = NULL;
653 gchar *selection = NULL;
655 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
656 selection = gtk_clipboard_wait_for_text (clipboard);
658 /* Question: why is the clipboard being used here?
659 * It doesn't really make a lot of sense. */
663 modest_address_book_add_address (selection);
669 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
671 /* This is currently only implemented for Maemo */
672 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
673 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
674 modest_run_account_setup_wizard (win);
677 /* Show the list of accounts: */
678 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
679 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
681 /* The accounts dialog must be modal */
682 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
683 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
686 GtkWidget *dialog, *label;
688 /* Create the widgets */
690 dialog = gtk_dialog_new_with_buttons ("Message",
692 GTK_DIALOG_DESTROY_WITH_PARENT,
696 label = gtk_label_new ("Hello World!");
698 /* Ensure that the dialog box is destroyed when the user responds. */
700 g_signal_connect_swapped (dialog, "response",
701 G_CALLBACK (gtk_widget_destroy),
704 /* Add the label, and show everything we've added to the dialog. */
706 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
708 gtk_widget_show_all (dialog);
709 #endif /* MODEST_PLATFORM_MAEMO */
713 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
715 /* Save any changes. */
716 modest_connection_specific_smtp_window_save_server_accounts (
717 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
718 gtk_widget_destroy (GTK_WIDGET (window));
724 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
726 /* This is currently only implemented for Maemo,
727 * because it requires an API (libconic) to detect different connection
730 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
732 /* Create the window if necessary: */
733 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
734 modest_connection_specific_smtp_window_fill_with_connections (
735 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
736 modest_runtime_get_account_mgr());
738 /* Show the window: */
739 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
740 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
741 gtk_widget_show (specific_window);
743 /* Save changes when the window is hidden: */
744 g_signal_connect (specific_window, "hide",
745 G_CALLBACK (on_smtp_servers_window_hide), win);
746 #endif /* MODEST_PLATFORM_MAEMO */
750 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
752 ModestWindow *msg_win = NULL;
754 TnyFolder *folder = NULL;
755 gchar *account_name = NULL;
756 gchar *from_str = NULL;
757 /* GError *err = NULL; */
758 TnyAccount *account = NULL;
759 ModestWindowMgr *mgr;
760 gchar *signature = NULL, *blank_and_signature = NULL;
762 /* if there are no accounts yet, just show the wizard */
763 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
764 const gboolean created = modest_run_account_setup_wizard (win);
769 account_name = g_strdup (modest_window_get_active_account (win));
771 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
773 g_printerr ("modest: no account found\n");
777 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
779 TNY_ACCOUNT_TYPE_STORE);
781 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
785 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
787 g_printerr ("modest: failed get from string for '%s'\n", account_name);
791 gboolean use_signature = FALSE;
792 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
795 blank_and_signature = g_strconcat ("\n", signature, NULL);
797 blank_and_signature = g_strdup ("");
802 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
804 g_printerr ("modest: failed to create new msg\n");
808 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
810 g_printerr ("modest: failed to find Drafts folder\n");
815 /* Create and register edit window */
816 /* This is destroyed by TODO. */
817 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
818 mgr = modest_runtime_get_window_mgr ();
819 modest_window_mgr_register_window (mgr, msg_win);
822 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
824 gtk_widget_show_all (GTK_WIDGET (msg_win));
827 g_free (account_name);
829 g_free (blank_and_signature);
831 g_object_unref (msg_win);
833 g_object_unref (G_OBJECT(account));
835 g_object_unref (G_OBJECT(msg));
837 g_object_unref (G_OBJECT(folder));
841 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
845 ModestMailOperationStatus status;
847 /* If there is no message or the operation was not successful */
848 status = modest_mail_operation_get_status (mail_op);
849 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
851 /* Remove the header from the preregistered uids */
852 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
862 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
864 ModestWindowMgr *mgr = NULL;
865 ModestWindow *parent_win = NULL;
866 ModestWindow *win = NULL;
867 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
868 gchar *account = NULL;
871 /* Do nothing if there was any problem with the mail
872 operation. The error will be shown by the error_handler of
873 the mail operation */
874 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
877 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
878 folder = tny_header_get_folder (header);
880 /* Mark header as read */
881 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
884 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
886 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
888 /* Gets folder type (OUTBOX headers will be opened in edit window */
889 if (modest_tny_folder_is_local_folder (folder))
890 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
892 /* If the header is in the drafts folder then open the editor,
893 else the message view window */
894 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
895 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
896 /* we cannot edit without a valid account... */
897 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
898 const gboolean created = modest_run_account_setup_wizard(parent_win);
902 win = modest_msg_edit_window_new (msg, account, TRUE);
906 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
909 gchar *uid = modest_tny_folder_get_header_unique_id (header);
911 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
912 GtkWidget *header_view;
913 GtkTreeSelection *sel;
914 GList *sel_list = NULL;
917 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
918 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
920 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
921 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
923 if (sel_list != NULL) {
924 GtkTreeRowReference *row_reference;
926 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
927 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
928 g_list_free (sel_list);
930 win = modest_msg_view_window_new_with_header_model (
931 msg, account, (const gchar*) uid,
932 model, row_reference);
933 gtk_tree_row_reference_free (row_reference);
935 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
938 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
943 /* Register and show new window */
945 mgr = modest_runtime_get_window_mgr ();
946 modest_window_mgr_register_window (mgr, win);
947 g_object_unref (win);
948 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
949 gtk_widget_show_all (GTK_WIDGET(win));
952 /* Update toolbar dimming state */
953 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
954 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
960 g_object_unref (parent_win);
961 g_object_unref (folder);
965 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
969 GObject *win = modest_mail_operation_get_source (mail_op);
971 error = modest_mail_operation_get_error (mail_op);
972 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
974 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
976 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
979 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
980 _("mail_ni_ui_folder_get_msg_folder_error"));
984 g_object_unref (win);
988 * This function is used by both modest_ui_actions_on_open and
989 * modest_ui_actions_on_header_activated. This way we always do the
990 * same when trying to open messages.
993 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
995 ModestWindowMgr *mgr = NULL;
996 TnyIterator *iter = NULL;
997 ModestMailOperation *mail_op = NULL;
998 TnyList *not_opened_headers = NULL;
999 TnyHeaderFlags flags = 0;
1001 g_return_if_fail (headers != NULL);
1003 /* Check that only one message is selected for opening */
1004 if (tny_list_get_length (headers) != 1) {
1005 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1006 _("mcen_ib_select_one_message"));
1011 /* Look if we already have a message view for each header. If
1012 true, then remove the header from the list of headers to
1014 mgr = modest_runtime_get_window_mgr ();
1015 iter = tny_list_create_iterator (headers);
1016 not_opened_headers = tny_simple_list_new ();
1018 while (!tny_iterator_is_done (iter)) {
1020 ModestWindow *window = NULL;
1021 TnyHeader *header = NULL;
1022 gboolean found = FALSE;
1024 header = TNY_HEADER (tny_iterator_get_current (iter));
1026 flags = tny_header_get_flags (header);
1029 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1031 /* Do not open again the message and present the
1032 window to the user */
1035 gtk_window_present (GTK_WINDOW (window));
1037 /* the header has been registered already, we don't do
1038 * anything but wait for the window to come up*/
1039 g_debug ("header %p already registered, waiting for window", header);
1041 tny_list_append (not_opened_headers, G_OBJECT (header));
1045 g_object_unref (header);
1047 tny_iterator_next (iter);
1049 g_object_unref (iter);
1052 /* If some messages would have to be downloaded, ask the user to
1053 * make a connection. It's generally easier to do this here (in the mainloop)
1054 * than later in a thread:
1056 if (tny_list_get_length (not_opened_headers) > 0) {
1058 gboolean found = FALSE;
1060 iter = tny_list_create_iterator (not_opened_headers);
1061 while (!tny_iterator_is_done (iter) && !found) {
1062 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1063 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1066 tny_iterator_next (iter);
1068 g_object_unref (header);
1070 g_object_unref (iter);
1072 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1073 g_object_unref (not_opened_headers);
1078 /* Register the headers before actually creating the windows: */
1079 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1080 while (!tny_iterator_is_done (iter_not_opened)) {
1081 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1083 modest_window_mgr_register_header (mgr, header);
1084 g_object_unref (header);
1087 tny_iterator_next (iter_not_opened);
1089 g_object_unref (iter_not_opened);
1090 iter_not_opened = NULL;
1092 /* Open each message */
1093 if (tny_list_get_length (not_opened_headers) > 0) {
1094 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1096 modest_ui_actions_get_msgs_full_error_handler,
1098 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1099 if (tny_list_get_length (not_opened_headers) > 1) {
1100 modest_mail_operation_get_msgs_full (mail_op,
1106 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1107 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1108 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1109 g_object_unref (header);
1110 g_object_unref (iter);
1112 g_object_unref (mail_op);
1116 if (not_opened_headers != NULL)
1117 g_object_unref (not_opened_headers);
1121 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1126 headers = get_selected_headers (win);
1131 _modest_ui_actions_open (headers, win);
1133 g_object_unref(headers);
1138 free_reply_forward_helper (gpointer data)
1140 ReplyForwardHelper *helper;
1142 helper = (ReplyForwardHelper *) data;
1143 g_free (helper->account_name);
1144 g_slice_free (ReplyForwardHelper, helper);
1148 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1152 ReplyForwardHelper *rf_helper;
1153 ModestWindow *msg_win = NULL;
1154 ModestEditType edit_type;
1156 TnyAccount *account = NULL;
1157 ModestWindowMgr *mgr = NULL;
1158 gchar *signature = NULL;
1160 /* If there was any error. The mail operation could be NULL,
1161 this means that we already have the message downloaded and
1162 that we didn't do a mail operation to retrieve it */
1163 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1166 g_return_if_fail (user_data != NULL);
1167 rf_helper = (ReplyForwardHelper *) user_data;
1169 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1170 rf_helper->account_name);
1171 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1172 rf_helper->account_name,
1173 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1174 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1175 rf_helper->account_name,
1176 MODEST_ACCOUNT_SIGNATURE, FALSE);
1179 /* Create reply mail */
1180 switch (rf_helper->action) {
1183 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1184 rf_helper->reply_forward_type,
1185 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1187 case ACTION_REPLY_TO_ALL:
1189 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1190 MODEST_TNY_MSG_REPLY_MODE_ALL);
1191 edit_type = MODEST_EDIT_TYPE_REPLY;
1193 case ACTION_FORWARD:
1195 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1196 edit_type = MODEST_EDIT_TYPE_FORWARD;
1199 g_return_if_reached ();
1206 g_printerr ("modest: failed to create message\n");
1210 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1211 rf_helper->account_name,
1212 TNY_ACCOUNT_TYPE_STORE);
1214 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1218 /* Create and register the windows */
1219 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1220 mgr = modest_runtime_get_window_mgr ();
1221 modest_window_mgr_register_window (mgr, msg_win);
1223 if (rf_helper->parent_window != NULL) {
1224 gdouble parent_zoom;
1226 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1227 modest_window_set_zoom (msg_win, parent_zoom);
1230 /* Show edit window */
1231 gtk_widget_show_all (GTK_WIDGET (msg_win));
1235 g_object_unref (msg_win);
1237 g_object_unref (G_OBJECT (new_msg));
1239 g_object_unref (G_OBJECT (account));
1240 /* g_object_unref (msg); */
1241 free_reply_forward_helper (rf_helper);
1244 /* Checks a list of headers. If any of them are not currently
1245 * downloaded (CACHED) then returns TRUE else returns FALSE.
1248 header_list_count_uncached_msgs (TnyList *header_list)
1251 gint uncached_messages = 0;
1253 iter = tny_list_create_iterator (header_list);
1254 while (!tny_iterator_is_done (iter)) {
1257 header = TNY_HEADER (tny_iterator_get_current (iter));
1259 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1260 uncached_messages ++;
1261 g_object_unref (header);
1264 tny_iterator_next (iter);
1266 g_object_unref (iter);
1268 return uncached_messages;
1271 /* Returns FALSE if the user does not want to download the
1272 * messages. Returns TRUE if the user allowed the download.
1275 connect_to_get_msg (GtkWindow *win,
1276 gint num_of_uncached_msgs)
1278 /* Allways download if we are online. */
1279 if (tny_device_is_online (modest_runtime_get_device ()))
1282 /* If offline, then ask for user permission to download the messages */
1283 GtkResponseType response;
1284 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1285 ngettext("mcen_nc_get_msg",
1287 num_of_uncached_msgs));
1288 if (response == GTK_RESPONSE_CANCEL)
1291 return modest_platform_connect_and_wait(win, NULL);
1295 * Common code for the reply and forward actions
1298 reply_forward (ReplyForwardAction action, ModestWindow *win)
1300 ModestMailOperation *mail_op = NULL;
1301 TnyList *header_list = NULL;
1302 ReplyForwardHelper *rf_helper = NULL;
1303 guint reply_forward_type;
1304 gboolean continue_download = TRUE;
1305 gboolean do_retrieve = TRUE;
1307 g_return_if_fail (MODEST_IS_WINDOW(win));
1309 /* we need an account when editing */
1310 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1311 const gboolean created = modest_run_account_setup_wizard (win);
1316 header_list = get_selected_headers (win);
1320 reply_forward_type =
1321 modest_conf_get_int (modest_runtime_get_conf (),
1322 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1325 /* check if we need to download msg before asking about it */
1326 do_retrieve = (action == ACTION_FORWARD) ||
1327 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1330 gint num_of_unc_msgs;
1331 /* check that the messages have been previously downloaded */
1332 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1333 /* If there are any uncached message ask the user
1334 * whether he/she wants to download them. */
1335 if (num_of_unc_msgs)
1336 continue_download = connect_to_get_msg (
1341 if (!continue_download) {
1342 g_object_unref (header_list);
1346 /* We assume that we can only select messages of the
1347 same folder and that we reply all of them from the
1348 same account. In fact the interface currently only
1349 allows single selection */
1352 rf_helper = g_slice_new0 (ReplyForwardHelper);
1353 rf_helper->reply_forward_type = reply_forward_type;
1354 rf_helper->action = action;
1355 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1357 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1358 rf_helper->parent_window = GTK_WIDGET (win);
1359 if (!rf_helper->account_name)
1360 rf_helper->account_name =
1361 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1363 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1366 /* Get header and message. Do not free them here, the
1367 reply_forward_cb must do it */
1368 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1369 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1370 if (!msg || !header) {
1372 g_object_unref (msg);
1373 g_printerr ("modest: no message found\n");
1376 reply_forward_cb (NULL, header, msg, rf_helper);
1379 g_object_unref (header);
1384 /* Only reply/forward to one message */
1385 iter = tny_list_create_iterator (header_list);
1386 header = TNY_HEADER (tny_iterator_get_current (iter));
1387 g_object_unref (iter);
1390 /* Retrieve messages */
1392 mail_op = modest_mail_operation_new_with_error_handling (
1393 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1395 modest_ui_actions_get_msgs_full_error_handler,
1397 modest_mail_operation_queue_add (
1398 modest_runtime_get_mail_operation_queue (), mail_op);
1400 modest_mail_operation_get_msg (mail_op,
1405 g_object_unref(mail_op);
1407 /* we put a ref here to prevent double unref as the reply
1408 * forward callback unrefs the header at its end */
1409 reply_forward_cb (NULL, header, NULL, rf_helper);
1413 g_object_unref (header);
1419 g_object_unref (header_list);
1423 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1425 g_return_if_fail (MODEST_IS_WINDOW(win));
1427 reply_forward (ACTION_REPLY, win);
1431 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1433 g_return_if_fail (MODEST_IS_WINDOW(win));
1435 reply_forward (ACTION_FORWARD, win);
1439 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1441 g_return_if_fail (MODEST_IS_WINDOW(win));
1443 reply_forward (ACTION_REPLY_TO_ALL, win);
1447 modest_ui_actions_on_next (GtkAction *action,
1448 ModestWindow *window)
1450 if (MODEST_IS_MAIN_WINDOW (window)) {
1451 GtkWidget *header_view;
1453 header_view = modest_main_window_get_child_widget (
1454 MODEST_MAIN_WINDOW(window),
1455 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1459 modest_header_view_select_next (
1460 MODEST_HEADER_VIEW(header_view));
1461 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1462 modest_msg_view_window_select_next_message (
1463 MODEST_MSG_VIEW_WINDOW (window));
1465 g_return_if_reached ();
1470 modest_ui_actions_on_prev (GtkAction *action,
1471 ModestWindow *window)
1473 g_return_if_fail (MODEST_IS_WINDOW(window));
1475 if (MODEST_IS_MAIN_WINDOW (window)) {
1476 GtkWidget *header_view;
1477 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1478 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1482 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1483 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1484 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1486 g_return_if_reached ();
1491 modest_ui_actions_on_sort (GtkAction *action,
1492 ModestWindow *window)
1494 g_return_if_fail (MODEST_IS_WINDOW(window));
1496 if (MODEST_IS_MAIN_WINDOW (window)) {
1497 GtkWidget *header_view;
1498 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1499 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1501 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1506 /* Show sorting dialog */
1507 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1512 new_messages_arrived (ModestMailOperation *self,
1513 TnyList *new_headers,
1516 ModestMainWindow *win = NULL;
1517 GtkWidget *folder_view = NULL;
1518 TnyFolderStore *folder = NULL;
1519 gboolean folder_empty = FALSE;
1521 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1522 win = MODEST_MAIN_WINDOW (user_data);
1524 /* Don't do anything if there are not new headers, this could
1525 happen if there was any problem with the mail operation */
1529 /* Set contents style of headers view */
1530 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1531 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1532 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1533 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1536 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1539 modest_main_window_set_contents_style (win,
1540 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1543 /* Notify new messages have been downloaded */
1544 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1545 TnyIterator *iter = tny_list_create_iterator (new_headers);
1547 TnyHeader *header = NULL;
1549 header = TNY_HEADER (tny_iterator_get_current (iter));
1550 modest_platform_on_new_header_received (header);
1551 g_object_unref (header);
1553 tny_iterator_next (iter);
1554 } while (!tny_iterator_is_done (iter));
1555 g_object_unref (iter);
1560 * This function performs the send & receive required actions. The
1561 * window is used to create the mail operation. Typically it should
1562 * always be the main window, but we pass it as argument in order to
1566 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1568 gchar *acc_name = NULL;
1569 ModestMailOperation *mail_op;
1570 TnyAccount *store_account = NULL;
1572 /* If no account name was provided then get the current account, and if
1573 there is no current account then pick the default one: */
1574 if (!account_name) {
1575 acc_name = g_strdup (modest_window_get_active_account(win));
1577 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1579 g_printerr ("modest: cannot get default account\n");
1583 acc_name = g_strdup (account_name);
1587 /* Ensure that we have a connection available */
1589 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1591 TNY_ACCOUNT_TYPE_STORE);
1592 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1593 g_object_unref (store_account);
1596 g_object_unref (store_account);
1598 /* Set send/receive operation in progress */
1599 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1601 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1603 modest_ui_actions_send_receive_error_handler,
1606 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1607 G_CALLBACK (_on_send_receive_progress_changed),
1610 /* Send & receive. */
1611 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1612 /* Receive and then send. The operation is tagged initially as
1613 a receive operation because the account update performs a
1614 receive and then a send. The operation changes its type
1615 internally, so the progress objects will receive the proper
1616 progress information */
1617 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1618 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1619 g_object_unref (G_OBJECT (mail_op));
1627 modest_ui_actions_do_cancel_send (const gchar *account_name,
1630 TnyTransportAccount *transport_account;
1631 TnySendQueue *send_queue = NULL;
1632 GError *error = NULL;
1634 /* Get transport account */
1636 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1637 (modest_runtime_get_account_store(),
1639 TNY_ACCOUNT_TYPE_TRANSPORT));
1640 if (!transport_account) {
1641 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1646 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1647 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1648 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1649 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1650 "modest: could not find send queue for account\n");
1652 /* Keeep messages in outbox folder */
1653 tny_send_queue_cancel (send_queue, FALSE, &error);
1657 if (transport_account != NULL)
1658 g_object_unref (G_OBJECT (transport_account));
1662 modest_ui_actions_cancel_send_all (ModestWindow *win)
1664 GSList *account_names, *iter;
1666 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1669 iter = account_names;
1671 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1672 iter = g_slist_next (iter);
1675 modest_account_mgr_free_account_names (account_names);
1676 account_names = NULL;
1680 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1683 /* Check if accounts exist */
1684 gboolean accounts_exist =
1685 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1687 /* If not, allow the user to create an account before trying to send/receive. */
1688 if (!accounts_exist)
1689 modest_ui_actions_on_accounts (NULL, win);
1691 /* Cancel all sending operaitons */
1692 modest_ui_actions_cancel_send_all (win);
1696 * Refreshes all accounts. This function will be used by automatic
1700 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1702 GSList *account_names, *iter;
1704 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1707 iter = account_names;
1709 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1710 iter = g_slist_next (iter);
1713 modest_account_mgr_free_account_names (account_names);
1714 account_names = NULL;
1718 modest_do_refresh_current_folder(ModestWindow *win)
1720 /* Refresh currently selected folder. Note that if we only
1721 want to retreive the headers, then the refresh only will
1722 invoke a poke_status over all folders, i.e., only the
1723 total/unread count will be updated */
1724 if (MODEST_IS_MAIN_WINDOW (win)) {
1725 GtkWidget *header_view, *folder_view;
1726 TnyFolderStore *folder_store;
1728 /* Get folder and header view */
1730 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1731 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1735 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1737 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1739 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1740 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1742 /* We do not need to set the contents style
1743 because it hasn't changed. We also do not
1744 need to save the widget status. Just force
1746 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1747 TNY_FOLDER (folder_store),
1748 folder_refreshed_cb,
1749 MODEST_MAIN_WINDOW (win));
1753 g_object_unref (folder_store);
1759 * Handler of the click on Send&Receive button in the main toolbar
1762 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1764 /* Check if accounts exist */
1765 gboolean accounts_exist =
1766 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1768 /* If not, allow the user to create an account before trying to send/receive. */
1769 if (!accounts_exist)
1770 modest_ui_actions_on_accounts (NULL, win);
1772 modest_do_refresh_current_folder (win);
1774 /* Refresh the active account */
1775 modest_ui_actions_do_send_receive (NULL, win);
1780 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1783 GtkWidget *header_view;
1785 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1787 header_view = modest_main_window_get_child_widget (main_window,
1788 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1792 conf = modest_runtime_get_conf ();
1794 /* what is saved/restored is depending on the style; thus; we save with
1795 * old style, then update the style, and restore for this new style
1797 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1799 if (modest_header_view_get_style
1800 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1801 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1802 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1804 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1805 MODEST_HEADER_VIEW_STYLE_DETAILS);
1807 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1808 MODEST_CONF_HEADER_VIEW_KEY);
1813 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1815 ModestMainWindow *main_window)
1817 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1818 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1820 /* in the case the folder is empty, show the empty folder message and focus
1822 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1823 if (modest_header_view_is_empty (header_view)) {
1824 TnyFolder *folder = modest_header_view_get_folder (header_view);
1825 GtkWidget *folder_view =
1826 modest_main_window_get_child_widget (main_window,
1827 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1829 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1830 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1834 /* If no header has been selected then exit */
1839 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1840 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1842 /* Update toolbar dimming state */
1843 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1847 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1849 ModestMainWindow *main_window)
1853 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1859 /* headers = tny_simple_list_new (); */
1860 /* tny_list_prepend (headers, G_OBJECT (header)); */
1861 headers = modest_header_view_get_selected_headers (header_view);
1863 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1865 g_object_unref (headers);
1869 set_active_account_from_tny_account (TnyAccount *account,
1870 ModestWindow *window)
1872 const gchar *server_acc_name = tny_account_get_id (account);
1874 /* We need the TnyAccount provided by the
1875 account store because that is the one that
1876 knows the name of the Modest account */
1877 TnyAccount *modest_server_account = modest_server_account =
1878 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1879 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1881 if (!modest_server_account) {
1882 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1886 /* Update active account, but only if it's not a pseudo-account */
1887 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1888 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1889 const gchar *modest_acc_name =
1890 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1891 if (modest_acc_name)
1892 modest_window_set_active_account (window, modest_acc_name);
1895 g_object_unref (modest_server_account);
1900 folder_refreshed_cb (ModestMailOperation *mail_op,
1904 ModestMainWindow *win = NULL;
1905 GtkWidget *header_view;
1906 gboolean folder_empty = FALSE;
1907 gboolean all_marked_as_deleted = FALSE;
1909 g_return_if_fail (TNY_IS_FOLDER (folder));
1911 win = MODEST_MAIN_WINDOW (user_data);
1913 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1916 TnyFolder *current_folder;
1918 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1919 if (current_folder != NULL && folder != current_folder) {
1920 g_object_unref (current_folder);
1923 g_object_unref (current_folder);
1926 /* Check if folder is empty and set headers view contents style */
1927 folder_empty = (tny_folder_get_all_count (folder) == 0);
1928 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1929 if (folder_empty || all_marked_as_deleted)
1930 modest_main_window_set_contents_style (win,
1931 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1935 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1936 TnyFolderStore *folder_store,
1938 ModestMainWindow *main_window)
1941 GtkWidget *header_view;
1943 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1945 header_view = modest_main_window_get_child_widget(main_window,
1946 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1950 conf = modest_runtime_get_conf ();
1952 if (TNY_IS_ACCOUNT (folder_store)) {
1954 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1956 /* Show account details */
1957 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1960 if (TNY_IS_FOLDER (folder_store) && selected) {
1962 /* Update the active account */
1963 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1965 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1966 g_object_unref (account);
1970 /* Set the header style by default, it could
1971 be changed later by the refresh callback to
1973 modest_main_window_set_contents_style (main_window,
1974 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1976 /* Set folder on header view. This function
1977 will call tny_folder_refresh_async so we
1978 pass a callback that will be called when
1979 finished. We use that callback to set the
1980 empty view if there are no messages */
1981 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1982 TNY_FOLDER (folder_store),
1983 folder_refreshed_cb,
1986 /* Restore configuration. We need to do this
1987 *after* the set_folder because the widget
1988 memory asks the header view about its
1990 modest_widget_memory_restore (modest_runtime_get_conf (),
1991 G_OBJECT(header_view),
1992 MODEST_CONF_HEADER_VIEW_KEY);
1994 /* Update the active account */
1995 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1996 /* Save only if we're seeing headers */
1997 if (modest_main_window_get_contents_style (main_window) ==
1998 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1999 modest_widget_memory_save (conf, G_OBJECT (header_view),
2000 MODEST_CONF_HEADER_VIEW_KEY);
2001 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2005 /* Update toolbar dimming state */
2006 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2010 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2017 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2019 online = tny_device_is_online (modest_runtime_get_device());
2022 /* already online -- the item is simply not there... */
2023 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2025 GTK_MESSAGE_WARNING,
2027 _("The %s you selected cannot be found"),
2029 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2030 gtk_dialog_run (GTK_DIALOG(dialog));
2032 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2035 _("mcen_bd_dialog_cancel"),
2036 GTK_RESPONSE_REJECT,
2037 _("mcen_bd_dialog_ok"),
2038 GTK_RESPONSE_ACCEPT,
2040 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2041 "Do you want to get online?"), item);
2042 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2043 gtk_label_new (txt), FALSE, FALSE, 0);
2044 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2047 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2048 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2049 /* TODO: Comment about why is this commented out: */
2050 /* modest_platform_connect_and_wait (); */
2053 gtk_widget_destroy (dialog);
2057 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2060 /* g_message ("%s %s", __FUNCTION__, link); */
2065 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2068 modest_platform_activate_uri (link);
2072 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2075 modest_platform_show_uri_popup (link);
2079 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2082 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2086 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2087 const gchar *address,
2090 /* g_message ("%s %s", __FUNCTION__, address); */
2094 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2096 TnyTransportAccount *transport_account;
2097 ModestMailOperation *mail_operation;
2099 gchar *account_name, *from;
2100 ModestAccountMgr *account_mgr;
2101 gchar *info_text = NULL;
2103 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2105 data = modest_msg_edit_window_get_msg_data (edit_window);
2107 account_mgr = modest_runtime_get_account_mgr();
2108 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2110 account_name = modest_account_mgr_get_default_account (account_mgr);
2111 if (!account_name) {
2112 g_printerr ("modest: no account found\n");
2113 modest_msg_edit_window_free_msg_data (edit_window, data);
2117 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2118 account_name = g_strdup (data->account_name);
2122 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2123 (modest_runtime_get_account_store(),
2125 TNY_ACCOUNT_TYPE_TRANSPORT));
2126 if (!transport_account) {
2127 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2128 g_free (account_name);
2129 modest_msg_edit_window_free_msg_data (edit_window, data);
2132 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2134 /* Create the mail operation */
2135 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2136 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2138 modest_mail_operation_save_to_drafts (mail_operation,
2150 data->priority_flags);
2153 g_free (account_name);
2154 g_object_unref (G_OBJECT (transport_account));
2155 g_object_unref (G_OBJECT (mail_operation));
2157 modest_msg_edit_window_free_msg_data (edit_window, data);
2159 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2160 modest_platform_information_banner (NULL, NULL, info_text);
2164 /* For instance, when clicking the Send toolbar button when editing a message: */
2166 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2170 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2173 /* Offer the connection dialog, if necessary: */
2174 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2177 /* FIXME: Code added just for testing. The final version will
2178 use the send queue provided by tinymail and some
2180 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2181 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2183 account_name = modest_account_mgr_get_default_account (account_mgr);
2185 if (!account_name) {
2186 /* Run account setup wizard */
2187 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2192 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2194 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2195 account_name = g_strdup (data->account_name);
2198 /* Get the currently-active transport account for this modest account: */
2199 TnyTransportAccount *transport_account =
2200 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2201 (modest_runtime_get_account_store(),
2203 if (!transport_account) {
2204 /* Run account setup wizard */
2205 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2210 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2212 /* Create the mail operation */
2213 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2214 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2216 modest_mail_operation_send_new_mail (mail_operation,
2227 data->priority_flags);
2231 g_free (account_name);
2232 g_object_unref (G_OBJECT (transport_account));
2233 g_object_unref (G_OBJECT (mail_operation));
2235 modest_msg_edit_window_free_msg_data (edit_window, data);
2236 modest_msg_edit_window_set_sent (edit_window, TRUE);
2238 /* Save settings and close the window: */
2239 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2243 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2244 ModestMsgEditWindow *window)
2246 ModestMsgEditFormatState *format_state = NULL;
2248 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2249 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2251 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2254 format_state = modest_msg_edit_window_get_format_state (window);
2255 g_return_if_fail (format_state != NULL);
2257 format_state->bold = gtk_toggle_action_get_active (action);
2258 modest_msg_edit_window_set_format_state (window, format_state);
2259 g_free (format_state);
2264 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2265 ModestMsgEditWindow *window)
2267 ModestMsgEditFormatState *format_state = NULL;
2269 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2270 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2272 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2275 format_state = modest_msg_edit_window_get_format_state (window);
2276 g_return_if_fail (format_state != NULL);
2278 format_state->italics = gtk_toggle_action_get_active (action);
2279 modest_msg_edit_window_set_format_state (window, format_state);
2280 g_free (format_state);
2285 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2286 ModestMsgEditWindow *window)
2288 ModestMsgEditFormatState *format_state = NULL;
2290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2291 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2293 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2296 format_state = modest_msg_edit_window_get_format_state (window);
2297 g_return_if_fail (format_state != NULL);
2299 format_state->bullet = gtk_toggle_action_get_active (action);
2300 modest_msg_edit_window_set_format_state (window, format_state);
2301 g_free (format_state);
2306 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2307 GtkRadioAction *selected,
2308 ModestMsgEditWindow *window)
2310 ModestMsgEditFormatState *format_state = NULL;
2311 GtkJustification value;
2313 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2315 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2318 value = gtk_radio_action_get_current_value (selected);
2320 format_state = modest_msg_edit_window_get_format_state (window);
2321 g_return_if_fail (format_state != NULL);
2323 format_state->justification = value;
2324 modest_msg_edit_window_set_format_state (window, format_state);
2325 g_free (format_state);
2329 modest_ui_actions_on_select_editor_color (GtkAction *action,
2330 ModestMsgEditWindow *window)
2332 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2333 g_return_if_fail (GTK_IS_ACTION (action));
2335 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2338 modest_msg_edit_window_select_color (window);
2342 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2343 ModestMsgEditWindow *window)
2345 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2346 g_return_if_fail (GTK_IS_ACTION (action));
2348 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2351 modest_msg_edit_window_select_background_color (window);
2355 modest_ui_actions_on_insert_image (GtkAction *action,
2356 ModestMsgEditWindow *window)
2358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2359 g_return_if_fail (GTK_IS_ACTION (action));
2361 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2364 modest_msg_edit_window_insert_image (window);
2368 modest_ui_actions_on_attach_file (GtkAction *action,
2369 ModestMsgEditWindow *window)
2371 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2372 g_return_if_fail (GTK_IS_ACTION (action));
2374 modest_msg_edit_window_offer_attach_file (window);
2378 modest_ui_actions_on_remove_attachments (GtkAction *action,
2379 ModestMsgEditWindow *window)
2381 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2382 g_return_if_fail (GTK_IS_ACTION (action));
2384 modest_msg_edit_window_remove_attachments (window, NULL);
2388 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2391 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2392 const GError *error = modest_mail_operation_get_error (mail_op);
2396 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2397 modest_mail_operation_get_error (mail_op)->message);
2402 modest_ui_actions_create_folder(GtkWidget *parent_window,
2403 GtkWidget *folder_view)
2405 TnyFolderStore *parent_folder;
2407 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2409 if (parent_folder) {
2410 gboolean finished = FALSE;
2412 gchar *folder_name = NULL, *suggested_name = NULL;
2413 const gchar *proto_str = NULL;
2414 TnyAccount *account;
2416 if (TNY_IS_ACCOUNT (parent_folder))
2417 account = g_object_ref (parent_folder);
2419 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2420 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2422 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2423 MODEST_PROTOCOL_STORE_POP) {
2425 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2427 g_object_unref (account);
2429 /* Run the new folder dialog */
2431 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2436 g_free (suggested_name);
2437 suggested_name = NULL;
2439 if (result == GTK_RESPONSE_REJECT) {
2442 ModestMailOperation *mail_op;
2443 TnyFolder *new_folder = NULL;
2445 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2446 G_OBJECT(parent_window),
2447 modest_ui_actions_new_folder_error_handler,
2450 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2452 new_folder = modest_mail_operation_create_folder (mail_op,
2454 (const gchar *) folder_name);
2456 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2459 g_object_unref (new_folder);
2462 g_object_unref (mail_op);
2465 suggested_name = folder_name;
2469 g_object_unref (parent_folder);
2474 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2476 GtkWidget *folder_view;
2478 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2480 folder_view = modest_main_window_get_child_widget (main_window,
2481 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2485 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2489 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2492 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2493 const GError *error = NULL;
2494 const gchar *message = NULL;
2496 /* Get error message */
2497 error = modest_mail_operation_get_error (mail_op);
2499 g_return_if_reached ();
2501 switch (error->code) {
2502 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2503 message = _CS("ckdg_ib_folder_already_exists");
2506 g_return_if_reached ();
2509 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2513 modest_ui_actions_on_rename_folder (GtkAction *action,
2514 ModestMainWindow *main_window)
2516 TnyFolderStore *folder;
2517 GtkWidget *folder_view;
2518 GtkWidget *header_view;
2520 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2522 folder_view = modest_main_window_get_child_widget (main_window,
2523 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2527 header_view = modest_main_window_get_child_widget (main_window,
2528 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2533 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2538 if (TNY_IS_FOLDER (folder)) {
2541 const gchar *current_name;
2542 TnyFolderStore *parent;
2543 gboolean do_rename = TRUE;
2545 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2546 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2547 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2548 parent, current_name,
2550 g_object_unref (parent);
2552 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2554 } else if (modest_platform_is_network_folderstore(folder) &&
2555 !tny_device_is_online (modest_runtime_get_device())) {
2556 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2557 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2558 g_object_unref(account);
2562 ModestMailOperation *mail_op;
2563 GtkTreeSelection *sel = NULL;
2566 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2567 G_OBJECT(main_window),
2568 modest_ui_actions_rename_folder_error_handler,
2571 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2574 /* Clear the headers view */
2575 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2576 gtk_tree_selection_unselect_all (sel);
2578 /* Select *after* the changes */
2579 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2580 TNY_FOLDER(folder), TRUE);
2582 /* Actually rename the folder */
2583 modest_mail_operation_rename_folder (mail_op,
2584 TNY_FOLDER (folder),
2585 (const gchar *) folder_name);
2587 g_object_unref (mail_op);
2588 g_free (folder_name);
2591 g_object_unref (folder);
2595 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2598 GObject *win = modest_mail_operation_get_source (mail_op);
2600 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2601 _("mail_in_ui_folder_delete_error"));
2602 g_object_unref (win);
2606 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2608 TnyFolderStore *folder;
2609 GtkWidget *folder_view;
2612 gboolean do_delete = TRUE;
2614 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2616 folder_view = modest_main_window_get_child_widget (main_window,
2617 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2621 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2623 /* Show an error if it's an account */
2624 if (!TNY_IS_FOLDER (folder)) {
2625 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2626 _("mail_in_ui_folder_delete_error"));
2627 g_object_unref (G_OBJECT (folder));
2632 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2633 tny_folder_get_name (TNY_FOLDER (folder)));
2634 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2635 (const gchar *) message);
2638 if (response != GTK_RESPONSE_OK) {
2640 } else if (modest_platform_is_network_folderstore(folder) &&
2641 !tny_device_is_online (modest_runtime_get_device())) {
2642 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2643 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2644 g_object_unref(account);
2648 ModestMailOperation *mail_op;
2649 GtkTreeSelection *sel;
2651 /* Unselect the folder before deleting it to free the headers */
2652 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2653 gtk_tree_selection_unselect_all (sel);
2655 /* Create the mail operation */
2657 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2658 G_OBJECT(main_window),
2659 modest_ui_actions_delete_folder_error_handler,
2662 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2664 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2665 g_object_unref (G_OBJECT (mail_op));
2668 g_object_unref (G_OBJECT (folder));
2674 modest_ui_actions_on_delete_folder (GtkAction *action,
2675 ModestMainWindow *main_window)
2677 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2679 if (delete_folder (main_window, FALSE)) {
2680 GtkWidget *folder_view;
2682 folder_view = modest_main_window_get_child_widget (main_window,
2683 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2684 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2689 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2691 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2693 delete_folder (main_window, TRUE);
2698 show_error (GtkWidget *parent_widget, const gchar* text)
2700 hildon_banner_show_information(parent_widget, NULL, text);
2703 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2705 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2712 gtk_dialog_run (dialog);
2713 gtk_widget_destroy (GTK_WIDGET (dialog));
2718 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2719 const gchar* server_account_name,
2724 ModestMainWindow *main_window)
2726 g_return_if_fail(server_account_name);
2727 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2729 /* Initalize output parameters: */
2736 #ifdef MODEST_PLATFORM_MAEMO
2737 /* Maemo uses a different (awkward) button order,
2738 * It should probably just use gtk_alternative_dialog_button_order ().
2740 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2743 _("mcen_bd_dialog_ok"),
2744 GTK_RESPONSE_ACCEPT,
2745 _("mcen_bd_dialog_cancel"),
2746 GTK_RESPONSE_REJECT,
2749 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2753 GTK_RESPONSE_REJECT,
2755 GTK_RESPONSE_ACCEPT,
2757 #endif /* MODEST_PLATFORM_MAEMO */
2759 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2761 gchar *server_name = modest_server_account_get_hostname (
2762 modest_runtime_get_account_mgr(), server_account_name);
2763 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2764 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2769 /* This causes a warning because the logical ID has no %s in it,
2770 * though the translation does, but there is not much we can do about that: */
2771 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2772 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2775 g_free (server_name);
2779 gchar *initial_username = modest_server_account_get_username (
2780 modest_runtime_get_account_mgr(), server_account_name);
2782 GtkWidget *entry_username = gtk_entry_new ();
2783 if (initial_username)
2784 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2785 /* Dim this if a connection has ever succeeded with this username,
2786 * as per the UI spec: */
2787 const gboolean username_known =
2788 modest_server_account_get_username_has_succeeded(
2789 modest_runtime_get_account_mgr(), server_account_name);
2790 gtk_widget_set_sensitive (entry_username, !username_known);
2792 #ifdef MODEST_PLATFORM_MAEMO
2793 /* Auto-capitalization is the default, so let's turn it off: */
2794 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2796 /* Create a size group to be used by all captions.
2797 * Note that HildonCaption does not create a default size group if we do not specify one.
2798 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2799 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2801 GtkWidget *caption = hildon_caption_new (sizegroup,
2802 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2803 gtk_widget_show (entry_username);
2804 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2805 FALSE, FALSE, MODEST_MARGIN_HALF);
2806 gtk_widget_show (caption);
2808 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2810 #endif /* MODEST_PLATFORM_MAEMO */
2813 GtkWidget *entry_password = gtk_entry_new ();
2814 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2815 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2817 #ifdef MODEST_PLATFORM_MAEMO
2818 /* Auto-capitalization is the default, so let's turn it off: */
2819 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2820 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2822 caption = hildon_caption_new (sizegroup,
2823 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2824 gtk_widget_show (entry_password);
2825 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2826 FALSE, FALSE, MODEST_MARGIN_HALF);
2827 gtk_widget_show (caption);
2828 g_object_unref (sizegroup);
2830 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2832 #endif /* MODEST_PLATFORM_MAEMO */
2834 /* This is not in the Maemo UI spec:
2835 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2836 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2840 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2842 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2844 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2846 modest_server_account_set_username (
2847 modest_runtime_get_account_mgr(), server_account_name,
2850 const gboolean username_was_changed =
2851 (strcmp (*username, initial_username) != 0);
2852 if (username_was_changed) {
2853 g_warning ("%s: tinymail does not yet support changing the "
2854 "username in the get_password() callback.\n", __FUNCTION__);
2859 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2861 /* We do not save the password in the configuration,
2862 * because this function is only called for passwords that should
2863 * not be remembered:
2864 modest_server_account_set_password (
2865 modest_runtime_get_account_mgr(), server_account_name,
2874 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2886 /* This is not in the Maemo UI spec:
2887 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2893 gtk_widget_destroy (dialog);
2895 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2899 modest_ui_actions_on_cut (GtkAction *action,
2900 ModestWindow *window)
2902 GtkWidget *focused_widget;
2903 GtkClipboard *clipboard;
2905 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2906 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2907 if (GTK_IS_EDITABLE (focused_widget)) {
2908 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2909 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2910 gtk_clipboard_store (clipboard);
2911 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2912 GtkTextBuffer *buffer;
2914 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2915 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2916 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2917 gtk_clipboard_store (clipboard);
2918 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2919 TnyList *header_list = modest_header_view_get_selected_headers (
2920 MODEST_HEADER_VIEW (focused_widget));
2921 gboolean continue_download = FALSE;
2922 gint num_of_unc_msgs;
2924 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2926 if (num_of_unc_msgs)
2927 continue_download = connect_to_get_msg(
2928 GTK_WINDOW (window),
2931 if (num_of_unc_msgs == 0 || continue_download) {
2932 /* modest_platform_information_banner (
2933 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2934 modest_header_view_cut_selection (
2935 MODEST_HEADER_VIEW (focused_widget));
2938 g_object_unref (header_list);
2939 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2940 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2945 modest_ui_actions_on_copy (GtkAction *action,
2946 ModestWindow *window)
2948 GtkClipboard *clipboard;
2949 GtkWidget *focused_widget;
2950 gboolean copied = TRUE;
2952 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2953 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2955 if (GTK_IS_LABEL (focused_widget)) {
2956 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2957 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2958 gtk_clipboard_store (clipboard);
2959 } else if (GTK_IS_EDITABLE (focused_widget)) {
2960 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2961 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2962 gtk_clipboard_store (clipboard);
2963 } else if (GTK_IS_HTML (focused_widget)) {
2964 gtk_html_copy (GTK_HTML (focused_widget));
2965 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2966 gtk_clipboard_store (clipboard);
2967 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2968 GtkTextBuffer *buffer;
2969 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2970 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2971 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2972 gtk_clipboard_store (clipboard);
2973 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2974 TnyList *header_list = modest_header_view_get_selected_headers (
2975 MODEST_HEADER_VIEW (focused_widget));
2976 gboolean continue_download = FALSE;
2977 gint num_of_unc_msgs;
2979 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2981 if (num_of_unc_msgs)
2982 continue_download = connect_to_get_msg(
2983 GTK_WINDOW (window),
2986 if (num_of_unc_msgs == 0 || continue_download) {
2987 modest_platform_information_banner (
2988 NULL, NULL, _CS("mcen_ib_getting_items"));
2989 modest_header_view_copy_selection (
2990 MODEST_HEADER_VIEW (focused_widget));
2994 g_object_unref (header_list);
2996 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2997 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3000 /* Show information banner if there was a copy to clipboard */
3002 modest_platform_information_banner (
3003 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3007 modest_ui_actions_on_undo (GtkAction *action,
3008 ModestWindow *window)
3010 ModestEmailClipboard *clipboard = NULL;
3012 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3013 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3014 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3015 /* Clear clipboard source */
3016 clipboard = modest_runtime_get_email_clipboard ();
3017 modest_email_clipboard_clear (clipboard);
3020 g_return_if_reached ();
3025 modest_ui_actions_on_redo (GtkAction *action,
3026 ModestWindow *window)
3028 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3029 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3032 g_return_if_reached ();
3038 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3040 /* destroy information note */
3041 gtk_widget_destroy (GTK_WIDGET(user_data));
3046 paste_as_attachment_free (gpointer data)
3048 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3050 gtk_widget_destroy (helper->banner);
3051 g_object_unref (helper->banner);
3056 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3061 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3062 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3067 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3072 modest_ui_actions_on_paste (GtkAction *action,
3073 ModestWindow *window)
3075 GtkWidget *focused_widget = NULL;
3076 GtkWidget *inf_note = NULL;
3077 ModestMailOperation *mail_op = NULL;
3079 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3080 if (GTK_IS_EDITABLE (focused_widget)) {
3081 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3082 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3083 ModestEmailClipboard *e_clipboard = NULL;
3084 e_clipboard = modest_runtime_get_email_clipboard ();
3085 if (modest_email_clipboard_cleared (e_clipboard)) {
3086 GtkTextBuffer *buffer;
3087 GtkClipboard *clipboard;
3089 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3090 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3091 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3092 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3093 ModestMailOperation *mail_op;
3094 TnyFolder *src_folder;
3097 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3098 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3099 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3100 _CS("ckct_nw_pasting"));
3101 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3102 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3104 if (helper->banner != NULL) {
3105 g_object_ref (G_OBJECT (helper->banner));
3106 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3107 gtk_widget_show (GTK_WIDGET (helper->banner));
3111 modest_mail_operation_get_msgs_full (mail_op,
3113 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3115 paste_as_attachment_free);
3118 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3119 ModestEmailClipboard *clipboard = NULL;
3120 TnyFolder *src_folder = NULL;
3121 TnyFolderStore *folder_store = NULL;
3122 TnyList *data = NULL;
3123 gboolean delete = FALSE;
3125 /* Check clipboard source */
3126 clipboard = modest_runtime_get_email_clipboard ();
3127 if (modest_email_clipboard_cleared (clipboard))
3130 /* Get elements to paste */
3131 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3133 /* Create a new mail operation */
3134 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3136 /* Get destination folder */
3137 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3139 /* transfer messages */
3143 /* Ask for user confirmation */
3144 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3145 TNY_FOLDER (folder_store),
3149 if (response == GTK_RESPONSE_OK) {
3150 /* Launch notification */
3151 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3152 _CS("ckct_nw_pasting"));
3153 if (inf_note != NULL) {
3154 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3155 gtk_widget_show (GTK_WIDGET(inf_note));
3158 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3159 modest_mail_operation_xfer_msgs (mail_op,
3161 TNY_FOLDER (folder_store),
3163 destroy_information_note,
3166 g_object_unref (mail_op);
3169 } else if (src_folder != NULL) {
3170 /* Launch notification */
3171 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3172 _CS("ckct_nw_pasting"));
3173 if (inf_note != NULL) {
3174 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3175 gtk_widget_show (GTK_WIDGET(inf_note));
3178 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3179 modest_mail_operation_xfer_folder (mail_op,
3183 destroy_information_note,
3189 g_object_unref (data);
3190 if (src_folder != NULL)
3191 g_object_unref (src_folder);
3192 if (folder_store != NULL)
3193 g_object_unref (folder_store);
3199 modest_ui_actions_on_select_all (GtkAction *action,
3200 ModestWindow *window)
3202 GtkWidget *focused_widget;
3204 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3205 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3206 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3207 } else if (GTK_IS_LABEL (focused_widget)) {
3208 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3209 } else if (GTK_IS_EDITABLE (focused_widget)) {
3210 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3211 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3212 GtkTextBuffer *buffer;
3213 GtkTextIter start, end;
3215 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3216 gtk_text_buffer_get_start_iter (buffer, &start);
3217 gtk_text_buffer_get_end_iter (buffer, &end);
3218 gtk_text_buffer_select_range (buffer, &start, &end);
3219 } else if (GTK_IS_HTML (focused_widget)) {
3220 gtk_html_select_all (GTK_HTML (focused_widget));
3221 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3222 GtkWidget *header_view = focused_widget;
3223 GtkTreeSelection *selection = NULL;
3225 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3226 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3227 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3230 /* Disable window dimming management */
3231 modest_window_disable_dimming (MODEST_WINDOW(window));
3233 /* Select all messages */
3234 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3235 gtk_tree_selection_select_all (selection);
3237 /* Set focuse on header view */
3238 gtk_widget_grab_focus (header_view);
3241 /* Enable window dimming management */
3242 modest_window_enable_dimming (MODEST_WINDOW(window));
3243 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3249 modest_ui_actions_on_mark_as_read (GtkAction *action,
3250 ModestWindow *window)
3252 g_return_if_fail (MODEST_IS_WINDOW(window));
3254 /* Mark each header as read */
3255 do_headers_action (window, headers_action_mark_as_read, NULL);
3259 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3260 ModestWindow *window)
3262 g_return_if_fail (MODEST_IS_WINDOW(window));
3264 /* Mark each header as read */
3265 do_headers_action (window, headers_action_mark_as_unread, NULL);
3269 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3270 GtkRadioAction *selected,
3271 ModestWindow *window)
3275 value = gtk_radio_action_get_current_value (selected);
3276 if (MODEST_IS_WINDOW (window)) {
3277 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3282 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3283 GtkRadioAction *selected,
3284 ModestWindow *window)
3286 TnyHeaderFlags flags;
3287 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3289 flags = gtk_radio_action_get_current_value (selected);
3290 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3294 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3295 GtkRadioAction *selected,
3296 ModestWindow *window)
3300 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3302 file_format = gtk_radio_action_get_current_value (selected);
3303 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3308 modest_ui_actions_on_zoom_plus (GtkAction *action,
3309 ModestWindow *window)
3311 g_return_if_fail (MODEST_IS_WINDOW (window));
3313 modest_window_zoom_plus (MODEST_WINDOW (window));
3317 modest_ui_actions_on_zoom_minus (GtkAction *action,
3318 ModestWindow *window)
3320 g_return_if_fail (MODEST_IS_WINDOW (window));
3322 modest_window_zoom_minus (MODEST_WINDOW (window));
3326 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3327 ModestWindow *window)
3329 ModestWindowMgr *mgr;
3330 gboolean fullscreen, active;
3331 g_return_if_fail (MODEST_IS_WINDOW (window));
3333 mgr = modest_runtime_get_window_mgr ();
3335 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3336 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3338 if (active != fullscreen) {
3339 modest_window_mgr_set_fullscreen_mode (mgr, active);
3340 gtk_window_present (GTK_WINDOW (window));
3345 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3346 ModestWindow *window)
3348 ModestWindowMgr *mgr;
3349 gboolean fullscreen;
3351 g_return_if_fail (MODEST_IS_WINDOW (window));
3353 mgr = modest_runtime_get_window_mgr ();
3354 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3355 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3357 gtk_window_present (GTK_WINDOW (window));
3361 * Used by modest_ui_actions_on_details to call do_headers_action
3364 headers_action_show_details (TnyHeader *header,
3365 ModestWindow *window,
3372 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3375 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3376 gtk_widget_show_all (dialog);
3377 gtk_dialog_run (GTK_DIALOG (dialog));
3379 gtk_widget_destroy (dialog);
3383 * Show the folder details in a ModestDetailsDialog widget
3386 show_folder_details (TnyFolder *folder,
3392 dialog = modest_details_dialog_new_with_folder (window, folder);
3395 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3396 gtk_widget_show_all (dialog);
3397 gtk_dialog_run (GTK_DIALOG (dialog));
3399 gtk_widget_destroy (dialog);
3403 * Show the header details in a ModestDetailsDialog widget
3406 modest_ui_actions_on_details (GtkAction *action,
3409 TnyList * headers_list;
3413 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3416 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3419 g_object_unref (msg);
3421 headers_list = get_selected_headers (win);
3425 iter = tny_list_create_iterator (headers_list);
3427 header = TNY_HEADER (tny_iterator_get_current (iter));
3429 headers_action_show_details (header, win, NULL);
3430 g_object_unref (header);
3433 g_object_unref (iter);
3434 g_object_unref (headers_list);
3436 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3437 GtkWidget *folder_view, *header_view;
3439 /* Check which widget has the focus */
3440 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3441 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3442 if (gtk_widget_is_focus (folder_view)) {
3443 TnyFolderStore *folder_store
3444 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3445 if (!folder_store) {
3446 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3449 /* Show only when it's a folder */
3450 /* This function should not be called for account items,
3451 * because we dim the menu item for them. */
3452 if (TNY_IS_FOLDER (folder_store)) {
3453 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3456 g_object_unref (folder_store);
3459 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3460 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3461 /* Show details of each header */
3462 do_headers_action (win, headers_action_show_details, header_view);
3468 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3469 ModestMsgEditWindow *window)
3471 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3473 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3477 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3478 ModestMsgEditWindow *window)
3480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3482 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3486 modest_ui_actions_toggle_folders_view (GtkAction *action,
3487 ModestMainWindow *main_window)
3489 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3491 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3492 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3494 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3498 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3499 ModestWindow *window)
3501 gboolean active, fullscreen = FALSE;
3502 ModestWindowMgr *mgr;
3504 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3506 /* Check if we want to toggle the toolbar vuew in fullscreen
3508 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3509 "ViewShowToolbarFullScreen")) {
3513 /* Toggle toolbar */
3514 mgr = modest_runtime_get_window_mgr ();
3515 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3519 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3520 ModestMsgEditWindow *window)
3522 modest_msg_edit_window_select_font (window);
3526 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3527 const gchar *display_name,
3530 /* Do not change the application name if the widget has not
3531 the focus. This callback could be called even if the folder
3532 view has not the focus, because the handled signal could be
3533 emitted when the folder view is redrawn */
3534 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3536 gtk_window_set_title (window, display_name);
3538 gtk_window_set_title (window, " ");
3543 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3545 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3546 modest_msg_edit_window_select_contacts (window);
3550 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3553 modest_msg_edit_window_check_names (window, FALSE);
3557 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3559 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3560 GTK_WIDGET (user_data));
3564 * This function is used to track changes in the selection of the
3565 * folder view that is inside the "move to" dialog to enable/disable
3566 * the OK button because we do not want the user to select a disallowed
3567 * destination for a folder.
3568 * The user also not desired to be able to use NEW button on items where
3569 * folder creation is not possibel.
3572 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3573 TnyFolderStore *folder_store,
3577 GtkWidget *dialog = NULL;
3578 GtkWidget *ok_button = NULL, *new_button = NULL;
3579 GList *children = NULL;
3580 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3581 gboolean moving_folder = FALSE;
3582 gboolean is_local_account = TRUE;
3583 GtkWidget *folder_view = NULL;
3584 ModestTnyFolderRules rules;
3589 /* Get the OK button */
3590 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3594 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3595 ok_button = GTK_WIDGET (children->next->next->data);
3596 new_button = GTK_WIDGET (children->next->data);
3597 g_list_free (children);
3599 /* check if folder_store is an remote account */
3600 if (TNY_IS_ACCOUNT (folder_store)) {
3601 TnyAccount *local_account = NULL;
3602 ModestTnyAccountStore *account_store = NULL;
3604 account_store = modest_runtime_get_account_store ();
3605 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3607 if ((gpointer) local_account != (gpointer) folder_store) {
3608 is_local_account = FALSE;
3609 /* New button should be dimmed on remote
3611 new_sensitive = FALSE;
3613 g_object_unref (local_account);
3616 /* Check the target folder rules */
3617 if (TNY_IS_FOLDER (folder_store)) {
3618 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3619 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3620 ok_sensitive = FALSE;
3621 new_sensitive = FALSE;
3626 /* Check if we're moving a folder */
3627 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3628 /* Get the widgets */
3629 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3630 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3631 if (gtk_widget_is_focus (folder_view))
3632 moving_folder = TRUE;
3635 if (moving_folder) {
3636 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3638 /* Get the folder to move */
3639 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3641 /* Check that we're not moving to the same folder */
3642 if (TNY_IS_FOLDER (moved_folder)) {
3643 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3644 if (parent == folder_store)
3645 ok_sensitive = FALSE;
3646 g_object_unref (parent);
3649 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3650 /* Do not allow to move to an account unless it's the
3651 local folders account */
3652 if (!is_local_account)
3653 ok_sensitive = FALSE;
3656 if (ok_sensitive && (moved_folder == folder_store)) {
3657 /* Do not allow to move to itself */
3658 ok_sensitive = FALSE;
3660 g_object_unref (moved_folder);
3662 TnyHeader *header = NULL;
3663 TnyFolder *src_folder = NULL;
3665 /* Moving a message */
3666 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3667 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3668 src_folder = tny_header_get_folder (header);
3669 g_object_unref (header);
3672 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3675 /* Do not allow to move the msg to the same folder */
3676 /* Do not allow to move the msg to an account */
3677 if ((gpointer) src_folder == (gpointer) folder_store ||
3678 TNY_IS_ACCOUNT (folder_store))
3679 ok_sensitive = FALSE;
3680 g_object_unref (src_folder);
3684 /* Set sensitivity of the OK button */
3685 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3686 /* Set sensitivity of the NEW button */
3687 gtk_widget_set_sensitive (new_button, new_sensitive);
3691 create_move_to_dialog (GtkWindow *win,
3692 GtkWidget *folder_view,
3693 GtkWidget **tree_view)
3695 GtkWidget *dialog, *scroll;
3696 GtkWidget *new_button;
3698 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3700 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3703 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3704 /* We do this manually so GTK+ does not associate a response ID for
3706 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3707 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3708 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3710 /* Create scrolled window */
3711 scroll = gtk_scrolled_window_new (NULL, NULL);
3712 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3713 GTK_POLICY_AUTOMATIC,
3714 GTK_POLICY_AUTOMATIC);
3716 /* Create folder view */
3717 *tree_view = modest_platform_create_folder_view (NULL);
3719 /* Track changes in the selection to
3720 * disable the OK button whenever "Move to" is not possible
3721 * disbale NEW button whenever New is not possible */
3722 g_signal_connect (*tree_view,
3723 "folder_selection_changed",
3724 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3727 /* Listen to clicks on New button */
3728 g_signal_connect (G_OBJECT (new_button),
3730 G_CALLBACK(create_move_to_dialog_on_new_folder),
3733 /* It could happen that we're trying to move a message from a
3734 window (msg window for example) after the main window was
3735 closed, so we can not just get the model of the folder
3737 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3738 const gchar *visible_id = NULL;
3740 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3741 MODEST_FOLDER_VIEW(*tree_view));
3744 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3746 /* Show the same account than the one that is shown in the main window */
3747 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3750 const gchar *active_account_name = NULL;
3751 ModestAccountMgr *mgr = NULL;
3752 ModestAccountData *acc_data = NULL;
3754 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3755 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3757 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3758 mgr = modest_runtime_get_account_mgr ();
3759 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3761 /* Set the new visible & active account */
3762 if (acc_data && acc_data->store_account) {
3763 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3764 acc_data->store_account->account_name);
3765 modest_account_mgr_free_account_data (mgr, acc_data);
3769 /* Hide special folders */
3770 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3772 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3774 /* Add scroll to dialog */
3775 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3776 scroll, TRUE, TRUE, 0);
3778 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3779 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3785 * Returns TRUE if at least one of the headers of the list belongs to
3786 * a message that has been fully retrieved.
3788 #if 0 /* no longer in use. delete in 2007.10 */
3790 has_retrieved_msgs (TnyList *list)
3793 gboolean found = FALSE;
3795 iter = tny_list_create_iterator (list);
3796 while (!tny_iterator_is_done (iter) && !found) {
3798 TnyHeaderFlags flags = 0;
3800 header = TNY_HEADER (tny_iterator_get_current (iter));
3802 flags = tny_header_get_flags (header);
3803 if (flags & TNY_HEADER_FLAG_CACHED)
3804 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3807 g_object_unref (header);
3811 tny_iterator_next (iter);
3813 g_object_unref (iter);
3821 * Shows a confirmation dialog to the user when we're moving messages
3822 * from a remote server to the local storage. Returns the dialog
3823 * response. If it's other kind of movement then it always returns
3826 * This one is used by the next functions:
3827 * modest_ui_actions_on_paste - commented out
3828 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3831 msgs_move_to_confirmation (GtkWindow *win,
3832 TnyFolder *dest_folder,
3836 gint response = GTK_RESPONSE_OK;
3838 /* return with OK if the destination is a remote folder */
3839 if (modest_tny_folder_is_remote_folder (dest_folder))
3840 return GTK_RESPONSE_OK;
3842 TnyFolder *src_folder = NULL;
3843 TnyIterator *iter = NULL;
3844 TnyHeader *header = NULL;
3846 /* Get source folder */
3847 iter = tny_list_create_iterator (headers);
3848 header = TNY_HEADER (tny_iterator_get_current (iter));
3850 src_folder = tny_header_get_folder (header);
3851 g_object_unref (header);
3853 g_object_unref (iter);
3855 /* if no src_folder, message may be an attahcment */
3856 if (src_folder == NULL)
3857 return GTK_RESPONSE_CANCEL;
3859 /* If the source is a local or MMC folder */
3860 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3861 g_object_unref (src_folder);
3862 return GTK_RESPONSE_OK;
3864 g_object_unref (src_folder);
3866 /* now if offline we ask the user */
3867 if(connect_to_get_msg( GTK_WINDOW (win),
3868 tny_list_get_length (headers)))
3869 response = GTK_RESPONSE_OK;
3871 response = GTK_RESPONSE_CANCEL;
3879 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3881 /* Note that the operation could have failed, in that case do
3883 if (modest_mail_operation_get_status (mail_op) ==
3884 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3886 GObject *object = modest_mail_operation_get_source (mail_op);
3887 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3888 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3890 if (!modest_msg_view_window_select_next_message (self))
3891 if (!modest_msg_view_window_select_previous_message (self))
3892 /* No more messages to view, so close this window */
3893 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3895 g_object_unref (object);
3898 /* Close the "Pasting" information banner */
3899 gtk_widget_destroy (GTK_WIDGET(user_data));
3903 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3906 ModestWindow *main_window = NULL;
3907 GtkWidget *folder_view = NULL;
3908 GObject *win = modest_mail_operation_get_source (mail_op);
3909 const GError *error = NULL;
3910 const gchar *message = NULL;
3912 /* Get error message */
3913 error = modest_mail_operation_get_error (mail_op);
3914 if (error != NULL && error->message != NULL) {
3915 message = error->message;
3917 message = _("mail_in_ui_folder_move_target_error");
3920 /* Disable next automatic folder selection */
3921 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3922 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3923 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3924 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3926 if (user_data && TNY_IS_FOLDER (user_data)) {
3927 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3928 TNY_FOLDER (user_data), FALSE);
3931 /* Show notification dialog */
3932 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3933 g_object_unref (win);
3937 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3940 GObject *win = modest_mail_operation_get_source (mail_op);
3941 const GError *error = modest_mail_operation_get_error (mail_op);
3943 g_return_if_fail (error != NULL);
3944 if (error->message != NULL)
3945 g_printerr ("modest: %s\n", error->message);
3947 g_printerr ("modest: unkonw error on send&receive operation");
3949 /* Show error message */
3950 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3951 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3952 /* _CS("sfil_ib_unable_to_receive")); */
3954 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3955 /* _CS("sfil_ib_unable_to_send")); */
3956 g_object_unref (win);
3960 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3967 gint pending_purges = 0;
3968 gboolean some_purged = FALSE;
3969 ModestWindow *win = MODEST_WINDOW (user_data);
3970 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3972 /* If there was any error */
3973 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3974 modest_window_mgr_unregister_header (mgr, header);
3978 /* Once the message has been retrieved for purging, we check if
3979 * it's all ok for purging */
3981 parts = tny_simple_list_new ();
3982 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3983 iter = tny_list_create_iterator (parts);
3985 while (!tny_iterator_is_done (iter)) {
3987 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3988 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3989 if (tny_mime_part_is_purged (part))
3996 g_object_unref (part);
3998 tny_iterator_next (iter);
4001 if (pending_purges>0) {
4003 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4005 if (response == GTK_RESPONSE_OK) {
4006 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4007 tny_iterator_first (iter);
4008 while (!tny_iterator_is_done (iter)) {
4011 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4012 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4013 tny_mime_part_set_purged (part);
4016 g_object_unref (part);
4018 tny_iterator_next (iter);
4021 tny_msg_rewrite_cache (msg);
4024 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4027 /* remove attachments */
4028 tny_iterator_first (iter);
4029 while (!tny_iterator_is_done (iter)) {
4032 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4034 /* One for the reference given by tny_iterator_get_current(): */
4035 g_object_unref (part);
4037 /* TODO: Is this meant to remove the attachment by doing another unref()?
4038 * Otherwise, this seems useless. */
4041 tny_iterator_next (iter);
4043 modest_window_mgr_unregister_header (mgr, header);
4045 g_object_unref (iter);
4046 g_object_unref (parts);
4050 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4051 ModestMainWindow *win)
4053 GtkWidget *header_view;
4054 TnyList *header_list;
4057 TnyHeaderFlags flags;
4058 ModestWindow *msg_view_window = NULL;
4061 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4063 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4064 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4066 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4068 if (tny_list_get_length (header_list) == 1) {
4069 iter = tny_list_create_iterator (header_list);
4070 header = TNY_HEADER (tny_iterator_get_current (iter));
4071 g_object_unref (iter);
4076 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4077 header, &msg_view_window);
4078 flags = tny_header_get_flags (header);
4079 if (!(flags & TNY_HEADER_FLAG_CACHED))
4082 if (msg_view_window != NULL)
4083 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4085 /* do nothing; uid was registered before, so window is probably on it's way */
4086 g_warning ("debug: header %p has already been registered", header);
4089 ModestMailOperation *mail_op = NULL;
4090 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4091 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4093 modest_ui_actions_get_msgs_full_error_handler,
4095 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4096 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4098 g_object_unref (mail_op);
4101 g_object_unref (header);
4103 g_object_unref (header_list);
4107 * Utility function that transfer messages from both the main window
4108 * and the msg view window when using the "Move to" dialog
4111 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4114 TnyList *headers = NULL;
4115 TnyAccount *dst_account = NULL;
4116 const gchar *proto_str = NULL;
4117 gboolean dst_is_pop = FALSE;
4119 if (!TNY_IS_FOLDER (dst_folder)) {
4120 modest_platform_information_banner (GTK_WIDGET (win),
4122 _CS("ckdg_ib_unable_to_move_to_current_location"));
4126 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4127 proto_str = tny_account_get_proto (dst_account);
4129 /* tinymail will return NULL for local folders it seems */
4130 dst_is_pop = proto_str &&
4131 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4132 MODEST_PROTOCOL_STORE_POP);
4134 g_object_unref (dst_account);
4136 /* Get selected headers */
4137 headers = get_selected_headers (MODEST_WINDOW (win));
4140 modest_platform_information_banner (GTK_WIDGET (win),
4142 ngettext("mail_in_ui_folder_move_target_error",
4143 "mail_in_ui_folder_move_targets_error",
4144 tny_list_get_length (headers)));
4145 g_object_unref (headers);
4149 GtkWidget *inf_note;
4150 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4151 _CS("ckct_nw_pasting"));
4152 if (inf_note != NULL) {
4153 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4154 gtk_widget_show (GTK_WIDGET(inf_note));
4157 ModestMailOperation *mail_op =
4158 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4160 modest_ui_actions_move_folder_error_handler,
4162 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4165 modest_mail_operation_xfer_msgs (mail_op,
4167 TNY_FOLDER (dst_folder),
4172 g_object_unref (G_OBJECT (mail_op));
4173 g_object_unref (headers);
4177 * UI handler for the "Move to" action when invoked from the
4181 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4182 GtkWidget *folder_view,
4183 TnyFolderStore *dst_folder,
4184 ModestMainWindow *win)
4186 ModestHeaderView *header_view = NULL;
4187 ModestMailOperation *mail_op = NULL;
4188 TnyFolderStore *src_folder;
4189 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4191 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4193 /* Get the source folder */
4194 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4196 /* Get header view */
4197 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4199 /* Get folder or messages to transfer */
4200 if (gtk_widget_is_focus (folder_view)) {
4201 GtkTreeSelection *sel;
4202 gboolean do_xfer = TRUE;
4204 /* Allow only to transfer folders to the local root folder */
4205 if (TNY_IS_ACCOUNT (dst_folder) &&
4206 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4208 } else if (!TNY_IS_FOLDER (src_folder)) {
4209 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4211 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4212 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4213 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4219 GtkWidget *inf_note;
4220 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4221 _CS("ckct_nw_pasting"));
4222 if (inf_note != NULL) {
4223 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4224 gtk_widget_show (GTK_WIDGET(inf_note));
4226 /* Clean folder on header view before moving it */
4227 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4228 gtk_tree_selection_unselect_all (sel);
4231 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4233 modest_ui_actions_move_folder_error_handler,
4235 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4238 /* Select *after* the changes */
4239 /* TODO: this function hangs UI after transfer */
4240 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4241 /* TNY_FOLDER (src_folder), TRUE); */
4243 modest_mail_operation_xfer_folder (mail_op,
4244 TNY_FOLDER (src_folder),
4249 /* Unref mail operation */
4250 g_object_unref (G_OBJECT (mail_op));
4252 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4253 gboolean do_xfer = TRUE;
4254 /* Ask for confirmation if the source folder is remote and we're not connected */
4255 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4256 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4257 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4258 guint num_headers = tny_list_get_length(headers);
4259 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4263 g_object_unref(headers);
4265 if (do_xfer) /* Transfer messages */
4266 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4270 g_object_unref (src_folder);
4275 * UI handler for the "Move to" action when invoked from the
4276 * ModestMsgViewWindow
4279 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4280 TnyFolderStore *dst_folder,
4281 ModestMsgViewWindow *win)
4283 TnyHeader *header = NULL;
4284 TnyFolderStore *src_folder;
4286 /* Create header list */
4287 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4288 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4289 g_object_unref (header);
4291 /* Transfer the message if online or confirmed by the user */
4292 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4293 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4294 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4297 g_object_unref (src_folder);
4301 modest_ui_actions_on_move_to (GtkAction *action,
4304 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4306 TnyFolderStore *dst_folder = NULL;
4307 ModestMainWindow *main_window;
4309 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4310 MODEST_IS_MSG_VIEW_WINDOW (win));
4312 /* Get the main window if exists */
4313 if (MODEST_IS_MAIN_WINDOW (win))
4314 main_window = MODEST_MAIN_WINDOW (win);
4317 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4319 /* Get the folder view widget if exists */
4321 folder_view = modest_main_window_get_child_widget (main_window,
4322 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4326 /* Create and run the dialog */
4327 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4328 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4329 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4330 result = gtk_dialog_run (GTK_DIALOG(dialog));
4331 g_object_ref (tree_view);
4332 gtk_widget_destroy (dialog);
4334 if (result != GTK_RESPONSE_ACCEPT)
4337 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4338 /* Do window specific stuff */
4339 if (MODEST_IS_MAIN_WINDOW (win)) {
4340 modest_ui_actions_on_main_window_move_to (action,
4343 MODEST_MAIN_WINDOW (win));
4345 modest_ui_actions_on_msg_view_window_move_to (action,
4347 MODEST_MSG_VIEW_WINDOW (win));
4351 g_object_unref (dst_folder);
4355 * Calls #HeadersFunc for each header already selected in the main
4356 * window or the message currently being shown in the msg view window
4359 do_headers_action (ModestWindow *win,
4363 TnyList *headers_list = NULL;
4364 TnyIterator *iter = NULL;
4365 TnyHeader *header = NULL;
4366 TnyFolder *folder = NULL;
4369 headers_list = get_selected_headers (win);
4373 /* Get the folder */
4374 iter = tny_list_create_iterator (headers_list);
4375 header = TNY_HEADER (tny_iterator_get_current (iter));
4377 folder = tny_header_get_folder (header);
4378 g_object_unref (header);
4381 /* Call the function for each header */
4382 while (!tny_iterator_is_done (iter)) {
4383 header = TNY_HEADER (tny_iterator_get_current (iter));
4384 func (header, win, user_data);
4385 g_object_unref (header);
4386 tny_iterator_next (iter);
4389 /* Trick: do a poke status in order to speed up the signaling
4391 tny_folder_poke_status (folder);
4394 g_object_unref (folder);
4395 g_object_unref (iter);
4396 g_object_unref (headers_list);
4400 modest_ui_actions_view_attachment (GtkAction *action,
4401 ModestWindow *window)
4403 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4404 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4406 /* not supported window for this action */
4407 g_return_if_reached ();
4412 modest_ui_actions_save_attachments (GtkAction *action,
4413 ModestWindow *window)
4415 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4416 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4418 /* not supported window for this action */
4419 g_return_if_reached ();
4424 modest_ui_actions_remove_attachments (GtkAction *action,
4425 ModestWindow *window)
4427 if (MODEST_IS_MAIN_WINDOW (window)) {
4428 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4429 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4430 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4432 /* not supported window for this action */
4433 g_return_if_reached ();
4438 modest_ui_actions_on_settings (GtkAction *action,
4443 dialog = modest_platform_get_global_settings_dialog ();
4444 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4445 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4446 gtk_widget_show_all (dialog);
4448 gtk_dialog_run (GTK_DIALOG (dialog));
4450 gtk_widget_destroy (dialog);
4454 modest_ui_actions_on_help (GtkAction *action,
4457 const gchar *help_id = NULL;
4459 if (MODEST_IS_MAIN_WINDOW (win)) {
4460 GtkWidget *folder_view;
4461 TnyFolderStore *folder_store;
4463 /* Get selected folder */
4464 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4465 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4466 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4468 /* Switch help_id */
4469 if (TNY_IS_FOLDER (folder_store)) {
4470 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4471 case TNY_FOLDER_TYPE_NORMAL:
4472 help_id = "applications_email_managefolders";
4474 case TNY_FOLDER_TYPE_INBOX:
4475 help_id = "applications_email_inbox";
4477 case TNY_FOLDER_TYPE_OUTBOX:
4478 help_id = "applications_email_outbox";
4480 case TNY_FOLDER_TYPE_SENT:
4481 help_id = "applications_email_sent";
4483 case TNY_FOLDER_TYPE_DRAFTS:
4484 help_id = "applications_email_drafts";
4486 case TNY_FOLDER_TYPE_ARCHIVE:
4487 help_id = "applications_email_managefolders";
4490 help_id = "applications_email_managefolders";
4493 help_id = "applications_email_mainview";
4495 g_object_unref (folder_store);
4496 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4497 help_id = "applications_email_viewer";
4498 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4499 help_id = "applications_email_editor";
4501 modest_platform_show_help (GTK_WINDOW (win), help_id);
4505 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4506 ModestWindow *window)
4508 ModestMailOperation *mail_op;
4512 headers = get_selected_headers (window);
4516 /* Create mail operation */
4517 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4519 modest_ui_actions_get_msgs_full_error_handler,
4521 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4522 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4525 g_object_unref (headers);
4526 g_object_unref (mail_op);
4530 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4531 ModestWindow *window)
4533 g_return_if_fail (MODEST_IS_WINDOW (window));
4536 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4540 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4541 ModestWindow *window)
4543 g_return_if_fail (MODEST_IS_WINDOW (window));
4546 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4550 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4551 ModestWindow *window)
4553 g_return_if_fail (MODEST_IS_WINDOW (window));
4556 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4560 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4561 ModestWindow *window)
4563 g_return_if_fail (MODEST_IS_WINDOW (window));
4566 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4570 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4571 ModestWindow *window)
4573 g_return_if_fail (MODEST_IS_WINDOW (window));
4576 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4580 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4581 ModestWindow *window)
4583 g_return_if_fail (MODEST_IS_WINDOW (window));
4586 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4590 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4591 ModestWindow *window)
4593 g_return_if_fail (MODEST_IS_WINDOW (window));
4596 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4600 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4601 ModestWindow *window)
4603 g_return_if_fail (MODEST_IS_WINDOW (window));
4606 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4610 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4611 ModestWindow *window)
4613 g_return_if_fail (MODEST_IS_WINDOW (window));
4616 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4620 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4622 g_return_if_fail (MODEST_IS_WINDOW (window));
4625 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4629 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4631 g_return_if_fail (MODEST_IS_WINDOW (window));
4633 modest_platform_show_search_messages (GTK_WINDOW (window));
4637 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4639 g_return_if_fail (MODEST_IS_WINDOW (win));
4640 modest_platform_show_addressbook (GTK_WINDOW (win));
4645 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4646 ModestWindow *window)
4648 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4650 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4654 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4655 ModestMailOperationState *state,
4658 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4660 /* Set send/receive operation finished */
4661 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4662 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4668 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4674 const gchar* server_name = NULL;
4675 TnyTransportAccount *server_account;
4676 gchar *message = NULL;
4678 /* Don't show anything if the user cancelled something */
4679 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4682 /* Get the server name: */
4684 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4685 if (server_account) {
4686 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4688 g_object_unref (server_account);
4689 server_account = NULL;
4692 g_return_if_fail (server_name);
4694 /* Show the appropriate message text for the GError: */
4695 switch (err->code) {
4696 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4697 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4699 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4700 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4702 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4703 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4705 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4706 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4709 g_return_if_reached ();
4712 /* TODO if the username or the password where not defined we
4713 should show the Accounts Settings dialog or the Connection
4714 specific SMTP server window */
4716 modest_platform_run_information_dialog (NULL, message);
4721 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4726 ModestMainWindow *main_window = NULL;
4727 ModestWindowMgr *mgr = NULL;
4728 GtkWidget *folder_view = NULL, *header_view = NULL;
4729 TnyFolderStore *selected_folder = NULL;
4730 TnyFolderType folder_type;
4732 mgr = modest_runtime_get_window_mgr ();
4733 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4738 /* Check if selected folder is OUTBOX */
4739 folder_view = modest_main_window_get_child_widget (main_window,
4740 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4741 header_view = modest_main_window_get_child_widget (main_window,
4742 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4744 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4745 if (!TNY_IS_FOLDER (selected_folder))
4748 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4749 #if GTK_CHECK_VERSION(2, 8, 0)
4750 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4751 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4752 GtkTreeViewColumn *tree_column;
4754 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4755 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4756 gtk_tree_view_column_queue_resize (tree_column);
4759 gtk_widget_queue_draw (header_view);
4764 if (selected_folder != NULL)
4765 g_object_unref (selected_folder);