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));
1874 if (modest_header_view_count_selected_headers (header_view) > 1) {
1875 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1880 /* headers = tny_simple_list_new (); */
1881 /* tny_list_prepend (headers, G_OBJECT (header)); */
1882 headers = modest_header_view_get_selected_headers (header_view);
1884 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1886 g_object_unref (headers);
1890 set_active_account_from_tny_account (TnyAccount *account,
1891 ModestWindow *window)
1893 const gchar *server_acc_name = tny_account_get_id (account);
1895 /* We need the TnyAccount provided by the
1896 account store because that is the one that
1897 knows the name of the Modest account */
1898 TnyAccount *modest_server_account = modest_server_account =
1899 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1900 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1902 if (!modest_server_account) {
1903 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1907 /* Update active account, but only if it's not a pseudo-account */
1908 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1909 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1910 const gchar *modest_acc_name =
1911 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1912 if (modest_acc_name)
1913 modest_window_set_active_account (window, modest_acc_name);
1916 g_object_unref (modest_server_account);
1921 folder_refreshed_cb (ModestMailOperation *mail_op,
1925 ModestMainWindow *win = NULL;
1926 GtkWidget *header_view;
1927 gboolean folder_empty = FALSE;
1928 gboolean all_marked_as_deleted = FALSE;
1930 g_return_if_fail (TNY_IS_FOLDER (folder));
1932 win = MODEST_MAIN_WINDOW (user_data);
1934 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1937 TnyFolder *current_folder;
1939 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1940 if (current_folder != NULL && folder != current_folder) {
1941 g_object_unref (current_folder);
1944 g_object_unref (current_folder);
1947 /* Check if folder is empty and set headers view contents style */
1948 folder_empty = (tny_folder_get_all_count (folder) == 0);
1949 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1950 if (folder_empty || all_marked_as_deleted)
1951 modest_main_window_set_contents_style (win,
1952 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1956 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1957 TnyFolderStore *folder_store,
1959 ModestMainWindow *main_window)
1962 GtkWidget *header_view;
1964 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1966 header_view = modest_main_window_get_child_widget(main_window,
1967 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1971 conf = modest_runtime_get_conf ();
1973 if (TNY_IS_ACCOUNT (folder_store)) {
1975 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1977 /* Show account details */
1978 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1981 if (TNY_IS_FOLDER (folder_store) && selected) {
1983 /* Update the active account */
1984 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1986 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1987 g_object_unref (account);
1991 /* Set the header style by default, it could
1992 be changed later by the refresh callback to
1994 modest_main_window_set_contents_style (main_window,
1995 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1997 /* Set folder on header view. This function
1998 will call tny_folder_refresh_async so we
1999 pass a callback that will be called when
2000 finished. We use that callback to set the
2001 empty view if there are no messages */
2002 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2003 TNY_FOLDER (folder_store),
2004 folder_refreshed_cb,
2007 /* Restore configuration. We need to do this
2008 *after* the set_folder because the widget
2009 memory asks the header view about its
2011 modest_widget_memory_restore (modest_runtime_get_conf (),
2012 G_OBJECT(header_view),
2013 MODEST_CONF_HEADER_VIEW_KEY);
2015 /* Update the active account */
2016 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2017 /* Save only if we're seeing headers */
2018 if (modest_main_window_get_contents_style (main_window) ==
2019 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2020 modest_widget_memory_save (conf, G_OBJECT (header_view),
2021 MODEST_CONF_HEADER_VIEW_KEY);
2022 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2026 /* Update toolbar dimming state */
2027 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2031 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2038 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2040 online = tny_device_is_online (modest_runtime_get_device());
2043 /* already online -- the item is simply not there... */
2044 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2046 GTK_MESSAGE_WARNING,
2048 _("The %s you selected cannot be found"),
2050 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2051 gtk_dialog_run (GTK_DIALOG(dialog));
2053 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2056 _("mcen_bd_dialog_cancel"),
2057 GTK_RESPONSE_REJECT,
2058 _("mcen_bd_dialog_ok"),
2059 GTK_RESPONSE_ACCEPT,
2061 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2062 "Do you want to get online?"), item);
2063 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2064 gtk_label_new (txt), FALSE, FALSE, 0);
2065 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2068 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2069 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2070 /* TODO: Comment about why is this commented out: */
2071 /* modest_platform_connect_and_wait (); */
2074 gtk_widget_destroy (dialog);
2078 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2081 /* g_message ("%s %s", __FUNCTION__, link); */
2086 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2089 modest_platform_activate_uri (link);
2093 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2096 modest_platform_show_uri_popup (link);
2100 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2103 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2107 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2108 const gchar *address,
2111 /* g_message ("%s %s", __FUNCTION__, address); */
2115 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2117 TnyTransportAccount *transport_account;
2118 ModestMailOperation *mail_operation;
2120 gchar *account_name, *from;
2121 ModestAccountMgr *account_mgr;
2122 gchar *info_text = NULL;
2124 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2126 data = modest_msg_edit_window_get_msg_data (edit_window);
2128 account_mgr = modest_runtime_get_account_mgr();
2129 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2131 account_name = modest_account_mgr_get_default_account (account_mgr);
2132 if (!account_name) {
2133 g_printerr ("modest: no account found\n");
2134 modest_msg_edit_window_free_msg_data (edit_window, data);
2138 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2139 account_name = g_strdup (data->account_name);
2143 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2144 (modest_runtime_get_account_store(),
2146 TNY_ACCOUNT_TYPE_TRANSPORT));
2147 if (!transport_account) {
2148 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2149 g_free (account_name);
2150 modest_msg_edit_window_free_msg_data (edit_window, data);
2153 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2155 /* Create the mail operation */
2156 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2157 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2159 modest_mail_operation_save_to_drafts (mail_operation,
2171 data->priority_flags);
2174 g_free (account_name);
2175 g_object_unref (G_OBJECT (transport_account));
2176 g_object_unref (G_OBJECT (mail_operation));
2178 modest_msg_edit_window_free_msg_data (edit_window, data);
2180 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2181 modest_platform_information_banner (NULL, NULL, info_text);
2182 modest_msg_edit_window_reset_modified (edit_window);
2186 /* For instance, when clicking the Send toolbar button when editing a message: */
2188 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2190 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2192 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2195 /* Offer the connection dialog, if necessary: */
2196 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2199 /* FIXME: Code added just for testing. The final version will
2200 use the send queue provided by tinymail and some
2202 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2203 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2205 account_name = modest_account_mgr_get_default_account (account_mgr);
2207 if (!account_name) {
2208 /* Run account setup wizard */
2209 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2214 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2216 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2217 account_name = g_strdup (data->account_name);
2220 /* Get the currently-active transport account for this modest account: */
2221 TnyTransportAccount *transport_account =
2222 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2223 (modest_runtime_get_account_store(),
2225 if (!transport_account) {
2226 /* Run account setup wizard */
2227 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2232 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2234 /* Create the mail operation */
2235 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2236 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2238 modest_mail_operation_send_new_mail (mail_operation,
2249 data->priority_flags);
2253 g_free (account_name);
2254 g_object_unref (G_OBJECT (transport_account));
2255 g_object_unref (G_OBJECT (mail_operation));
2257 modest_msg_edit_window_free_msg_data (edit_window, data);
2258 modest_msg_edit_window_set_sent (edit_window, TRUE);
2260 /* Save settings and close the window: */
2261 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2265 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2266 ModestMsgEditWindow *window)
2268 ModestMsgEditFormatState *format_state = NULL;
2270 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2271 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2273 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2276 format_state = modest_msg_edit_window_get_format_state (window);
2277 g_return_if_fail (format_state != NULL);
2279 format_state->bold = gtk_toggle_action_get_active (action);
2280 modest_msg_edit_window_set_format_state (window, format_state);
2281 g_free (format_state);
2286 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2287 ModestMsgEditWindow *window)
2289 ModestMsgEditFormatState *format_state = NULL;
2291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2292 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2294 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2297 format_state = modest_msg_edit_window_get_format_state (window);
2298 g_return_if_fail (format_state != NULL);
2300 format_state->italics = gtk_toggle_action_get_active (action);
2301 modest_msg_edit_window_set_format_state (window, format_state);
2302 g_free (format_state);
2307 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2308 ModestMsgEditWindow *window)
2310 ModestMsgEditFormatState *format_state = NULL;
2312 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2313 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2315 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2318 format_state = modest_msg_edit_window_get_format_state (window);
2319 g_return_if_fail (format_state != NULL);
2321 format_state->bullet = gtk_toggle_action_get_active (action);
2322 modest_msg_edit_window_set_format_state (window, format_state);
2323 g_free (format_state);
2328 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2329 GtkRadioAction *selected,
2330 ModestMsgEditWindow *window)
2332 ModestMsgEditFormatState *format_state = NULL;
2333 GtkJustification value;
2335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2337 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2340 value = gtk_radio_action_get_current_value (selected);
2342 format_state = modest_msg_edit_window_get_format_state (window);
2343 g_return_if_fail (format_state != NULL);
2345 format_state->justification = value;
2346 modest_msg_edit_window_set_format_state (window, format_state);
2347 g_free (format_state);
2351 modest_ui_actions_on_select_editor_color (GtkAction *action,
2352 ModestMsgEditWindow *window)
2354 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2355 g_return_if_fail (GTK_IS_ACTION (action));
2357 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2360 modest_msg_edit_window_select_color (window);
2364 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2365 ModestMsgEditWindow *window)
2367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2368 g_return_if_fail (GTK_IS_ACTION (action));
2370 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2373 modest_msg_edit_window_select_background_color (window);
2377 modest_ui_actions_on_insert_image (GtkAction *action,
2378 ModestMsgEditWindow *window)
2380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2381 g_return_if_fail (GTK_IS_ACTION (action));
2383 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2386 modest_msg_edit_window_insert_image (window);
2390 modest_ui_actions_on_attach_file (GtkAction *action,
2391 ModestMsgEditWindow *window)
2393 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2394 g_return_if_fail (GTK_IS_ACTION (action));
2396 modest_msg_edit_window_offer_attach_file (window);
2400 modest_ui_actions_on_remove_attachments (GtkAction *action,
2401 ModestMsgEditWindow *window)
2403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2404 g_return_if_fail (GTK_IS_ACTION (action));
2406 modest_msg_edit_window_remove_attachments (window, NULL);
2410 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2413 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2414 const GError *error = modest_mail_operation_get_error (mail_op);
2417 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2418 _("mail_in_ui_folder_create_error"));
2423 modest_ui_actions_create_folder(GtkWidget *parent_window,
2424 GtkWidget *folder_view)
2426 TnyFolderStore *parent_folder;
2428 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2430 if (parent_folder) {
2431 gboolean finished = FALSE;
2433 gchar *folder_name = NULL, *suggested_name = NULL;
2434 const gchar *proto_str = NULL;
2435 TnyAccount *account;
2437 if (TNY_IS_ACCOUNT (parent_folder))
2438 account = g_object_ref (parent_folder);
2440 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2441 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2443 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2444 MODEST_PROTOCOL_STORE_POP) {
2446 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2448 g_object_unref (account);
2450 /* Run the new folder dialog */
2452 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2457 g_free (suggested_name);
2458 suggested_name = NULL;
2460 if (result == GTK_RESPONSE_REJECT) {
2463 ModestMailOperation *mail_op;
2464 TnyFolder *new_folder = NULL;
2466 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2467 G_OBJECT(parent_window),
2468 modest_ui_actions_new_folder_error_handler,
2471 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2473 new_folder = modest_mail_operation_create_folder (mail_op,
2475 (const gchar *) folder_name);
2477 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2480 g_object_unref (new_folder);
2483 g_object_unref (mail_op);
2486 suggested_name = folder_name;
2490 g_object_unref (parent_folder);
2495 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2497 GtkWidget *folder_view;
2499 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2501 folder_view = modest_main_window_get_child_widget (main_window,
2502 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2506 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2510 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2513 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2514 const GError *error = NULL;
2515 const gchar *message = NULL;
2517 /* Get error message */
2518 error = modest_mail_operation_get_error (mail_op);
2520 g_return_if_reached ();
2522 switch (error->code) {
2523 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2524 message = _CS("ckdg_ib_folder_already_exists");
2527 g_return_if_reached ();
2530 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2534 modest_ui_actions_on_rename_folder (GtkAction *action,
2535 ModestMainWindow *main_window)
2537 TnyFolderStore *folder;
2538 GtkWidget *folder_view;
2539 GtkWidget *header_view;
2541 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2543 folder_view = modest_main_window_get_child_widget (main_window,
2544 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2548 header_view = modest_main_window_get_child_widget (main_window,
2549 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2554 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2559 if (TNY_IS_FOLDER (folder)) {
2562 const gchar *current_name;
2563 TnyFolderStore *parent;
2564 gboolean do_rename = TRUE;
2566 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2567 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2568 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2569 parent, current_name,
2571 g_object_unref (parent);
2573 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2575 } else if (modest_platform_is_network_folderstore(folder) &&
2576 !tny_device_is_online (modest_runtime_get_device())) {
2577 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2578 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2579 g_object_unref(account);
2583 ModestMailOperation *mail_op;
2584 GtkTreeSelection *sel = NULL;
2587 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2588 G_OBJECT(main_window),
2589 modest_ui_actions_rename_folder_error_handler,
2592 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2595 /* Clear the headers view */
2596 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2597 gtk_tree_selection_unselect_all (sel);
2599 /* Select *after* the changes */
2600 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2601 TNY_FOLDER(folder), TRUE);
2603 /* Actually rename the folder */
2604 modest_mail_operation_rename_folder (mail_op,
2605 TNY_FOLDER (folder),
2606 (const gchar *) folder_name);
2608 g_object_unref (mail_op);
2609 g_free (folder_name);
2612 g_object_unref (folder);
2616 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2619 GObject *win = modest_mail_operation_get_source (mail_op);
2621 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2622 _("mail_in_ui_folder_delete_error"));
2623 g_object_unref (win);
2627 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2629 TnyFolderStore *folder;
2630 GtkWidget *folder_view;
2633 gboolean do_delete = TRUE;
2635 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2637 folder_view = modest_main_window_get_child_widget (main_window,
2638 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2642 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2644 /* Show an error if it's an account */
2645 if (!TNY_IS_FOLDER (folder)) {
2646 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2647 _("mail_in_ui_folder_delete_error"));
2648 g_object_unref (G_OBJECT (folder));
2653 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2654 tny_folder_get_name (TNY_FOLDER (folder)));
2655 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2656 (const gchar *) message);
2659 if (response != GTK_RESPONSE_OK) {
2661 } else if (modest_platform_is_network_folderstore(folder) &&
2662 !tny_device_is_online (modest_runtime_get_device())) {
2663 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2664 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2665 g_object_unref(account);
2669 ModestMailOperation *mail_op;
2670 GtkTreeSelection *sel;
2672 /* Unselect the folder before deleting it to free the headers */
2673 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2674 gtk_tree_selection_unselect_all (sel);
2676 /* Create the mail operation */
2678 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2679 G_OBJECT(main_window),
2680 modest_ui_actions_delete_folder_error_handler,
2683 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2685 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2686 g_object_unref (G_OBJECT (mail_op));
2689 g_object_unref (G_OBJECT (folder));
2695 modest_ui_actions_on_delete_folder (GtkAction *action,
2696 ModestMainWindow *main_window)
2698 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2700 if (delete_folder (main_window, FALSE)) {
2701 GtkWidget *folder_view;
2703 folder_view = modest_main_window_get_child_widget (main_window,
2704 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2705 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2710 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2712 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2714 delete_folder (main_window, TRUE);
2719 show_error (GtkWidget *parent_widget, const gchar* text)
2721 hildon_banner_show_information(parent_widget, NULL, text);
2724 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2726 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2733 gtk_dialog_run (dialog);
2734 gtk_widget_destroy (GTK_WIDGET (dialog));
2739 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2740 const gchar* server_account_name,
2745 ModestMainWindow *main_window)
2747 g_return_if_fail(server_account_name);
2748 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2750 /* Initalize output parameters: */
2757 #ifdef MODEST_PLATFORM_MAEMO
2758 /* Maemo uses a different (awkward) button order,
2759 * It should probably just use gtk_alternative_dialog_button_order ().
2761 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2764 _("mcen_bd_dialog_ok"),
2765 GTK_RESPONSE_ACCEPT,
2766 _("mcen_bd_dialog_cancel"),
2767 GTK_RESPONSE_REJECT,
2770 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2774 GTK_RESPONSE_REJECT,
2776 GTK_RESPONSE_ACCEPT,
2778 #endif /* MODEST_PLATFORM_MAEMO */
2780 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2782 gchar *server_name = modest_server_account_get_hostname (
2783 modest_runtime_get_account_mgr(), server_account_name);
2784 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2785 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2790 /* This causes a warning because the logical ID has no %s in it,
2791 * though the translation does, but there is not much we can do about that: */
2792 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2793 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2796 g_free (server_name);
2800 gchar *initial_username = modest_server_account_get_username (
2801 modest_runtime_get_account_mgr(), server_account_name);
2803 GtkWidget *entry_username = gtk_entry_new ();
2804 if (initial_username)
2805 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2806 /* Dim this if a connection has ever succeeded with this username,
2807 * as per the UI spec: */
2808 const gboolean username_known =
2809 modest_server_account_get_username_has_succeeded(
2810 modest_runtime_get_account_mgr(), server_account_name);
2811 gtk_widget_set_sensitive (entry_username, !username_known);
2813 #ifdef MODEST_PLATFORM_MAEMO
2814 /* Auto-capitalization is the default, so let's turn it off: */
2815 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2817 /* Create a size group to be used by all captions.
2818 * Note that HildonCaption does not create a default size group if we do not specify one.
2819 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2820 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2822 GtkWidget *caption = hildon_caption_new (sizegroup,
2823 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2824 gtk_widget_show (entry_username);
2825 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2826 FALSE, FALSE, MODEST_MARGIN_HALF);
2827 gtk_widget_show (caption);
2829 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2831 #endif /* MODEST_PLATFORM_MAEMO */
2834 GtkWidget *entry_password = gtk_entry_new ();
2835 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2836 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2838 #ifdef MODEST_PLATFORM_MAEMO
2839 /* Auto-capitalization is the default, so let's turn it off: */
2840 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2841 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2843 caption = hildon_caption_new (sizegroup,
2844 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2845 gtk_widget_show (entry_password);
2846 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2847 FALSE, FALSE, MODEST_MARGIN_HALF);
2848 gtk_widget_show (caption);
2849 g_object_unref (sizegroup);
2851 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2853 #endif /* MODEST_PLATFORM_MAEMO */
2855 if (initial_username != NULL)
2856 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2858 /* This is not in the Maemo UI spec:
2859 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2860 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2864 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2866 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2868 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2870 modest_server_account_set_username (
2871 modest_runtime_get_account_mgr(), server_account_name,
2874 const gboolean username_was_changed =
2875 (strcmp (*username, initial_username) != 0);
2876 if (username_was_changed) {
2877 g_warning ("%s: tinymail does not yet support changing the "
2878 "username in the get_password() callback.\n", __FUNCTION__);
2883 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2885 /* We do not save the password in the configuration,
2886 * because this function is only called for passwords that should
2887 * not be remembered:
2888 modest_server_account_set_password (
2889 modest_runtime_get_account_mgr(), server_account_name,
2898 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2910 /* This is not in the Maemo UI spec:
2911 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2917 gtk_widget_destroy (dialog);
2919 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2923 modest_ui_actions_on_cut (GtkAction *action,
2924 ModestWindow *window)
2926 GtkWidget *focused_widget;
2927 GtkClipboard *clipboard;
2929 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2930 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2931 if (GTK_IS_EDITABLE (focused_widget)) {
2932 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2933 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2934 gtk_clipboard_store (clipboard);
2935 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2936 GtkTextBuffer *buffer;
2938 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2939 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2940 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2941 gtk_clipboard_store (clipboard);
2942 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2943 TnyList *header_list = modest_header_view_get_selected_headers (
2944 MODEST_HEADER_VIEW (focused_widget));
2945 gboolean continue_download = FALSE;
2946 gint num_of_unc_msgs;
2948 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2950 if (num_of_unc_msgs)
2951 continue_download = connect_to_get_msg(
2952 GTK_WINDOW (window),
2955 if (num_of_unc_msgs == 0 || continue_download) {
2956 /* modest_platform_information_banner (
2957 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2958 modest_header_view_cut_selection (
2959 MODEST_HEADER_VIEW (focused_widget));
2962 g_object_unref (header_list);
2963 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2964 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2969 modest_ui_actions_on_copy (GtkAction *action,
2970 ModestWindow *window)
2972 GtkClipboard *clipboard;
2973 GtkWidget *focused_widget;
2974 gboolean copied = TRUE;
2976 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2977 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2979 if (GTK_IS_LABEL (focused_widget)) {
2980 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2981 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2982 gtk_clipboard_store (clipboard);
2983 } else if (GTK_IS_EDITABLE (focused_widget)) {
2984 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2985 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2986 gtk_clipboard_store (clipboard);
2987 } else if (GTK_IS_HTML (focused_widget)) {
2988 gtk_html_copy (GTK_HTML (focused_widget));
2989 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2990 gtk_clipboard_store (clipboard);
2991 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2992 GtkTextBuffer *buffer;
2993 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2994 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2995 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2996 gtk_clipboard_store (clipboard);
2997 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2998 TnyList *header_list = modest_header_view_get_selected_headers (
2999 MODEST_HEADER_VIEW (focused_widget));
3000 gboolean continue_download = FALSE;
3001 gint num_of_unc_msgs;
3003 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3005 if (num_of_unc_msgs)
3006 continue_download = connect_to_get_msg(
3007 GTK_WINDOW (window),
3010 if (num_of_unc_msgs == 0 || continue_download) {
3011 modest_platform_information_banner (
3012 NULL, NULL, _CS("mcen_ib_getting_items"));
3013 modest_header_view_copy_selection (
3014 MODEST_HEADER_VIEW (focused_widget));
3018 g_object_unref (header_list);
3020 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3021 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3024 /* Show information banner if there was a copy to clipboard */
3026 modest_platform_information_banner (
3027 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3031 modest_ui_actions_on_undo (GtkAction *action,
3032 ModestWindow *window)
3034 ModestEmailClipboard *clipboard = NULL;
3036 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3037 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3038 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3039 /* Clear clipboard source */
3040 clipboard = modest_runtime_get_email_clipboard ();
3041 modest_email_clipboard_clear (clipboard);
3044 g_return_if_reached ();
3049 modest_ui_actions_on_redo (GtkAction *action,
3050 ModestWindow *window)
3052 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3053 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3056 g_return_if_reached ();
3062 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3064 /* destroy information note */
3065 gtk_widget_destroy (GTK_WIDGET(user_data));
3070 paste_as_attachment_free (gpointer data)
3072 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3074 gtk_widget_destroy (helper->banner);
3075 g_object_unref (helper->banner);
3080 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3085 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3086 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3091 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3096 modest_ui_actions_on_paste (GtkAction *action,
3097 ModestWindow *window)
3099 GtkWidget *focused_widget = NULL;
3100 GtkWidget *inf_note = NULL;
3101 ModestMailOperation *mail_op = NULL;
3103 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3104 if (GTK_IS_EDITABLE (focused_widget)) {
3105 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3106 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3107 ModestEmailClipboard *e_clipboard = NULL;
3108 e_clipboard = modest_runtime_get_email_clipboard ();
3109 if (modest_email_clipboard_cleared (e_clipboard)) {
3110 GtkTextBuffer *buffer;
3111 GtkClipboard *clipboard;
3113 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3114 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3115 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3116 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3117 ModestMailOperation *mail_op;
3118 TnyFolder *src_folder;
3121 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3122 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3123 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3124 _CS("ckct_nw_pasting"));
3125 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3126 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3128 if (helper->banner != NULL) {
3129 g_object_ref (G_OBJECT (helper->banner));
3130 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3131 gtk_widget_show (GTK_WIDGET (helper->banner));
3135 modest_mail_operation_get_msgs_full (mail_op,
3137 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3139 paste_as_attachment_free);
3142 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3143 ModestEmailClipboard *clipboard = NULL;
3144 TnyFolder *src_folder = NULL;
3145 TnyFolderStore *folder_store = NULL;
3146 TnyList *data = NULL;
3147 gboolean delete = FALSE;
3149 /* Check clipboard source */
3150 clipboard = modest_runtime_get_email_clipboard ();
3151 if (modest_email_clipboard_cleared (clipboard))
3154 /* Get elements to paste */
3155 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3157 /* Create a new mail operation */
3158 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3160 /* Get destination folder */
3161 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3163 /* transfer messages */
3167 /* Ask for user confirmation */
3169 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3170 TNY_FOLDER (folder_store),
3174 if (response == GTK_RESPONSE_OK) {
3175 /* Launch notification */
3176 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3177 _CS("ckct_nw_pasting"));
3178 if (inf_note != NULL) {
3179 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3180 gtk_widget_show (GTK_WIDGET(inf_note));
3183 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3184 modest_mail_operation_xfer_msgs (mail_op,
3186 TNY_FOLDER (folder_store),
3188 destroy_information_note,
3191 g_object_unref (mail_op);
3194 } else if (src_folder != NULL) {
3195 /* Launch notification */
3196 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3197 _CS("ckct_nw_pasting"));
3198 if (inf_note != NULL) {
3199 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3200 gtk_widget_show (GTK_WIDGET(inf_note));
3203 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3204 modest_mail_operation_xfer_folder (mail_op,
3208 destroy_information_note,
3214 g_object_unref (data);
3215 if (src_folder != NULL)
3216 g_object_unref (src_folder);
3217 if (folder_store != NULL)
3218 g_object_unref (folder_store);
3224 modest_ui_actions_on_select_all (GtkAction *action,
3225 ModestWindow *window)
3227 GtkWidget *focused_widget;
3229 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3230 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3231 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3232 } else if (GTK_IS_LABEL (focused_widget)) {
3233 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3234 } else if (GTK_IS_EDITABLE (focused_widget)) {
3235 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3236 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3237 GtkTextBuffer *buffer;
3238 GtkTextIter start, end;
3240 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3241 gtk_text_buffer_get_start_iter (buffer, &start);
3242 gtk_text_buffer_get_end_iter (buffer, &end);
3243 gtk_text_buffer_select_range (buffer, &start, &end);
3244 } else if (GTK_IS_HTML (focused_widget)) {
3245 gtk_html_select_all (GTK_HTML (focused_widget));
3246 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3247 GtkWidget *header_view = focused_widget;
3248 GtkTreeSelection *selection = NULL;
3250 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3251 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3252 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3255 /* Disable window dimming management */
3256 modest_window_disable_dimming (MODEST_WINDOW(window));
3258 /* Select all messages */
3259 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3260 gtk_tree_selection_select_all (selection);
3262 /* Set focuse on header view */
3263 gtk_widget_grab_focus (header_view);
3266 /* Enable window dimming management */
3267 modest_window_enable_dimming (MODEST_WINDOW(window));
3268 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3274 modest_ui_actions_on_mark_as_read (GtkAction *action,
3275 ModestWindow *window)
3277 g_return_if_fail (MODEST_IS_WINDOW(window));
3279 /* Mark each header as read */
3280 do_headers_action (window, headers_action_mark_as_read, NULL);
3284 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3285 ModestWindow *window)
3287 g_return_if_fail (MODEST_IS_WINDOW(window));
3289 /* Mark each header as read */
3290 do_headers_action (window, headers_action_mark_as_unread, NULL);
3294 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3295 GtkRadioAction *selected,
3296 ModestWindow *window)
3300 value = gtk_radio_action_get_current_value (selected);
3301 if (MODEST_IS_WINDOW (window)) {
3302 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3307 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3308 GtkRadioAction *selected,
3309 ModestWindow *window)
3311 TnyHeaderFlags flags;
3312 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3314 flags = gtk_radio_action_get_current_value (selected);
3315 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3319 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3320 GtkRadioAction *selected,
3321 ModestWindow *window)
3325 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3327 file_format = gtk_radio_action_get_current_value (selected);
3328 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3333 modest_ui_actions_on_zoom_plus (GtkAction *action,
3334 ModestWindow *window)
3336 g_return_if_fail (MODEST_IS_WINDOW (window));
3338 modest_window_zoom_plus (MODEST_WINDOW (window));
3342 modest_ui_actions_on_zoom_minus (GtkAction *action,
3343 ModestWindow *window)
3345 g_return_if_fail (MODEST_IS_WINDOW (window));
3347 modest_window_zoom_minus (MODEST_WINDOW (window));
3351 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3352 ModestWindow *window)
3354 ModestWindowMgr *mgr;
3355 gboolean fullscreen, active;
3356 g_return_if_fail (MODEST_IS_WINDOW (window));
3358 mgr = modest_runtime_get_window_mgr ();
3360 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3361 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3363 if (active != fullscreen) {
3364 modest_window_mgr_set_fullscreen_mode (mgr, active);
3365 gtk_window_present (GTK_WINDOW (window));
3370 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3371 ModestWindow *window)
3373 ModestWindowMgr *mgr;
3374 gboolean fullscreen;
3376 g_return_if_fail (MODEST_IS_WINDOW (window));
3378 mgr = modest_runtime_get_window_mgr ();
3379 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3380 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3382 gtk_window_present (GTK_WINDOW (window));
3386 * Used by modest_ui_actions_on_details to call do_headers_action
3389 headers_action_show_details (TnyHeader *header,
3390 ModestWindow *window,
3397 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3400 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3401 gtk_widget_show_all (dialog);
3402 gtk_dialog_run (GTK_DIALOG (dialog));
3404 gtk_widget_destroy (dialog);
3408 * Show the folder details in a ModestDetailsDialog widget
3411 show_folder_details (TnyFolder *folder,
3417 dialog = modest_details_dialog_new_with_folder (window, folder);
3420 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3421 gtk_widget_show_all (dialog);
3422 gtk_dialog_run (GTK_DIALOG (dialog));
3424 gtk_widget_destroy (dialog);
3428 * Show the header details in a ModestDetailsDialog widget
3431 modest_ui_actions_on_details (GtkAction *action,
3434 TnyList * headers_list;
3438 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3441 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3444 g_object_unref (msg);
3446 headers_list = get_selected_headers (win);
3450 iter = tny_list_create_iterator (headers_list);
3452 header = TNY_HEADER (tny_iterator_get_current (iter));
3454 headers_action_show_details (header, win, NULL);
3455 g_object_unref (header);
3458 g_object_unref (iter);
3459 g_object_unref (headers_list);
3461 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3462 GtkWidget *folder_view, *header_view;
3464 /* Check which widget has the focus */
3465 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3466 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3467 if (gtk_widget_is_focus (folder_view)) {
3468 TnyFolderStore *folder_store
3469 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3470 if (!folder_store) {
3471 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3474 /* Show only when it's a folder */
3475 /* This function should not be called for account items,
3476 * because we dim the menu item for them. */
3477 if (TNY_IS_FOLDER (folder_store)) {
3478 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3481 g_object_unref (folder_store);
3484 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3485 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3486 /* Show details of each header */
3487 do_headers_action (win, headers_action_show_details, header_view);
3493 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3494 ModestMsgEditWindow *window)
3496 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3498 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3502 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3503 ModestMsgEditWindow *window)
3505 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3507 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3511 modest_ui_actions_toggle_folders_view (GtkAction *action,
3512 ModestMainWindow *main_window)
3514 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3516 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3517 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3519 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3523 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3524 ModestWindow *window)
3526 gboolean active, fullscreen = FALSE;
3527 ModestWindowMgr *mgr;
3529 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3531 /* Check if we want to toggle the toolbar vuew in fullscreen
3533 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3534 "ViewShowToolbarFullScreen")) {
3538 /* Toggle toolbar */
3539 mgr = modest_runtime_get_window_mgr ();
3540 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3544 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3545 ModestMsgEditWindow *window)
3547 modest_msg_edit_window_select_font (window);
3551 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3552 const gchar *display_name,
3555 /* Do not change the application name if the widget has not
3556 the focus. This callback could be called even if the folder
3557 view has not the focus, because the handled signal could be
3558 emitted when the folder view is redrawn */
3559 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3561 gtk_window_set_title (window, display_name);
3563 gtk_window_set_title (window, " ");
3568 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3570 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3571 modest_msg_edit_window_select_contacts (window);
3575 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3577 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3578 modest_msg_edit_window_check_names (window, FALSE);
3582 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3584 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3585 GTK_WIDGET (user_data));
3589 * This function is used to track changes in the selection of the
3590 * folder view that is inside the "move to" dialog to enable/disable
3591 * the OK button because we do not want the user to select a disallowed
3592 * destination for a folder.
3593 * The user also not desired to be able to use NEW button on items where
3594 * folder creation is not possibel.
3597 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3598 TnyFolderStore *folder_store,
3602 GtkWidget *dialog = NULL;
3603 GtkWidget *ok_button = NULL, *new_button = NULL;
3604 GList *children = NULL;
3605 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3606 gboolean moving_folder = FALSE;
3607 gboolean is_local_account = TRUE;
3608 GtkWidget *folder_view = NULL;
3609 ModestTnyFolderRules rules;
3614 /* Get the OK button */
3615 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3619 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3620 ok_button = GTK_WIDGET (children->next->next->data);
3621 new_button = GTK_WIDGET (children->next->data);
3622 g_list_free (children);
3624 /* check if folder_store is an remote account */
3625 if (TNY_IS_ACCOUNT (folder_store)) {
3626 TnyAccount *local_account = NULL;
3627 ModestTnyAccountStore *account_store = NULL;
3629 account_store = modest_runtime_get_account_store ();
3630 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3632 if ((gpointer) local_account != (gpointer) folder_store) {
3633 is_local_account = FALSE;
3634 /* New button should be dimmed on remote
3636 new_sensitive = FALSE;
3638 g_object_unref (local_account);
3641 /* Check the target folder rules */
3642 if (TNY_IS_FOLDER (folder_store)) {
3643 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3644 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3645 ok_sensitive = FALSE;
3646 new_sensitive = FALSE;
3651 /* Check if we're moving a folder */
3652 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3653 /* Get the widgets */
3654 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3655 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3656 if (gtk_widget_is_focus (folder_view))
3657 moving_folder = TRUE;
3660 if (moving_folder) {
3661 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3663 /* Get the folder to move */
3664 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3666 /* Check that we're not moving to the same folder */
3667 if (TNY_IS_FOLDER (moved_folder)) {
3668 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3669 if (parent == folder_store)
3670 ok_sensitive = FALSE;
3671 g_object_unref (parent);
3674 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3675 /* Do not allow to move to an account unless it's the
3676 local folders account */
3677 if (!is_local_account)
3678 ok_sensitive = FALSE;
3681 if (ok_sensitive && (moved_folder == folder_store)) {
3682 /* Do not allow to move to itself */
3683 ok_sensitive = FALSE;
3685 g_object_unref (moved_folder);
3687 TnyHeader *header = NULL;
3688 TnyFolder *src_folder = NULL;
3690 /* Moving a message */
3691 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3692 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3693 src_folder = tny_header_get_folder (header);
3694 g_object_unref (header);
3697 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3700 /* Do not allow to move the msg to the same folder */
3701 /* Do not allow to move the msg to an account */
3702 if ((gpointer) src_folder == (gpointer) folder_store ||
3703 TNY_IS_ACCOUNT (folder_store))
3704 ok_sensitive = FALSE;
3705 g_object_unref (src_folder);
3709 /* Set sensitivity of the OK button */
3710 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3711 /* Set sensitivity of the NEW button */
3712 gtk_widget_set_sensitive (new_button, new_sensitive);
3716 create_move_to_dialog (GtkWindow *win,
3717 GtkWidget *folder_view,
3718 GtkWidget **tree_view)
3720 GtkWidget *dialog, *scroll;
3721 GtkWidget *new_button;
3723 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3725 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3728 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3729 /* We do this manually so GTK+ does not associate a response ID for
3731 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3732 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3733 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3735 /* Create scrolled window */
3736 scroll = gtk_scrolled_window_new (NULL, NULL);
3737 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3738 GTK_POLICY_AUTOMATIC,
3739 GTK_POLICY_AUTOMATIC);
3741 /* Create folder view */
3742 *tree_view = modest_platform_create_folder_view (NULL);
3744 /* Track changes in the selection to
3745 * disable the OK button whenever "Move to" is not possible
3746 * disbale NEW button whenever New is not possible */
3747 g_signal_connect (*tree_view,
3748 "folder_selection_changed",
3749 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3752 /* Listen to clicks on New button */
3753 g_signal_connect (G_OBJECT (new_button),
3755 G_CALLBACK(create_move_to_dialog_on_new_folder),
3758 /* It could happen that we're trying to move a message from a
3759 window (msg window for example) after the main window was
3760 closed, so we can not just get the model of the folder
3762 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3763 const gchar *visible_id = NULL;
3765 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3766 MODEST_FOLDER_VIEW(*tree_view));
3769 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3771 /* Show the same account than the one that is shown in the main window */
3772 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3775 const gchar *active_account_name = NULL;
3776 ModestAccountMgr *mgr = NULL;
3777 ModestAccountData *acc_data = NULL;
3779 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3780 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3782 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3783 mgr = modest_runtime_get_account_mgr ();
3784 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3786 /* Set the new visible & active account */
3787 if (acc_data && acc_data->store_account) {
3788 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3789 acc_data->store_account->account_name);
3790 modest_account_mgr_free_account_data (mgr, acc_data);
3794 /* Hide special folders */
3795 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3797 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3799 /* Add scroll to dialog */
3800 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3801 scroll, TRUE, TRUE, 0);
3803 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3804 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3810 * Returns TRUE if at least one of the headers of the list belongs to
3811 * a message that has been fully retrieved.
3813 #if 0 /* no longer in use. delete in 2007.10 */
3815 has_retrieved_msgs (TnyList *list)
3818 gboolean found = FALSE;
3820 iter = tny_list_create_iterator (list);
3821 while (!tny_iterator_is_done (iter) && !found) {
3823 TnyHeaderFlags flags = 0;
3825 header = TNY_HEADER (tny_iterator_get_current (iter));
3827 flags = tny_header_get_flags (header);
3828 if (flags & TNY_HEADER_FLAG_CACHED)
3829 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3832 g_object_unref (header);
3836 tny_iterator_next (iter);
3838 g_object_unref (iter);
3846 * Shows a confirmation dialog to the user when we're moving messages
3847 * from a remote server to the local storage. Returns the dialog
3848 * response. If it's other kind of movement then it always returns
3851 * This one is used by the next functions:
3852 * modest_ui_actions_on_paste - commented out
3853 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3856 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3857 TnyFolder *dest_folder,
3861 gint response = GTK_RESPONSE_OK;
3863 /* return with OK if the destination is a remote folder */
3864 if (modest_tny_folder_is_remote_folder (dest_folder))
3865 return GTK_RESPONSE_OK;
3867 TnyFolder *src_folder = NULL;
3868 TnyIterator *iter = NULL;
3869 TnyHeader *header = NULL;
3871 /* Get source folder */
3872 iter = tny_list_create_iterator (headers);
3873 header = TNY_HEADER (tny_iterator_get_current (iter));
3875 src_folder = tny_header_get_folder (header);
3876 g_object_unref (header);
3878 g_object_unref (iter);
3880 /* if no src_folder, message may be an attahcment */
3881 if (src_folder == NULL)
3882 return GTK_RESPONSE_CANCEL;
3884 /* If the source is a local or MMC folder */
3885 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3886 g_object_unref (src_folder);
3887 return GTK_RESPONSE_OK;
3889 g_object_unref (src_folder);
3891 /* now if offline we ask the user */
3892 if(connect_to_get_msg( GTK_WINDOW (win),
3893 tny_list_get_length (headers)))
3894 response = GTK_RESPONSE_OK;
3896 response = GTK_RESPONSE_CANCEL;
3904 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3906 /* Note that the operation could have failed, in that case do
3908 if (modest_mail_operation_get_status (mail_op) ==
3909 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3911 GObject *object = modest_mail_operation_get_source (mail_op);
3912 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3913 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3915 if (!modest_msg_view_window_select_next_message (self))
3916 if (!modest_msg_view_window_select_previous_message (self))
3917 /* No more messages to view, so close this window */
3918 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3920 g_object_unref (object);
3923 /* Close the "Pasting" information banner */
3924 gtk_widget_destroy (GTK_WIDGET(user_data));
3928 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3931 ModestWindow *main_window = NULL;
3932 GtkWidget *folder_view = NULL;
3933 GObject *win = modest_mail_operation_get_source (mail_op);
3934 const GError *error = NULL;
3935 const gchar *message = NULL;
3937 /* Get error message */
3938 error = modest_mail_operation_get_error (mail_op);
3939 if (error != NULL && error->message != NULL) {
3940 message = error->message;
3942 message = _("mail_in_ui_folder_move_target_error");
3945 /* Disable next automatic folder selection */
3946 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3947 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3948 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3949 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3951 if (user_data && TNY_IS_FOLDER (user_data)) {
3952 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3953 TNY_FOLDER (user_data), FALSE);
3956 /* Show notification dialog */
3957 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3958 g_object_unref (win);
3962 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3965 GObject *win = modest_mail_operation_get_source (mail_op);
3966 const GError *error = modest_mail_operation_get_error (mail_op);
3968 g_return_if_fail (error != NULL);
3969 if (error->message != NULL)
3970 g_printerr ("modest: %s\n", error->message);
3972 g_printerr ("modest: unkonw error on send&receive operation");
3974 /* Show error message */
3975 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3976 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3977 /* _CS("sfil_ib_unable_to_receive")); */
3979 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3980 /* _CS("sfil_ib_unable_to_send")); */
3981 g_object_unref (win);
3985 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3992 gint pending_purges = 0;
3993 gboolean some_purged = FALSE;
3994 ModestWindow *win = MODEST_WINDOW (user_data);
3995 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3997 /* If there was any error */
3998 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3999 modest_window_mgr_unregister_header (mgr, header);
4003 /* Once the message has been retrieved for purging, we check if
4004 * it's all ok for purging */
4006 parts = tny_simple_list_new ();
4007 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4008 iter = tny_list_create_iterator (parts);
4010 while (!tny_iterator_is_done (iter)) {
4012 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4013 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4014 if (tny_mime_part_is_purged (part))
4021 g_object_unref (part);
4023 tny_iterator_next (iter);
4025 g_object_unref (iter);
4028 if (pending_purges>0) {
4030 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4032 if (response == GTK_RESPONSE_OK) {
4033 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4034 iter = tny_list_create_iterator (parts);
4035 while (!tny_iterator_is_done (iter)) {
4038 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4039 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4040 tny_mime_part_set_purged (part);
4043 g_object_unref (part);
4045 tny_iterator_next (iter);
4048 tny_msg_rewrite_cache (msg);
4051 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4053 g_object_unref (iter);
4055 modest_window_mgr_unregister_header (mgr, header);
4057 g_object_unref (parts);
4061 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4062 ModestMainWindow *win)
4064 GtkWidget *header_view;
4065 TnyList *header_list;
4068 TnyHeaderFlags flags;
4069 ModestWindow *msg_view_window = NULL;
4072 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4074 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4075 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4077 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4079 if (tny_list_get_length (header_list) == 1) {
4080 iter = tny_list_create_iterator (header_list);
4081 header = TNY_HEADER (tny_iterator_get_current (iter));
4082 g_object_unref (iter);
4087 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4088 header, &msg_view_window);
4089 flags = tny_header_get_flags (header);
4090 if (!(flags & TNY_HEADER_FLAG_CACHED))
4093 if (msg_view_window != NULL)
4094 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4096 /* do nothing; uid was registered before, so window is probably on it's way */
4097 g_warning ("debug: header %p has already been registered", header);
4100 ModestMailOperation *mail_op = NULL;
4101 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4102 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4104 modest_ui_actions_get_msgs_full_error_handler,
4106 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4107 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4109 g_object_unref (mail_op);
4112 g_object_unref (header);
4114 g_object_unref (header_list);
4118 * Utility function that transfer messages from both the main window
4119 * and the msg view window when using the "Move to" dialog
4122 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4125 TnyList *headers = NULL;
4126 TnyAccount *dst_account = NULL;
4127 const gchar *proto_str = NULL;
4128 gboolean dst_is_pop = FALSE;
4130 if (!TNY_IS_FOLDER (dst_folder)) {
4131 modest_platform_information_banner (GTK_WIDGET (win),
4133 _CS("ckdg_ib_unable_to_move_to_current_location"));
4137 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4138 proto_str = tny_account_get_proto (dst_account);
4140 /* tinymail will return NULL for local folders it seems */
4141 dst_is_pop = proto_str &&
4142 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4143 MODEST_PROTOCOL_STORE_POP);
4145 g_object_unref (dst_account);
4147 /* Get selected headers */
4148 headers = get_selected_headers (MODEST_WINDOW (win));
4151 modest_platform_information_banner (GTK_WIDGET (win),
4153 ngettext("mail_in_ui_folder_move_target_error",
4154 "mail_in_ui_folder_move_targets_error",
4155 tny_list_get_length (headers)));
4156 g_object_unref (headers);
4160 GtkWidget *inf_note;
4161 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4162 _CS("ckct_nw_pasting"));
4163 if (inf_note != NULL) {
4164 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4165 gtk_widget_show (GTK_WIDGET(inf_note));
4168 ModestMailOperation *mail_op =
4169 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4171 modest_ui_actions_move_folder_error_handler,
4173 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4176 modest_mail_operation_xfer_msgs (mail_op,
4178 TNY_FOLDER (dst_folder),
4183 g_object_unref (G_OBJECT (mail_op));
4184 g_object_unref (headers);
4188 * UI handler for the "Move to" action when invoked from the
4192 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4193 GtkWidget *folder_view,
4194 TnyFolderStore *dst_folder,
4195 ModestMainWindow *win)
4197 ModestHeaderView *header_view = NULL;
4198 ModestMailOperation *mail_op = NULL;
4199 TnyFolderStore *src_folder;
4200 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4202 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4204 /* Get the source folder */
4205 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4207 /* Get header view */
4208 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4210 /* Get folder or messages to transfer */
4211 if (gtk_widget_is_focus (folder_view)) {
4212 GtkTreeSelection *sel;
4213 gboolean do_xfer = TRUE;
4215 /* Allow only to transfer folders to the local root folder */
4216 if (TNY_IS_ACCOUNT (dst_folder) &&
4217 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4219 } else if (!TNY_IS_FOLDER (src_folder)) {
4220 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4222 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4223 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4224 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4230 GtkWidget *inf_note;
4231 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4232 _CS("ckct_nw_pasting"));
4233 if (inf_note != NULL) {
4234 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4235 gtk_widget_show (GTK_WIDGET(inf_note));
4237 /* Clean folder on header view before moving it */
4238 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4239 gtk_tree_selection_unselect_all (sel);
4242 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4244 modest_ui_actions_move_folder_error_handler,
4246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4249 /* Select *after* the changes */
4250 /* TODO: this function hangs UI after transfer */
4251 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4252 /* TNY_FOLDER (src_folder), TRUE); */
4254 modest_mail_operation_xfer_folder (mail_op,
4255 TNY_FOLDER (src_folder),
4260 /* Unref mail operation */
4261 g_object_unref (G_OBJECT (mail_op));
4263 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4264 gboolean do_xfer = TRUE;
4265 /* Ask for confirmation if the source folder is remote and we're not connected */
4266 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4267 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4268 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4269 guint num_headers = tny_list_get_length(headers);
4270 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4274 g_object_unref(headers);
4276 if (do_xfer) /* Transfer messages */
4277 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4281 g_object_unref (src_folder);
4286 * UI handler for the "Move to" action when invoked from the
4287 * ModestMsgViewWindow
4290 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4291 TnyFolderStore *dst_folder,
4292 ModestMsgViewWindow *win)
4294 TnyHeader *header = NULL;
4295 TnyFolderStore *src_folder;
4297 /* Create header list */
4298 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4299 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4300 g_object_unref (header);
4302 /* Transfer the message if online or confirmed by the user */
4303 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4304 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4305 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4308 g_object_unref (src_folder);
4312 modest_ui_actions_on_move_to (GtkAction *action,
4315 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4317 TnyFolderStore *dst_folder = NULL;
4318 ModestMainWindow *main_window;
4320 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4321 MODEST_IS_MSG_VIEW_WINDOW (win));
4323 /* Get the main window if exists */
4324 if (MODEST_IS_MAIN_WINDOW (win))
4325 main_window = MODEST_MAIN_WINDOW (win);
4328 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4330 /* Get the folder view widget if exists */
4332 folder_view = modest_main_window_get_child_widget (main_window,
4333 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4337 /* Create and run the dialog */
4338 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4339 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4340 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4341 result = gtk_dialog_run (GTK_DIALOG(dialog));
4342 g_object_ref (tree_view);
4343 gtk_widget_destroy (dialog);
4345 if (result != GTK_RESPONSE_ACCEPT)
4348 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4349 /* Do window specific stuff */
4350 if (MODEST_IS_MAIN_WINDOW (win)) {
4351 modest_ui_actions_on_main_window_move_to (action,
4354 MODEST_MAIN_WINDOW (win));
4356 modest_ui_actions_on_msg_view_window_move_to (action,
4358 MODEST_MSG_VIEW_WINDOW (win));
4362 g_object_unref (dst_folder);
4366 * Calls #HeadersFunc for each header already selected in the main
4367 * window or the message currently being shown in the msg view window
4370 do_headers_action (ModestWindow *win,
4374 TnyList *headers_list = NULL;
4375 TnyIterator *iter = NULL;
4376 TnyHeader *header = NULL;
4377 TnyFolder *folder = NULL;
4380 headers_list = get_selected_headers (win);
4384 /* Get the folder */
4385 iter = tny_list_create_iterator (headers_list);
4386 header = TNY_HEADER (tny_iterator_get_current (iter));
4388 folder = tny_header_get_folder (header);
4389 g_object_unref (header);
4392 /* Call the function for each header */
4393 while (!tny_iterator_is_done (iter)) {
4394 header = TNY_HEADER (tny_iterator_get_current (iter));
4395 func (header, win, user_data);
4396 g_object_unref (header);
4397 tny_iterator_next (iter);
4400 /* Trick: do a poke status in order to speed up the signaling
4402 tny_folder_poke_status (folder);
4405 g_object_unref (folder);
4406 g_object_unref (iter);
4407 g_object_unref (headers_list);
4411 modest_ui_actions_view_attachment (GtkAction *action,
4412 ModestWindow *window)
4414 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4415 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4417 /* not supported window for this action */
4418 g_return_if_reached ();
4423 modest_ui_actions_save_attachments (GtkAction *action,
4424 ModestWindow *window)
4426 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4427 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4429 /* not supported window for this action */
4430 g_return_if_reached ();
4435 modest_ui_actions_remove_attachments (GtkAction *action,
4436 ModestWindow *window)
4438 if (MODEST_IS_MAIN_WINDOW (window)) {
4439 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4440 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4441 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4443 /* not supported window for this action */
4444 g_return_if_reached ();
4449 modest_ui_actions_on_settings (GtkAction *action,
4454 dialog = modest_platform_get_global_settings_dialog ();
4455 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4456 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4457 gtk_widget_show_all (dialog);
4459 gtk_dialog_run (GTK_DIALOG (dialog));
4461 gtk_widget_destroy (dialog);
4465 modest_ui_actions_on_help (GtkAction *action,
4468 const gchar *help_id = NULL;
4470 if (MODEST_IS_MAIN_WINDOW (win)) {
4471 GtkWidget *folder_view;
4472 TnyFolderStore *folder_store;
4474 /* Get selected folder */
4475 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4476 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4477 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4479 /* Switch help_id */
4480 if (TNY_IS_FOLDER (folder_store)) {
4481 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4482 case TNY_FOLDER_TYPE_NORMAL:
4483 help_id = "applications_email_managefolders";
4485 case TNY_FOLDER_TYPE_INBOX:
4486 help_id = "applications_email_inbox";
4488 case TNY_FOLDER_TYPE_OUTBOX:
4489 help_id = "applications_email_outbox";
4491 case TNY_FOLDER_TYPE_SENT:
4492 help_id = "applications_email_sent";
4494 case TNY_FOLDER_TYPE_DRAFTS:
4495 help_id = "applications_email_drafts";
4497 case TNY_FOLDER_TYPE_ARCHIVE:
4498 help_id = "applications_email_managefolders";
4501 help_id = "applications_email_managefolders";
4504 help_id = "applications_email_mainview";
4506 g_object_unref (folder_store);
4507 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4508 help_id = "applications_email_viewer";
4509 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4510 help_id = "applications_email_editor";
4512 modest_platform_show_help (GTK_WINDOW (win), help_id);
4516 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4517 ModestWindow *window)
4519 ModestMailOperation *mail_op;
4523 headers = get_selected_headers (window);
4527 /* Create mail operation */
4528 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4530 modest_ui_actions_get_msgs_full_error_handler,
4532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4533 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4536 g_object_unref (headers);
4537 g_object_unref (mail_op);
4541 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4542 ModestWindow *window)
4544 g_return_if_fail (MODEST_IS_WINDOW (window));
4547 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4551 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4552 ModestWindow *window)
4554 g_return_if_fail (MODEST_IS_WINDOW (window));
4557 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4561 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4562 ModestWindow *window)
4564 g_return_if_fail (MODEST_IS_WINDOW (window));
4567 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4571 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4572 ModestWindow *window)
4574 g_return_if_fail (MODEST_IS_WINDOW (window));
4577 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4581 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4582 ModestWindow *window)
4584 g_return_if_fail (MODEST_IS_WINDOW (window));
4587 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4591 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4592 ModestWindow *window)
4594 g_return_if_fail (MODEST_IS_WINDOW (window));
4597 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4601 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4602 ModestWindow *window)
4604 g_return_if_fail (MODEST_IS_WINDOW (window));
4607 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4611 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4612 ModestWindow *window)
4614 g_return_if_fail (MODEST_IS_WINDOW (window));
4617 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4621 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4622 ModestWindow *window)
4624 g_return_if_fail (MODEST_IS_WINDOW (window));
4627 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4631 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4633 g_return_if_fail (MODEST_IS_WINDOW (window));
4636 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4640 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4642 g_return_if_fail (MODEST_IS_WINDOW (window));
4644 modest_platform_show_search_messages (GTK_WINDOW (window));
4648 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4650 g_return_if_fail (MODEST_IS_WINDOW (win));
4651 modest_platform_show_addressbook (GTK_WINDOW (win));
4656 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4657 ModestWindow *window)
4659 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4661 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4665 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4666 ModestMailOperationState *state,
4669 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4671 /* Set send/receive operation finished */
4672 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4673 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4679 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4685 const gchar* server_name = NULL;
4686 TnyTransportAccount *server_account;
4687 gchar *message = NULL;
4689 /* Don't show anything if the user cancelled something */
4690 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4693 /* Get the server name: */
4695 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4696 if (server_account) {
4697 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4699 g_object_unref (server_account);
4700 server_account = NULL;
4703 g_return_if_fail (server_name);
4705 /* Show the appropriate message text for the GError: */
4706 switch (err->code) {
4707 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4708 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4710 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4711 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4713 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4714 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4716 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4717 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4720 g_return_if_reached ();
4723 /* TODO if the username or the password where not defined we
4724 should show the Accounts Settings dialog or the Connection
4725 specific SMTP server window */
4727 modest_platform_run_information_dialog (NULL, message);
4732 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4737 ModestMainWindow *main_window = NULL;
4738 ModestWindowMgr *mgr = NULL;
4739 GtkWidget *folder_view = NULL, *header_view = NULL;
4740 TnyFolderStore *selected_folder = NULL;
4741 TnyFolderType folder_type;
4743 mgr = modest_runtime_get_window_mgr ();
4744 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4749 /* Check if selected folder is OUTBOX */
4750 folder_view = modest_main_window_get_child_widget (main_window,
4751 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4752 header_view = modest_main_window_get_child_widget (main_window,
4753 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4755 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4756 if (!TNY_IS_FOLDER (selected_folder))
4759 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4760 #if GTK_CHECK_VERSION(2, 8, 0)
4761 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4762 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4763 GtkTreeViewColumn *tree_column;
4765 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4766 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4767 gtk_tree_view_column_queue_resize (tree_column);
4770 gtk_widget_queue_draw (header_view);
4775 if (selected_folder != NULL)
4776 g_object_unref (selected_folder);