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);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkDialog *wizard, *dialog;
211 /* Show the easy-setup wizard: */
212 dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
213 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
214 /* old wizard is active already;
216 gtk_window_present (GTK_WINDOW(dialog));
221 /* there is no such wizard yet */
223 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
225 g_printerr ("modest: failed to create easysetup wizard\n");
229 modest_window_mgr_set_modal_dialog
230 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
233 /* there is no such wizard yet */
234 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
235 modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
238 /* make it non-modal; if though we register it as a modal dialog above
239 * apparently, making it modal *at all* gives hangs -- FIXME: check this*/
240 gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
242 /* always present a main window in the background
243 * we do it here, so we cannot end up with to wizards (as this
244 * function might be called in modest_window_mgr_get_main_window as well */
246 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
248 /* make sure the mainwindow is visible */
249 gtk_widget_show_all (GTK_WIDGET(win));
250 gtk_window_present (GTK_WINDOW(win));
253 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
255 /* Don't make this a modal window, because secondary windows will then
256 * be unusable, freezing the UI: */
257 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
259 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
260 if (dialog_response == GTK_RESPONSE_CANCEL)
263 /* Check whether an account was created: */
264 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
267 gtk_widget_destroy (GTK_WIDGET (wizard));
269 /* clear it from the window mgr */
270 modest_window_mgr_set_modal_dialog
271 (modest_runtime_get_window_mgr(), NULL);
278 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
281 const gchar *authors[] = {
282 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
285 about = gtk_about_dialog_new ();
286 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
287 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
288 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
289 _("Copyright (c) 2006, Nokia Corporation\n"
290 "All rights reserved."));
291 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
292 _("a modest e-mail client\n\n"
293 "design and implementation: Dirk-Jan C. Binnema\n"
294 "contributions from the fine people at KC and Ig\n"
295 "uses the tinymail email framework written by Philip van Hoof"));
296 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
297 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
298 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
299 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
301 gtk_dialog_run (GTK_DIALOG (about));
302 gtk_widget_destroy(about);
306 * Gets the list of currently selected messages. If the win is the
307 * main window, then it returns a newly allocated list of the headers
308 * selected in the header view. If win is the msg view window, then
309 * the value returned is a list with just a single header.
311 * The caller of this funcion must free the list.
314 get_selected_headers (ModestWindow *win)
316 if (MODEST_IS_MAIN_WINDOW(win)) {
317 GtkWidget *header_view;
319 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
321 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
323 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
324 /* for MsgViewWindows, we simply return a list with one element */
326 TnyList *list = NULL;
328 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
329 if (header != NULL) {
330 list = tny_simple_list_new ();
331 tny_list_prepend (list, G_OBJECT(header));
332 g_object_unref (G_OBJECT(header));
342 headers_action_mark_as_read (TnyHeader *header,
346 TnyHeaderFlags flags;
348 g_return_if_fail (TNY_IS_HEADER(header));
350 flags = tny_header_get_flags (header);
351 if (flags & TNY_HEADER_FLAG_SEEN) return;
352 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
356 headers_action_mark_as_unread (TnyHeader *header,
360 TnyHeaderFlags flags;
362 g_return_if_fail (TNY_IS_HEADER(header));
364 flags = tny_header_get_flags (header);
365 if (flags & TNY_HEADER_FLAG_SEEN) {
366 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
370 /** A convenience method, because deleting a message is
371 * otherwise complicated, and it's best to change it in one place
374 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
376 ModestMailOperation *mail_op = NULL;
377 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
378 win ? G_OBJECT(win) : NULL);
379 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
382 /* Always delete. TODO: Move to trash still not supported */
383 modest_mail_operation_remove_msg (mail_op, header, FALSE);
384 g_object_unref (G_OBJECT (mail_op));
387 /** A convenience method, because deleting a message is
388 * otherwise complicated, and it's best to change it in one place
391 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
393 ModestMailOperation *mail_op = NULL;
394 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
395 win ? G_OBJECT(win) : NULL);
396 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
399 /* Always delete. TODO: Move to trash still not supported */
400 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
401 g_object_unref (G_OBJECT (mail_op));
404 /** After deleing a message that is currently visible in a window,
405 * show the next message from the list, or close the window if there are no more messages.
408 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
410 /* Close msg view window or select next */
411 if (modest_msg_view_window_last_message_selected (win) &&
412 modest_msg_view_window_first_message_selected (win)) {
413 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
414 } else if (!modest_msg_view_window_select_next_message (win)) {
416 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
421 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
423 TnyList *header_list = NULL;
424 TnyIterator *iter = NULL;
425 TnyHeader *header = NULL;
426 gchar *message = NULL;
429 ModestWindowMgr *mgr;
430 GtkWidget *header_view = NULL;
432 g_return_if_fail (MODEST_IS_WINDOW(win));
434 /* Check first if the header view has the focus */
435 if (MODEST_IS_MAIN_WINDOW (win)) {
437 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
438 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
439 if (!gtk_widget_is_focus (header_view))
443 /* Get the headers, either from the header view (if win is the main window),
444 * or from the message view window: */
445 header_list = get_selected_headers (win);
446 if (!header_list) return;
448 /* Check if any of the headers are already opened, or in the process of being opened */
449 if (MODEST_IS_MAIN_WINDOW (win)) {
450 gint opened_headers = 0;
452 iter = tny_list_create_iterator (header_list);
453 mgr = modest_runtime_get_window_mgr ();
454 while (!tny_iterator_is_done (iter)) {
455 header = TNY_HEADER (tny_iterator_get_current (iter));
457 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
459 g_object_unref (header);
461 tny_iterator_next (iter);
463 g_object_unref (iter);
465 if (opened_headers > 0) {
468 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
471 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
474 g_object_unref (header_list);
480 if (tny_list_get_length(header_list) == 1) {
481 iter = tny_list_create_iterator (header_list);
482 header = TNY_HEADER (tny_iterator_get_current (iter));
484 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
485 g_object_unref (header);
488 g_object_unref (iter);
490 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
491 tny_list_get_length(header_list)), desc);
493 /* Confirmation dialog */
494 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
498 if (response == GTK_RESPONSE_OK) {
499 ModestWindow *main_window = NULL;
500 ModestWindowMgr *mgr = NULL;
501 GtkTreeModel *model = NULL;
502 GtkTreeSelection *sel = NULL;
503 GList *sel_list = NULL, *tmp = NULL;
504 GtkTreeRowReference *next_row_reference = NULL;
505 GtkTreeRowReference *prev_row_reference = NULL;
506 GtkTreePath *next_path = NULL;
507 GtkTreePath *prev_path = NULL;
510 /* Find last selected row */
511 if (MODEST_IS_MAIN_WINDOW (win)) {
512 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
513 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
514 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
515 for (tmp=sel_list; tmp; tmp=tmp->next) {
516 if (tmp->next == NULL) {
517 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
518 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
520 gtk_tree_path_prev (prev_path);
521 gtk_tree_path_next (next_path);
523 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
524 next_row_reference = gtk_tree_row_reference_new (model, next_path);
529 /* Disable window dimming management */
530 modest_window_disable_dimming (MODEST_WINDOW(win));
532 /* Remove each header. If it's a view window header_view == NULL */
533 modest_do_messages_delete (header_list, win);
535 /* Enable window dimming management */
537 gtk_tree_selection_unselect_all (sel);
539 modest_window_enable_dimming (MODEST_WINDOW(win));
541 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
542 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
544 /* Get main window */
545 mgr = modest_runtime_get_window_mgr ();
546 main_window = modest_window_mgr_get_main_window (mgr);
549 /* Move cursor to next row */
552 /* Select next or previous row */
553 if (gtk_tree_row_reference_valid (next_row_reference)) {
554 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
555 gtk_tree_selection_select_path (sel, next_path);
557 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
558 gtk_tree_selection_select_path (sel, prev_path);
562 if (next_row_reference != NULL)
563 gtk_tree_row_reference_free (next_row_reference);
564 if (next_path != NULL)
565 gtk_tree_path_free (next_path);
566 if (prev_row_reference != NULL)
567 gtk_tree_row_reference_free (prev_row_reference);
568 if (prev_path != NULL)
569 gtk_tree_path_free (prev_path);
573 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
577 /* Update toolbar dimming state */
578 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
581 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
582 g_list_free (sel_list);
588 g_object_unref (header_list);
594 /* delete either message or folder, based on where we are */
596 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
598 g_return_if_fail (MODEST_IS_WINDOW(win));
600 /* Check first if the header view has the focus */
601 if (MODEST_IS_MAIN_WINDOW (win)) {
603 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
604 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
605 if (gtk_widget_is_focus (w)) {
606 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
610 modest_ui_actions_on_delete_message (action, win);
616 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
618 ModestWindowMgr *mgr = NULL;
620 #ifdef MODEST_PLATFORM_MAEMO
621 modest_osso_save_state();
622 #endif /* MODEST_PLATFORM_MAEMO */
624 g_debug ("closing down, clearing %d item(s) from operation queue",
625 modest_mail_operation_queue_num_elements
626 (modest_runtime_get_mail_operation_queue()));
628 /* cancel all outstanding operations */
629 modest_mail_operation_queue_cancel_all
630 (modest_runtime_get_mail_operation_queue());
632 g_debug ("queue has been cleared");
635 /* Check if there are opened editing windows */
636 mgr = modest_runtime_get_window_mgr ();
637 modest_window_mgr_close_all_windows (mgr);
639 /* note: when modest-tny-account-store is finalized,
640 it will automatically set all network connections
643 /* gtk_main_quit (); */
647 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
651 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
653 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
654 /* gtk_widget_destroy (GTK_WIDGET (win)); */
655 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
656 /* gboolean ret_value; */
657 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
658 /* } else if (MODEST_IS_WINDOW (win)) { */
659 /* gtk_widget_destroy (GTK_WIDGET (win)); */
661 /* g_return_if_reached (); */
666 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
668 GtkClipboard *clipboard = NULL;
669 gchar *selection = NULL;
671 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
672 selection = gtk_clipboard_wait_for_text (clipboard);
674 /* Question: why is the clipboard being used here?
675 * It doesn't really make a lot of sense. */
679 modest_address_book_add_address (selection);
685 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
687 /* This is currently only implemented for Maemo */
688 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
689 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
690 modest_run_account_setup_wizard (win);
693 /* Show the list of accounts: */
694 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
695 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
697 /* The accounts dialog must be modal */
698 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
699 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
702 GtkWidget *dialog, *label;
704 /* Create the widgets */
706 dialog = gtk_dialog_new_with_buttons ("Message",
708 GTK_DIALOG_DESTROY_WITH_PARENT,
712 label = gtk_label_new ("Hello World!");
714 /* Ensure that the dialog box is destroyed when the user responds. */
716 g_signal_connect_swapped (dialog, "response",
717 G_CALLBACK (gtk_widget_destroy),
720 /* Add the label, and show everything we've added to the dialog. */
722 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
724 gtk_widget_show_all (dialog);
725 #endif /* MODEST_PLATFORM_MAEMO */
729 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
731 /* Save any changes. */
732 modest_connection_specific_smtp_window_save_server_accounts (
733 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
734 gtk_widget_destroy (GTK_WIDGET (window));
740 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
742 /* This is currently only implemented for Maemo,
743 * because it requires an API (libconic) to detect different connection
746 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
748 /* Create the window if necessary: */
749 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
750 modest_connection_specific_smtp_window_fill_with_connections (
751 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
752 modest_runtime_get_account_mgr());
754 /* Show the window: */
755 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
756 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
757 gtk_widget_show (specific_window);
759 /* Save changes when the window is hidden: */
760 g_signal_connect (specific_window, "hide",
761 G_CALLBACK (on_smtp_servers_window_hide), win);
762 #endif /* MODEST_PLATFORM_MAEMO */
766 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
768 ModestWindow *msg_win = NULL;
770 TnyFolder *folder = NULL;
771 gchar *account_name = NULL;
772 gchar *from_str = NULL;
773 /* GError *err = NULL; */
774 TnyAccount *account = NULL;
775 ModestWindowMgr *mgr;
776 gchar *signature = NULL, *blank_and_signature = NULL;
778 /* if there are no accounts yet, just show the wizard */
779 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
780 const gboolean created = modest_run_account_setup_wizard (win);
785 account_name = g_strdup (modest_window_get_active_account (win));
787 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
789 g_printerr ("modest: no account found\n");
793 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
795 TNY_ACCOUNT_TYPE_STORE);
797 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
801 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
803 g_printerr ("modest: failed get from string for '%s'\n", account_name);
807 gboolean use_signature = FALSE;
808 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
811 blank_and_signature = g_strconcat ("\n", signature, NULL);
813 blank_and_signature = g_strdup ("");
818 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
820 g_printerr ("modest: failed to create new msg\n");
824 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
826 g_printerr ("modest: failed to find Drafts folder\n");
831 /* Create and register edit window */
832 /* This is destroyed by TODO. */
833 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
834 mgr = modest_runtime_get_window_mgr ();
835 modest_window_mgr_register_window (mgr, msg_win);
838 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
840 gtk_widget_show_all (GTK_WIDGET (msg_win));
843 g_free (account_name);
845 g_free (blank_and_signature);
847 g_object_unref (msg_win);
849 g_object_unref (G_OBJECT(account));
851 g_object_unref (G_OBJECT(msg));
853 g_object_unref (G_OBJECT(folder));
857 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
861 ModestMailOperationStatus status;
863 /* If there is no message or the operation was not successful */
864 status = modest_mail_operation_get_status (mail_op);
865 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
867 /* Remove the header from the preregistered uids */
868 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
878 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
880 ModestWindowMgr *mgr = NULL;
881 ModestWindow *parent_win = NULL;
882 ModestWindow *win = NULL;
883 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
884 gchar *account = NULL;
887 /* Do nothing if there was any problem with the mail
888 operation. The error will be shown by the error_handler of
889 the mail operation */
890 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
893 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
894 folder = tny_header_get_folder (header);
896 /* Mark header as read */
897 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
900 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
902 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
904 /* Gets folder type (OUTBOX headers will be opened in edit window */
905 if (modest_tny_folder_is_local_folder (folder))
906 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
908 /* If the header is in the drafts folder then open the editor,
909 else the message view window */
910 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
911 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
912 /* we cannot edit without a valid account... */
913 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
914 const gboolean created = modest_run_account_setup_wizard(parent_win);
918 win = modest_msg_edit_window_new (msg, account, TRUE);
922 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
925 gchar *uid = modest_tny_folder_get_header_unique_id (header);
927 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
928 GtkWidget *header_view;
929 GtkTreeSelection *sel;
930 GList *sel_list = NULL;
933 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
934 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
936 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
937 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
939 if (sel_list != NULL) {
940 GtkTreeRowReference *row_reference;
942 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
943 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
944 g_list_free (sel_list);
946 win = modest_msg_view_window_new_with_header_model (
947 msg, account, (const gchar*) uid,
948 model, row_reference);
949 gtk_tree_row_reference_free (row_reference);
951 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
954 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
959 /* Register and show new window */
961 mgr = modest_runtime_get_window_mgr ();
962 modest_window_mgr_register_window (mgr, win);
963 g_object_unref (win);
964 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
965 gtk_widget_show_all (GTK_WIDGET(win));
968 /* Update toolbar dimming state */
969 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
970 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
976 g_object_unref (parent_win);
977 g_object_unref (folder);
981 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
985 GObject *win = modest_mail_operation_get_source (mail_op);
987 error = modest_mail_operation_get_error (mail_op);
988 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
990 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
992 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
995 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
996 _("mail_ni_ui_folder_get_msg_folder_error"));
1000 g_object_unref (win);
1004 * This function is used by both modest_ui_actions_on_open and
1005 * modest_ui_actions_on_header_activated. This way we always do the
1006 * same when trying to open messages.
1009 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1011 ModestWindowMgr *mgr = NULL;
1012 TnyIterator *iter = NULL;
1013 ModestMailOperation *mail_op = NULL;
1014 TnyList *not_opened_headers = NULL;
1015 TnyHeaderFlags flags = 0;
1017 g_return_if_fail (headers != NULL);
1019 /* Check that only one message is selected for opening */
1020 if (tny_list_get_length (headers) != 1) {
1021 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1022 _("mcen_ib_select_one_message"));
1027 /* Look if we already have a message view for each header. If
1028 true, then remove the header from the list of headers to
1030 mgr = modest_runtime_get_window_mgr ();
1031 iter = tny_list_create_iterator (headers);
1032 not_opened_headers = tny_simple_list_new ();
1034 while (!tny_iterator_is_done (iter)) {
1036 ModestWindow *window = NULL;
1037 TnyHeader *header = NULL;
1038 gboolean found = FALSE;
1040 header = TNY_HEADER (tny_iterator_get_current (iter));
1042 flags = tny_header_get_flags (header);
1045 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1047 /* Do not open again the message and present the
1048 window to the user */
1051 gtk_window_present (GTK_WINDOW (window));
1053 /* the header has been registered already, we don't do
1054 * anything but wait for the window to come up*/
1055 g_debug ("header %p already registered, waiting for window", header);
1057 tny_list_append (not_opened_headers, G_OBJECT (header));
1061 g_object_unref (header);
1063 tny_iterator_next (iter);
1065 g_object_unref (iter);
1068 /* If some messages would have to be downloaded, ask the user to
1069 * make a connection. It's generally easier to do this here (in the mainloop)
1070 * than later in a thread:
1072 if (tny_list_get_length (not_opened_headers) > 0) {
1074 gboolean found = FALSE;
1076 iter = tny_list_create_iterator (not_opened_headers);
1077 while (!tny_iterator_is_done (iter) && !found) {
1078 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1079 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1082 tny_iterator_next (iter);
1084 g_object_unref (header);
1086 g_object_unref (iter);
1088 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1089 g_object_unref (not_opened_headers);
1094 /* Register the headers before actually creating the windows: */
1095 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1096 while (!tny_iterator_is_done (iter_not_opened)) {
1097 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1099 modest_window_mgr_register_header (mgr, header);
1100 g_object_unref (header);
1103 tny_iterator_next (iter_not_opened);
1105 g_object_unref (iter_not_opened);
1106 iter_not_opened = NULL;
1108 /* Open each message */
1109 if (tny_list_get_length (not_opened_headers) > 0) {
1110 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1112 modest_ui_actions_get_msgs_full_error_handler,
1114 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1115 if (tny_list_get_length (not_opened_headers) > 1) {
1116 modest_mail_operation_get_msgs_full (mail_op,
1122 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1123 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1124 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1125 g_object_unref (header);
1126 g_object_unref (iter);
1128 g_object_unref (mail_op);
1132 if (not_opened_headers != NULL)
1133 g_object_unref (not_opened_headers);
1137 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1142 headers = get_selected_headers (win);
1147 _modest_ui_actions_open (headers, win);
1149 g_object_unref(headers);
1154 free_reply_forward_helper (gpointer data)
1156 ReplyForwardHelper *helper;
1158 helper = (ReplyForwardHelper *) data;
1159 g_free (helper->account_name);
1160 g_slice_free (ReplyForwardHelper, helper);
1164 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1168 ReplyForwardHelper *rf_helper;
1169 ModestWindow *msg_win = NULL;
1170 ModestEditType edit_type;
1172 TnyAccount *account = NULL;
1173 ModestWindowMgr *mgr = NULL;
1174 gchar *signature = NULL;
1176 /* If there was any error. The mail operation could be NULL,
1177 this means that we already have the message downloaded and
1178 that we didn't do a mail operation to retrieve it */
1179 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1182 g_return_if_fail (user_data != NULL);
1183 rf_helper = (ReplyForwardHelper *) user_data;
1185 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1186 rf_helper->account_name);
1187 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1188 rf_helper->account_name,
1189 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1190 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1191 rf_helper->account_name,
1192 MODEST_ACCOUNT_SIGNATURE, FALSE);
1195 /* Create reply mail */
1196 switch (rf_helper->action) {
1199 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1200 rf_helper->reply_forward_type,
1201 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1203 case ACTION_REPLY_TO_ALL:
1205 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1206 MODEST_TNY_MSG_REPLY_MODE_ALL);
1207 edit_type = MODEST_EDIT_TYPE_REPLY;
1209 case ACTION_FORWARD:
1211 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1212 edit_type = MODEST_EDIT_TYPE_FORWARD;
1215 g_return_if_reached ();
1222 g_printerr ("modest: failed to create message\n");
1226 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1227 rf_helper->account_name,
1228 TNY_ACCOUNT_TYPE_STORE);
1230 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1234 /* Create and register the windows */
1235 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1236 mgr = modest_runtime_get_window_mgr ();
1237 modest_window_mgr_register_window (mgr, msg_win);
1239 if (rf_helper->parent_window != NULL) {
1240 gdouble parent_zoom;
1242 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1243 modest_window_set_zoom (msg_win, parent_zoom);
1246 /* Show edit window */
1247 gtk_widget_show_all (GTK_WIDGET (msg_win));
1251 g_object_unref (msg_win);
1253 g_object_unref (G_OBJECT (new_msg));
1255 g_object_unref (G_OBJECT (account));
1256 /* g_object_unref (msg); */
1257 free_reply_forward_helper (rf_helper);
1260 /* Checks a list of headers. If any of them are not currently
1261 * downloaded (CACHED) then returns TRUE else returns FALSE.
1264 header_list_count_uncached_msgs (TnyList *header_list)
1267 gint uncached_messages = 0;
1269 iter = tny_list_create_iterator (header_list);
1270 while (!tny_iterator_is_done (iter)) {
1273 header = TNY_HEADER (tny_iterator_get_current (iter));
1275 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1276 uncached_messages ++;
1277 g_object_unref (header);
1280 tny_iterator_next (iter);
1282 g_object_unref (iter);
1284 return uncached_messages;
1287 /* Returns FALSE if the user does not want to download the
1288 * messages. Returns TRUE if the user allowed the download.
1291 connect_to_get_msg (GtkWindow *win,
1292 gint num_of_uncached_msgs)
1294 /* Allways download if we are online. */
1295 if (tny_device_is_online (modest_runtime_get_device ()))
1298 /* If offline, then ask for user permission to download the messages */
1299 GtkResponseType response;
1300 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1301 ngettext("mcen_nc_get_msg",
1303 num_of_uncached_msgs));
1304 if (response == GTK_RESPONSE_CANCEL)
1307 return modest_platform_connect_and_wait(win, NULL);
1311 * Common code for the reply and forward actions
1314 reply_forward (ReplyForwardAction action, ModestWindow *win)
1316 ModestMailOperation *mail_op = NULL;
1317 TnyList *header_list = NULL;
1318 ReplyForwardHelper *rf_helper = NULL;
1319 guint reply_forward_type;
1320 gboolean continue_download = TRUE;
1321 gboolean do_retrieve = TRUE;
1323 g_return_if_fail (MODEST_IS_WINDOW(win));
1325 /* we need an account when editing */
1326 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1327 const gboolean created = modest_run_account_setup_wizard (win);
1332 header_list = get_selected_headers (win);
1336 reply_forward_type =
1337 modest_conf_get_int (modest_runtime_get_conf (),
1338 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1341 /* check if we need to download msg before asking about it */
1342 do_retrieve = (action == ACTION_FORWARD) ||
1343 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1346 gint num_of_unc_msgs;
1347 /* check that the messages have been previously downloaded */
1348 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1349 /* If there are any uncached message ask the user
1350 * whether he/she wants to download them. */
1351 if (num_of_unc_msgs)
1352 continue_download = connect_to_get_msg (
1357 if (!continue_download) {
1358 g_object_unref (header_list);
1362 /* We assume that we can only select messages of the
1363 same folder and that we reply all of them from the
1364 same account. In fact the interface currently only
1365 allows single selection */
1368 rf_helper = g_slice_new0 (ReplyForwardHelper);
1369 rf_helper->reply_forward_type = reply_forward_type;
1370 rf_helper->action = action;
1371 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1373 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1374 rf_helper->parent_window = GTK_WIDGET (win);
1375 if (!rf_helper->account_name)
1376 rf_helper->account_name =
1377 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1379 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1382 /* Get header and message. Do not free them here, the
1383 reply_forward_cb must do it */
1384 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1385 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1386 if (!msg || !header) {
1388 g_object_unref (msg);
1389 g_printerr ("modest: no message found\n");
1392 reply_forward_cb (NULL, header, msg, rf_helper);
1395 g_object_unref (header);
1400 /* Only reply/forward to one message */
1401 iter = tny_list_create_iterator (header_list);
1402 header = TNY_HEADER (tny_iterator_get_current (iter));
1403 g_object_unref (iter);
1406 /* Retrieve messages */
1408 mail_op = modest_mail_operation_new_with_error_handling (
1409 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1411 modest_ui_actions_get_msgs_full_error_handler,
1413 modest_mail_operation_queue_add (
1414 modest_runtime_get_mail_operation_queue (), mail_op);
1416 modest_mail_operation_get_msg (mail_op,
1421 g_object_unref(mail_op);
1423 /* we put a ref here to prevent double unref as the reply
1424 * forward callback unrefs the header at its end */
1425 reply_forward_cb (NULL, header, NULL, rf_helper);
1429 g_object_unref (header);
1435 g_object_unref (header_list);
1439 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1441 g_return_if_fail (MODEST_IS_WINDOW(win));
1443 reply_forward (ACTION_REPLY, win);
1447 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1449 g_return_if_fail (MODEST_IS_WINDOW(win));
1451 reply_forward (ACTION_FORWARD, win);
1455 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1457 g_return_if_fail (MODEST_IS_WINDOW(win));
1459 reply_forward (ACTION_REPLY_TO_ALL, win);
1463 modest_ui_actions_on_next (GtkAction *action,
1464 ModestWindow *window)
1466 if (MODEST_IS_MAIN_WINDOW (window)) {
1467 GtkWidget *header_view;
1469 header_view = modest_main_window_get_child_widget (
1470 MODEST_MAIN_WINDOW(window),
1471 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1475 modest_header_view_select_next (
1476 MODEST_HEADER_VIEW(header_view));
1477 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1478 modest_msg_view_window_select_next_message (
1479 MODEST_MSG_VIEW_WINDOW (window));
1481 g_return_if_reached ();
1486 modest_ui_actions_on_prev (GtkAction *action,
1487 ModestWindow *window)
1489 g_return_if_fail (MODEST_IS_WINDOW(window));
1491 if (MODEST_IS_MAIN_WINDOW (window)) {
1492 GtkWidget *header_view;
1493 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1494 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1498 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1499 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1500 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1502 g_return_if_reached ();
1507 modest_ui_actions_on_sort (GtkAction *action,
1508 ModestWindow *window)
1510 g_return_if_fail (MODEST_IS_WINDOW(window));
1512 if (MODEST_IS_MAIN_WINDOW (window)) {
1513 GtkWidget *header_view;
1514 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1515 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1517 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1522 /* Show sorting dialog */
1523 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1528 new_messages_arrived (ModestMailOperation *self,
1529 TnyList *new_headers,
1532 ModestMainWindow *win = NULL;
1533 GtkWidget *folder_view = NULL;
1534 TnyFolderStore *folder = NULL;
1535 gboolean folder_empty = FALSE;
1537 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1538 win = MODEST_MAIN_WINDOW (user_data);
1540 /* Don't do anything if there are not new headers, this could
1541 happen if there was any problem with the mail operation */
1545 /* Set contents style of headers view */
1546 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1547 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1548 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1549 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1552 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1555 modest_main_window_set_contents_style (win,
1556 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1559 /* Notify new messages have been downloaded */
1560 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1561 TnyIterator *iter = tny_list_create_iterator (new_headers);
1563 TnyHeader *header = NULL;
1565 header = TNY_HEADER (tny_iterator_get_current (iter));
1566 modest_platform_on_new_header_received (header);
1567 g_object_unref (header);
1569 tny_iterator_next (iter);
1570 } while (!tny_iterator_is_done (iter));
1571 g_object_unref (iter);
1576 * This function performs the send & receive required actions. The
1577 * window is used to create the mail operation. Typically it should
1578 * always be the main window, but we pass it as argument in order to
1582 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1584 gchar *acc_name = NULL;
1585 ModestMailOperation *mail_op;
1586 TnyAccount *store_account = NULL;
1588 /* If no account name was provided then get the current account, and if
1589 there is no current account then pick the default one: */
1590 if (!account_name) {
1591 acc_name = g_strdup (modest_window_get_active_account(win));
1593 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1595 g_printerr ("modest: cannot get default account\n");
1599 acc_name = g_strdup (account_name);
1603 /* Ensure that we have a connection available */
1605 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1607 TNY_ACCOUNT_TYPE_STORE);
1608 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1609 g_object_unref (store_account);
1612 g_object_unref (store_account);
1614 /* Set send/receive operation in progress */
1615 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1617 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1619 modest_ui_actions_send_receive_error_handler,
1622 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1623 G_CALLBACK (_on_send_receive_progress_changed),
1626 /* Send & receive. */
1627 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1628 /* Receive and then send. The operation is tagged initially as
1629 a receive operation because the account update performs a
1630 receive and then a send. The operation changes its type
1631 internally, so the progress objects will receive the proper
1632 progress information */
1633 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1634 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1635 g_object_unref (G_OBJECT (mail_op));
1643 modest_ui_actions_do_cancel_send (const gchar *account_name,
1646 TnyTransportAccount *transport_account;
1647 TnySendQueue *send_queue = NULL;
1648 GError *error = NULL;
1650 /* Get transport account */
1652 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1653 (modest_runtime_get_account_store(),
1655 TNY_ACCOUNT_TYPE_TRANSPORT));
1656 if (!transport_account) {
1657 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1662 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1663 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1664 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1665 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1666 "modest: could not find send queue for account\n");
1668 /* Keeep messages in outbox folder */
1669 tny_send_queue_cancel (send_queue, FALSE, &error);
1673 if (transport_account != NULL)
1674 g_object_unref (G_OBJECT (transport_account));
1678 modest_ui_actions_cancel_send_all (ModestWindow *win)
1680 GSList *account_names, *iter;
1682 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1685 iter = account_names;
1687 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1688 iter = g_slist_next (iter);
1691 modest_account_mgr_free_account_names (account_names);
1692 account_names = NULL;
1696 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1699 /* Check if accounts exist */
1700 gboolean accounts_exist =
1701 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1703 /* If not, allow the user to create an account before trying to send/receive. */
1704 if (!accounts_exist)
1705 modest_ui_actions_on_accounts (NULL, win);
1707 /* Cancel all sending operaitons */
1708 modest_ui_actions_cancel_send_all (win);
1712 * Refreshes all accounts. This function will be used by automatic
1716 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1718 GSList *account_names, *iter;
1720 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1723 iter = account_names;
1725 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1726 iter = g_slist_next (iter);
1729 modest_account_mgr_free_account_names (account_names);
1730 account_names = NULL;
1734 modest_do_refresh_current_folder(ModestWindow *win)
1736 /* Refresh currently selected folder. Note that if we only
1737 want to retreive the headers, then the refresh only will
1738 invoke a poke_status over all folders, i.e., only the
1739 total/unread count will be updated */
1740 if (MODEST_IS_MAIN_WINDOW (win)) {
1741 GtkWidget *header_view, *folder_view;
1742 TnyFolderStore *folder_store;
1744 /* Get folder and header view */
1746 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1747 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1751 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1753 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1755 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1756 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1758 /* We do not need to set the contents style
1759 because it hasn't changed. We also do not
1760 need to save the widget status. Just force
1762 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1763 TNY_FOLDER (folder_store),
1764 folder_refreshed_cb,
1765 MODEST_MAIN_WINDOW (win));
1769 g_object_unref (folder_store);
1775 * Handler of the click on Send&Receive button in the main toolbar
1778 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1780 /* Check if accounts exist */
1781 gboolean accounts_exist =
1782 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1784 /* If not, allow the user to create an account before trying to send/receive. */
1785 if (!accounts_exist)
1786 modest_ui_actions_on_accounts (NULL, win);
1788 modest_do_refresh_current_folder (win);
1790 /* Refresh the active account */
1791 modest_ui_actions_do_send_receive (NULL, win);
1796 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1799 GtkWidget *header_view;
1801 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1803 header_view = modest_main_window_get_child_widget (main_window,
1804 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1808 conf = modest_runtime_get_conf ();
1810 /* what is saved/restored is depending on the style; thus; we save with
1811 * old style, then update the style, and restore for this new style
1813 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1815 if (modest_header_view_get_style
1816 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1817 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1818 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1820 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1821 MODEST_HEADER_VIEW_STYLE_DETAILS);
1823 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1824 MODEST_CONF_HEADER_VIEW_KEY);
1829 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1831 ModestMainWindow *main_window)
1833 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1834 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1836 /* in the case the folder is empty, show the empty folder message and focus
1838 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1839 if (modest_header_view_is_empty (header_view)) {
1840 TnyFolder *folder = modest_header_view_get_folder (header_view);
1841 GtkWidget *folder_view =
1842 modest_main_window_get_child_widget (main_window,
1843 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1845 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1846 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1850 /* If no header has been selected then exit */
1855 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1856 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1858 /* Update toolbar dimming state */
1859 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1863 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1865 ModestMainWindow *main_window)
1869 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1875 /* headers = tny_simple_list_new (); */
1876 /* tny_list_prepend (headers, G_OBJECT (header)); */
1877 headers = modest_header_view_get_selected_headers (header_view);
1879 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1881 g_object_unref (headers);
1885 set_active_account_from_tny_account (TnyAccount *account,
1886 ModestWindow *window)
1888 const gchar *server_acc_name = tny_account_get_id (account);
1890 /* We need the TnyAccount provided by the
1891 account store because that is the one that
1892 knows the name of the Modest account */
1893 TnyAccount *modest_server_account = modest_server_account =
1894 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1895 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1897 if (!modest_server_account) {
1898 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1902 /* Update active account, but only if it's not a pseudo-account */
1903 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1904 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1905 const gchar *modest_acc_name =
1906 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1907 if (modest_acc_name)
1908 modest_window_set_active_account (window, modest_acc_name);
1911 g_object_unref (modest_server_account);
1916 folder_refreshed_cb (ModestMailOperation *mail_op,
1920 ModestMainWindow *win = NULL;
1921 GtkWidget *header_view;
1922 gboolean folder_empty = FALSE;
1923 gboolean all_marked_as_deleted = FALSE;
1925 g_return_if_fail (TNY_IS_FOLDER (folder));
1927 win = MODEST_MAIN_WINDOW (user_data);
1929 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1932 TnyFolder *current_folder;
1934 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1935 if (current_folder != NULL && folder != current_folder) {
1936 g_object_unref (current_folder);
1939 g_object_unref (current_folder);
1942 /* Check if folder is empty and set headers view contents style */
1943 folder_empty = (tny_folder_get_all_count (folder) == 0);
1944 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1945 if (folder_empty || all_marked_as_deleted)
1946 modest_main_window_set_contents_style (win,
1947 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1951 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1952 TnyFolderStore *folder_store,
1954 ModestMainWindow *main_window)
1957 GtkWidget *header_view;
1959 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1961 header_view = modest_main_window_get_child_widget(main_window,
1962 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1966 conf = modest_runtime_get_conf ();
1968 if (TNY_IS_ACCOUNT (folder_store)) {
1970 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1972 /* Show account details */
1973 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1976 if (TNY_IS_FOLDER (folder_store) && selected) {
1978 /* Update the active account */
1979 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1981 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1982 g_object_unref (account);
1986 /* Set the header style by default, it could
1987 be changed later by the refresh callback to
1989 modest_main_window_set_contents_style (main_window,
1990 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1992 /* Set folder on header view. This function
1993 will call tny_folder_refresh_async so we
1994 pass a callback that will be called when
1995 finished. We use that callback to set the
1996 empty view if there are no messages */
1997 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1998 TNY_FOLDER (folder_store),
1999 folder_refreshed_cb,
2002 /* Restore configuration. We need to do this
2003 *after* the set_folder because the widget
2004 memory asks the header view about its
2006 modest_widget_memory_restore (modest_runtime_get_conf (),
2007 G_OBJECT(header_view),
2008 MODEST_CONF_HEADER_VIEW_KEY);
2010 /* Update the active account */
2011 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2012 /* Save only if we're seeing headers */
2013 if (modest_main_window_get_contents_style (main_window) ==
2014 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2015 modest_widget_memory_save (conf, G_OBJECT (header_view),
2016 MODEST_CONF_HEADER_VIEW_KEY);
2017 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2021 /* Update toolbar dimming state */
2022 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2026 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2033 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2035 online = tny_device_is_online (modest_runtime_get_device());
2038 /* already online -- the item is simply not there... */
2039 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2041 GTK_MESSAGE_WARNING,
2043 _("The %s you selected cannot be found"),
2045 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2046 gtk_dialog_run (GTK_DIALOG(dialog));
2048 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2051 _("mcen_bd_dialog_cancel"),
2052 GTK_RESPONSE_REJECT,
2053 _("mcen_bd_dialog_ok"),
2054 GTK_RESPONSE_ACCEPT,
2056 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2057 "Do you want to get online?"), item);
2058 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2059 gtk_label_new (txt), FALSE, FALSE, 0);
2060 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2063 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2064 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2065 /* TODO: Comment about why is this commented out: */
2066 /* modest_platform_connect_and_wait (); */
2069 gtk_widget_destroy (dialog);
2073 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2076 /* g_message ("%s %s", __FUNCTION__, link); */
2081 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2084 modest_platform_activate_uri (link);
2088 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2091 modest_platform_show_uri_popup (link);
2095 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2098 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2102 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2103 const gchar *address,
2106 /* g_message ("%s %s", __FUNCTION__, address); */
2110 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2112 TnyTransportAccount *transport_account;
2113 ModestMailOperation *mail_operation;
2115 gchar *account_name, *from;
2116 ModestAccountMgr *account_mgr;
2117 gchar *info_text = NULL;
2119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2121 data = modest_msg_edit_window_get_msg_data (edit_window);
2123 account_mgr = modest_runtime_get_account_mgr();
2124 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2126 account_name = modest_account_mgr_get_default_account (account_mgr);
2127 if (!account_name) {
2128 g_printerr ("modest: no account found\n");
2129 modest_msg_edit_window_free_msg_data (edit_window, data);
2133 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2134 account_name = g_strdup (data->account_name);
2138 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2139 (modest_runtime_get_account_store(),
2141 TNY_ACCOUNT_TYPE_TRANSPORT));
2142 if (!transport_account) {
2143 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2144 g_free (account_name);
2145 modest_msg_edit_window_free_msg_data (edit_window, data);
2148 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2150 /* Create the mail operation */
2151 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2152 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2154 modest_mail_operation_save_to_drafts (mail_operation,
2166 data->priority_flags);
2169 g_free (account_name);
2170 g_object_unref (G_OBJECT (transport_account));
2171 g_object_unref (G_OBJECT (mail_operation));
2173 modest_msg_edit_window_free_msg_data (edit_window, data);
2175 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2176 modest_platform_information_banner (NULL, NULL, info_text);
2180 /* For instance, when clicking the Send toolbar button when editing a message: */
2182 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2184 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2186 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2189 /* Offer the connection dialog, if necessary: */
2190 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2193 /* FIXME: Code added just for testing. The final version will
2194 use the send queue provided by tinymail and some
2196 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2197 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2199 account_name = modest_account_mgr_get_default_account (account_mgr);
2201 if (!account_name) {
2202 /* Run account setup wizard */
2203 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2208 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2210 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2211 account_name = g_strdup (data->account_name);
2214 /* Get the currently-active transport account for this modest account: */
2215 TnyTransportAccount *transport_account =
2216 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2217 (modest_runtime_get_account_store(),
2219 if (!transport_account) {
2220 /* Run account setup wizard */
2221 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2226 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2228 /* Create the mail operation */
2229 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2232 modest_mail_operation_send_new_mail (mail_operation,
2243 data->priority_flags);
2247 g_free (account_name);
2248 g_object_unref (G_OBJECT (transport_account));
2249 g_object_unref (G_OBJECT (mail_operation));
2251 modest_msg_edit_window_free_msg_data (edit_window, data);
2252 modest_msg_edit_window_set_sent (edit_window, TRUE);
2254 /* Save settings and close the window: */
2255 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2259 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2260 ModestMsgEditWindow *window)
2262 ModestMsgEditFormatState *format_state = NULL;
2264 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2265 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2267 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2270 format_state = modest_msg_edit_window_get_format_state (window);
2271 g_return_if_fail (format_state != NULL);
2273 format_state->bold = gtk_toggle_action_get_active (action);
2274 modest_msg_edit_window_set_format_state (window, format_state);
2275 g_free (format_state);
2280 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2281 ModestMsgEditWindow *window)
2283 ModestMsgEditFormatState *format_state = NULL;
2285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2286 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2288 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2291 format_state = modest_msg_edit_window_get_format_state (window);
2292 g_return_if_fail (format_state != NULL);
2294 format_state->italics = gtk_toggle_action_get_active (action);
2295 modest_msg_edit_window_set_format_state (window, format_state);
2296 g_free (format_state);
2301 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2302 ModestMsgEditWindow *window)
2304 ModestMsgEditFormatState *format_state = NULL;
2306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2307 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2309 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2312 format_state = modest_msg_edit_window_get_format_state (window);
2313 g_return_if_fail (format_state != NULL);
2315 format_state->bullet = gtk_toggle_action_get_active (action);
2316 modest_msg_edit_window_set_format_state (window, format_state);
2317 g_free (format_state);
2322 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2323 GtkRadioAction *selected,
2324 ModestMsgEditWindow *window)
2326 ModestMsgEditFormatState *format_state = NULL;
2327 GtkJustification value;
2329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2331 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2334 value = gtk_radio_action_get_current_value (selected);
2336 format_state = modest_msg_edit_window_get_format_state (window);
2337 g_return_if_fail (format_state != NULL);
2339 format_state->justification = value;
2340 modest_msg_edit_window_set_format_state (window, format_state);
2341 g_free (format_state);
2345 modest_ui_actions_on_select_editor_color (GtkAction *action,
2346 ModestMsgEditWindow *window)
2348 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2349 g_return_if_fail (GTK_IS_ACTION (action));
2351 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2354 modest_msg_edit_window_select_color (window);
2358 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2359 ModestMsgEditWindow *window)
2361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2362 g_return_if_fail (GTK_IS_ACTION (action));
2364 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2367 modest_msg_edit_window_select_background_color (window);
2371 modest_ui_actions_on_insert_image (GtkAction *action,
2372 ModestMsgEditWindow *window)
2374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2375 g_return_if_fail (GTK_IS_ACTION (action));
2377 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2380 modest_msg_edit_window_insert_image (window);
2384 modest_ui_actions_on_attach_file (GtkAction *action,
2385 ModestMsgEditWindow *window)
2387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2388 g_return_if_fail (GTK_IS_ACTION (action));
2390 modest_msg_edit_window_offer_attach_file (window);
2394 modest_ui_actions_on_remove_attachments (GtkAction *action,
2395 ModestMsgEditWindow *window)
2397 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2398 g_return_if_fail (GTK_IS_ACTION (action));
2400 modest_msg_edit_window_remove_attachments (window, NULL);
2404 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2407 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2408 const GError *error = modest_mail_operation_get_error (mail_op);
2412 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2413 modest_mail_operation_get_error (mail_op)->message);
2418 modest_ui_actions_create_folder(GtkWidget *parent_window,
2419 GtkWidget *folder_view)
2421 TnyFolderStore *parent_folder;
2423 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2425 if (parent_folder) {
2426 gboolean finished = FALSE;
2428 gchar *folder_name = NULL, *suggested_name = NULL;
2429 const gchar *proto_str = NULL;
2430 TnyAccount *account;
2432 if (TNY_IS_ACCOUNT (parent_folder))
2433 account = g_object_ref (parent_folder);
2435 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2436 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2438 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2439 MODEST_PROTOCOL_STORE_POP) {
2441 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2443 g_object_unref (account);
2445 /* Run the new folder dialog */
2447 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2452 g_free (suggested_name);
2453 suggested_name = NULL;
2455 if (result == GTK_RESPONSE_REJECT) {
2458 ModestMailOperation *mail_op;
2459 TnyFolder *new_folder = NULL;
2461 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2462 G_OBJECT(parent_window),
2463 modest_ui_actions_new_folder_error_handler,
2466 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2468 new_folder = modest_mail_operation_create_folder (mail_op,
2470 (const gchar *) folder_name);
2472 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2475 g_object_unref (new_folder);
2478 g_object_unref (mail_op);
2481 suggested_name = folder_name;
2485 g_object_unref (parent_folder);
2490 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2492 GtkWidget *folder_view;
2494 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2496 folder_view = modest_main_window_get_child_widget (main_window,
2497 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2501 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2505 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2508 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2509 const GError *error = NULL;
2510 const gchar *message = NULL;
2512 /* Get error message */
2513 error = modest_mail_operation_get_error (mail_op);
2515 g_return_if_reached ();
2517 switch (error->code) {
2518 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2519 message = _CS("ckdg_ib_folder_already_exists");
2522 g_return_if_reached ();
2525 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2529 modest_ui_actions_on_rename_folder (GtkAction *action,
2530 ModestMainWindow *main_window)
2532 TnyFolderStore *folder;
2533 GtkWidget *folder_view;
2534 GtkWidget *header_view;
2536 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2538 folder_view = modest_main_window_get_child_widget (main_window,
2539 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2543 header_view = modest_main_window_get_child_widget (main_window,
2544 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2549 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2554 if (TNY_IS_FOLDER (folder)) {
2557 const gchar *current_name;
2558 TnyFolderStore *parent;
2559 gboolean do_rename = TRUE;
2561 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2562 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2563 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2564 parent, current_name,
2566 g_object_unref (parent);
2568 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2570 } else if (modest_platform_is_network_folderstore(folder) &&
2571 !tny_device_is_online (modest_runtime_get_device())) {
2572 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2573 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2574 g_object_unref(account);
2578 ModestMailOperation *mail_op;
2579 GtkTreeSelection *sel = NULL;
2582 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2583 G_OBJECT(main_window),
2584 modest_ui_actions_rename_folder_error_handler,
2587 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2590 /* Clear the headers view */
2591 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2592 gtk_tree_selection_unselect_all (sel);
2594 /* Select *after* the changes */
2595 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2596 TNY_FOLDER(folder), TRUE);
2598 /* Actually rename the folder */
2599 modest_mail_operation_rename_folder (mail_op,
2600 TNY_FOLDER (folder),
2601 (const gchar *) folder_name);
2603 g_object_unref (mail_op);
2604 g_free (folder_name);
2607 g_object_unref (folder);
2611 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2614 GObject *win = modest_mail_operation_get_source (mail_op);
2616 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2617 _("mail_in_ui_folder_delete_error"));
2618 g_object_unref (win);
2622 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2624 TnyFolderStore *folder;
2625 GtkWidget *folder_view;
2628 gboolean do_delete = TRUE;
2630 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2632 folder_view = modest_main_window_get_child_widget (main_window,
2633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2637 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2639 /* Show an error if it's an account */
2640 if (!TNY_IS_FOLDER (folder)) {
2641 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2642 _("mail_in_ui_folder_delete_error"));
2643 g_object_unref (G_OBJECT (folder));
2648 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2649 tny_folder_get_name (TNY_FOLDER (folder)));
2650 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2651 (const gchar *) message);
2654 if (response != GTK_RESPONSE_OK) {
2656 } else if (modest_platform_is_network_folderstore(folder) &&
2657 !tny_device_is_online (modest_runtime_get_device())) {
2658 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2659 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2660 g_object_unref(account);
2664 ModestMailOperation *mail_op;
2665 GtkTreeSelection *sel;
2667 /* Unselect the folder before deleting it to free the headers */
2668 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2669 gtk_tree_selection_unselect_all (sel);
2671 /* Create the mail operation */
2673 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2674 G_OBJECT(main_window),
2675 modest_ui_actions_delete_folder_error_handler,
2678 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2680 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2681 g_object_unref (G_OBJECT (mail_op));
2684 g_object_unref (G_OBJECT (folder));
2690 modest_ui_actions_on_delete_folder (GtkAction *action,
2691 ModestMainWindow *main_window)
2693 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2695 if (delete_folder (main_window, FALSE)) {
2696 GtkWidget *folder_view;
2698 folder_view = modest_main_window_get_child_widget (main_window,
2699 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2700 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2705 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2707 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2709 delete_folder (main_window, TRUE);
2714 show_error (GtkWidget *parent_widget, const gchar* text)
2716 hildon_banner_show_information(parent_widget, NULL, text);
2719 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2721 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2728 gtk_dialog_run (dialog);
2729 gtk_widget_destroy (GTK_WIDGET (dialog));
2734 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2735 const gchar* server_account_name,
2740 ModestMainWindow *main_window)
2742 g_return_if_fail(server_account_name);
2743 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2745 /* Initalize output parameters: */
2752 #ifdef MODEST_PLATFORM_MAEMO
2753 /* Maemo uses a different (awkward) button order,
2754 * It should probably just use gtk_alternative_dialog_button_order ().
2756 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2759 _("mcen_bd_dialog_ok"),
2760 GTK_RESPONSE_ACCEPT,
2761 _("mcen_bd_dialog_cancel"),
2762 GTK_RESPONSE_REJECT,
2765 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2769 GTK_RESPONSE_REJECT,
2771 GTK_RESPONSE_ACCEPT,
2773 #endif /* MODEST_PLATFORM_MAEMO */
2775 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2777 gchar *server_name = modest_server_account_get_hostname (
2778 modest_runtime_get_account_mgr(), server_account_name);
2779 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2780 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2785 /* This causes a warning because the logical ID has no %s in it,
2786 * though the translation does, but there is not much we can do about that: */
2787 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2788 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2791 g_free (server_name);
2795 gchar *initial_username = modest_server_account_get_username (
2796 modest_runtime_get_account_mgr(), server_account_name);
2798 GtkWidget *entry_username = gtk_entry_new ();
2799 if (initial_username)
2800 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2801 /* Dim this if a connection has ever succeeded with this username,
2802 * as per the UI spec: */
2803 const gboolean username_known =
2804 modest_server_account_get_username_has_succeeded(
2805 modest_runtime_get_account_mgr(), server_account_name);
2806 gtk_widget_set_sensitive (entry_username, !username_known);
2808 #ifdef MODEST_PLATFORM_MAEMO
2809 /* Auto-capitalization is the default, so let's turn it off: */
2810 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2812 /* Create a size group to be used by all captions.
2813 * Note that HildonCaption does not create a default size group if we do not specify one.
2814 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2815 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2817 GtkWidget *caption = hildon_caption_new (sizegroup,
2818 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2819 gtk_widget_show (entry_username);
2820 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2821 FALSE, FALSE, MODEST_MARGIN_HALF);
2822 gtk_widget_show (caption);
2824 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2826 #endif /* MODEST_PLATFORM_MAEMO */
2829 GtkWidget *entry_password = gtk_entry_new ();
2830 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2831 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2833 #ifdef MODEST_PLATFORM_MAEMO
2834 /* Auto-capitalization is the default, so let's turn it off: */
2835 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2836 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2838 caption = hildon_caption_new (sizegroup,
2839 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2840 gtk_widget_show (entry_password);
2841 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2842 FALSE, FALSE, MODEST_MARGIN_HALF);
2843 gtk_widget_show (caption);
2844 g_object_unref (sizegroup);
2846 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2848 #endif /* MODEST_PLATFORM_MAEMO */
2850 /* This is not in the Maemo UI spec:
2851 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2852 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2856 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2858 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2860 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2862 modest_server_account_set_username (
2863 modest_runtime_get_account_mgr(), server_account_name,
2866 const gboolean username_was_changed =
2867 (strcmp (*username, initial_username) != 0);
2868 if (username_was_changed) {
2869 g_warning ("%s: tinymail does not yet support changing the "
2870 "username in the get_password() callback.\n", __FUNCTION__);
2875 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2877 /* We do not save the password in the configuration,
2878 * because this function is only called for passwords that should
2879 * not be remembered:
2880 modest_server_account_set_password (
2881 modest_runtime_get_account_mgr(), server_account_name,
2890 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2902 /* This is not in the Maemo UI spec:
2903 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2909 gtk_widget_destroy (dialog);
2911 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2915 modest_ui_actions_on_cut (GtkAction *action,
2916 ModestWindow *window)
2918 GtkWidget *focused_widget;
2919 GtkClipboard *clipboard;
2921 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2922 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2923 if (GTK_IS_EDITABLE (focused_widget)) {
2924 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2925 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2926 gtk_clipboard_store (clipboard);
2927 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2928 GtkTextBuffer *buffer;
2930 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2931 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2932 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2933 gtk_clipboard_store (clipboard);
2934 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2935 TnyList *header_list = modest_header_view_get_selected_headers (
2936 MODEST_HEADER_VIEW (focused_widget));
2937 gboolean continue_download = FALSE;
2938 gint num_of_unc_msgs;
2940 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2942 if (num_of_unc_msgs)
2943 continue_download = connect_to_get_msg(
2944 GTK_WINDOW (window),
2947 if (num_of_unc_msgs == 0 || continue_download) {
2948 /* modest_platform_information_banner (
2949 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2950 modest_header_view_cut_selection (
2951 MODEST_HEADER_VIEW (focused_widget));
2954 g_object_unref (header_list);
2955 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2956 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2961 modest_ui_actions_on_copy (GtkAction *action,
2962 ModestWindow *window)
2964 GtkClipboard *clipboard;
2965 GtkWidget *focused_widget;
2966 gboolean copied = TRUE;
2968 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2969 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2971 if (GTK_IS_LABEL (focused_widget)) {
2972 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2973 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2974 gtk_clipboard_store (clipboard);
2975 } else if (GTK_IS_EDITABLE (focused_widget)) {
2976 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2977 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2978 gtk_clipboard_store (clipboard);
2979 } else if (GTK_IS_HTML (focused_widget)) {
2980 gtk_html_copy (GTK_HTML (focused_widget));
2981 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2982 gtk_clipboard_store (clipboard);
2983 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2984 GtkTextBuffer *buffer;
2985 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2986 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2987 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2988 gtk_clipboard_store (clipboard);
2989 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2990 TnyList *header_list = modest_header_view_get_selected_headers (
2991 MODEST_HEADER_VIEW (focused_widget));
2992 gboolean continue_download = FALSE;
2993 gint num_of_unc_msgs;
2995 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2997 if (num_of_unc_msgs)
2998 continue_download = connect_to_get_msg(
2999 GTK_WINDOW (window),
3002 if (num_of_unc_msgs == 0 || continue_download) {
3003 modest_platform_information_banner (
3004 NULL, NULL, _CS("mcen_ib_getting_items"));
3005 modest_header_view_copy_selection (
3006 MODEST_HEADER_VIEW (focused_widget));
3010 g_object_unref (header_list);
3012 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3013 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3016 /* Show information banner if there was a copy to clipboard */
3018 modest_platform_information_banner (
3019 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3023 modest_ui_actions_on_undo (GtkAction *action,
3024 ModestWindow *window)
3026 ModestEmailClipboard *clipboard = NULL;
3028 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3029 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3030 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3031 /* Clear clipboard source */
3032 clipboard = modest_runtime_get_email_clipboard ();
3033 modest_email_clipboard_clear (clipboard);
3036 g_return_if_reached ();
3041 modest_ui_actions_on_redo (GtkAction *action,
3042 ModestWindow *window)
3044 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3045 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3048 g_return_if_reached ();
3054 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3056 /* destroy information note */
3057 gtk_widget_destroy (GTK_WIDGET(user_data));
3062 paste_as_attachment_free (gpointer data)
3064 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3066 gtk_widget_destroy (helper->banner);
3067 g_object_unref (helper->banner);
3072 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3077 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3078 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3083 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3088 modest_ui_actions_on_paste (GtkAction *action,
3089 ModestWindow *window)
3091 GtkWidget *focused_widget = NULL;
3092 GtkWidget *inf_note = NULL;
3093 ModestMailOperation *mail_op = NULL;
3095 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3096 if (GTK_IS_EDITABLE (focused_widget)) {
3097 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3098 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3099 ModestEmailClipboard *e_clipboard = NULL;
3100 e_clipboard = modest_runtime_get_email_clipboard ();
3101 if (modest_email_clipboard_cleared (e_clipboard)) {
3102 GtkTextBuffer *buffer;
3103 GtkClipboard *clipboard;
3105 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3106 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3107 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3108 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3109 ModestMailOperation *mail_op;
3110 TnyFolder *src_folder;
3113 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3114 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3115 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3116 _CS("ckct_nw_pasting"));
3117 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3118 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3120 if (helper->banner != NULL) {
3121 g_object_ref (G_OBJECT (helper->banner));
3122 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3123 gtk_widget_show (GTK_WIDGET (helper->banner));
3127 modest_mail_operation_get_msgs_full (mail_op,
3129 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3131 paste_as_attachment_free);
3134 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3135 ModestEmailClipboard *clipboard = NULL;
3136 TnyFolder *src_folder = NULL;
3137 TnyFolderStore *folder_store = NULL;
3138 TnyList *data = NULL;
3139 gboolean delete = FALSE;
3141 /* Check clipboard source */
3142 clipboard = modest_runtime_get_email_clipboard ();
3143 if (modest_email_clipboard_cleared (clipboard))
3146 /* Get elements to paste */
3147 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3149 /* Create a new mail operation */
3150 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3152 /* Get destination folder */
3153 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3155 /* transfer messages */
3159 /* Ask for user confirmation */
3161 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3162 TNY_FOLDER (folder_store),
3166 if (response == GTK_RESPONSE_OK) {
3167 /* Launch notification */
3168 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3169 _CS("ckct_nw_pasting"));
3170 if (inf_note != NULL) {
3171 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3172 gtk_widget_show (GTK_WIDGET(inf_note));
3175 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3176 modest_mail_operation_xfer_msgs (mail_op,
3178 TNY_FOLDER (folder_store),
3180 destroy_information_note,
3183 g_object_unref (mail_op);
3186 } else if (src_folder != NULL) {
3187 /* Launch notification */
3188 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3189 _CS("ckct_nw_pasting"));
3190 if (inf_note != NULL) {
3191 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3192 gtk_widget_show (GTK_WIDGET(inf_note));
3195 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3196 modest_mail_operation_xfer_folder (mail_op,
3200 destroy_information_note,
3206 g_object_unref (data);
3207 if (src_folder != NULL)
3208 g_object_unref (src_folder);
3209 if (folder_store != NULL)
3210 g_object_unref (folder_store);
3216 modest_ui_actions_on_select_all (GtkAction *action,
3217 ModestWindow *window)
3219 GtkWidget *focused_widget;
3221 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3222 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3223 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3224 } else if (GTK_IS_LABEL (focused_widget)) {
3225 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3226 } else if (GTK_IS_EDITABLE (focused_widget)) {
3227 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3228 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3229 GtkTextBuffer *buffer;
3230 GtkTextIter start, end;
3232 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3233 gtk_text_buffer_get_start_iter (buffer, &start);
3234 gtk_text_buffer_get_end_iter (buffer, &end);
3235 gtk_text_buffer_select_range (buffer, &start, &end);
3236 } else if (GTK_IS_HTML (focused_widget)) {
3237 gtk_html_select_all (GTK_HTML (focused_widget));
3238 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3239 GtkWidget *header_view = focused_widget;
3240 GtkTreeSelection *selection = NULL;
3242 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3243 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3244 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3247 /* Disable window dimming management */
3248 modest_window_disable_dimming (MODEST_WINDOW(window));
3250 /* Select all messages */
3251 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3252 gtk_tree_selection_select_all (selection);
3254 /* Set focuse on header view */
3255 gtk_widget_grab_focus (header_view);
3258 /* Enable window dimming management */
3259 modest_window_enable_dimming (MODEST_WINDOW(window));
3260 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3266 modest_ui_actions_on_mark_as_read (GtkAction *action,
3267 ModestWindow *window)
3269 g_return_if_fail (MODEST_IS_WINDOW(window));
3271 /* Mark each header as read */
3272 do_headers_action (window, headers_action_mark_as_read, NULL);
3276 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3277 ModestWindow *window)
3279 g_return_if_fail (MODEST_IS_WINDOW(window));
3281 /* Mark each header as read */
3282 do_headers_action (window, headers_action_mark_as_unread, NULL);
3286 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3287 GtkRadioAction *selected,
3288 ModestWindow *window)
3292 value = gtk_radio_action_get_current_value (selected);
3293 if (MODEST_IS_WINDOW (window)) {
3294 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3299 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3300 GtkRadioAction *selected,
3301 ModestWindow *window)
3303 TnyHeaderFlags flags;
3304 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3306 flags = gtk_radio_action_get_current_value (selected);
3307 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3311 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3312 GtkRadioAction *selected,
3313 ModestWindow *window)
3317 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3319 file_format = gtk_radio_action_get_current_value (selected);
3320 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3325 modest_ui_actions_on_zoom_plus (GtkAction *action,
3326 ModestWindow *window)
3328 g_return_if_fail (MODEST_IS_WINDOW (window));
3330 modest_window_zoom_plus (MODEST_WINDOW (window));
3334 modest_ui_actions_on_zoom_minus (GtkAction *action,
3335 ModestWindow *window)
3337 g_return_if_fail (MODEST_IS_WINDOW (window));
3339 modest_window_zoom_minus (MODEST_WINDOW (window));
3343 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3344 ModestWindow *window)
3346 ModestWindowMgr *mgr;
3347 gboolean fullscreen, active;
3348 g_return_if_fail (MODEST_IS_WINDOW (window));
3350 mgr = modest_runtime_get_window_mgr ();
3352 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3353 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3355 if (active != fullscreen) {
3356 modest_window_mgr_set_fullscreen_mode (mgr, active);
3357 gtk_window_present (GTK_WINDOW (window));
3362 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3363 ModestWindow *window)
3365 ModestWindowMgr *mgr;
3366 gboolean fullscreen;
3368 g_return_if_fail (MODEST_IS_WINDOW (window));
3370 mgr = modest_runtime_get_window_mgr ();
3371 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3372 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3374 gtk_window_present (GTK_WINDOW (window));
3378 * Used by modest_ui_actions_on_details to call do_headers_action
3381 headers_action_show_details (TnyHeader *header,
3382 ModestWindow *window,
3389 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3392 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3393 gtk_widget_show_all (dialog);
3394 gtk_dialog_run (GTK_DIALOG (dialog));
3396 gtk_widget_destroy (dialog);
3400 * Show the folder details in a ModestDetailsDialog widget
3403 show_folder_details (TnyFolder *folder,
3409 dialog = modest_details_dialog_new_with_folder (window, folder);
3412 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3413 gtk_widget_show_all (dialog);
3414 gtk_dialog_run (GTK_DIALOG (dialog));
3416 gtk_widget_destroy (dialog);
3420 * Show the header details in a ModestDetailsDialog widget
3423 modest_ui_actions_on_details (GtkAction *action,
3426 TnyList * headers_list;
3430 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3433 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3436 g_object_unref (msg);
3438 headers_list = get_selected_headers (win);
3442 iter = tny_list_create_iterator (headers_list);
3444 header = TNY_HEADER (tny_iterator_get_current (iter));
3446 headers_action_show_details (header, win, NULL);
3447 g_object_unref (header);
3450 g_object_unref (iter);
3451 g_object_unref (headers_list);
3453 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3454 GtkWidget *folder_view, *header_view;
3456 /* Check which widget has the focus */
3457 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3458 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3459 if (gtk_widget_is_focus (folder_view)) {
3460 TnyFolderStore *folder_store
3461 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3462 if (!folder_store) {
3463 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3466 /* Show only when it's a folder */
3467 /* This function should not be called for account items,
3468 * because we dim the menu item for them. */
3469 if (TNY_IS_FOLDER (folder_store)) {
3470 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3473 g_object_unref (folder_store);
3476 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3477 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3478 /* Show details of each header */
3479 do_headers_action (win, headers_action_show_details, header_view);
3485 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3486 ModestMsgEditWindow *window)
3488 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3490 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3494 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3495 ModestMsgEditWindow *window)
3497 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3499 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3503 modest_ui_actions_toggle_folders_view (GtkAction *action,
3504 ModestMainWindow *main_window)
3506 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3508 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3509 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3511 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3515 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3516 ModestWindow *window)
3518 gboolean active, fullscreen = FALSE;
3519 ModestWindowMgr *mgr;
3521 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3523 /* Check if we want to toggle the toolbar vuew in fullscreen
3525 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3526 "ViewShowToolbarFullScreen")) {
3530 /* Toggle toolbar */
3531 mgr = modest_runtime_get_window_mgr ();
3532 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3536 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3537 ModestMsgEditWindow *window)
3539 modest_msg_edit_window_select_font (window);
3543 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3544 const gchar *display_name,
3547 /* Do not change the application name if the widget has not
3548 the focus. This callback could be called even if the folder
3549 view has not the focus, because the handled signal could be
3550 emitted when the folder view is redrawn */
3551 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3553 gtk_window_set_title (window, display_name);
3555 gtk_window_set_title (window, " ");
3560 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3563 modest_msg_edit_window_select_contacts (window);
3567 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3570 modest_msg_edit_window_check_names (window, FALSE);
3574 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3576 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3577 GTK_WIDGET (user_data));
3581 * This function is used to track changes in the selection of the
3582 * folder view that is inside the "move to" dialog to enable/disable
3583 * the OK button because we do not want the user to select a disallowed
3584 * destination for a folder.
3585 * The user also not desired to be able to use NEW button on items where
3586 * folder creation is not possibel.
3589 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3590 TnyFolderStore *folder_store,
3594 GtkWidget *dialog = NULL;
3595 GtkWidget *ok_button = NULL, *new_button = NULL;
3596 GList *children = NULL;
3597 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3598 gboolean moving_folder = FALSE;
3599 gboolean is_local_account = TRUE;
3600 GtkWidget *folder_view = NULL;
3601 ModestTnyFolderRules rules;
3606 /* Get the OK button */
3607 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3611 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3612 ok_button = GTK_WIDGET (children->next->next->data);
3613 new_button = GTK_WIDGET (children->next->data);
3614 g_list_free (children);
3616 /* check if folder_store is an remote account */
3617 if (TNY_IS_ACCOUNT (folder_store)) {
3618 TnyAccount *local_account = NULL;
3619 ModestTnyAccountStore *account_store = NULL;
3621 account_store = modest_runtime_get_account_store ();
3622 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3624 if ((gpointer) local_account != (gpointer) folder_store) {
3625 is_local_account = FALSE;
3626 /* New button should be dimmed on remote
3628 new_sensitive = FALSE;
3630 g_object_unref (local_account);
3633 /* Check the target folder rules */
3634 if (TNY_IS_FOLDER (folder_store)) {
3635 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3636 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3637 ok_sensitive = FALSE;
3638 new_sensitive = FALSE;
3643 /* Check if we're moving a folder */
3644 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3645 /* Get the widgets */
3646 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3647 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3648 if (gtk_widget_is_focus (folder_view))
3649 moving_folder = TRUE;
3652 if (moving_folder) {
3653 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3655 /* Get the folder to move */
3656 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3658 /* Check that we're not moving to the same folder */
3659 if (TNY_IS_FOLDER (moved_folder)) {
3660 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3661 if (parent == folder_store)
3662 ok_sensitive = FALSE;
3663 g_object_unref (parent);
3666 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3667 /* Do not allow to move to an account unless it's the
3668 local folders account */
3669 if (!is_local_account)
3670 ok_sensitive = FALSE;
3673 if (ok_sensitive && (moved_folder == folder_store)) {
3674 /* Do not allow to move to itself */
3675 ok_sensitive = FALSE;
3677 g_object_unref (moved_folder);
3679 TnyHeader *header = NULL;
3680 TnyFolder *src_folder = NULL;
3682 /* Moving a message */
3683 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3684 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3685 src_folder = tny_header_get_folder (header);
3686 g_object_unref (header);
3689 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3692 /* Do not allow to move the msg to the same folder */
3693 /* Do not allow to move the msg to an account */
3694 if ((gpointer) src_folder == (gpointer) folder_store ||
3695 TNY_IS_ACCOUNT (folder_store))
3696 ok_sensitive = FALSE;
3697 g_object_unref (src_folder);
3701 /* Set sensitivity of the OK button */
3702 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3703 /* Set sensitivity of the NEW button */
3704 gtk_widget_set_sensitive (new_button, new_sensitive);
3708 create_move_to_dialog (GtkWindow *win,
3709 GtkWidget *folder_view,
3710 GtkWidget **tree_view)
3712 GtkWidget *dialog, *scroll;
3713 GtkWidget *new_button;
3715 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3717 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3720 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3721 /* We do this manually so GTK+ does not associate a response ID for
3723 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3724 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3725 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3727 /* Create scrolled window */
3728 scroll = gtk_scrolled_window_new (NULL, NULL);
3729 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3730 GTK_POLICY_AUTOMATIC,
3731 GTK_POLICY_AUTOMATIC);
3733 /* Create folder view */
3734 *tree_view = modest_platform_create_folder_view (NULL);
3736 /* Track changes in the selection to
3737 * disable the OK button whenever "Move to" is not possible
3738 * disbale NEW button whenever New is not possible */
3739 g_signal_connect (*tree_view,
3740 "folder_selection_changed",
3741 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3744 /* Listen to clicks on New button */
3745 g_signal_connect (G_OBJECT (new_button),
3747 G_CALLBACK(create_move_to_dialog_on_new_folder),
3750 /* It could happen that we're trying to move a message from a
3751 window (msg window for example) after the main window was
3752 closed, so we can not just get the model of the folder
3754 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3755 const gchar *visible_id = NULL;
3757 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3758 MODEST_FOLDER_VIEW(*tree_view));
3761 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3763 /* Show the same account than the one that is shown in the main window */
3764 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3767 const gchar *active_account_name = NULL;
3768 ModestAccountMgr *mgr = NULL;
3769 ModestAccountData *acc_data = NULL;
3771 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3772 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3774 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3775 mgr = modest_runtime_get_account_mgr ();
3776 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3778 /* Set the new visible & active account */
3779 if (acc_data && acc_data->store_account) {
3780 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3781 acc_data->store_account->account_name);
3782 modest_account_mgr_free_account_data (mgr, acc_data);
3786 /* Hide special folders */
3787 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3789 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3791 /* Add scroll to dialog */
3792 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3793 scroll, TRUE, TRUE, 0);
3795 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3796 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3802 * Returns TRUE if at least one of the headers of the list belongs to
3803 * a message that has been fully retrieved.
3805 #if 0 /* no longer in use. delete in 2007.10 */
3807 has_retrieved_msgs (TnyList *list)
3810 gboolean found = FALSE;
3812 iter = tny_list_create_iterator (list);
3813 while (!tny_iterator_is_done (iter) && !found) {
3815 TnyHeaderFlags flags = 0;
3817 header = TNY_HEADER (tny_iterator_get_current (iter));
3819 flags = tny_header_get_flags (header);
3820 if (flags & TNY_HEADER_FLAG_CACHED)
3821 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3824 g_object_unref (header);
3828 tny_iterator_next (iter);
3830 g_object_unref (iter);
3838 * Shows a confirmation dialog to the user when we're moving messages
3839 * from a remote server to the local storage. Returns the dialog
3840 * response. If it's other kind of movement then it always returns
3843 * This one is used by the next functions:
3844 * modest_ui_actions_on_paste - commented out
3845 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3848 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3849 TnyFolder *dest_folder,
3853 gint response = GTK_RESPONSE_OK;
3855 /* return with OK if the destination is a remote folder */
3856 if (modest_tny_folder_is_remote_folder (dest_folder))
3857 return GTK_RESPONSE_OK;
3859 TnyFolder *src_folder = NULL;
3860 TnyIterator *iter = NULL;
3861 TnyHeader *header = NULL;
3863 /* Get source folder */
3864 iter = tny_list_create_iterator (headers);
3865 header = TNY_HEADER (tny_iterator_get_current (iter));
3867 src_folder = tny_header_get_folder (header);
3868 g_object_unref (header);
3870 g_object_unref (iter);
3872 /* if no src_folder, message may be an attahcment */
3873 if (src_folder == NULL)
3874 return GTK_RESPONSE_CANCEL;
3876 /* If the source is a local or MMC folder */
3877 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3878 g_object_unref (src_folder);
3879 return GTK_RESPONSE_OK;
3881 g_object_unref (src_folder);
3883 /* now if offline we ask the user */
3884 if(connect_to_get_msg( GTK_WINDOW (win),
3885 tny_list_get_length (headers)))
3886 response = GTK_RESPONSE_OK;
3888 response = GTK_RESPONSE_CANCEL;
3896 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3898 /* Note that the operation could have failed, in that case do
3900 if (modest_mail_operation_get_status (mail_op) ==
3901 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3903 GObject *object = modest_mail_operation_get_source (mail_op);
3904 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3905 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3907 if (!modest_msg_view_window_select_next_message (self))
3908 if (!modest_msg_view_window_select_previous_message (self))
3909 /* No more messages to view, so close this window */
3910 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3912 g_object_unref (object);
3915 /* Close the "Pasting" information banner */
3916 gtk_widget_destroy (GTK_WIDGET(user_data));
3920 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3923 ModestWindow *main_window = NULL;
3924 GtkWidget *folder_view = NULL;
3925 GObject *win = modest_mail_operation_get_source (mail_op);
3926 const GError *error = NULL;
3927 const gchar *message = NULL;
3929 /* Get error message */
3930 error = modest_mail_operation_get_error (mail_op);
3931 if (error != NULL && error->message != NULL) {
3932 message = error->message;
3934 message = _("mail_in_ui_folder_move_target_error");
3937 /* Disable next automatic folder selection */
3938 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3939 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3940 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3941 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3943 if (user_data && TNY_IS_FOLDER (user_data)) {
3944 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3945 TNY_FOLDER (user_data), FALSE);
3948 /* Show notification dialog */
3949 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3950 g_object_unref (win);
3954 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3957 GObject *win = modest_mail_operation_get_source (mail_op);
3958 const GError *error = modest_mail_operation_get_error (mail_op);
3960 g_return_if_fail (error != NULL);
3961 if (error->message != NULL)
3962 g_printerr ("modest: %s\n", error->message);
3964 g_printerr ("modest: unkonw error on send&receive operation");
3966 /* Show error message */
3967 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3968 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3969 /* _CS("sfil_ib_unable_to_receive")); */
3971 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3972 /* _CS("sfil_ib_unable_to_send")); */
3973 g_object_unref (win);
3977 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3984 gint pending_purges = 0;
3985 gboolean some_purged = FALSE;
3986 ModestWindow *win = MODEST_WINDOW (user_data);
3987 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3989 /* If there was any error */
3990 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3991 modest_window_mgr_unregister_header (mgr, header);
3995 /* Once the message has been retrieved for purging, we check if
3996 * it's all ok for purging */
3998 parts = tny_simple_list_new ();
3999 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4000 iter = tny_list_create_iterator (parts);
4002 while (!tny_iterator_is_done (iter)) {
4004 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4005 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4006 if (tny_mime_part_is_purged (part))
4013 g_object_unref (part);
4015 tny_iterator_next (iter);
4017 g_object_unref (iter);
4020 if (pending_purges>0) {
4022 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4024 if (response == GTK_RESPONSE_OK) {
4025 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4026 iter = tny_list_create_iterator (parts);
4027 while (!tny_iterator_is_done (iter)) {
4030 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4031 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4032 tny_mime_part_set_purged (part);
4035 g_object_unref (part);
4037 tny_iterator_next (iter);
4040 tny_msg_rewrite_cache (msg);
4043 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4045 g_object_unref (iter);
4047 modest_window_mgr_unregister_header (mgr, header);
4049 g_object_unref (parts);
4053 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4054 ModestMainWindow *win)
4056 GtkWidget *header_view;
4057 TnyList *header_list;
4060 TnyHeaderFlags flags;
4061 ModestWindow *msg_view_window = NULL;
4064 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4066 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4067 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4069 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4071 if (tny_list_get_length (header_list) == 1) {
4072 iter = tny_list_create_iterator (header_list);
4073 header = TNY_HEADER (tny_iterator_get_current (iter));
4074 g_object_unref (iter);
4079 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4080 header, &msg_view_window);
4081 flags = tny_header_get_flags (header);
4082 if (!(flags & TNY_HEADER_FLAG_CACHED))
4085 if (msg_view_window != NULL)
4086 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4088 /* do nothing; uid was registered before, so window is probably on it's way */
4089 g_warning ("debug: header %p has already been registered", header);
4092 ModestMailOperation *mail_op = NULL;
4093 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4094 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4096 modest_ui_actions_get_msgs_full_error_handler,
4098 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4099 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4101 g_object_unref (mail_op);
4104 g_object_unref (header);
4106 g_object_unref (header_list);
4110 * Utility function that transfer messages from both the main window
4111 * and the msg view window when using the "Move to" dialog
4114 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4117 TnyList *headers = NULL;
4118 TnyAccount *dst_account = NULL;
4119 const gchar *proto_str = NULL;
4120 gboolean dst_is_pop = FALSE;
4122 if (!TNY_IS_FOLDER (dst_folder)) {
4123 modest_platform_information_banner (GTK_WIDGET (win),
4125 _CS("ckdg_ib_unable_to_move_to_current_location"));
4129 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4130 proto_str = tny_account_get_proto (dst_account);
4132 /* tinymail will return NULL for local folders it seems */
4133 dst_is_pop = proto_str &&
4134 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4135 MODEST_PROTOCOL_STORE_POP);
4137 g_object_unref (dst_account);
4139 /* Get selected headers */
4140 headers = get_selected_headers (MODEST_WINDOW (win));
4143 modest_platform_information_banner (GTK_WIDGET (win),
4145 ngettext("mail_in_ui_folder_move_target_error",
4146 "mail_in_ui_folder_move_targets_error",
4147 tny_list_get_length (headers)));
4148 g_object_unref (headers);
4152 GtkWidget *inf_note;
4153 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4154 _CS("ckct_nw_pasting"));
4155 if (inf_note != NULL) {
4156 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4157 gtk_widget_show (GTK_WIDGET(inf_note));
4160 ModestMailOperation *mail_op =
4161 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4163 modest_ui_actions_move_folder_error_handler,
4165 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4168 modest_mail_operation_xfer_msgs (mail_op,
4170 TNY_FOLDER (dst_folder),
4175 g_object_unref (G_OBJECT (mail_op));
4176 g_object_unref (headers);
4180 * UI handler for the "Move to" action when invoked from the
4184 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4185 GtkWidget *folder_view,
4186 TnyFolderStore *dst_folder,
4187 ModestMainWindow *win)
4189 ModestHeaderView *header_view = NULL;
4190 ModestMailOperation *mail_op = NULL;
4191 TnyFolderStore *src_folder;
4192 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4194 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4196 /* Get the source folder */
4197 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4199 /* Get header view */
4200 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4202 /* Get folder or messages to transfer */
4203 if (gtk_widget_is_focus (folder_view)) {
4204 GtkTreeSelection *sel;
4205 gboolean do_xfer = TRUE;
4207 /* Allow only to transfer folders to the local root folder */
4208 if (TNY_IS_ACCOUNT (dst_folder) &&
4209 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4211 } else if (!TNY_IS_FOLDER (src_folder)) {
4212 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4214 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4215 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4216 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4222 GtkWidget *inf_note;
4223 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4224 _CS("ckct_nw_pasting"));
4225 if (inf_note != NULL) {
4226 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4227 gtk_widget_show (GTK_WIDGET(inf_note));
4229 /* Clean folder on header view before moving it */
4230 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4231 gtk_tree_selection_unselect_all (sel);
4234 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4236 modest_ui_actions_move_folder_error_handler,
4238 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4241 /* Select *after* the changes */
4242 /* TODO: this function hangs UI after transfer */
4243 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4244 /* TNY_FOLDER (src_folder), TRUE); */
4246 modest_mail_operation_xfer_folder (mail_op,
4247 TNY_FOLDER (src_folder),
4252 /* Unref mail operation */
4253 g_object_unref (G_OBJECT (mail_op));
4255 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4256 gboolean do_xfer = TRUE;
4257 /* Ask for confirmation if the source folder is remote and we're not connected */
4258 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4259 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4260 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4261 guint num_headers = tny_list_get_length(headers);
4262 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4266 g_object_unref(headers);
4268 if (do_xfer) /* Transfer messages */
4269 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4273 g_object_unref (src_folder);
4278 * UI handler for the "Move to" action when invoked from the
4279 * ModestMsgViewWindow
4282 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4283 TnyFolderStore *dst_folder,
4284 ModestMsgViewWindow *win)
4286 TnyHeader *header = NULL;
4287 TnyFolderStore *src_folder;
4289 /* Create header list */
4290 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4291 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4292 g_object_unref (header);
4294 /* Transfer the message if online or confirmed by the user */
4295 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4296 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4297 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4300 g_object_unref (src_folder);
4304 modest_ui_actions_on_move_to (GtkAction *action,
4307 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4309 TnyFolderStore *dst_folder = NULL;
4310 ModestMainWindow *main_window;
4312 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4313 MODEST_IS_MSG_VIEW_WINDOW (win));
4315 /* Get the main window if exists */
4316 if (MODEST_IS_MAIN_WINDOW (win))
4317 main_window = MODEST_MAIN_WINDOW (win);
4320 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4322 /* Get the folder view widget if exists */
4324 folder_view = modest_main_window_get_child_widget (main_window,
4325 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4329 /* Create and run the dialog */
4330 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4331 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4332 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4333 result = gtk_dialog_run (GTK_DIALOG(dialog));
4334 g_object_ref (tree_view);
4335 gtk_widget_destroy (dialog);
4337 if (result != GTK_RESPONSE_ACCEPT)
4340 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4341 /* Do window specific stuff */
4342 if (MODEST_IS_MAIN_WINDOW (win)) {
4343 modest_ui_actions_on_main_window_move_to (action,
4346 MODEST_MAIN_WINDOW (win));
4348 modest_ui_actions_on_msg_view_window_move_to (action,
4350 MODEST_MSG_VIEW_WINDOW (win));
4354 g_object_unref (dst_folder);
4358 * Calls #HeadersFunc for each header already selected in the main
4359 * window or the message currently being shown in the msg view window
4362 do_headers_action (ModestWindow *win,
4366 TnyList *headers_list = NULL;
4367 TnyIterator *iter = NULL;
4368 TnyHeader *header = NULL;
4369 TnyFolder *folder = NULL;
4372 headers_list = get_selected_headers (win);
4376 /* Get the folder */
4377 iter = tny_list_create_iterator (headers_list);
4378 header = TNY_HEADER (tny_iterator_get_current (iter));
4380 folder = tny_header_get_folder (header);
4381 g_object_unref (header);
4384 /* Call the function for each header */
4385 while (!tny_iterator_is_done (iter)) {
4386 header = TNY_HEADER (tny_iterator_get_current (iter));
4387 func (header, win, user_data);
4388 g_object_unref (header);
4389 tny_iterator_next (iter);
4392 /* Trick: do a poke status in order to speed up the signaling
4394 tny_folder_poke_status (folder);
4397 g_object_unref (folder);
4398 g_object_unref (iter);
4399 g_object_unref (headers_list);
4403 modest_ui_actions_view_attachment (GtkAction *action,
4404 ModestWindow *window)
4406 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4407 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4409 /* not supported window for this action */
4410 g_return_if_reached ();
4415 modest_ui_actions_save_attachments (GtkAction *action,
4416 ModestWindow *window)
4418 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4419 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4421 /* not supported window for this action */
4422 g_return_if_reached ();
4427 modest_ui_actions_remove_attachments (GtkAction *action,
4428 ModestWindow *window)
4430 if (MODEST_IS_MAIN_WINDOW (window)) {
4431 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4432 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4433 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4435 /* not supported window for this action */
4436 g_return_if_reached ();
4441 modest_ui_actions_on_settings (GtkAction *action,
4446 dialog = modest_platform_get_global_settings_dialog ();
4447 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4448 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4449 gtk_widget_show_all (dialog);
4451 gtk_dialog_run (GTK_DIALOG (dialog));
4453 gtk_widget_destroy (dialog);
4457 modest_ui_actions_on_help (GtkAction *action,
4460 const gchar *help_id = NULL;
4462 if (MODEST_IS_MAIN_WINDOW (win)) {
4463 GtkWidget *folder_view;
4464 TnyFolderStore *folder_store;
4466 /* Get selected folder */
4467 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4468 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4469 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4471 /* Switch help_id */
4472 if (TNY_IS_FOLDER (folder_store)) {
4473 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4474 case TNY_FOLDER_TYPE_NORMAL:
4475 help_id = "applications_email_managefolders";
4477 case TNY_FOLDER_TYPE_INBOX:
4478 help_id = "applications_email_inbox";
4480 case TNY_FOLDER_TYPE_OUTBOX:
4481 help_id = "applications_email_outbox";
4483 case TNY_FOLDER_TYPE_SENT:
4484 help_id = "applications_email_sent";
4486 case TNY_FOLDER_TYPE_DRAFTS:
4487 help_id = "applications_email_drafts";
4489 case TNY_FOLDER_TYPE_ARCHIVE:
4490 help_id = "applications_email_managefolders";
4493 help_id = "applications_email_managefolders";
4496 help_id = "applications_email_mainview";
4498 g_object_unref (folder_store);
4499 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4500 help_id = "applications_email_viewer";
4501 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4502 help_id = "applications_email_editor";
4504 modest_platform_show_help (GTK_WINDOW (win), help_id);
4508 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4509 ModestWindow *window)
4511 ModestMailOperation *mail_op;
4515 headers = get_selected_headers (window);
4519 /* Create mail operation */
4520 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4522 modest_ui_actions_get_msgs_full_error_handler,
4524 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4525 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4528 g_object_unref (headers);
4529 g_object_unref (mail_op);
4533 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4534 ModestWindow *window)
4536 g_return_if_fail (MODEST_IS_WINDOW (window));
4539 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4543 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4544 ModestWindow *window)
4546 g_return_if_fail (MODEST_IS_WINDOW (window));
4549 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4553 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4554 ModestWindow *window)
4556 g_return_if_fail (MODEST_IS_WINDOW (window));
4559 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4563 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4564 ModestWindow *window)
4566 g_return_if_fail (MODEST_IS_WINDOW (window));
4569 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4573 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4574 ModestWindow *window)
4576 g_return_if_fail (MODEST_IS_WINDOW (window));
4579 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4583 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4584 ModestWindow *window)
4586 g_return_if_fail (MODEST_IS_WINDOW (window));
4589 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4593 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4594 ModestWindow *window)
4596 g_return_if_fail (MODEST_IS_WINDOW (window));
4599 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4603 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4604 ModestWindow *window)
4606 g_return_if_fail (MODEST_IS_WINDOW (window));
4609 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4613 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4614 ModestWindow *window)
4616 g_return_if_fail (MODEST_IS_WINDOW (window));
4619 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4623 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4625 g_return_if_fail (MODEST_IS_WINDOW (window));
4628 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4632 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4634 g_return_if_fail (MODEST_IS_WINDOW (window));
4636 modest_platform_show_search_messages (GTK_WINDOW (window));
4640 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4642 g_return_if_fail (MODEST_IS_WINDOW (win));
4643 modest_platform_show_addressbook (GTK_WINDOW (win));
4648 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4649 ModestWindow *window)
4651 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4653 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4657 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4658 ModestMailOperationState *state,
4661 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4663 /* Set send/receive operation finished */
4664 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4665 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4671 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4677 const gchar* server_name = NULL;
4678 TnyTransportAccount *server_account;
4679 gchar *message = NULL;
4681 /* Don't show anything if the user cancelled something */
4682 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4685 /* Get the server name: */
4687 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4688 if (server_account) {
4689 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4691 g_object_unref (server_account);
4692 server_account = NULL;
4695 g_return_if_fail (server_name);
4697 /* Show the appropriate message text for the GError: */
4698 switch (err->code) {
4699 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4700 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4702 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4703 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4705 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4706 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4708 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4709 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4712 g_return_if_reached ();
4715 /* TODO if the username or the password where not defined we
4716 should show the Accounts Settings dialog or the Connection
4717 specific SMTP server window */
4719 modest_platform_run_information_dialog (NULL, message);
4724 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4729 ModestMainWindow *main_window = NULL;
4730 ModestWindowMgr *mgr = NULL;
4731 GtkWidget *folder_view = NULL, *header_view = NULL;
4732 TnyFolderStore *selected_folder = NULL;
4733 TnyFolderType folder_type;
4735 mgr = modest_runtime_get_window_mgr ();
4736 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4741 /* Check if selected folder is OUTBOX */
4742 folder_view = modest_main_window_get_child_widget (main_window,
4743 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4744 header_view = modest_main_window_get_child_widget (main_window,
4745 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4747 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4748 if (!TNY_IS_FOLDER (selected_folder))
4751 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4752 #if GTK_CHECK_VERSION(2, 8, 0)
4753 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4754 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4755 GtkTreeViewColumn *tree_column;
4757 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4758 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4759 gtk_tree_view_column_queue_resize (tree_column);
4762 gtk_widget_queue_draw (header_view);
4767 if (selected_folder != NULL)
4768 g_object_unref (selected_folder);