1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _MoveToHelper {
107 ModestMailOperation *mail_op;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
144 ModestMailOperationState *state,
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
150 gint num_of_uncached_msgs);
152 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
154 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
155 const TnyFolderStore *src_folder);
159 * This function checks whether a TnyFolderStore is a pop account
162 remote_folder_is_pop (const TnyFolderStore *folder)
164 const gchar *proto = NULL;
165 TnyAccount *account = NULL;
167 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
169 if (TNY_IS_ACCOUNT (folder)) {
170 account = TNY_ACCOUNT(folder);
171 g_object_ref(account);
172 } else if (TNY_IS_FOLDER (folder)) {
173 account = tny_folder_get_account(TNY_FOLDER(folder));
176 proto = tny_account_get_proto(account);
177 g_object_unref (account);
180 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
184 * This functions checks whether if a list of messages are already
185 * deleted from the server: that is, if the server is a POP account
186 * and all messages are already cached.
189 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
192 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
194 gboolean src_is_pop = remote_folder_is_pop (src_folder);
195 gint uncached_msgs = header_list_count_uncached_msgs (headers);
197 return (src_is_pop && !uncached_msgs);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkDialog *wizard, *dialog;
211 /* Show the easy-setup wizard: */
212 dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
213 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
214 /* old wizard is active already;
216 gtk_window_present (GTK_WINDOW(dialog));
221 /* there is no such wizard yet */
223 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
225 g_printerr ("modest: failed to create easysetup wizard\n");
229 modest_window_mgr_set_modal_dialog
230 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
233 /* there is no such wizard yet */
234 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
235 modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
238 /* make it non-modal; if though we register it as a modal dialog above
239 * apparently, making it modal *at all* gives hangs -- FIXME: check this*/
240 gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
242 /* always present a main window in the background
243 * we do it here, so we cannot end up with to wizards (as this
244 * function might be called in modest_window_mgr_get_main_window as well */
246 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
248 /* make sure the mainwindow is visible */
249 gtk_widget_show_all (GTK_WIDGET(win));
250 gtk_window_present (GTK_WINDOW(win));
253 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
255 /* Don't make this a modal window, because secondary windows will then
256 * be unusable, freezing the UI: */
257 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
259 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
260 if (dialog_response == GTK_RESPONSE_CANCEL)
263 /* Check whether an account was created: */
264 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
267 gtk_widget_destroy (GTK_WIDGET (wizard));
269 /* clear it from the window mgr */
270 modest_window_mgr_set_modal_dialog
271 (modest_runtime_get_window_mgr(), NULL);
278 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
281 const gchar *authors[] = {
282 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
285 about = gtk_about_dialog_new ();
286 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
287 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
288 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
289 _("Copyright (c) 2006, Nokia Corporation\n"
290 "All rights reserved."));
291 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
292 _("a modest e-mail client\n\n"
293 "design and implementation: Dirk-Jan C. Binnema\n"
294 "contributions from the fine people at KC and Ig\n"
295 "uses the tinymail email framework written by Philip van Hoof"));
296 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
297 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
298 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
299 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
301 gtk_dialog_run (GTK_DIALOG (about));
302 gtk_widget_destroy(about);
306 * Gets the list of currently selected messages. If the win is the
307 * main window, then it returns a newly allocated list of the headers
308 * selected in the header view. If win is the msg view window, then
309 * the value returned is a list with just a single header.
311 * The caller of this funcion must free the list.
314 get_selected_headers (ModestWindow *win)
316 if (MODEST_IS_MAIN_WINDOW(win)) {
317 GtkWidget *header_view;
319 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
321 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
323 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
324 /* for MsgViewWindows, we simply return a list with one element */
326 TnyList *list = NULL;
328 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
329 if (header != NULL) {
330 list = tny_simple_list_new ();
331 tny_list_prepend (list, G_OBJECT(header));
332 g_object_unref (G_OBJECT(header));
342 headers_action_mark_as_read (TnyHeader *header,
346 TnyHeaderFlags flags;
348 g_return_if_fail (TNY_IS_HEADER(header));
350 flags = tny_header_get_flags (header);
351 if (flags & TNY_HEADER_FLAG_SEEN) return;
352 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
356 headers_action_mark_as_unread (TnyHeader *header,
360 TnyHeaderFlags flags;
362 g_return_if_fail (TNY_IS_HEADER(header));
364 flags = tny_header_get_flags (header);
365 if (flags & TNY_HEADER_FLAG_SEEN) {
366 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
370 /** A convenience method, because deleting a message is
371 * otherwise complicated, and it's best to change it in one place
374 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
376 ModestMailOperation *mail_op = NULL;
377 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
378 win ? G_OBJECT(win) : NULL);
379 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
382 /* Always delete. TODO: Move to trash still not supported */
383 modest_mail_operation_remove_msg (mail_op, header, FALSE);
384 g_object_unref (G_OBJECT (mail_op));
387 /** A convenience method, because deleting a message is
388 * otherwise complicated, and it's best to change it in one place
391 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
393 ModestMailOperation *mail_op = NULL;
394 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
395 win ? G_OBJECT(win) : NULL);
396 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
399 /* Always delete. TODO: Move to trash still not supported */
400 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
401 g_object_unref (G_OBJECT (mail_op));
404 /** After deleing a message that is currently visible in a window,
405 * show the next message from the list, or close the window if there are no more messages.
408 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
410 /* Close msg view window or select next */
411 if (modest_msg_view_window_last_message_selected (win) &&
412 modest_msg_view_window_first_message_selected (win)) {
413 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
414 } else if (!modest_msg_view_window_select_next_message (win)) {
416 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
421 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
423 TnyList *header_list = NULL;
424 TnyIterator *iter = NULL;
425 TnyHeader *header = NULL;
426 gchar *message = NULL;
429 ModestWindowMgr *mgr;
430 GtkWidget *header_view = NULL;
432 g_return_if_fail (MODEST_IS_WINDOW(win));
434 /* Check first if the header view has the focus */
435 if (MODEST_IS_MAIN_WINDOW (win)) {
437 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
438 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
439 if (!gtk_widget_is_focus (header_view))
443 /* Get the headers, either from the header view (if win is the main window),
444 * or from the message view window: */
445 header_list = get_selected_headers (win);
446 if (!header_list) return;
448 /* Check if any of the headers are already opened, or in the process of being opened */
449 if (MODEST_IS_MAIN_WINDOW (win)) {
450 gint opened_headers = 0;
452 iter = tny_list_create_iterator (header_list);
453 mgr = modest_runtime_get_window_mgr ();
454 while (!tny_iterator_is_done (iter)) {
455 header = TNY_HEADER (tny_iterator_get_current (iter));
457 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
459 g_object_unref (header);
461 tny_iterator_next (iter);
463 g_object_unref (iter);
465 if (opened_headers > 0) {
468 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
471 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
474 g_object_unref (header_list);
480 if (tny_list_get_length(header_list) == 1) {
481 iter = tny_list_create_iterator (header_list);
482 header = TNY_HEADER (tny_iterator_get_current (iter));
484 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
485 g_object_unref (header);
488 g_object_unref (iter);
490 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
491 tny_list_get_length(header_list)), desc);
493 /* Confirmation dialog */
494 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
498 if (response == GTK_RESPONSE_OK) {
499 ModestWindow *main_window = NULL;
500 ModestWindowMgr *mgr = NULL;
501 GtkTreeModel *model = NULL;
502 GtkTreeSelection *sel = NULL;
503 GList *sel_list = NULL, *tmp = NULL;
504 GtkTreeRowReference *next_row_reference = NULL;
505 GtkTreeRowReference *prev_row_reference = NULL;
506 GtkTreePath *next_path = NULL;
507 GtkTreePath *prev_path = NULL;
510 /* Find last selected row */
511 if (MODEST_IS_MAIN_WINDOW (win)) {
512 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
513 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
514 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
515 for (tmp=sel_list; tmp; tmp=tmp->next) {
516 if (tmp->next == NULL) {
517 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
518 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
520 gtk_tree_path_prev (prev_path);
521 gtk_tree_path_next (next_path);
523 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
524 next_row_reference = gtk_tree_row_reference_new (model, next_path);
529 /* Disable window dimming management */
530 modest_window_disable_dimming (MODEST_WINDOW(win));
532 /* Remove each header. If it's a view window header_view == NULL */
533 modest_do_messages_delete (header_list, win);
535 /* Enable window dimming management */
537 gtk_tree_selection_unselect_all (sel);
539 modest_window_enable_dimming (MODEST_WINDOW(win));
541 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
542 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
544 /* Get main window */
545 mgr = modest_runtime_get_window_mgr ();
546 main_window = modest_window_mgr_get_main_window (mgr);
549 /* Move cursor to next row */
552 /* Select next or previous row */
553 if (gtk_tree_row_reference_valid (next_row_reference)) {
554 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
555 gtk_tree_selection_select_path (sel, next_path);
557 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
558 gtk_tree_selection_select_path (sel, prev_path);
562 if (next_row_reference != NULL)
563 gtk_tree_row_reference_free (next_row_reference);
564 if (next_path != NULL)
565 gtk_tree_path_free (next_path);
566 if (prev_row_reference != NULL)
567 gtk_tree_row_reference_free (prev_row_reference);
568 if (prev_path != NULL)
569 gtk_tree_path_free (prev_path);
573 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
577 /* Update toolbar dimming state */
578 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
581 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
582 g_list_free (sel_list);
588 g_object_unref (header_list);
594 /* delete either message or folder, based on where we are */
596 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
598 g_return_if_fail (MODEST_IS_WINDOW(win));
600 /* Check first if the header view has the focus */
601 if (MODEST_IS_MAIN_WINDOW (win)) {
603 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
604 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
605 if (gtk_widget_is_focus (w)) {
606 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
610 modest_ui_actions_on_delete_message (action, win);
616 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
618 ModestWindowMgr *mgr = NULL;
620 #ifdef MODEST_PLATFORM_MAEMO
621 modest_osso_save_state();
622 #endif /* MODEST_PLATFORM_MAEMO */
624 g_debug ("closing down, clearing %d item(s) from operation queue",
625 modest_mail_operation_queue_num_elements
626 (modest_runtime_get_mail_operation_queue()));
628 /* cancel all outstanding operations */
629 modest_mail_operation_queue_cancel_all
630 (modest_runtime_get_mail_operation_queue());
632 g_debug ("queue has been cleared");
635 /* Check if there are opened editing windows */
636 mgr = modest_runtime_get_window_mgr ();
637 modest_window_mgr_close_all_windows (mgr);
639 /* note: when modest-tny-account-store is finalized,
640 it will automatically set all network connections
643 /* gtk_main_quit (); */
647 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
651 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
653 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
654 /* gtk_widget_destroy (GTK_WIDGET (win)); */
655 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
656 /* gboolean ret_value; */
657 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
658 /* } else if (MODEST_IS_WINDOW (win)) { */
659 /* gtk_widget_destroy (GTK_WIDGET (win)); */
661 /* g_return_if_reached (); */
666 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
668 GtkClipboard *clipboard = NULL;
669 gchar *selection = NULL;
671 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
672 selection = gtk_clipboard_wait_for_text (clipboard);
674 /* Question: why is the clipboard being used here?
675 * It doesn't really make a lot of sense. */
679 modest_address_book_add_address (selection);
685 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
687 /* This is currently only implemented for Maemo */
688 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
689 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
690 modest_run_account_setup_wizard (win);
693 /* Show the list of accounts: */
694 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
695 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
697 /* The accounts dialog must be modal */
698 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
699 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
702 GtkWidget *dialog, *label;
704 /* Create the widgets */
706 dialog = gtk_dialog_new_with_buttons ("Message",
708 GTK_DIALOG_DESTROY_WITH_PARENT,
712 label = gtk_label_new ("Hello World!");
714 /* Ensure that the dialog box is destroyed when the user responds. */
716 g_signal_connect_swapped (dialog, "response",
717 G_CALLBACK (gtk_widget_destroy),
720 /* Add the label, and show everything we've added to the dialog. */
722 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
724 gtk_widget_show_all (dialog);
725 #endif /* MODEST_PLATFORM_MAEMO */
729 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
731 /* Save any changes. */
732 modest_connection_specific_smtp_window_save_server_accounts (
733 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
734 gtk_widget_destroy (GTK_WIDGET (window));
740 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
742 /* This is currently only implemented for Maemo,
743 * because it requires an API (libconic) to detect different connection
746 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
748 /* Create the window if necessary: */
749 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
750 modest_connection_specific_smtp_window_fill_with_connections (
751 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
752 modest_runtime_get_account_mgr());
754 /* Show the window: */
755 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
756 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
757 gtk_widget_show (specific_window);
759 /* Save changes when the window is hidden: */
760 g_signal_connect (specific_window, "hide",
761 G_CALLBACK (on_smtp_servers_window_hide), win);
762 #endif /* MODEST_PLATFORM_MAEMO */
766 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
768 ModestWindow *msg_win = NULL;
770 TnyFolder *folder = NULL;
771 gchar *account_name = NULL;
772 gchar *from_str = NULL;
773 /* GError *err = NULL; */
774 TnyAccount *account = NULL;
775 ModestWindowMgr *mgr;
776 gchar *signature = NULL, *blank_and_signature = NULL;
778 /* if there are no accounts yet, just show the wizard */
779 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
780 const gboolean created = modest_run_account_setup_wizard (win);
785 account_name = g_strdup (modest_window_get_active_account (win));
787 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
789 g_printerr ("modest: no account found\n");
793 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
795 TNY_ACCOUNT_TYPE_STORE);
797 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
801 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
803 g_printerr ("modest: failed get from string for '%s'\n", account_name);
807 gboolean use_signature = FALSE;
808 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
811 blank_and_signature = g_strconcat ("\n", signature, NULL);
813 blank_and_signature = g_strdup ("");
818 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
820 g_printerr ("modest: failed to create new msg\n");
824 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
826 g_printerr ("modest: failed to find Drafts folder\n");
831 /* Create and register edit window */
832 /* This is destroyed by TODO. */
833 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
834 mgr = modest_runtime_get_window_mgr ();
835 modest_window_mgr_register_window (mgr, msg_win);
838 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
840 gtk_widget_show_all (GTK_WIDGET (msg_win));
843 g_free (account_name);
845 g_free (blank_and_signature);
847 g_object_unref (msg_win);
849 g_object_unref (G_OBJECT(account));
851 g_object_unref (G_OBJECT(msg));
853 g_object_unref (G_OBJECT(folder));
857 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
861 ModestMailOperationStatus status;
863 /* If there is no message or the operation was not successful */
864 status = modest_mail_operation_get_status (mail_op);
865 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
867 /* Remove the header from the preregistered uids */
868 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
878 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
880 ModestWindowMgr *mgr = NULL;
881 ModestWindow *parent_win = NULL;
882 ModestWindow *win = NULL;
883 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
884 gchar *account = NULL;
887 /* Do nothing if there was any problem with the mail
888 operation. The error will be shown by the error_handler of
889 the mail operation */
890 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
893 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
894 folder = tny_header_get_folder (header);
896 /* Mark header as read */
897 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
900 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
902 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
904 /* Gets folder type (OUTBOX headers will be opened in edit window */
905 if (modest_tny_folder_is_local_folder (folder))
906 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
908 /* If the header is in the drafts folder then open the editor,
909 else the message view window */
910 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
911 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
912 /* we cannot edit without a valid account... */
913 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
914 const gboolean created = modest_run_account_setup_wizard(parent_win);
918 win = modest_msg_edit_window_new (msg, account, TRUE);
922 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
925 gchar *uid = modest_tny_folder_get_header_unique_id (header);
927 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
928 GtkWidget *header_view;
929 GtkTreeSelection *sel;
930 GList *sel_list = NULL;
933 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
934 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
936 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
937 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
939 if (sel_list != NULL) {
940 GtkTreeRowReference *row_reference;
942 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
943 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
944 g_list_free (sel_list);
946 win = modest_msg_view_window_new_with_header_model (
947 msg, account, (const gchar*) uid,
948 model, row_reference);
949 gtk_tree_row_reference_free (row_reference);
951 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
954 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
959 /* Register and show new window */
961 mgr = modest_runtime_get_window_mgr ();
962 modest_window_mgr_register_window (mgr, win);
963 g_object_unref (win);
964 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
965 gtk_widget_show_all (GTK_WIDGET(win));
968 /* Update toolbar dimming state */
969 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
970 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
976 g_object_unref (parent_win);
977 g_object_unref (folder);
981 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
985 GObject *win = modest_mail_operation_get_source (mail_op);
987 error = modest_mail_operation_get_error (mail_op);
988 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
990 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
992 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
995 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
996 _("mail_ni_ui_folder_get_msg_folder_error"));
1000 g_object_unref (win);
1004 * This function is used by both modest_ui_actions_on_open and
1005 * modest_ui_actions_on_header_activated. This way we always do the
1006 * same when trying to open messages.
1009 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1011 ModestWindowMgr *mgr = NULL;
1012 TnyIterator *iter = NULL;
1013 ModestMailOperation *mail_op = NULL;
1014 TnyList *not_opened_headers = NULL;
1015 TnyHeaderFlags flags = 0;
1017 g_return_if_fail (headers != NULL);
1019 /* Check that only one message is selected for opening */
1020 if (tny_list_get_length (headers) != 1) {
1021 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1022 _("mcen_ib_select_one_message"));
1027 /* Look if we already have a message view for each header. If
1028 true, then remove the header from the list of headers to
1030 mgr = modest_runtime_get_window_mgr ();
1031 iter = tny_list_create_iterator (headers);
1032 not_opened_headers = tny_simple_list_new ();
1034 while (!tny_iterator_is_done (iter)) {
1036 ModestWindow *window = NULL;
1037 TnyHeader *header = NULL;
1038 gboolean found = FALSE;
1040 header = TNY_HEADER (tny_iterator_get_current (iter));
1042 flags = tny_header_get_flags (header);
1045 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1047 /* Do not open again the message and present the
1048 window to the user */
1051 gtk_window_present (GTK_WINDOW (window));
1053 /* the header has been registered already, we don't do
1054 * anything but wait for the window to come up*/
1055 g_debug ("header %p already registered, waiting for window", header);
1057 tny_list_append (not_opened_headers, G_OBJECT (header));
1061 g_object_unref (header);
1063 tny_iterator_next (iter);
1065 g_object_unref (iter);
1068 /* If some messages would have to be downloaded, ask the user to
1069 * make a connection. It's generally easier to do this here (in the mainloop)
1070 * than later in a thread:
1072 if (tny_list_get_length (not_opened_headers) > 0) {
1074 gboolean found = FALSE;
1076 iter = tny_list_create_iterator (not_opened_headers);
1077 while (!tny_iterator_is_done (iter) && !found) {
1078 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1079 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1082 tny_iterator_next (iter);
1084 g_object_unref (header);
1086 g_object_unref (iter);
1088 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1089 g_object_unref (not_opened_headers);
1094 /* Register the headers before actually creating the windows: */
1095 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1096 while (!tny_iterator_is_done (iter_not_opened)) {
1097 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1099 modest_window_mgr_register_header (mgr, header);
1100 g_object_unref (header);
1103 tny_iterator_next (iter_not_opened);
1105 g_object_unref (iter_not_opened);
1106 iter_not_opened = NULL;
1108 /* Open each message */
1109 if (tny_list_get_length (not_opened_headers) > 0) {
1110 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1112 modest_ui_actions_get_msgs_full_error_handler,
1114 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1115 if (tny_list_get_length (not_opened_headers) > 1) {
1116 modest_mail_operation_get_msgs_full (mail_op,
1122 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1123 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1124 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1125 g_object_unref (header);
1126 g_object_unref (iter);
1128 g_object_unref (mail_op);
1132 if (not_opened_headers != NULL)
1133 g_object_unref (not_opened_headers);
1137 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1142 headers = get_selected_headers (win);
1147 _modest_ui_actions_open (headers, win);
1149 g_object_unref(headers);
1154 free_reply_forward_helper (gpointer data)
1156 ReplyForwardHelper *helper;
1158 helper = (ReplyForwardHelper *) data;
1159 g_free (helper->account_name);
1160 g_slice_free (ReplyForwardHelper, helper);
1164 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1168 ReplyForwardHelper *rf_helper;
1169 ModestWindow *msg_win = NULL;
1170 ModestEditType edit_type;
1172 TnyAccount *account = NULL;
1173 ModestWindowMgr *mgr = NULL;
1174 gchar *signature = NULL;
1176 /* If there was any error. The mail operation could be NULL,
1177 this means that we already have the message downloaded and
1178 that we didn't do a mail operation to retrieve it */
1179 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1182 g_return_if_fail (user_data != NULL);
1183 rf_helper = (ReplyForwardHelper *) user_data;
1185 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1186 rf_helper->account_name);
1187 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1188 rf_helper->account_name,
1189 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1190 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1191 rf_helper->account_name,
1192 MODEST_ACCOUNT_SIGNATURE, FALSE);
1195 /* Create reply mail */
1196 switch (rf_helper->action) {
1199 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1200 rf_helper->reply_forward_type,
1201 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1203 case ACTION_REPLY_TO_ALL:
1205 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1206 MODEST_TNY_MSG_REPLY_MODE_ALL);
1207 edit_type = MODEST_EDIT_TYPE_REPLY;
1209 case ACTION_FORWARD:
1211 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1212 edit_type = MODEST_EDIT_TYPE_FORWARD;
1215 g_return_if_reached ();
1222 g_printerr ("modest: failed to create message\n");
1226 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1227 rf_helper->account_name,
1228 TNY_ACCOUNT_TYPE_STORE);
1230 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1234 /* Create and register the windows */
1235 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1236 mgr = modest_runtime_get_window_mgr ();
1237 modest_window_mgr_register_window (mgr, msg_win);
1239 if (rf_helper->parent_window != NULL) {
1240 gdouble parent_zoom;
1242 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1243 modest_window_set_zoom (msg_win, parent_zoom);
1246 /* Show edit window */
1247 gtk_widget_show_all (GTK_WIDGET (msg_win));
1251 g_object_unref (msg_win);
1253 g_object_unref (G_OBJECT (new_msg));
1255 g_object_unref (G_OBJECT (account));
1256 /* g_object_unref (msg); */
1257 free_reply_forward_helper (rf_helper);
1260 /* Checks a list of headers. If any of them are not currently
1261 * downloaded (CACHED) then returns TRUE else returns FALSE.
1264 header_list_count_uncached_msgs (TnyList *header_list)
1267 gint uncached_messages = 0;
1269 iter = tny_list_create_iterator (header_list);
1270 while (!tny_iterator_is_done (iter)) {
1273 header = TNY_HEADER (tny_iterator_get_current (iter));
1275 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1276 uncached_messages ++;
1277 g_object_unref (header);
1280 tny_iterator_next (iter);
1282 g_object_unref (iter);
1284 return uncached_messages;
1287 /* Returns FALSE if the user does not want to download the
1288 * messages. Returns TRUE if the user allowed the download.
1291 connect_to_get_msg (GtkWindow *win,
1292 gint num_of_uncached_msgs)
1294 /* Allways download if we are online. */
1295 if (tny_device_is_online (modest_runtime_get_device ()))
1298 /* If offline, then ask for user permission to download the messages */
1299 GtkResponseType response;
1300 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1301 ngettext("mcen_nc_get_msg",
1303 num_of_uncached_msgs));
1304 if (response == GTK_RESPONSE_CANCEL)
1307 return modest_platform_connect_and_wait(win, NULL);
1311 * Common code for the reply and forward actions
1314 reply_forward (ReplyForwardAction action, ModestWindow *win)
1316 ModestMailOperation *mail_op = NULL;
1317 TnyList *header_list = NULL;
1318 ReplyForwardHelper *rf_helper = NULL;
1319 guint reply_forward_type;
1320 gboolean continue_download = TRUE;
1321 gboolean do_retrieve = TRUE;
1323 g_return_if_fail (MODEST_IS_WINDOW(win));
1325 /* we need an account when editing */
1326 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1327 const gboolean created = modest_run_account_setup_wizard (win);
1332 header_list = get_selected_headers (win);
1336 reply_forward_type =
1337 modest_conf_get_int (modest_runtime_get_conf (),
1338 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1341 /* check if we need to download msg before asking about it */
1342 do_retrieve = (action == ACTION_FORWARD) ||
1343 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1346 gint num_of_unc_msgs;
1347 /* check that the messages have been previously downloaded */
1348 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1349 /* If there are any uncached message ask the user
1350 * whether he/she wants to download them. */
1351 if (num_of_unc_msgs)
1352 continue_download = connect_to_get_msg (
1357 if (!continue_download) {
1358 g_object_unref (header_list);
1362 /* We assume that we can only select messages of the
1363 same folder and that we reply all of them from the
1364 same account. In fact the interface currently only
1365 allows single selection */
1368 rf_helper = g_slice_new0 (ReplyForwardHelper);
1369 rf_helper->reply_forward_type = reply_forward_type;
1370 rf_helper->action = action;
1371 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1373 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1374 rf_helper->parent_window = GTK_WIDGET (win);
1375 if (!rf_helper->account_name)
1376 rf_helper->account_name =
1377 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1379 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1382 /* Get header and message. Do not free them here, the
1383 reply_forward_cb must do it */
1384 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1385 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1386 if (!msg || !header) {
1388 g_object_unref (msg);
1389 g_printerr ("modest: no message found\n");
1392 reply_forward_cb (NULL, header, msg, rf_helper);
1395 g_object_unref (header);
1400 /* Only reply/forward to one message */
1401 iter = tny_list_create_iterator (header_list);
1402 header = TNY_HEADER (tny_iterator_get_current (iter));
1403 g_object_unref (iter);
1406 /* Retrieve messages */
1408 mail_op = modest_mail_operation_new_with_error_handling (
1409 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1411 modest_ui_actions_get_msgs_full_error_handler,
1413 modest_mail_operation_queue_add (
1414 modest_runtime_get_mail_operation_queue (), mail_op);
1416 modest_mail_operation_get_msg (mail_op,
1421 g_object_unref(mail_op);
1423 /* we put a ref here to prevent double unref as the reply
1424 * forward callback unrefs the header at its end */
1425 reply_forward_cb (NULL, header, NULL, rf_helper);
1429 g_object_unref (header);
1435 g_object_unref (header_list);
1439 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1441 g_return_if_fail (MODEST_IS_WINDOW(win));
1443 reply_forward (ACTION_REPLY, win);
1447 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1449 g_return_if_fail (MODEST_IS_WINDOW(win));
1451 reply_forward (ACTION_FORWARD, win);
1455 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1457 g_return_if_fail (MODEST_IS_WINDOW(win));
1459 reply_forward (ACTION_REPLY_TO_ALL, win);
1463 modest_ui_actions_on_next (GtkAction *action,
1464 ModestWindow *window)
1466 if (MODEST_IS_MAIN_WINDOW (window)) {
1467 GtkWidget *header_view;
1469 header_view = modest_main_window_get_child_widget (
1470 MODEST_MAIN_WINDOW(window),
1471 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1475 modest_header_view_select_next (
1476 MODEST_HEADER_VIEW(header_view));
1477 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1478 modest_msg_view_window_select_next_message (
1479 MODEST_MSG_VIEW_WINDOW (window));
1481 g_return_if_reached ();
1486 modest_ui_actions_on_prev (GtkAction *action,
1487 ModestWindow *window)
1489 g_return_if_fail (MODEST_IS_WINDOW(window));
1491 if (MODEST_IS_MAIN_WINDOW (window)) {
1492 GtkWidget *header_view;
1493 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1494 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1498 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1499 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1500 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1502 g_return_if_reached ();
1507 modest_ui_actions_on_sort (GtkAction *action,
1508 ModestWindow *window)
1510 g_return_if_fail (MODEST_IS_WINDOW(window));
1512 if (MODEST_IS_MAIN_WINDOW (window)) {
1513 GtkWidget *header_view;
1514 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1515 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1517 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1522 /* Show sorting dialog */
1523 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1528 new_messages_arrived (ModestMailOperation *self,
1529 TnyList *new_headers,
1532 ModestMainWindow *win = NULL;
1533 GtkWidget *folder_view = NULL;
1534 TnyFolderStore *folder = NULL;
1535 gboolean folder_empty = FALSE;
1537 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1538 win = MODEST_MAIN_WINDOW (user_data);
1540 /* Don't do anything if there are not new headers, this could
1541 happen if there was any problem with the mail operation */
1545 /* Set contents style of headers view */
1546 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1547 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1548 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1549 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1552 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1555 modest_main_window_set_contents_style (win,
1556 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1559 /* Notify new messages have been downloaded */
1560 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1561 TnyIterator *iter = tny_list_create_iterator (new_headers);
1563 TnyHeader *header = NULL;
1565 header = TNY_HEADER (tny_iterator_get_current (iter));
1566 modest_platform_on_new_header_received (header);
1567 g_object_unref (header);
1569 tny_iterator_next (iter);
1570 } while (!tny_iterator_is_done (iter));
1571 g_object_unref (iter);
1576 * This function performs the send & receive required actions. The
1577 * window is used to create the mail operation. Typically it should
1578 * always be the main window, but we pass it as argument in order to
1582 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1584 gchar *acc_name = NULL;
1585 ModestMailOperation *mail_op;
1586 TnyAccount *store_account = NULL;
1588 /* If no account name was provided then get the current account, and if
1589 there is no current account then pick the default one: */
1590 if (!account_name) {
1591 acc_name = g_strdup (modest_window_get_active_account(win));
1593 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1595 g_printerr ("modest: cannot get default account\n");
1599 acc_name = g_strdup (account_name);
1603 /* Ensure that we have a connection available */
1605 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1607 TNY_ACCOUNT_TYPE_STORE);
1608 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1609 g_object_unref (store_account);
1612 g_object_unref (store_account);
1614 /* Set send/receive operation in progress */
1615 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1617 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1619 modest_ui_actions_send_receive_error_handler,
1622 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1623 G_CALLBACK (_on_send_receive_progress_changed),
1626 /* Send & receive. */
1627 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1628 /* Receive and then send. The operation is tagged initially as
1629 a receive operation because the account update performs a
1630 receive and then a send. The operation changes its type
1631 internally, so the progress objects will receive the proper
1632 progress information */
1633 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1634 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1635 g_object_unref (G_OBJECT (mail_op));
1643 modest_ui_actions_do_cancel_send (const gchar *account_name,
1646 TnyTransportAccount *transport_account;
1647 TnySendQueue *send_queue = NULL;
1648 GError *error = NULL;
1650 /* Get transport account */
1652 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1653 (modest_runtime_get_account_store(),
1655 TNY_ACCOUNT_TYPE_TRANSPORT));
1656 if (!transport_account) {
1657 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1662 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1663 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1664 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1665 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1666 "modest: could not find send queue for account\n");
1668 /* Keeep messages in outbox folder */
1669 tny_send_queue_cancel (send_queue, FALSE, &error);
1673 if (transport_account != NULL)
1674 g_object_unref (G_OBJECT (transport_account));
1678 modest_ui_actions_cancel_send_all (ModestWindow *win)
1680 GSList *account_names, *iter;
1682 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1685 iter = account_names;
1687 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1688 iter = g_slist_next (iter);
1691 modest_account_mgr_free_account_names (account_names);
1692 account_names = NULL;
1696 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1699 /* Check if accounts exist */
1700 gboolean accounts_exist =
1701 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1703 /* If not, allow the user to create an account before trying to send/receive. */
1704 if (!accounts_exist)
1705 modest_ui_actions_on_accounts (NULL, win);
1707 /* Cancel all sending operaitons */
1708 modest_ui_actions_cancel_send_all (win);
1712 * Refreshes all accounts. This function will be used by automatic
1716 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1718 GSList *account_names, *iter;
1720 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1723 iter = account_names;
1725 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1726 iter = g_slist_next (iter);
1729 modest_account_mgr_free_account_names (account_names);
1730 account_names = NULL;
1734 modest_do_refresh_current_folder(ModestWindow *win)
1736 /* Refresh currently selected folder. Note that if we only
1737 want to retreive the headers, then the refresh only will
1738 invoke a poke_status over all folders, i.e., only the
1739 total/unread count will be updated */
1740 if (MODEST_IS_MAIN_WINDOW (win)) {
1741 GtkWidget *header_view, *folder_view;
1742 TnyFolderStore *folder_store;
1744 /* Get folder and header view */
1746 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1747 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1751 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1753 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1755 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1756 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1758 /* We do not need to set the contents style
1759 because it hasn't changed. We also do not
1760 need to save the widget status. Just force
1762 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1763 TNY_FOLDER (folder_store),
1764 folder_refreshed_cb,
1765 MODEST_MAIN_WINDOW (win));
1769 g_object_unref (folder_store);
1775 * Handler of the click on Send&Receive button in the main toolbar
1778 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1780 /* Check if accounts exist */
1781 gboolean accounts_exist =
1782 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1784 /* If not, allow the user to create an account before trying to send/receive. */
1785 if (!accounts_exist)
1786 modest_ui_actions_on_accounts (NULL, win);
1788 modest_do_refresh_current_folder (win);
1790 /* Refresh the active account */
1791 modest_ui_actions_do_send_receive (NULL, win);
1796 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1799 GtkWidget *header_view;
1801 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1803 header_view = modest_main_window_get_child_widget (main_window,
1804 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1808 conf = modest_runtime_get_conf ();
1810 /* what is saved/restored is depending on the style; thus; we save with
1811 * old style, then update the style, and restore for this new style
1813 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1815 if (modest_header_view_get_style
1816 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1817 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1818 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1820 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1821 MODEST_HEADER_VIEW_STYLE_DETAILS);
1823 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1824 MODEST_CONF_HEADER_VIEW_KEY);
1829 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1831 ModestMainWindow *main_window)
1833 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1834 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1836 /* in the case the folder is empty, show the empty folder message and focus
1838 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1839 if (modest_header_view_is_empty (header_view)) {
1840 TnyFolder *folder = modest_header_view_get_folder (header_view);
1841 GtkWidget *folder_view =
1842 modest_main_window_get_child_widget (main_window,
1843 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1845 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1846 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1850 /* If no header has been selected then exit */
1855 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1856 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1858 /* Update toolbar dimming state */
1859 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1863 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1865 ModestMainWindow *main_window)
1869 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1875 /* headers = tny_simple_list_new (); */
1876 /* tny_list_prepend (headers, G_OBJECT (header)); */
1877 headers = modest_header_view_get_selected_headers (header_view);
1879 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1881 g_object_unref (headers);
1885 set_active_account_from_tny_account (TnyAccount *account,
1886 ModestWindow *window)
1888 const gchar *server_acc_name = tny_account_get_id (account);
1890 /* We need the TnyAccount provided by the
1891 account store because that is the one that
1892 knows the name of the Modest account */
1893 TnyAccount *modest_server_account = modest_server_account =
1894 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1895 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1897 if (!modest_server_account) {
1898 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1902 /* Update active account, but only if it's not a pseudo-account */
1903 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1904 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1905 const gchar *modest_acc_name =
1906 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1907 if (modest_acc_name)
1908 modest_window_set_active_account (window, modest_acc_name);
1911 g_object_unref (modest_server_account);
1916 folder_refreshed_cb (ModestMailOperation *mail_op,
1920 ModestMainWindow *win = NULL;
1921 GtkWidget *header_view;
1922 gboolean folder_empty = FALSE;
1923 gboolean all_marked_as_deleted = FALSE;
1925 g_return_if_fail (TNY_IS_FOLDER (folder));
1927 win = MODEST_MAIN_WINDOW (user_data);
1929 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1932 TnyFolder *current_folder;
1934 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1935 if (current_folder != NULL && folder != current_folder) {
1936 g_object_unref (current_folder);
1939 g_object_unref (current_folder);
1942 /* Check if folder is empty and set headers view contents style */
1943 folder_empty = (tny_folder_get_all_count (folder) == 0);
1944 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1945 if (folder_empty || all_marked_as_deleted)
1946 modest_main_window_set_contents_style (win,
1947 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1951 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1952 TnyFolderStore *folder_store,
1954 ModestMainWindow *main_window)
1957 GtkWidget *header_view;
1959 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1961 header_view = modest_main_window_get_child_widget(main_window,
1962 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1966 conf = modest_runtime_get_conf ();
1968 if (TNY_IS_ACCOUNT (folder_store)) {
1970 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1972 /* Show account details */
1973 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1976 if (TNY_IS_FOLDER (folder_store) && selected) {
1978 /* Update the active account */
1979 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1981 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1982 g_object_unref (account);
1986 /* Set the header style by default, it could
1987 be changed later by the refresh callback to
1989 modest_main_window_set_contents_style (main_window,
1990 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1992 /* Set folder on header view. This function
1993 will call tny_folder_refresh_async so we
1994 pass a callback that will be called when
1995 finished. We use that callback to set the
1996 empty view if there are no messages */
1997 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1998 TNY_FOLDER (folder_store),
1999 folder_refreshed_cb,
2002 /* Restore configuration. We need to do this
2003 *after* the set_folder because the widget
2004 memory asks the header view about its
2006 modest_widget_memory_restore (modest_runtime_get_conf (),
2007 G_OBJECT(header_view),
2008 MODEST_CONF_HEADER_VIEW_KEY);
2010 /* Update the active account */
2011 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2012 /* Save only if we're seeing headers */
2013 if (modest_main_window_get_contents_style (main_window) ==
2014 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2015 modest_widget_memory_save (conf, G_OBJECT (header_view),
2016 MODEST_CONF_HEADER_VIEW_KEY);
2017 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2021 /* Update toolbar dimming state */
2022 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2026 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2033 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2035 online = tny_device_is_online (modest_runtime_get_device());
2038 /* already online -- the item is simply not there... */
2039 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2041 GTK_MESSAGE_WARNING,
2043 _("The %s you selected cannot be found"),
2045 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2046 gtk_dialog_run (GTK_DIALOG(dialog));
2048 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2051 _("mcen_bd_dialog_cancel"),
2052 GTK_RESPONSE_REJECT,
2053 _("mcen_bd_dialog_ok"),
2054 GTK_RESPONSE_ACCEPT,
2056 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2057 "Do you want to get online?"), item);
2058 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2059 gtk_label_new (txt), FALSE, FALSE, 0);
2060 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2063 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2064 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2065 /* TODO: Comment about why is this commented out: */
2066 /* modest_platform_connect_and_wait (); */
2069 gtk_widget_destroy (dialog);
2073 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2076 /* g_message ("%s %s", __FUNCTION__, link); */
2081 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2084 modest_platform_activate_uri (link);
2088 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2091 modest_platform_show_uri_popup (link);
2095 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2098 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2102 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2103 const gchar *address,
2106 /* g_message ("%s %s", __FUNCTION__, address); */
2110 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2112 TnyTransportAccount *transport_account;
2113 ModestMailOperation *mail_operation;
2115 gchar *account_name, *from;
2116 ModestAccountMgr *account_mgr;
2117 gchar *info_text = NULL;
2119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2121 data = modest_msg_edit_window_get_msg_data (edit_window);
2123 account_mgr = modest_runtime_get_account_mgr();
2124 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2126 account_name = modest_account_mgr_get_default_account (account_mgr);
2127 if (!account_name) {
2128 g_printerr ("modest: no account found\n");
2129 modest_msg_edit_window_free_msg_data (edit_window, data);
2133 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2134 account_name = g_strdup (data->account_name);
2138 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2139 (modest_runtime_get_account_store(),
2141 TNY_ACCOUNT_TYPE_TRANSPORT));
2142 if (!transport_account) {
2143 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2144 g_free (account_name);
2145 modest_msg_edit_window_free_msg_data (edit_window, data);
2148 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2150 /* Create the mail operation */
2151 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2152 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2154 modest_mail_operation_save_to_drafts (mail_operation,
2166 data->priority_flags);
2169 g_free (account_name);
2170 g_object_unref (G_OBJECT (transport_account));
2171 g_object_unref (G_OBJECT (mail_operation));
2173 modest_msg_edit_window_free_msg_data (edit_window, data);
2175 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2176 modest_platform_information_banner (NULL, NULL, info_text);
2180 /* For instance, when clicking the Send toolbar button when editing a message: */
2182 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2184 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2186 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2189 /* Offer the connection dialog, if necessary: */
2190 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2193 /* FIXME: Code added just for testing. The final version will
2194 use the send queue provided by tinymail and some
2196 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2197 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2199 account_name = modest_account_mgr_get_default_account (account_mgr);
2201 if (!account_name) {
2202 /* Run account setup wizard */
2203 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2208 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2210 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2211 account_name = g_strdup (data->account_name);
2214 /* Get the currently-active transport account for this modest account: */
2215 TnyTransportAccount *transport_account =
2216 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2217 (modest_runtime_get_account_store(),
2219 if (!transport_account) {
2220 /* Run account setup wizard */
2221 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2226 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2228 /* Create the mail operation */
2229 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2232 modest_mail_operation_send_new_mail (mail_operation,
2243 data->priority_flags);
2247 g_free (account_name);
2248 g_object_unref (G_OBJECT (transport_account));
2249 g_object_unref (G_OBJECT (mail_operation));
2251 modest_msg_edit_window_free_msg_data (edit_window, data);
2252 modest_msg_edit_window_set_sent (edit_window, TRUE);
2254 /* Save settings and close the window: */
2255 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2259 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2260 ModestMsgEditWindow *window)
2262 ModestMsgEditFormatState *format_state = NULL;
2264 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2265 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2267 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2270 format_state = modest_msg_edit_window_get_format_state (window);
2271 g_return_if_fail (format_state != NULL);
2273 format_state->bold = gtk_toggle_action_get_active (action);
2274 modest_msg_edit_window_set_format_state (window, format_state);
2275 g_free (format_state);
2280 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2281 ModestMsgEditWindow *window)
2283 ModestMsgEditFormatState *format_state = NULL;
2285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2286 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2288 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2291 format_state = modest_msg_edit_window_get_format_state (window);
2292 g_return_if_fail (format_state != NULL);
2294 format_state->italics = gtk_toggle_action_get_active (action);
2295 modest_msg_edit_window_set_format_state (window, format_state);
2296 g_free (format_state);
2301 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2302 ModestMsgEditWindow *window)
2304 ModestMsgEditFormatState *format_state = NULL;
2306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2307 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2309 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2312 format_state = modest_msg_edit_window_get_format_state (window);
2313 g_return_if_fail (format_state != NULL);
2315 format_state->bullet = gtk_toggle_action_get_active (action);
2316 modest_msg_edit_window_set_format_state (window, format_state);
2317 g_free (format_state);
2322 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2323 GtkRadioAction *selected,
2324 ModestMsgEditWindow *window)
2326 ModestMsgEditFormatState *format_state = NULL;
2327 GtkJustification value;
2329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2331 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2334 value = gtk_radio_action_get_current_value (selected);
2336 format_state = modest_msg_edit_window_get_format_state (window);
2337 g_return_if_fail (format_state != NULL);
2339 format_state->justification = value;
2340 modest_msg_edit_window_set_format_state (window, format_state);
2341 g_free (format_state);
2345 modest_ui_actions_on_select_editor_color (GtkAction *action,
2346 ModestMsgEditWindow *window)
2348 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2349 g_return_if_fail (GTK_IS_ACTION (action));
2351 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2354 modest_msg_edit_window_select_color (window);
2358 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2359 ModestMsgEditWindow *window)
2361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2362 g_return_if_fail (GTK_IS_ACTION (action));
2364 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2367 modest_msg_edit_window_select_background_color (window);
2371 modest_ui_actions_on_insert_image (GtkAction *action,
2372 ModestMsgEditWindow *window)
2374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2375 g_return_if_fail (GTK_IS_ACTION (action));
2377 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2380 modest_msg_edit_window_insert_image (window);
2384 modest_ui_actions_on_attach_file (GtkAction *action,
2385 ModestMsgEditWindow *window)
2387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2388 g_return_if_fail (GTK_IS_ACTION (action));
2390 modest_msg_edit_window_offer_attach_file (window);
2394 modest_ui_actions_on_remove_attachments (GtkAction *action,
2395 ModestMsgEditWindow *window)
2397 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2398 g_return_if_fail (GTK_IS_ACTION (action));
2400 modest_msg_edit_window_remove_attachments (window, NULL);
2404 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2407 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2408 const GError *error = modest_mail_operation_get_error (mail_op);
2411 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2412 _("mail_in_ui_folder_create_error"));
2417 modest_ui_actions_create_folder(GtkWidget *parent_window,
2418 GtkWidget *folder_view)
2420 TnyFolderStore *parent_folder;
2422 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2424 if (parent_folder) {
2425 gboolean finished = FALSE;
2427 gchar *folder_name = NULL, *suggested_name = NULL;
2428 const gchar *proto_str = NULL;
2429 TnyAccount *account;
2431 if (TNY_IS_ACCOUNT (parent_folder))
2432 account = g_object_ref (parent_folder);
2434 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2435 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2437 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2438 MODEST_PROTOCOL_STORE_POP) {
2440 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2442 g_object_unref (account);
2444 /* Run the new folder dialog */
2446 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2451 g_free (suggested_name);
2452 suggested_name = NULL;
2454 if (result == GTK_RESPONSE_REJECT) {
2457 ModestMailOperation *mail_op;
2458 TnyFolder *new_folder = NULL;
2460 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2461 G_OBJECT(parent_window),
2462 modest_ui_actions_new_folder_error_handler,
2465 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2467 new_folder = modest_mail_operation_create_folder (mail_op,
2469 (const gchar *) folder_name);
2471 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2474 g_object_unref (new_folder);
2477 g_object_unref (mail_op);
2480 suggested_name = folder_name;
2484 g_object_unref (parent_folder);
2489 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2491 GtkWidget *folder_view;
2493 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2495 folder_view = modest_main_window_get_child_widget (main_window,
2496 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2500 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2504 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2507 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2508 const GError *error = NULL;
2509 const gchar *message = NULL;
2511 /* Get error message */
2512 error = modest_mail_operation_get_error (mail_op);
2514 g_return_if_reached ();
2516 switch (error->code) {
2517 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2518 message = _CS("ckdg_ib_folder_already_exists");
2521 g_return_if_reached ();
2524 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2528 modest_ui_actions_on_rename_folder (GtkAction *action,
2529 ModestMainWindow *main_window)
2531 TnyFolderStore *folder;
2532 GtkWidget *folder_view;
2533 GtkWidget *header_view;
2535 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2537 folder_view = modest_main_window_get_child_widget (main_window,
2538 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2542 header_view = modest_main_window_get_child_widget (main_window,
2543 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2548 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2553 if (TNY_IS_FOLDER (folder)) {
2556 const gchar *current_name;
2557 TnyFolderStore *parent;
2558 gboolean do_rename = TRUE;
2560 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2561 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2562 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2563 parent, current_name,
2565 g_object_unref (parent);
2567 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2569 } else if (modest_platform_is_network_folderstore(folder) &&
2570 !tny_device_is_online (modest_runtime_get_device())) {
2571 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2572 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2573 g_object_unref(account);
2577 ModestMailOperation *mail_op;
2578 GtkTreeSelection *sel = NULL;
2581 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2582 G_OBJECT(main_window),
2583 modest_ui_actions_rename_folder_error_handler,
2586 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2589 /* Clear the headers view */
2590 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2591 gtk_tree_selection_unselect_all (sel);
2593 /* Select *after* the changes */
2594 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2595 TNY_FOLDER(folder), TRUE);
2597 /* Actually rename the folder */
2598 modest_mail_operation_rename_folder (mail_op,
2599 TNY_FOLDER (folder),
2600 (const gchar *) folder_name);
2602 g_object_unref (mail_op);
2603 g_free (folder_name);
2606 g_object_unref (folder);
2610 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2613 GObject *win = modest_mail_operation_get_source (mail_op);
2615 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2616 _("mail_in_ui_folder_delete_error"));
2617 g_object_unref (win);
2621 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2623 TnyFolderStore *folder;
2624 GtkWidget *folder_view;
2627 gboolean do_delete = TRUE;
2629 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2631 folder_view = modest_main_window_get_child_widget (main_window,
2632 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2636 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2638 /* Show an error if it's an account */
2639 if (!TNY_IS_FOLDER (folder)) {
2640 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2641 _("mail_in_ui_folder_delete_error"));
2642 g_object_unref (G_OBJECT (folder));
2647 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2648 tny_folder_get_name (TNY_FOLDER (folder)));
2649 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2650 (const gchar *) message);
2653 if (response != GTK_RESPONSE_OK) {
2655 } else if (modest_platform_is_network_folderstore(folder) &&
2656 !tny_device_is_online (modest_runtime_get_device())) {
2657 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2658 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2659 g_object_unref(account);
2663 ModestMailOperation *mail_op;
2664 GtkTreeSelection *sel;
2666 /* Unselect the folder before deleting it to free the headers */
2667 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2668 gtk_tree_selection_unselect_all (sel);
2670 /* Create the mail operation */
2672 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2673 G_OBJECT(main_window),
2674 modest_ui_actions_delete_folder_error_handler,
2677 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2679 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2680 g_object_unref (G_OBJECT (mail_op));
2683 g_object_unref (G_OBJECT (folder));
2689 modest_ui_actions_on_delete_folder (GtkAction *action,
2690 ModestMainWindow *main_window)
2692 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2694 if (delete_folder (main_window, FALSE)) {
2695 GtkWidget *folder_view;
2697 folder_view = modest_main_window_get_child_widget (main_window,
2698 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2699 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2704 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2706 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2708 delete_folder (main_window, TRUE);
2713 show_error (GtkWidget *parent_widget, const gchar* text)
2715 hildon_banner_show_information(parent_widget, NULL, text);
2718 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2720 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2727 gtk_dialog_run (dialog);
2728 gtk_widget_destroy (GTK_WIDGET (dialog));
2733 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2734 const gchar* server_account_name,
2739 ModestMainWindow *main_window)
2741 g_return_if_fail(server_account_name);
2742 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2744 /* Initalize output parameters: */
2751 #ifdef MODEST_PLATFORM_MAEMO
2752 /* Maemo uses a different (awkward) button order,
2753 * It should probably just use gtk_alternative_dialog_button_order ().
2755 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2758 _("mcen_bd_dialog_ok"),
2759 GTK_RESPONSE_ACCEPT,
2760 _("mcen_bd_dialog_cancel"),
2761 GTK_RESPONSE_REJECT,
2764 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2768 GTK_RESPONSE_REJECT,
2770 GTK_RESPONSE_ACCEPT,
2772 #endif /* MODEST_PLATFORM_MAEMO */
2774 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2776 gchar *server_name = modest_server_account_get_hostname (
2777 modest_runtime_get_account_mgr(), server_account_name);
2778 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2779 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2784 /* This causes a warning because the logical ID has no %s in it,
2785 * though the translation does, but there is not much we can do about that: */
2786 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2787 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2790 g_free (server_name);
2794 gchar *initial_username = modest_server_account_get_username (
2795 modest_runtime_get_account_mgr(), server_account_name);
2797 GtkWidget *entry_username = gtk_entry_new ();
2798 if (initial_username)
2799 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2800 /* Dim this if a connection has ever succeeded with this username,
2801 * as per the UI spec: */
2802 const gboolean username_known =
2803 modest_server_account_get_username_has_succeeded(
2804 modest_runtime_get_account_mgr(), server_account_name);
2805 gtk_widget_set_sensitive (entry_username, !username_known);
2807 #ifdef MODEST_PLATFORM_MAEMO
2808 /* Auto-capitalization is the default, so let's turn it off: */
2809 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2811 /* Create a size group to be used by all captions.
2812 * Note that HildonCaption does not create a default size group if we do not specify one.
2813 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2814 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2816 GtkWidget *caption = hildon_caption_new (sizegroup,
2817 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2818 gtk_widget_show (entry_username);
2819 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2820 FALSE, FALSE, MODEST_MARGIN_HALF);
2821 gtk_widget_show (caption);
2823 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2825 #endif /* MODEST_PLATFORM_MAEMO */
2828 GtkWidget *entry_password = gtk_entry_new ();
2829 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2830 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2832 #ifdef MODEST_PLATFORM_MAEMO
2833 /* Auto-capitalization is the default, so let's turn it off: */
2834 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2835 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2837 caption = hildon_caption_new (sizegroup,
2838 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2839 gtk_widget_show (entry_password);
2840 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2841 FALSE, FALSE, MODEST_MARGIN_HALF);
2842 gtk_widget_show (caption);
2843 g_object_unref (sizegroup);
2845 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2847 #endif /* MODEST_PLATFORM_MAEMO */
2849 /* This is not in the Maemo UI spec:
2850 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2851 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2855 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2857 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2859 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2861 modest_server_account_set_username (
2862 modest_runtime_get_account_mgr(), server_account_name,
2865 const gboolean username_was_changed =
2866 (strcmp (*username, initial_username) != 0);
2867 if (username_was_changed) {
2868 g_warning ("%s: tinymail does not yet support changing the "
2869 "username in the get_password() callback.\n", __FUNCTION__);
2874 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2876 /* We do not save the password in the configuration,
2877 * because this function is only called for passwords that should
2878 * not be remembered:
2879 modest_server_account_set_password (
2880 modest_runtime_get_account_mgr(), server_account_name,
2889 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2901 /* This is not in the Maemo UI spec:
2902 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2908 gtk_widget_destroy (dialog);
2910 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2914 modest_ui_actions_on_cut (GtkAction *action,
2915 ModestWindow *window)
2917 GtkWidget *focused_widget;
2918 GtkClipboard *clipboard;
2920 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2921 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2922 if (GTK_IS_EDITABLE (focused_widget)) {
2923 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2924 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2925 gtk_clipboard_store (clipboard);
2926 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2927 GtkTextBuffer *buffer;
2929 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2930 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2931 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2932 gtk_clipboard_store (clipboard);
2933 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2934 TnyList *header_list = modest_header_view_get_selected_headers (
2935 MODEST_HEADER_VIEW (focused_widget));
2936 gboolean continue_download = FALSE;
2937 gint num_of_unc_msgs;
2939 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2941 if (num_of_unc_msgs)
2942 continue_download = connect_to_get_msg(
2943 GTK_WINDOW (window),
2946 if (num_of_unc_msgs == 0 || continue_download) {
2947 /* modest_platform_information_banner (
2948 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2949 modest_header_view_cut_selection (
2950 MODEST_HEADER_VIEW (focused_widget));
2953 g_object_unref (header_list);
2954 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2955 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2960 modest_ui_actions_on_copy (GtkAction *action,
2961 ModestWindow *window)
2963 GtkClipboard *clipboard;
2964 GtkWidget *focused_widget;
2965 gboolean copied = TRUE;
2967 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2968 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2970 if (GTK_IS_LABEL (focused_widget)) {
2971 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2972 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2973 gtk_clipboard_store (clipboard);
2974 } else if (GTK_IS_EDITABLE (focused_widget)) {
2975 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2976 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2977 gtk_clipboard_store (clipboard);
2978 } else if (GTK_IS_HTML (focused_widget)) {
2979 gtk_html_copy (GTK_HTML (focused_widget));
2980 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2981 gtk_clipboard_store (clipboard);
2982 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2983 GtkTextBuffer *buffer;
2984 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2985 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2986 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2987 gtk_clipboard_store (clipboard);
2988 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2989 TnyList *header_list = modest_header_view_get_selected_headers (
2990 MODEST_HEADER_VIEW (focused_widget));
2991 gboolean continue_download = FALSE;
2992 gint num_of_unc_msgs;
2994 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2996 if (num_of_unc_msgs)
2997 continue_download = connect_to_get_msg(
2998 GTK_WINDOW (window),
3001 if (num_of_unc_msgs == 0 || continue_download) {
3002 modest_platform_information_banner (
3003 NULL, NULL, _CS("mcen_ib_getting_items"));
3004 modest_header_view_copy_selection (
3005 MODEST_HEADER_VIEW (focused_widget));
3009 g_object_unref (header_list);
3011 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3012 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3015 /* Show information banner if there was a copy to clipboard */
3017 modest_platform_information_banner (
3018 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3022 modest_ui_actions_on_undo (GtkAction *action,
3023 ModestWindow *window)
3025 ModestEmailClipboard *clipboard = NULL;
3027 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3028 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3029 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3030 /* Clear clipboard source */
3031 clipboard = modest_runtime_get_email_clipboard ();
3032 modest_email_clipboard_clear (clipboard);
3035 g_return_if_reached ();
3040 modest_ui_actions_on_redo (GtkAction *action,
3041 ModestWindow *window)
3043 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3044 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3047 g_return_if_reached ();
3053 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3055 /* destroy information note */
3056 gtk_widget_destroy (GTK_WIDGET(user_data));
3061 paste_as_attachment_free (gpointer data)
3063 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3065 gtk_widget_destroy (helper->banner);
3066 g_object_unref (helper->banner);
3071 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3076 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3077 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3082 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3087 modest_ui_actions_on_paste (GtkAction *action,
3088 ModestWindow *window)
3090 GtkWidget *focused_widget = NULL;
3091 GtkWidget *inf_note = NULL;
3092 ModestMailOperation *mail_op = NULL;
3094 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3095 if (GTK_IS_EDITABLE (focused_widget)) {
3096 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3097 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3098 ModestEmailClipboard *e_clipboard = NULL;
3099 e_clipboard = modest_runtime_get_email_clipboard ();
3100 if (modest_email_clipboard_cleared (e_clipboard)) {
3101 GtkTextBuffer *buffer;
3102 GtkClipboard *clipboard;
3104 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3105 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3106 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3107 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3108 ModestMailOperation *mail_op;
3109 TnyFolder *src_folder;
3112 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3113 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3114 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3115 _CS("ckct_nw_pasting"));
3116 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3117 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3119 if (helper->banner != NULL) {
3120 g_object_ref (G_OBJECT (helper->banner));
3121 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3122 gtk_widget_show (GTK_WIDGET (helper->banner));
3126 modest_mail_operation_get_msgs_full (mail_op,
3128 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3130 paste_as_attachment_free);
3133 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3134 ModestEmailClipboard *clipboard = NULL;
3135 TnyFolder *src_folder = NULL;
3136 TnyFolderStore *folder_store = NULL;
3137 TnyList *data = NULL;
3138 gboolean delete = FALSE;
3140 /* Check clipboard source */
3141 clipboard = modest_runtime_get_email_clipboard ();
3142 if (modest_email_clipboard_cleared (clipboard))
3145 /* Get elements to paste */
3146 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3148 /* Create a new mail operation */
3149 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3151 /* Get destination folder */
3152 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3154 /* transfer messages */
3158 /* Ask for user confirmation */
3160 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3161 TNY_FOLDER (folder_store),
3165 if (response == GTK_RESPONSE_OK) {
3166 /* Launch notification */
3167 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3168 _CS("ckct_nw_pasting"));
3169 if (inf_note != NULL) {
3170 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3171 gtk_widget_show (GTK_WIDGET(inf_note));
3174 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3175 modest_mail_operation_xfer_msgs (mail_op,
3177 TNY_FOLDER (folder_store),
3179 destroy_information_note,
3182 g_object_unref (mail_op);
3185 } else if (src_folder != NULL) {
3186 /* Launch notification */
3187 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3188 _CS("ckct_nw_pasting"));
3189 if (inf_note != NULL) {
3190 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3191 gtk_widget_show (GTK_WIDGET(inf_note));
3194 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3195 modest_mail_operation_xfer_folder (mail_op,
3199 destroy_information_note,
3205 g_object_unref (data);
3206 if (src_folder != NULL)
3207 g_object_unref (src_folder);
3208 if (folder_store != NULL)
3209 g_object_unref (folder_store);
3215 modest_ui_actions_on_select_all (GtkAction *action,
3216 ModestWindow *window)
3218 GtkWidget *focused_widget;
3220 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3221 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3222 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3223 } else if (GTK_IS_LABEL (focused_widget)) {
3224 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3225 } else if (GTK_IS_EDITABLE (focused_widget)) {
3226 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3227 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3228 GtkTextBuffer *buffer;
3229 GtkTextIter start, end;
3231 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3232 gtk_text_buffer_get_start_iter (buffer, &start);
3233 gtk_text_buffer_get_end_iter (buffer, &end);
3234 gtk_text_buffer_select_range (buffer, &start, &end);
3235 } else if (GTK_IS_HTML (focused_widget)) {
3236 gtk_html_select_all (GTK_HTML (focused_widget));
3237 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3238 GtkWidget *header_view = focused_widget;
3239 GtkTreeSelection *selection = NULL;
3241 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3242 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3243 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3246 /* Disable window dimming management */
3247 modest_window_disable_dimming (MODEST_WINDOW(window));
3249 /* Select all messages */
3250 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3251 gtk_tree_selection_select_all (selection);
3253 /* Set focuse on header view */
3254 gtk_widget_grab_focus (header_view);
3257 /* Enable window dimming management */
3258 modest_window_enable_dimming (MODEST_WINDOW(window));
3259 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3265 modest_ui_actions_on_mark_as_read (GtkAction *action,
3266 ModestWindow *window)
3268 g_return_if_fail (MODEST_IS_WINDOW(window));
3270 /* Mark each header as read */
3271 do_headers_action (window, headers_action_mark_as_read, NULL);
3275 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3276 ModestWindow *window)
3278 g_return_if_fail (MODEST_IS_WINDOW(window));
3280 /* Mark each header as read */
3281 do_headers_action (window, headers_action_mark_as_unread, NULL);
3285 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3286 GtkRadioAction *selected,
3287 ModestWindow *window)
3291 value = gtk_radio_action_get_current_value (selected);
3292 if (MODEST_IS_WINDOW (window)) {
3293 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3298 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3299 GtkRadioAction *selected,
3300 ModestWindow *window)
3302 TnyHeaderFlags flags;
3303 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3305 flags = gtk_radio_action_get_current_value (selected);
3306 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3310 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3311 GtkRadioAction *selected,
3312 ModestWindow *window)
3316 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3318 file_format = gtk_radio_action_get_current_value (selected);
3319 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3324 modest_ui_actions_on_zoom_plus (GtkAction *action,
3325 ModestWindow *window)
3327 g_return_if_fail (MODEST_IS_WINDOW (window));
3329 modest_window_zoom_plus (MODEST_WINDOW (window));
3333 modest_ui_actions_on_zoom_minus (GtkAction *action,
3334 ModestWindow *window)
3336 g_return_if_fail (MODEST_IS_WINDOW (window));
3338 modest_window_zoom_minus (MODEST_WINDOW (window));
3342 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3343 ModestWindow *window)
3345 ModestWindowMgr *mgr;
3346 gboolean fullscreen, active;
3347 g_return_if_fail (MODEST_IS_WINDOW (window));
3349 mgr = modest_runtime_get_window_mgr ();
3351 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3352 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3354 if (active != fullscreen) {
3355 modest_window_mgr_set_fullscreen_mode (mgr, active);
3356 gtk_window_present (GTK_WINDOW (window));
3361 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3362 ModestWindow *window)
3364 ModestWindowMgr *mgr;
3365 gboolean fullscreen;
3367 g_return_if_fail (MODEST_IS_WINDOW (window));
3369 mgr = modest_runtime_get_window_mgr ();
3370 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3371 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3373 gtk_window_present (GTK_WINDOW (window));
3377 * Used by modest_ui_actions_on_details to call do_headers_action
3380 headers_action_show_details (TnyHeader *header,
3381 ModestWindow *window,
3388 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3391 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3392 gtk_widget_show_all (dialog);
3393 gtk_dialog_run (GTK_DIALOG (dialog));
3395 gtk_widget_destroy (dialog);
3399 * Show the folder details in a ModestDetailsDialog widget
3402 show_folder_details (TnyFolder *folder,
3408 dialog = modest_details_dialog_new_with_folder (window, folder);
3411 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3412 gtk_widget_show_all (dialog);
3413 gtk_dialog_run (GTK_DIALOG (dialog));
3415 gtk_widget_destroy (dialog);
3419 * Show the header details in a ModestDetailsDialog widget
3422 modest_ui_actions_on_details (GtkAction *action,
3425 TnyList * headers_list;
3429 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3432 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3435 g_object_unref (msg);
3437 headers_list = get_selected_headers (win);
3441 iter = tny_list_create_iterator (headers_list);
3443 header = TNY_HEADER (tny_iterator_get_current (iter));
3445 headers_action_show_details (header, win, NULL);
3446 g_object_unref (header);
3449 g_object_unref (iter);
3450 g_object_unref (headers_list);
3452 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3453 GtkWidget *folder_view, *header_view;
3455 /* Check which widget has the focus */
3456 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3457 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3458 if (gtk_widget_is_focus (folder_view)) {
3459 TnyFolderStore *folder_store
3460 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3461 if (!folder_store) {
3462 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3465 /* Show only when it's a folder */
3466 /* This function should not be called for account items,
3467 * because we dim the menu item for them. */
3468 if (TNY_IS_FOLDER (folder_store)) {
3469 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3472 g_object_unref (folder_store);
3475 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3476 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3477 /* Show details of each header */
3478 do_headers_action (win, headers_action_show_details, header_view);
3484 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3485 ModestMsgEditWindow *window)
3487 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3489 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3493 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3494 ModestMsgEditWindow *window)
3496 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3498 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3502 modest_ui_actions_toggle_folders_view (GtkAction *action,
3503 ModestMainWindow *main_window)
3505 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3507 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3508 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3510 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3514 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3515 ModestWindow *window)
3517 gboolean active, fullscreen = FALSE;
3518 ModestWindowMgr *mgr;
3520 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3522 /* Check if we want to toggle the toolbar vuew in fullscreen
3524 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3525 "ViewShowToolbarFullScreen")) {
3529 /* Toggle toolbar */
3530 mgr = modest_runtime_get_window_mgr ();
3531 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3535 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3536 ModestMsgEditWindow *window)
3538 modest_msg_edit_window_select_font (window);
3542 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3543 const gchar *display_name,
3546 /* Do not change the application name if the widget has not
3547 the focus. This callback could be called even if the folder
3548 view has not the focus, because the handled signal could be
3549 emitted when the folder view is redrawn */
3550 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3552 gtk_window_set_title (window, display_name);
3554 gtk_window_set_title (window, " ");
3559 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3561 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3562 modest_msg_edit_window_select_contacts (window);
3566 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3568 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3569 modest_msg_edit_window_check_names (window, FALSE);
3573 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3575 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3576 GTK_WIDGET (user_data));
3580 * This function is used to track changes in the selection of the
3581 * folder view that is inside the "move to" dialog to enable/disable
3582 * the OK button because we do not want the user to select a disallowed
3583 * destination for a folder.
3584 * The user also not desired to be able to use NEW button on items where
3585 * folder creation is not possibel.
3588 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3589 TnyFolderStore *folder_store,
3593 GtkWidget *dialog = NULL;
3594 GtkWidget *ok_button = NULL, *new_button = NULL;
3595 GList *children = NULL;
3596 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3597 gboolean moving_folder = FALSE;
3598 gboolean is_local_account = TRUE;
3599 GtkWidget *folder_view = NULL;
3600 ModestTnyFolderRules rules;
3605 /* Get the OK button */
3606 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3610 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3611 ok_button = GTK_WIDGET (children->next->next->data);
3612 new_button = GTK_WIDGET (children->next->data);
3613 g_list_free (children);
3615 /* check if folder_store is an remote account */
3616 if (TNY_IS_ACCOUNT (folder_store)) {
3617 TnyAccount *local_account = NULL;
3618 ModestTnyAccountStore *account_store = NULL;
3620 account_store = modest_runtime_get_account_store ();
3621 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3623 if ((gpointer) local_account != (gpointer) folder_store) {
3624 is_local_account = FALSE;
3625 /* New button should be dimmed on remote
3627 new_sensitive = FALSE;
3629 g_object_unref (local_account);
3632 /* Check the target folder rules */
3633 if (TNY_IS_FOLDER (folder_store)) {
3634 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3635 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3636 ok_sensitive = FALSE;
3637 new_sensitive = FALSE;
3642 /* Check if we're moving a folder */
3643 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3644 /* Get the widgets */
3645 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3646 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3647 if (gtk_widget_is_focus (folder_view))
3648 moving_folder = TRUE;
3651 if (moving_folder) {
3652 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3654 /* Get the folder to move */
3655 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3657 /* Check that we're not moving to the same folder */
3658 if (TNY_IS_FOLDER (moved_folder)) {
3659 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3660 if (parent == folder_store)
3661 ok_sensitive = FALSE;
3662 g_object_unref (parent);
3665 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3666 /* Do not allow to move to an account unless it's the
3667 local folders account */
3668 if (!is_local_account)
3669 ok_sensitive = FALSE;
3672 if (ok_sensitive && (moved_folder == folder_store)) {
3673 /* Do not allow to move to itself */
3674 ok_sensitive = FALSE;
3676 g_object_unref (moved_folder);
3678 TnyHeader *header = NULL;
3679 TnyFolder *src_folder = NULL;
3681 /* Moving a message */
3682 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3683 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3684 src_folder = tny_header_get_folder (header);
3685 g_object_unref (header);
3688 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3691 /* Do not allow to move the msg to the same folder */
3692 /* Do not allow to move the msg to an account */
3693 if ((gpointer) src_folder == (gpointer) folder_store ||
3694 TNY_IS_ACCOUNT (folder_store))
3695 ok_sensitive = FALSE;
3696 g_object_unref (src_folder);
3700 /* Set sensitivity of the OK button */
3701 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3702 /* Set sensitivity of the NEW button */
3703 gtk_widget_set_sensitive (new_button, new_sensitive);
3707 create_move_to_dialog (GtkWindow *win,
3708 GtkWidget *folder_view,
3709 GtkWidget **tree_view)
3711 GtkWidget *dialog, *scroll;
3712 GtkWidget *new_button;
3714 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3716 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3719 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3720 /* We do this manually so GTK+ does not associate a response ID for
3722 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3723 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3724 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3726 /* Create scrolled window */
3727 scroll = gtk_scrolled_window_new (NULL, NULL);
3728 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3729 GTK_POLICY_AUTOMATIC,
3730 GTK_POLICY_AUTOMATIC);
3732 /* Create folder view */
3733 *tree_view = modest_platform_create_folder_view (NULL);
3735 /* Track changes in the selection to
3736 * disable the OK button whenever "Move to" is not possible
3737 * disbale NEW button whenever New is not possible */
3738 g_signal_connect (*tree_view,
3739 "folder_selection_changed",
3740 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3743 /* Listen to clicks on New button */
3744 g_signal_connect (G_OBJECT (new_button),
3746 G_CALLBACK(create_move_to_dialog_on_new_folder),
3749 /* It could happen that we're trying to move a message from a
3750 window (msg window for example) after the main window was
3751 closed, so we can not just get the model of the folder
3753 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3754 const gchar *visible_id = NULL;
3756 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3757 MODEST_FOLDER_VIEW(*tree_view));
3760 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3762 /* Show the same account than the one that is shown in the main window */
3763 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3766 const gchar *active_account_name = NULL;
3767 ModestAccountMgr *mgr = NULL;
3768 ModestAccountData *acc_data = NULL;
3770 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3771 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3773 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3774 mgr = modest_runtime_get_account_mgr ();
3775 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3777 /* Set the new visible & active account */
3778 if (acc_data && acc_data->store_account) {
3779 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3780 acc_data->store_account->account_name);
3781 modest_account_mgr_free_account_data (mgr, acc_data);
3785 /* Hide special folders */
3786 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3788 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3790 /* Add scroll to dialog */
3791 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3792 scroll, TRUE, TRUE, 0);
3794 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3795 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3801 * Returns TRUE if at least one of the headers of the list belongs to
3802 * a message that has been fully retrieved.
3804 #if 0 /* no longer in use. delete in 2007.10 */
3806 has_retrieved_msgs (TnyList *list)
3809 gboolean found = FALSE;
3811 iter = tny_list_create_iterator (list);
3812 while (!tny_iterator_is_done (iter) && !found) {
3814 TnyHeaderFlags flags = 0;
3816 header = TNY_HEADER (tny_iterator_get_current (iter));
3818 flags = tny_header_get_flags (header);
3819 if (flags & TNY_HEADER_FLAG_CACHED)
3820 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3823 g_object_unref (header);
3827 tny_iterator_next (iter);
3829 g_object_unref (iter);
3837 * Shows a confirmation dialog to the user when we're moving messages
3838 * from a remote server to the local storage. Returns the dialog
3839 * response. If it's other kind of movement then it always returns
3842 * This one is used by the next functions:
3843 * modest_ui_actions_on_paste - commented out
3844 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3847 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3848 TnyFolder *dest_folder,
3852 gint response = GTK_RESPONSE_OK;
3854 /* return with OK if the destination is a remote folder */
3855 if (modest_tny_folder_is_remote_folder (dest_folder))
3856 return GTK_RESPONSE_OK;
3858 TnyFolder *src_folder = NULL;
3859 TnyIterator *iter = NULL;
3860 TnyHeader *header = NULL;
3862 /* Get source folder */
3863 iter = tny_list_create_iterator (headers);
3864 header = TNY_HEADER (tny_iterator_get_current (iter));
3866 src_folder = tny_header_get_folder (header);
3867 g_object_unref (header);
3869 g_object_unref (iter);
3871 /* if no src_folder, message may be an attahcment */
3872 if (src_folder == NULL)
3873 return GTK_RESPONSE_CANCEL;
3875 /* If the source is a local or MMC folder */
3876 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3877 g_object_unref (src_folder);
3878 return GTK_RESPONSE_OK;
3880 g_object_unref (src_folder);
3882 /* now if offline we ask the user */
3883 if(connect_to_get_msg( GTK_WINDOW (win),
3884 tny_list_get_length (headers)))
3885 response = GTK_RESPONSE_OK;
3887 response = GTK_RESPONSE_CANCEL;
3895 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3897 /* Note that the operation could have failed, in that case do
3899 if (modest_mail_operation_get_status (mail_op) ==
3900 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3902 GObject *object = modest_mail_operation_get_source (mail_op);
3903 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3904 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3906 if (!modest_msg_view_window_select_next_message (self))
3907 if (!modest_msg_view_window_select_previous_message (self))
3908 /* No more messages to view, so close this window */
3909 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3911 g_object_unref (object);
3914 /* Close the "Pasting" information banner */
3915 gtk_widget_destroy (GTK_WIDGET(user_data));
3919 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3922 ModestWindow *main_window = NULL;
3923 GtkWidget *folder_view = NULL;
3924 GObject *win = modest_mail_operation_get_source (mail_op);
3925 const GError *error = NULL;
3926 const gchar *message = NULL;
3928 /* Get error message */
3929 error = modest_mail_operation_get_error (mail_op);
3930 if (error != NULL && error->message != NULL) {
3931 message = error->message;
3933 message = _("mail_in_ui_folder_move_target_error");
3936 /* Disable next automatic folder selection */
3937 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3938 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3939 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3940 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3942 if (user_data && TNY_IS_FOLDER (user_data)) {
3943 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3944 TNY_FOLDER (user_data), FALSE);
3947 /* Show notification dialog */
3948 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3949 g_object_unref (win);
3953 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3956 GObject *win = modest_mail_operation_get_source (mail_op);
3957 const GError *error = modest_mail_operation_get_error (mail_op);
3959 g_return_if_fail (error != NULL);
3960 if (error->message != NULL)
3961 g_printerr ("modest: %s\n", error->message);
3963 g_printerr ("modest: unkonw error on send&receive operation");
3965 /* Show error message */
3966 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3967 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3968 /* _CS("sfil_ib_unable_to_receive")); */
3970 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3971 /* _CS("sfil_ib_unable_to_send")); */
3972 g_object_unref (win);
3976 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3983 gint pending_purges = 0;
3984 gboolean some_purged = FALSE;
3985 ModestWindow *win = MODEST_WINDOW (user_data);
3986 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3988 /* If there was any error */
3989 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3990 modest_window_mgr_unregister_header (mgr, header);
3994 /* Once the message has been retrieved for purging, we check if
3995 * it's all ok for purging */
3997 parts = tny_simple_list_new ();
3998 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3999 iter = tny_list_create_iterator (parts);
4001 while (!tny_iterator_is_done (iter)) {
4003 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4004 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4005 if (tny_mime_part_is_purged (part))
4012 g_object_unref (part);
4014 tny_iterator_next (iter);
4016 g_object_unref (iter);
4019 if (pending_purges>0) {
4021 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4023 if (response == GTK_RESPONSE_OK) {
4024 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4025 iter = tny_list_create_iterator (parts);
4026 while (!tny_iterator_is_done (iter)) {
4029 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4030 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4031 tny_mime_part_set_purged (part);
4034 g_object_unref (part);
4036 tny_iterator_next (iter);
4039 tny_msg_rewrite_cache (msg);
4042 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4044 g_object_unref (iter);
4046 modest_window_mgr_unregister_header (mgr, header);
4048 g_object_unref (parts);
4052 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4053 ModestMainWindow *win)
4055 GtkWidget *header_view;
4056 TnyList *header_list;
4059 TnyHeaderFlags flags;
4060 ModestWindow *msg_view_window = NULL;
4063 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4065 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4066 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4068 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4070 if (tny_list_get_length (header_list) == 1) {
4071 iter = tny_list_create_iterator (header_list);
4072 header = TNY_HEADER (tny_iterator_get_current (iter));
4073 g_object_unref (iter);
4078 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4079 header, &msg_view_window);
4080 flags = tny_header_get_flags (header);
4081 if (!(flags & TNY_HEADER_FLAG_CACHED))
4084 if (msg_view_window != NULL)
4085 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4087 /* do nothing; uid was registered before, so window is probably on it's way */
4088 g_warning ("debug: header %p has already been registered", header);
4091 ModestMailOperation *mail_op = NULL;
4092 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4093 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4095 modest_ui_actions_get_msgs_full_error_handler,
4097 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4098 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4100 g_object_unref (mail_op);
4103 g_object_unref (header);
4105 g_object_unref (header_list);
4109 * Utility function that transfer messages from both the main window
4110 * and the msg view window when using the "Move to" dialog
4113 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4116 TnyList *headers = NULL;
4117 TnyAccount *dst_account = NULL;
4118 const gchar *proto_str = NULL;
4119 gboolean dst_is_pop = FALSE;
4121 if (!TNY_IS_FOLDER (dst_folder)) {
4122 modest_platform_information_banner (GTK_WIDGET (win),
4124 _CS("ckdg_ib_unable_to_move_to_current_location"));
4128 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4129 proto_str = tny_account_get_proto (dst_account);
4131 /* tinymail will return NULL for local folders it seems */
4132 dst_is_pop = proto_str &&
4133 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4134 MODEST_PROTOCOL_STORE_POP);
4136 g_object_unref (dst_account);
4138 /* Get selected headers */
4139 headers = get_selected_headers (MODEST_WINDOW (win));
4142 modest_platform_information_banner (GTK_WIDGET (win),
4144 ngettext("mail_in_ui_folder_move_target_error",
4145 "mail_in_ui_folder_move_targets_error",
4146 tny_list_get_length (headers)));
4147 g_object_unref (headers);
4151 GtkWidget *inf_note;
4152 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4153 _CS("ckct_nw_pasting"));
4154 if (inf_note != NULL) {
4155 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4156 gtk_widget_show (GTK_WIDGET(inf_note));
4159 ModestMailOperation *mail_op =
4160 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4162 modest_ui_actions_move_folder_error_handler,
4164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4167 modest_mail_operation_xfer_msgs (mail_op,
4169 TNY_FOLDER (dst_folder),
4174 g_object_unref (G_OBJECT (mail_op));
4175 g_object_unref (headers);
4179 * UI handler for the "Move to" action when invoked from the
4183 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4184 GtkWidget *folder_view,
4185 TnyFolderStore *dst_folder,
4186 ModestMainWindow *win)
4188 ModestHeaderView *header_view = NULL;
4189 ModestMailOperation *mail_op = NULL;
4190 TnyFolderStore *src_folder;
4191 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4193 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4195 /* Get the source folder */
4196 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4198 /* Get header view */
4199 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4201 /* Get folder or messages to transfer */
4202 if (gtk_widget_is_focus (folder_view)) {
4203 GtkTreeSelection *sel;
4204 gboolean do_xfer = TRUE;
4206 /* Allow only to transfer folders to the local root folder */
4207 if (TNY_IS_ACCOUNT (dst_folder) &&
4208 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4210 } else if (!TNY_IS_FOLDER (src_folder)) {
4211 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4213 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4214 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4215 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4221 GtkWidget *inf_note;
4222 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4223 _CS("ckct_nw_pasting"));
4224 if (inf_note != NULL) {
4225 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4226 gtk_widget_show (GTK_WIDGET(inf_note));
4228 /* Clean folder on header view before moving it */
4229 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4230 gtk_tree_selection_unselect_all (sel);
4233 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4235 modest_ui_actions_move_folder_error_handler,
4237 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4240 /* Select *after* the changes */
4241 /* TODO: this function hangs UI after transfer */
4242 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4243 /* TNY_FOLDER (src_folder), TRUE); */
4245 modest_mail_operation_xfer_folder (mail_op,
4246 TNY_FOLDER (src_folder),
4251 /* Unref mail operation */
4252 g_object_unref (G_OBJECT (mail_op));
4254 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4255 gboolean do_xfer = TRUE;
4256 /* Ask for confirmation if the source folder is remote and we're not connected */
4257 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4258 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4259 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4260 guint num_headers = tny_list_get_length(headers);
4261 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4265 g_object_unref(headers);
4267 if (do_xfer) /* Transfer messages */
4268 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4272 g_object_unref (src_folder);
4277 * UI handler for the "Move to" action when invoked from the
4278 * ModestMsgViewWindow
4281 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4282 TnyFolderStore *dst_folder,
4283 ModestMsgViewWindow *win)
4285 TnyHeader *header = NULL;
4286 TnyFolderStore *src_folder;
4288 /* Create header list */
4289 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4290 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4291 g_object_unref (header);
4293 /* Transfer the message if online or confirmed by the user */
4294 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4295 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4296 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4299 g_object_unref (src_folder);
4303 modest_ui_actions_on_move_to (GtkAction *action,
4306 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4308 TnyFolderStore *dst_folder = NULL;
4309 ModestMainWindow *main_window;
4311 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4312 MODEST_IS_MSG_VIEW_WINDOW (win));
4314 /* Get the main window if exists */
4315 if (MODEST_IS_MAIN_WINDOW (win))
4316 main_window = MODEST_MAIN_WINDOW (win);
4319 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4321 /* Get the folder view widget if exists */
4323 folder_view = modest_main_window_get_child_widget (main_window,
4324 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4328 /* Create and run the dialog */
4329 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4330 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4331 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4332 result = gtk_dialog_run (GTK_DIALOG(dialog));
4333 g_object_ref (tree_view);
4334 gtk_widget_destroy (dialog);
4336 if (result != GTK_RESPONSE_ACCEPT)
4339 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4340 /* Do window specific stuff */
4341 if (MODEST_IS_MAIN_WINDOW (win)) {
4342 modest_ui_actions_on_main_window_move_to (action,
4345 MODEST_MAIN_WINDOW (win));
4347 modest_ui_actions_on_msg_view_window_move_to (action,
4349 MODEST_MSG_VIEW_WINDOW (win));
4353 g_object_unref (dst_folder);
4357 * Calls #HeadersFunc for each header already selected in the main
4358 * window or the message currently being shown in the msg view window
4361 do_headers_action (ModestWindow *win,
4365 TnyList *headers_list = NULL;
4366 TnyIterator *iter = NULL;
4367 TnyHeader *header = NULL;
4368 TnyFolder *folder = NULL;
4371 headers_list = get_selected_headers (win);
4375 /* Get the folder */
4376 iter = tny_list_create_iterator (headers_list);
4377 header = TNY_HEADER (tny_iterator_get_current (iter));
4379 folder = tny_header_get_folder (header);
4380 g_object_unref (header);
4383 /* Call the function for each header */
4384 while (!tny_iterator_is_done (iter)) {
4385 header = TNY_HEADER (tny_iterator_get_current (iter));
4386 func (header, win, user_data);
4387 g_object_unref (header);
4388 tny_iterator_next (iter);
4391 /* Trick: do a poke status in order to speed up the signaling
4393 tny_folder_poke_status (folder);
4396 g_object_unref (folder);
4397 g_object_unref (iter);
4398 g_object_unref (headers_list);
4402 modest_ui_actions_view_attachment (GtkAction *action,
4403 ModestWindow *window)
4405 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4406 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4408 /* not supported window for this action */
4409 g_return_if_reached ();
4414 modest_ui_actions_save_attachments (GtkAction *action,
4415 ModestWindow *window)
4417 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4418 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4420 /* not supported window for this action */
4421 g_return_if_reached ();
4426 modest_ui_actions_remove_attachments (GtkAction *action,
4427 ModestWindow *window)
4429 if (MODEST_IS_MAIN_WINDOW (window)) {
4430 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4431 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4432 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4434 /* not supported window for this action */
4435 g_return_if_reached ();
4440 modest_ui_actions_on_settings (GtkAction *action,
4445 dialog = modest_platform_get_global_settings_dialog ();
4446 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4447 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4448 gtk_widget_show_all (dialog);
4450 gtk_dialog_run (GTK_DIALOG (dialog));
4452 gtk_widget_destroy (dialog);
4456 modest_ui_actions_on_help (GtkAction *action,
4459 const gchar *help_id = NULL;
4461 if (MODEST_IS_MAIN_WINDOW (win)) {
4462 GtkWidget *folder_view;
4463 TnyFolderStore *folder_store;
4465 /* Get selected folder */
4466 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4467 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4468 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4470 /* Switch help_id */
4471 if (TNY_IS_FOLDER (folder_store)) {
4472 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4473 case TNY_FOLDER_TYPE_NORMAL:
4474 help_id = "applications_email_managefolders";
4476 case TNY_FOLDER_TYPE_INBOX:
4477 help_id = "applications_email_inbox";
4479 case TNY_FOLDER_TYPE_OUTBOX:
4480 help_id = "applications_email_outbox";
4482 case TNY_FOLDER_TYPE_SENT:
4483 help_id = "applications_email_sent";
4485 case TNY_FOLDER_TYPE_DRAFTS:
4486 help_id = "applications_email_drafts";
4488 case TNY_FOLDER_TYPE_ARCHIVE:
4489 help_id = "applications_email_managefolders";
4492 help_id = "applications_email_managefolders";
4495 help_id = "applications_email_mainview";
4497 g_object_unref (folder_store);
4498 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4499 help_id = "applications_email_viewer";
4500 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4501 help_id = "applications_email_editor";
4503 modest_platform_show_help (GTK_WINDOW (win), help_id);
4507 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4508 ModestWindow *window)
4510 ModestMailOperation *mail_op;
4514 headers = get_selected_headers (window);
4518 /* Create mail operation */
4519 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4521 modest_ui_actions_get_msgs_full_error_handler,
4523 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4524 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4527 g_object_unref (headers);
4528 g_object_unref (mail_op);
4532 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4533 ModestWindow *window)
4535 g_return_if_fail (MODEST_IS_WINDOW (window));
4538 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4542 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4543 ModestWindow *window)
4545 g_return_if_fail (MODEST_IS_WINDOW (window));
4548 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4552 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4553 ModestWindow *window)
4555 g_return_if_fail (MODEST_IS_WINDOW (window));
4558 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4562 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4563 ModestWindow *window)
4565 g_return_if_fail (MODEST_IS_WINDOW (window));
4568 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4572 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4573 ModestWindow *window)
4575 g_return_if_fail (MODEST_IS_WINDOW (window));
4578 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4582 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4583 ModestWindow *window)
4585 g_return_if_fail (MODEST_IS_WINDOW (window));
4588 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4592 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4593 ModestWindow *window)
4595 g_return_if_fail (MODEST_IS_WINDOW (window));
4598 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4602 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4603 ModestWindow *window)
4605 g_return_if_fail (MODEST_IS_WINDOW (window));
4608 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4612 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4613 ModestWindow *window)
4615 g_return_if_fail (MODEST_IS_WINDOW (window));
4618 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4622 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4624 g_return_if_fail (MODEST_IS_WINDOW (window));
4627 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4631 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4633 g_return_if_fail (MODEST_IS_WINDOW (window));
4635 modest_platform_show_search_messages (GTK_WINDOW (window));
4639 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4641 g_return_if_fail (MODEST_IS_WINDOW (win));
4642 modest_platform_show_addressbook (GTK_WINDOW (win));
4647 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4648 ModestWindow *window)
4650 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4652 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4656 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4657 ModestMailOperationState *state,
4660 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4662 /* Set send/receive operation finished */
4663 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4664 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4670 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4676 const gchar* server_name = NULL;
4677 TnyTransportAccount *server_account;
4678 gchar *message = NULL;
4680 /* Don't show anything if the user cancelled something */
4681 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4684 /* Get the server name: */
4686 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4687 if (server_account) {
4688 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4690 g_object_unref (server_account);
4691 server_account = NULL;
4694 g_return_if_fail (server_name);
4696 /* Show the appropriate message text for the GError: */
4697 switch (err->code) {
4698 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4699 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4701 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4702 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4704 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4705 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4707 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4708 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4711 g_return_if_reached ();
4714 /* TODO if the username or the password where not defined we
4715 should show the Accounts Settings dialog or the Connection
4716 specific SMTP server window */
4718 modest_platform_run_information_dialog (NULL, message);
4723 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4728 ModestMainWindow *main_window = NULL;
4729 ModestWindowMgr *mgr = NULL;
4730 GtkWidget *folder_view = NULL, *header_view = NULL;
4731 TnyFolderStore *selected_folder = NULL;
4732 TnyFolderType folder_type;
4734 mgr = modest_runtime_get_window_mgr ();
4735 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4740 /* Check if selected folder is OUTBOX */
4741 folder_view = modest_main_window_get_child_widget (main_window,
4742 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4743 header_view = modest_main_window_get_child_widget (main_window,
4744 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4746 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4747 if (!TNY_IS_FOLDER (selected_folder))
4750 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4751 #if GTK_CHECK_VERSION(2, 8, 0)
4752 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4753 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4754 GtkTreeViewColumn *tree_column;
4756 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4757 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4758 gtk_tree_view_column_queue_resize (tree_column);
4761 gtk_widget_queue_draw (header_view);
4766 if (selected_folder != NULL)
4767 g_object_unref (selected_folder);