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"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-global-settings-dialog.h"
59 #include "modest-connection-specific-smtp-window.h"
60 #include "modest-account-mgr-helpers.h"
61 #include "modest-mail-operation.h"
62 #include "modest-text-utils.h"
64 #ifdef MODEST_HAVE_EASYSETUP
65 #include "easysetup/modest-easysetup-wizard.h"
66 #endif /* MODEST_HAVE_EASYSETUP */
68 #include <modest-widget-memory.h>
69 #include <tny-error.h>
70 #include <tny-simple-list.h>
71 #include <tny-msg-view.h>
72 #include <tny-device.h>
73 #include <tny-merge-folder.h>
75 typedef struct _GetMsgAsyncHelper {
77 ModestMailOperation *mail_op;
84 typedef enum _ReplyForwardAction {
90 typedef struct _ReplyForwardHelper {
91 guint reply_forward_type;
92 ReplyForwardAction action;
97 * The do_headers_action uses this kind of functions to perform some
98 * action to each member of a list of headers
100 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
103 do_headers_action (ModestWindow *win,
108 static void open_msg_cb (ModestMailOperation *mail_op,
113 static void reply_forward_cb (ModestMailOperation *mail_op,
118 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
120 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
123 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
126 const gchar *authors[] = {
127 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
130 about = gtk_about_dialog_new ();
131 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
132 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
133 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
134 _("Copyright (c) 2006, Nokia Corporation\n"
135 "All rights reserved."));
136 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
137 _("a modest e-mail client\n\n"
138 "design and implementation: Dirk-Jan C. Binnema\n"
139 "contributions from the fine people at KC and Ig\n"
140 "uses the tinymail email framework written by Philip van Hoof"));
141 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
142 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
144 gtk_dialog_run (GTK_DIALOG (about));
145 gtk_widget_destroy(about);
149 * Gets the list of currently selected messages. If the win is the
150 * main window, then it returns a newly allocated list of the headers
151 * selected in the header view. If win is the msg view window, then
152 * the value returned is a list with just a single header.
154 * The caller of this funcion must free the list.
157 get_selected_headers (ModestWindow *win)
159 if (MODEST_IS_MAIN_WINDOW(win)) {
160 GtkWidget *header_view;
162 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
163 MODEST_WIDGET_TYPE_HEADER_VIEW);
164 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
166 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
167 /* for MsgViewWindows, we simply return a list with one element */
169 TnyList *list = NULL;
171 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
172 if (header != NULL) {
173 list = tny_simple_list_new ();
174 tny_list_prepend (list, G_OBJECT(header));
175 g_object_unref (G_OBJECT(header));
185 headers_action_mark_as_read (TnyHeader *header,
189 TnyHeaderFlags flags;
191 g_return_if_fail (TNY_IS_HEADER(header));
193 flags = tny_header_get_flags (header);
194 if (flags & TNY_HEADER_FLAG_SEEN) return;
195 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
199 headers_action_mark_as_unread (TnyHeader *header,
203 TnyHeaderFlags flags;
205 g_return_if_fail (TNY_IS_HEADER(header));
207 flags = tny_header_get_flags (header);
208 if (flags & TNY_HEADER_FLAG_SEEN) {
209 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
215 headers_action_delete (TnyHeader *header,
219 ModestMailOperation *mail_op = NULL;
221 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
222 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
225 /* Always delete. TODO: Move to trash still not supported */
226 modest_mail_operation_remove_msg (mail_op, header, FALSE);
227 g_object_unref (G_OBJECT (mail_op));
231 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
233 TnyList *header_list = NULL;
234 TnyIterator *iter = NULL;
235 TnyHeader *header = NULL;
236 gchar *message = NULL;
240 ModestWindowMgr *mgr;
242 g_return_if_fail (MODEST_IS_WINDOW(win));
244 header_list = get_selected_headers (win);
245 if (!header_list) return;
247 /* Check if any of the headers is already opened */
248 iter = tny_list_create_iterator (header_list);
250 mgr = modest_runtime_get_window_mgr ();
251 while (!tny_iterator_is_done (iter) && !found) {
252 header = TNY_HEADER (tny_iterator_get_current (iter));
253 if (modest_window_mgr_find_window_by_header (mgr, header))
255 g_object_unref (header);
256 tny_iterator_next (iter);
258 g_object_unref (iter);
263 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
264 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
266 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
270 g_object_unref (header_list);
275 if (tny_list_get_length(header_list) > 1)
276 message = g_strdup(_("emev_nc_delete_messages"));
278 iter = tny_list_create_iterator (header_list);
279 header = TNY_HEADER (tny_iterator_get_current (iter));
280 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
281 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
282 g_object_unref (header);
283 g_object_unref (iter);
286 /* Confirmation dialog */
287 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
291 if (response == GTK_RESPONSE_OK) {
292 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
294 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
298 /* Remove each header */
299 do_headers_action (win, headers_action_delete, NULL);
301 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
302 gtk_widget_destroy (GTK_WIDGET(win));
309 g_object_unref (header_list);
314 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
316 #ifdef MODEST_PLATFORM_MAEMO
317 modest_osso_save_state();
318 #endif /* MODEST_PLATFORM_MAEMO */
324 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
326 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
327 gtk_widget_destroy (GTK_WIDGET (win));
328 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
330 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
331 } else if (MODEST_IS_WINDOW (win)) {
332 gtk_widget_destroy (GTK_WIDGET (win));
334 g_return_if_reached ();
339 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
341 GtkClipboard *clipboard = NULL;
342 gchar *selection = NULL;
344 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
345 selection = gtk_clipboard_wait_for_text (clipboard);
347 /* Question: why is the clipboard being used here?
348 * It doesn't really make a lot of sense. */
352 modest_address_book_add_address (selection);
358 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
360 /* This is currently only implemented for Maemo,
361 * because it requires a providers preset file which is not publically available.
363 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
364 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
365 TRUE /* enabled accounts only */);
366 gboolean accounts_exist = account_names != NULL;
367 g_slist_free (account_names);
369 if (!accounts_exist) {
370 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
371 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
372 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
373 gtk_dialog_run (GTK_DIALOG (wizard));
374 gtk_widget_destroy (GTK_WIDGET (wizard));
376 /* Show the list of accounts: */
377 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
378 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
379 gtk_dialog_run (account_win);
380 gtk_widget_destroy (GTK_WIDGET(account_win));
383 GtkWidget *dialog, *label;
385 /* Create the widgets */
387 dialog = gtk_dialog_new_with_buttons ("Message",
389 GTK_DIALOG_DESTROY_WITH_PARENT,
393 label = gtk_label_new ("Hello World!");
395 /* Ensure that the dialog box is destroyed when the user responds. */
397 g_signal_connect_swapped (dialog, "response",
398 G_CALLBACK (gtk_widget_destroy),
401 /* Add the label, and show everything we've added to the dialog. */
403 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
405 gtk_widget_show_all (dialog);
406 #endif /* MODEST_PLATFORM_MAEMO */
410 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
412 ModestWindow *main_window = MODEST_WINDOW (user_data);
414 /* Save any changes. */
415 modest_connection_specific_smtp_window_save_server_accounts (
416 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
417 modest_window_get_active_account (main_window));
418 gtk_widget_destroy (GTK_WIDGET (window));
422 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
424 /* This is currently only implemented for Maemo,
425 * because it requires an API (libconic) to detect different connection
428 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
430 /* Create the window if necessary: */
431 const gchar *active_account_name = modest_window_get_active_account (win);
433 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
434 * or show the default account?
435 * If we show the default account then the account name should be shown in
436 * the window when we show it. */
437 if (!active_account_name) {
438 g_warning ("%s: No account is active.", __FUNCTION__);
442 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
443 modest_connection_specific_smtp_window_fill_with_connections (
444 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
445 modest_runtime_get_account_mgr(),
446 active_account_name);
448 /* Show the window: */
449 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
450 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
451 gtk_widget_show (specific_window);
453 /* Save changes when the window is hidden: */
454 g_signal_connect (specific_window, "hide",
455 G_CALLBACK (on_smtp_servers_window_hide), win);
456 #endif /* MODEST_PLATFORM_MAEMO */
460 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
462 ModestWindow *msg_win;
464 TnyFolder *folder = NULL;
465 gchar *account_name = NULL;
466 gchar *from_str = NULL;
467 /* GError *err = NULL; */
468 TnyAccount *account = NULL;
469 ModestWindowMgr *mgr;
470 gchar *signature = NULL;
472 account_name = g_strdup(modest_window_get_active_account (win));
474 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
476 g_printerr ("modest: no account found\n");
480 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
482 TNY_ACCOUNT_TYPE_STORE);
484 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
488 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
490 g_printerr ("modest: failed get from string for '%s'\n", account_name);
494 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
495 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
496 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
497 MODEST_ACCOUNT_SIGNATURE, FALSE);
499 signature = g_strdup ("");
502 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
504 g_printerr ("modest: failed to create new msg\n");
508 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
510 g_printerr ("modest: failed to find Drafts folder\n");
514 /* tny_folder_add_msg (folder, msg, &err); */
516 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
518 /* g_error_free (err); */
522 /* Create and register edit window */
523 /* This is destroyed by TOOD. */
524 msg_win = modest_msg_edit_window_new (msg, account_name);
525 mgr = modest_runtime_get_window_mgr ();
526 modest_window_mgr_register_window (mgr, msg_win);
529 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
531 gtk_widget_show_all (GTK_WIDGET (msg_win));
534 g_free (account_name);
538 g_object_unref (G_OBJECT(account));
540 g_object_unref (G_OBJECT(msg));
542 g_object_unref (G_OBJECT(folder));
546 open_msg_cb (ModestMailOperation *mail_op,
551 ModestWindowMgr *mgr = NULL;
552 ModestWindow *parent_win = NULL;
553 ModestWindow *win = NULL;
554 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
555 gchar *account = NULL;
558 /* TODO: Show an error? (review the specs) */
562 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
563 folder = tny_header_get_folder (header);
565 /* Mark header as read */
566 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
569 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
571 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
573 /* Gets folder type (OUTBOX headers will be opened in edit window */
574 if (modest_tny_folder_is_local_folder (folder))
575 folder_type = modest_tny_folder_get_local_folder_type (folder);
577 /* If the header is in the drafts folder then open the editor,
578 else the message view window */
579 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
580 win = modest_msg_edit_window_new (msg, account);
582 gchar *uid = modest_tny_folder_get_header_unique_id (header);
584 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
585 GtkWidget *header_view;
586 GtkTreeSelection *sel;
587 GList *sel_list = NULL;
590 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
591 MODEST_WIDGET_TYPE_HEADER_VIEW);
593 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
594 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
596 if (sel_list != NULL) {
597 GtkTreeRowReference *row_reference;
599 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
600 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
601 g_list_free (sel_list);
603 win = modest_msg_view_window_new_with_header_model (msg,
608 gtk_tree_row_reference_free (row_reference);
610 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
613 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
618 /* Register and show new window */
620 mgr = modest_runtime_get_window_mgr ();
621 modest_window_mgr_register_window (mgr, win);
622 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
623 gtk_widget_show_all (GTK_WIDGET(win));
628 g_object_unref (msg);
629 g_object_unref (folder);
630 g_object_unref (header);
634 * This function is the error handler of the
635 * modest_mail_operation_get_msgs_full operation
638 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
643 error = modest_mail_operation_get_error (mail_op);
644 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
645 GObject *win = modest_mail_operation_get_source (mail_op);
647 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
653 * This function is used by both modest_ui_actions_on_open and
654 * modest_ui_actions_on_header_activated. This way we always do the
655 * same when trying to open messages.
658 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
660 ModestWindowMgr *mgr;
662 ModestMailOperation *mail_op;
664 /* Look if we already have a message view for each header. If
665 true, then remove the header from the list of headers to
667 mgr = modest_runtime_get_window_mgr ();
668 iter = tny_list_create_iterator (headers);
669 while (!tny_iterator_is_done (iter)) {
670 ModestWindow *window;
673 header = TNY_HEADER (tny_iterator_get_current (iter));
674 window = modest_window_mgr_find_window_by_header (mgr, header);
676 /* Do not open again the message and present
677 the window to the user */
678 tny_list_remove (headers, G_OBJECT (header));
679 gtk_window_present (GTK_WINDOW (window));
682 g_object_unref (header);
683 tny_iterator_next (iter);
686 /* Open each message */
687 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
689 modest_ui_actions_get_msgs_full_error_handler,
691 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
692 modest_mail_operation_get_msgs_full (mail_op,
699 g_object_unref(mail_op);
703 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
708 headers = get_selected_headers (win);
713 _modest_ui_actions_open (headers, win);
715 g_object_unref(headers);
720 free_reply_forward_helper (gpointer data)
722 ReplyForwardHelper *helper;
724 helper = (ReplyForwardHelper *) data;
725 g_free (helper->account_name);
726 g_slice_free (ReplyForwardHelper, helper);
730 reply_forward_cb (ModestMailOperation *mail_op,
736 ReplyForwardHelper *rf_helper;
737 ModestWindow *msg_win;
738 ModestEditType edit_type;
741 TnyFolder *folder = NULL;
742 TnyAccount *account = NULL;
743 ModestWindowMgr *mgr;
744 gchar *signature = NULL;
746 g_return_if_fail (user_data != NULL);
747 rf_helper = (ReplyForwardHelper *) user_data;
749 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
750 rf_helper->account_name);
751 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
752 rf_helper->account_name,
753 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
754 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
755 rf_helper->account_name,
756 MODEST_ACCOUNT_SIGNATURE, FALSE);
759 /* Create reply mail */
760 switch (rf_helper->action) {
763 modest_tny_msg_create_reply_msg (msg, from, signature,
764 rf_helper->reply_forward_type,
765 MODEST_TNY_MSG_REPLY_MODE_SENDER);
767 case ACTION_REPLY_TO_ALL:
769 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
770 MODEST_TNY_MSG_REPLY_MODE_ALL);
771 edit_type = MODEST_EDIT_TYPE_REPLY;
775 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
776 edit_type = MODEST_EDIT_TYPE_FORWARD;
779 g_return_if_reached ();
786 g_printerr ("modest: failed to create message\n");
790 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
791 rf_helper->account_name,
792 TNY_ACCOUNT_TYPE_STORE);
794 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
798 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
800 g_printerr ("modest: failed to find Drafts folder\n");
804 tny_folder_add_msg (folder, msg, &err);
806 g_printerr ("modest: error adding msg to Drafts folder: %s",
812 /* Create and register the windows */
813 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
814 mgr = modest_runtime_get_window_mgr ();
815 modest_window_mgr_register_window (mgr, msg_win);
817 /* Show edit window */
818 gtk_widget_show_all (GTK_WIDGET (msg_win));
822 g_object_unref (G_OBJECT (new_msg));
824 g_object_unref (G_OBJECT (folder));
826 g_object_unref (G_OBJECT (account));
827 g_object_unref (msg);
828 g_object_unref (header);
832 * Checks a list of headers. If any of them are not currently
833 * downloaded (CACHED) then it asks the user for permission to
836 * Returns FALSE if the user does not want to download the
837 * messages. Returns TRUE if the user allowed the download or if all
838 * of them are currently downloaded
841 download_uncached_messages (TnyList *header_list, GtkWindow *win)
844 gboolean found, retval;
846 iter = tny_list_create_iterator (header_list);
848 while (!tny_iterator_is_done (iter) && !found) {
850 TnyHeaderFlags flags;
852 header = TNY_HEADER (tny_iterator_get_current (iter));
853 flags = tny_header_get_flags (header);
854 /* TODO: is this the right flag?, it seems that some
855 headers that have been previously downloaded do not
857 found = !(flags & TNY_HEADER_FLAG_CACHED);
858 g_object_unref (header);
859 tny_iterator_next (iter);
861 g_object_unref (iter);
863 /* Ask for user permission to download the messages */
866 GtkResponseType response;
868 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
869 _("mcen_nc_get_multi_msg_txt"));
870 if (response == GTK_RESPONSE_CANCEL)
878 * Common code for the reply and forward actions
881 reply_forward (ReplyForwardAction action, ModestWindow *win)
883 ModestMailOperation *mail_op = NULL;
884 TnyList *header_list = NULL;
885 ReplyForwardHelper *rf_helper = NULL;
886 guint reply_forward_type;
887 gboolean continue_download;
889 g_return_if_fail (MODEST_IS_WINDOW(win));
891 header_list = get_selected_headers (win);
895 /* Check that the messages have been previously downloaded */
896 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
897 if (!continue_download) {
898 g_object_unref (header_list);
903 modest_conf_get_int (modest_runtime_get_conf (),
904 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
906 /* We assume that we can only select messages of the
907 same folder and that we reply all of them from the
908 same account. In fact the interface currently only
909 allows single selection */
912 rf_helper = g_slice_new0 (ReplyForwardHelper);
913 rf_helper->reply_forward_type = reply_forward_type;
914 rf_helper->action = action;
915 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
916 if (!rf_helper->account_name)
917 rf_helper->account_name =
918 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
920 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
923 /* Get header and message. Do not free them here, the
924 reply_forward_cb must do it */
925 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
926 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
927 if (!msg || !header) {
929 g_object_unref (msg);
931 g_object_unref (header);
932 g_printerr ("modest: no message found\n");
935 reply_forward_cb (NULL, header, msg, rf_helper);
937 /* Retrieve messages */
938 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
940 modest_ui_actions_get_msgs_full_error_handler,
942 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
943 modest_mail_operation_get_msgs_full (mail_op,
947 free_reply_forward_helper);
950 g_object_unref(mail_op);
954 g_object_unref (header_list);
958 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
960 g_return_if_fail (MODEST_IS_WINDOW(win));
962 reply_forward (ACTION_REPLY, win);
966 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
968 g_return_if_fail (MODEST_IS_WINDOW(win));
970 reply_forward (ACTION_FORWARD, win);
974 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
976 g_return_if_fail (MODEST_IS_WINDOW(win));
978 reply_forward (ACTION_REPLY_TO_ALL, win);
982 modest_ui_actions_on_next (GtkAction *action,
983 ModestWindow *window)
985 if (MODEST_IS_MAIN_WINDOW (window)) {
986 GtkWidget *header_view;
988 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
989 MODEST_WIDGET_TYPE_HEADER_VIEW);
993 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
994 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
995 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
997 g_return_if_reached ();
1002 modest_ui_actions_on_prev (GtkAction *action,
1003 ModestWindow *window)
1005 g_return_if_fail (MODEST_IS_WINDOW(window));
1007 if (MODEST_IS_MAIN_WINDOW (window)) {
1008 GtkWidget *header_view;
1009 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1010 MODEST_WIDGET_TYPE_HEADER_VIEW);
1014 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1015 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1016 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1018 g_return_if_reached ();
1023 modest_ui_actions_on_sort (GtkAction *action,
1024 ModestWindow *window)
1026 g_return_if_fail (MODEST_IS_WINDOW(window));
1028 if (MODEST_IS_MAIN_WINDOW (window)) {
1029 GtkWidget *header_view;
1030 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1031 MODEST_WIDGET_TYPE_HEADER_VIEW);
1035 /* Show sorting dialog */
1036 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1041 * This function performs the send & receive required actions. The
1042 * window is used to create the mail operation. Typically it should
1043 * always be the main window, but we pass it as argument in order to
1047 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1049 gchar *acc_name = NULL;
1050 ModestMailOperation *mail_op;
1052 /* If no account name was provided then get the current account, and if
1053 there is no current account then pick the default one: */
1054 if (!account_name) {
1055 acc_name = g_strdup (modest_window_get_active_account(win));
1057 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1059 g_printerr ("modest: cannot get default account\n");
1063 acc_name = g_strdup (account_name);
1066 /* Send & receive. */
1067 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1068 /* Receive and then send. The operation is tagged initially as
1069 a receive operation because the account update performs a
1070 receive and then a send. The operation changes its type
1071 internally, so the progress objects will receive the proper
1072 progress information */
1073 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1074 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1075 modest_mail_operation_update_account (mail_op, acc_name);
1076 g_object_unref (G_OBJECT (mail_op));
1083 * Refreshes all accounts. This function will be used by automatic
1087 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1089 GSList *account_names, *iter;
1091 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1094 iter = account_names;
1096 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1097 iter = g_slist_next (iter);
1100 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1101 g_slist_free (account_names);
1105 * Handler of the click on Send&Receive button in the main toolbar
1108 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1110 /* Check that at least one account exists: */
1111 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1112 TRUE /* enabled accounts only */);
1113 gboolean accounts_exist = account_names != NULL;
1114 g_slist_free (account_names);
1116 /* If not, allow the user to create an account before trying to send/receive. */
1117 if (!accounts_exist)
1118 modest_ui_actions_on_accounts (NULL, win);
1120 /* Refresh the active account */
1121 modest_ui_actions_do_send_receive (NULL, win);
1126 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1129 GtkWidget *header_view;
1131 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1133 header_view = modest_main_window_get_child_widget (main_window,
1134 MODEST_WIDGET_TYPE_HEADER_VIEW);
1138 conf = modest_runtime_get_conf ();
1140 /* what is saved/restored is depending on the style; thus; we save with
1141 * old style, then update the style, and restore for this new style
1143 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1145 if (modest_header_view_get_style
1146 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1147 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1148 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1150 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1151 MODEST_HEADER_VIEW_STYLE_DETAILS);
1153 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1154 MODEST_CONF_HEADER_VIEW_KEY);
1159 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1161 ModestMainWindow *main_window)
1163 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1165 /* If no header has been selected then exit */
1169 /* Update Main window title */
1170 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1171 const gchar *subject = tny_header_get_subject (header);
1172 if (subject && strcmp (subject, ""))
1173 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1175 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1180 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1182 ModestMainWindow *main_window)
1186 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1191 headers = tny_simple_list_new ();
1192 tny_list_prepend (headers, G_OBJECT (header));
1194 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1196 g_object_unref (headers);
1200 set_active_account_from_tny_account (TnyAccount *account,
1201 ModestWindow *window)
1203 const gchar *server_acc_name = tny_account_get_id (account);
1205 /* We need the TnyAccount provided by the
1206 account store because that is the one that
1207 knows the name of the Modest account */
1208 TnyAccount *modest_server_account = modest_server_account =
1209 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1212 const gchar *modest_acc_name =
1213 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1214 modest_window_set_active_account (window, modest_acc_name);
1215 g_object_unref (modest_server_account);
1219 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1220 TnyFolderStore *folder_store,
1222 ModestMainWindow *main_window)
1225 GtkWidget *header_view;
1227 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1229 header_view = modest_main_window_get_child_widget(main_window,
1230 MODEST_WIDGET_TYPE_HEADER_VIEW);
1234 conf = modest_runtime_get_conf ();
1236 if (TNY_IS_ACCOUNT (folder_store)) {
1237 /* Update active account */
1238 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1239 /* Show account details */
1240 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1241 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1242 //TODO: Set the virtual folder store as the "active account" somehow:
1243 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1245 if (TNY_IS_FOLDER (folder_store) && selected) {
1247 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1248 /* Update the active account */
1249 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1250 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1251 g_object_unref (account);
1254 /* Set folder on header view */
1255 modest_main_window_set_contents_style (main_window,
1256 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1257 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1258 TNY_FOLDER (folder_store));
1259 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1260 MODEST_CONF_HEADER_VIEW_KEY);
1262 /* Update the active account */
1263 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1264 /* Do not show folder */
1265 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1266 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1272 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1279 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1281 if (g_main_depth > 0)
1282 gdk_threads_enter ();
1283 online = tny_device_is_online (modest_runtime_get_device());
1286 /* already online -- the item is simply not there... */
1287 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1289 GTK_MESSAGE_WARNING,
1291 _("The %s you selected cannot be found"),
1293 gtk_dialog_run (GTK_DIALOG(dialog));
1295 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1299 GTK_RESPONSE_REJECT,
1301 GTK_RESPONSE_ACCEPT,
1303 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1304 "Do you want to get online?"), item);
1305 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1306 gtk_label_new (txt), FALSE, FALSE, 0);
1307 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1310 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1311 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1312 // modest_platform_connect_and_wait ();;
1315 gtk_widget_destroy (dialog);
1316 if (g_main_depth > 0)
1317 gdk_threads_leave ();
1321 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1324 /* g_message ("%s %s", __FUNCTION__, link); */
1329 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1332 modest_platform_activate_uri (link);
1336 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1339 modest_platform_show_uri_popup (link);
1343 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1346 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1350 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1351 const gchar *address,
1354 /* g_message ("%s %s", __FUNCTION__, address); */
1358 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1360 TnyTransportAccount *transport_account;
1361 ModestMailOperation *mail_operation;
1363 gchar *account_name, *from;
1364 ModestAccountMgr *account_mgr;
1366 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1368 data = modest_msg_edit_window_get_msg_data (edit_window);
1370 account_mgr = modest_runtime_get_account_mgr();
1371 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1373 account_name = modest_account_mgr_get_default_account (account_mgr);
1374 if (!account_name) {
1375 g_printerr ("modest: no account found\n");
1376 modest_msg_edit_window_free_msg_data (edit_window, data);
1380 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1381 (modest_runtime_get_account_store(),
1383 TNY_ACCOUNT_TYPE_TRANSPORT));
1384 if (!transport_account) {
1385 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1386 g_free (account_name);
1387 modest_msg_edit_window_free_msg_data (edit_window, data);
1390 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1392 /* Create the mail operation */
1393 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1394 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1396 modest_mail_operation_save_to_drafts (mail_operation,
1406 data->priority_flags);
1409 g_free (account_name);
1410 g_object_unref (G_OBJECT (transport_account));
1411 g_object_unref (G_OBJECT (mail_operation));
1413 modest_msg_edit_window_free_msg_data (edit_window, data);
1415 /* Save settings and close the window */
1416 gtk_widget_destroy (GTK_WIDGET (edit_window));
1419 /* For instance, when clicking the Send toolbar button when editing a message: */
1421 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1423 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1425 if (!modest_msg_edit_window_check_names (edit_window))
1428 /* FIXME: Code added just for testing. The final version will
1429 use the send queue provided by tinymail and some
1431 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1432 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1434 account_name = modest_account_mgr_get_default_account (account_mgr);
1436 if (!account_name) {
1437 g_printerr ("modest: no account found\n");
1441 /* Get the currently-active transport account for this modest account: */
1442 TnyTransportAccount *transport_account =
1443 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1444 (modest_runtime_get_account_store(),
1446 if (!transport_account) {
1447 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1448 g_free (account_name);
1452 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1454 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1456 /* mail content checks and dialogs */
1457 if (data->subject == NULL || data->subject[0] == '\0') {
1458 GtkResponseType response;
1459 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1460 _("mcen_nc_subject_is_empty_send"));
1461 if (response == GTK_RESPONSE_CANCEL) {
1462 g_free (account_name);
1467 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1468 GtkResponseType response;
1469 gchar *note_message;
1470 gchar *note_subject = data->subject;
1471 if (note_subject == NULL || note_subject[0] == '\0')
1472 note_subject = _("mail_va_no_subject");
1473 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1474 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1476 g_free (note_message);
1477 if (response == GTK_RESPONSE_CANCEL) {
1478 g_free (account_name);
1483 /* Create the mail operation */
1484 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1485 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1487 modest_mail_operation_send_new_mail (mail_operation,
1497 data->priority_flags);
1501 g_free (account_name);
1502 g_object_unref (G_OBJECT (transport_account));
1503 g_object_unref (G_OBJECT (mail_operation));
1505 modest_msg_edit_window_free_msg_data (edit_window, data);
1507 /* Save settings and close the window: */
1508 gtk_widget_destroy (GTK_WIDGET (edit_window));
1512 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1513 ModestMsgEditWindow *window)
1515 ModestMsgEditFormatState *format_state = NULL;
1517 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1518 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1520 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1523 format_state = modest_msg_edit_window_get_format_state (window);
1524 g_return_if_fail (format_state != NULL);
1526 format_state->bold = gtk_toggle_action_get_active (action);
1527 modest_msg_edit_window_set_format_state (window, format_state);
1528 g_free (format_state);
1533 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1534 ModestMsgEditWindow *window)
1536 ModestMsgEditFormatState *format_state = NULL;
1538 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1539 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1541 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1544 format_state = modest_msg_edit_window_get_format_state (window);
1545 g_return_if_fail (format_state != NULL);
1547 format_state->italics = gtk_toggle_action_get_active (action);
1548 modest_msg_edit_window_set_format_state (window, format_state);
1549 g_free (format_state);
1554 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1555 ModestMsgEditWindow *window)
1557 ModestMsgEditFormatState *format_state = NULL;
1559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1560 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1562 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1565 format_state = modest_msg_edit_window_get_format_state (window);
1566 g_return_if_fail (format_state != NULL);
1568 format_state->bullet = gtk_toggle_action_get_active (action);
1569 modest_msg_edit_window_set_format_state (window, format_state);
1570 g_free (format_state);
1575 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1576 GtkRadioAction *selected,
1577 ModestMsgEditWindow *window)
1579 ModestMsgEditFormatState *format_state = NULL;
1580 GtkJustification value;
1582 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1584 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1587 value = gtk_radio_action_get_current_value (selected);
1589 format_state = modest_msg_edit_window_get_format_state (window);
1590 g_return_if_fail (format_state != NULL);
1592 format_state->justification = value;
1593 modest_msg_edit_window_set_format_state (window, format_state);
1594 g_free (format_state);
1598 modest_ui_actions_on_select_editor_color (GtkAction *action,
1599 ModestMsgEditWindow *window)
1601 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1602 g_return_if_fail (GTK_IS_ACTION (action));
1604 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1607 modest_msg_edit_window_select_color (window);
1611 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1612 ModestMsgEditWindow *window)
1614 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1615 g_return_if_fail (GTK_IS_ACTION (action));
1617 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1620 modest_msg_edit_window_select_background_color (window);
1624 modest_ui_actions_on_insert_image (GtkAction *action,
1625 ModestMsgEditWindow *window)
1627 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1628 g_return_if_fail (GTK_IS_ACTION (action));
1630 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1633 modest_msg_edit_window_insert_image (window);
1637 modest_ui_actions_on_attach_file (GtkAction *action,
1638 ModestMsgEditWindow *window)
1640 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1641 g_return_if_fail (GTK_IS_ACTION (action));
1643 modest_msg_edit_window_attach_file (window);
1647 modest_ui_actions_on_remove_attachments (GtkAction *action,
1648 ModestMsgEditWindow *window)
1650 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1651 g_return_if_fail (GTK_IS_ACTION (action));
1653 modest_msg_edit_window_remove_attachments (window, NULL);
1657 * Shows a dialog with an entry that asks for some text. The returned
1658 * value must be freed by the caller. The dialog window title will be
1662 ask_for_folder_name (GtkWindow *parent_window,
1665 GtkWidget *dialog, *entry;
1666 gchar *folder_name = NULL;
1668 /* Ask for folder name */
1669 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1673 GTK_RESPONSE_REJECT,
1675 GTK_RESPONSE_ACCEPT,
1677 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1678 gtk_label_new(title),
1681 entry = gtk_entry_new_with_max_length (40);
1682 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1686 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1688 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1689 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1691 gtk_widget_destroy (dialog);
1697 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1699 TnyFolderStore *parent_folder;
1700 GtkWidget *folder_view;
1702 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1704 folder_view = modest_main_window_get_child_widget (main_window,
1705 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1709 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1711 if (parent_folder) {
1712 gboolean finished = FALSE;
1714 gchar *folder_name = NULL, *suggested_name = NULL;
1716 /* Run the new folder dialog */
1718 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1723 if (result == GTK_RESPONSE_REJECT) {
1726 ModestMailOperation *mail_op;
1727 TnyFolder *new_folder = NULL;
1729 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1730 G_OBJECT(main_window));
1731 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1733 new_folder = modest_mail_operation_create_folder (mail_op,
1735 (const gchar *) folder_name);
1737 g_object_unref (new_folder);
1740 g_object_unref (mail_op);
1742 g_free (folder_name);
1746 g_object_unref (parent_folder);
1751 modest_ui_actions_on_rename_folder (GtkAction *action,
1752 ModestMainWindow *main_window)
1754 TnyFolderStore *folder;
1755 GtkWidget *folder_view;
1756 GtkWidget *header_view;
1758 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1760 folder_view = modest_main_window_get_child_widget (main_window,
1761 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1765 header_view = modest_main_window_get_child_widget (main_window,
1766 MODEST_WIDGET_TYPE_HEADER_VIEW);
1771 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1773 if (folder && TNY_IS_FOLDER (folder)) {
1775 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1776 _("Please enter a new name for the folder"));
1778 if (folder_name != NULL && strlen (folder_name) > 0) {
1779 ModestMailOperation *mail_op;
1781 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1782 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1785 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1787 modest_mail_operation_rename_folder (mail_op,
1788 TNY_FOLDER (folder),
1789 (const gchar *) folder_name);
1791 g_object_unref (mail_op);
1792 g_free (folder_name);
1794 g_object_unref (folder);
1799 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1802 GObject *win = modest_mail_operation_get_source (mail_op);
1804 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1805 _("mail_in_ui_folder_delete_error"));
1809 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1811 TnyFolderStore *folder;
1812 GtkWidget *folder_view;
1816 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1818 folder_view = modest_main_window_get_child_widget (main_window,
1819 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1823 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1825 /* Show an error if it's an account */
1826 if (!TNY_IS_FOLDER (folder)) {
1827 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1828 _("mail_in_ui_folder_delete_error"));
1833 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1834 tny_folder_get_name (TNY_FOLDER (folder)));
1835 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1836 (const gchar *) message);
1839 if (response == GTK_RESPONSE_OK) {
1840 ModestMailOperation *mail_op =
1841 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1842 G_OBJECT(main_window),
1843 modest_ui_actions_delete_folder_error_handler,
1846 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1848 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1849 g_object_unref (G_OBJECT (mail_op));
1852 g_object_unref (G_OBJECT (folder));
1856 modest_ui_actions_on_delete_folder (GtkAction *action,
1857 ModestMainWindow *main_window)
1859 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1861 delete_folder (main_window, FALSE);
1865 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1867 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1869 delete_folder (main_window, TRUE);
1873 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1874 const gchar* server_account_name,
1879 ModestMainWindow *main_window)
1881 g_return_if_fail(server_account_name);
1882 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1884 /* Initalize output parameters: */
1891 #ifdef MODEST_PLATFORM_MAEMO
1892 /* Maemo uses a different (awkward) button order,
1893 * It should probably just use gtk_alternative_dialog_button_order ().
1895 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1899 GTK_RESPONSE_ACCEPT,
1901 GTK_RESPONSE_REJECT,
1904 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1908 GTK_RESPONSE_REJECT,
1910 GTK_RESPONSE_ACCEPT,
1912 #endif /* MODEST_PLATFORM_MAEMO */
1914 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1916 gchar *server_name = modest_server_account_get_hostname (
1917 modest_runtime_get_account_mgr(), server_account_name);
1919 /* This causes a warning because the logical ID has no %s in it,
1920 * though the translation does, but there is not much we can do about that: */
1921 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1922 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1925 g_free (server_name);
1929 gchar *initial_username = modest_server_account_get_username (
1930 modest_runtime_get_account_mgr(), server_account_name);
1932 GtkWidget *entry_username = gtk_entry_new ();
1933 if (initial_username)
1934 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1935 /* Dim this if a connection has ever succeeded with this username,
1936 * as per the UI spec: */
1937 const gboolean username_known =
1938 modest_server_account_get_username_has_succeeded(
1939 modest_runtime_get_account_mgr(), server_account_name);
1940 gtk_widget_set_sensitive (entry_username, !username_known);
1942 #ifdef MODEST_PLATFORM_MAEMO
1943 /* Auto-capitalization is the default, so let's turn it off: */
1944 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1946 /* Create a size group to be used by all captions.
1947 * Note that HildonCaption does not create a default size group if we do not specify one.
1948 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1949 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1951 GtkWidget *caption = hildon_caption_new (sizegroup,
1952 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1953 gtk_widget_show (entry_username);
1954 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1955 FALSE, FALSE, MODEST_MARGIN_HALF);
1956 gtk_widget_show (caption);
1958 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1960 #endif /* MODEST_PLATFORM_MAEMO */
1963 GtkWidget *entry_password = gtk_entry_new ();
1964 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1965 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1967 #ifdef MODEST_PLATFORM_MAEMO
1968 /* Auto-capitalization is the default, so let's turn it off: */
1969 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1970 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1972 caption = hildon_caption_new (sizegroup,
1973 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1974 gtk_widget_show (entry_password);
1975 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1976 FALSE, FALSE, MODEST_MARGIN_HALF);
1977 gtk_widget_show (caption);
1978 g_object_unref (sizegroup);
1980 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1982 #endif /* MODEST_PLATFORM_MAEMO */
1984 /* This is not in the Maemo UI spec:
1985 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1986 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1990 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1992 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1994 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
1996 modest_server_account_set_username (
1997 modest_runtime_get_account_mgr(), server_account_name,
2000 const gboolean username_was_changed =
2001 (strcmp (*username, initial_username) != 0);
2002 if (username_was_changed) {
2003 /* To actually use a changed username,
2004 * we must reset the connection, according to pvanhoof.
2005 * This _might_ be a sensible way to do that: */
2006 TnyDevice *device = modest_runtime_get_device();
2007 tny_device_force_offline (device);
2008 tny_device_force_online (device);
2013 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2015 /* We do not save the password in the configuration,
2016 * because this function is only called for passwords that should
2017 * not be remembered:
2018 modest_server_account_set_password (
2019 modest_runtime_get_account_mgr(), server_account_name,
2038 /* This is not in the Maemo UI spec:
2039 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2045 gtk_widget_destroy (dialog);
2047 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2051 modest_ui_actions_on_cut (GtkAction *action,
2052 ModestWindow *window)
2054 GtkWidget *focused_widget;
2056 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2057 if (GTK_IS_EDITABLE (focused_widget)) {
2058 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2059 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2060 GtkTextBuffer *buffer;
2061 GtkClipboard *clipboard;
2063 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2064 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2065 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2070 modest_ui_actions_on_copy (GtkAction *action,
2071 ModestWindow *window)
2073 GtkClipboard *clipboard;
2074 GtkWidget *focused_widget;
2076 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2077 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2078 if (GTK_IS_LABEL (focused_widget)) {
2079 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2080 } else if (GTK_IS_EDITABLE (focused_widget)) {
2081 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2082 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2083 GtkTextBuffer *buffer;
2085 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2086 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2091 modest_ui_actions_on_undo (GtkAction *action,
2092 ModestWindow *window)
2094 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2095 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2097 g_return_if_reached ();
2102 modest_ui_actions_on_paste (GtkAction *action,
2103 ModestWindow *window)
2105 GtkWidget *focused_widget;
2107 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2108 if (GTK_IS_EDITABLE (focused_widget)) {
2109 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2110 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2111 GtkTextBuffer *buffer;
2112 GtkClipboard *clipboard;
2114 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2115 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2116 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2121 modest_ui_actions_on_select_all (GtkAction *action,
2122 ModestWindow *window)
2124 GtkWidget *focused_widget;
2126 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2127 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2128 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2129 } else if (GTK_IS_LABEL (focused_widget)) {
2130 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2131 } else if (GTK_IS_EDITABLE (focused_widget)) {
2132 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2133 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2134 GtkTextBuffer *buffer;
2135 GtkTextIter start, end;
2137 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2138 gtk_text_buffer_get_start_iter (buffer, &start);
2139 gtk_text_buffer_get_end_iter (buffer, &end);
2140 gtk_text_buffer_select_range (buffer, &start, &end);
2145 modest_ui_actions_on_mark_as_read (GtkAction *action,
2146 ModestWindow *window)
2148 g_return_if_fail (MODEST_IS_WINDOW(window));
2150 /* Mark each header as read */
2151 do_headers_action (window, headers_action_mark_as_read, NULL);
2155 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2156 ModestWindow *window)
2158 g_return_if_fail (MODEST_IS_WINDOW(window));
2160 /* Mark each header as read */
2161 do_headers_action (window, headers_action_mark_as_unread, NULL);
2165 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2166 GtkRadioAction *selected,
2167 ModestWindow *window)
2171 value = gtk_radio_action_get_current_value (selected);
2172 if (MODEST_IS_WINDOW (window)) {
2173 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2177 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2178 GtkRadioAction *selected,
2179 ModestWindow *window)
2181 TnyHeaderFlags flags;
2182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 flags = gtk_radio_action_get_current_value (selected);
2185 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2188 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2189 GtkRadioAction *selected,
2190 ModestWindow *window)
2194 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2196 file_format = gtk_radio_action_get_current_value (selected);
2197 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2202 modest_ui_actions_on_zoom_plus (GtkAction *action,
2203 ModestWindow *window)
2205 g_return_if_fail (MODEST_IS_WINDOW (window));
2207 modest_window_zoom_plus (MODEST_WINDOW (window));
2211 modest_ui_actions_on_zoom_minus (GtkAction *action,
2212 ModestWindow *window)
2214 g_return_if_fail (MODEST_IS_WINDOW (window));
2216 modest_window_zoom_minus (MODEST_WINDOW (window));
2220 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2221 ModestWindow *window)
2223 ModestWindowMgr *mgr;
2224 gboolean fullscreen, active;
2225 g_return_if_fail (MODEST_IS_WINDOW (window));
2227 mgr = modest_runtime_get_window_mgr ();
2229 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2230 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2232 if (active != fullscreen) {
2233 modest_window_mgr_set_fullscreen_mode (mgr, active);
2234 gtk_window_present (GTK_WINDOW (window));
2239 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2240 ModestWindow *window)
2242 ModestWindowMgr *mgr;
2243 gboolean fullscreen;
2245 g_return_if_fail (MODEST_IS_WINDOW (window));
2247 mgr = modest_runtime_get_window_mgr ();
2248 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2249 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2251 gtk_window_present (GTK_WINDOW (window));
2255 * Used by modest_ui_actions_on_details to call do_headers_action
2258 headers_action_show_details (TnyHeader *header,
2259 ModestWindow *window,
2266 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2269 gtk_widget_show_all (dialog);
2270 gtk_dialog_run (GTK_DIALOG (dialog));
2272 gtk_widget_destroy (dialog);
2276 * Show the folder details in a ModestDetailsDialog widget
2279 show_folder_details (TnyFolder *folder,
2285 dialog = modest_details_dialog_new_with_folder (window, folder);
2288 gtk_widget_show_all (dialog);
2289 gtk_dialog_run (GTK_DIALOG (dialog));
2291 gtk_widget_destroy (dialog);
2295 * Show the header details in a ModestDetailsDialog widget
2298 modest_ui_actions_on_details (GtkAction *action,
2301 TnyList * headers_list;
2305 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2308 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2311 g_object_unref (msg);
2313 headers_list = get_selected_headers (win);
2317 iter = tny_list_create_iterator (headers_list);
2319 header = TNY_HEADER (tny_iterator_get_current (iter));
2320 headers_action_show_details (header, win, NULL);
2321 g_object_unref (header);
2323 g_object_unref (iter);
2324 g_object_unref (headers_list);
2326 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2327 GtkWidget *folder_view, *header_view;
2329 /* Check which widget has the focus */
2330 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2331 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2332 if (gtk_widget_is_focus (folder_view)) {
2335 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2337 /* Show only when it's a folder */
2338 if (!folder || !TNY_IS_FOLDER (folder))
2341 show_folder_details (folder, GTK_WINDOW (win));
2344 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2345 MODEST_WIDGET_TYPE_HEADER_VIEW);
2346 /* Show details of each header */
2347 do_headers_action (win, headers_action_show_details, header_view);
2353 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2354 ModestMsgEditWindow *window)
2356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2358 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2362 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2363 ModestMsgEditWindow *window)
2365 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2367 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2371 modest_ui_actions_toggle_folders_view (GtkAction *action,
2372 ModestMainWindow *main_window)
2376 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2378 conf = modest_runtime_get_conf ();
2380 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2381 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2383 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2387 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2388 ModestWindow *window)
2390 gboolean active, fullscreen = FALSE;
2391 ModestWindowMgr *mgr;
2393 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2395 /* Check if we want to toggle the toolbar vuew in fullscreen
2397 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2398 "ViewShowToolbarFullScreen")) {
2402 /* Toggle toolbar */
2403 mgr = modest_runtime_get_window_mgr ();
2404 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2408 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2409 ModestMsgEditWindow *window)
2411 modest_msg_edit_window_select_font (window);
2415 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2416 const gchar *display_name,
2419 /* Do not change the application name if the widget has not
2420 the focus. This callback could be called even if the folder
2421 view has not the focus, because the handled signal could be
2422 emitted when the folder view is redrawn */
2423 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2425 gtk_window_set_title (window, display_name);
2427 gtk_window_set_title (window, " ");
2432 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2434 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2435 modest_msg_edit_window_select_contacts (window);
2439 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2441 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2442 modest_msg_edit_window_check_names (window);
2447 create_move_to_dialog (ModestWindow *win,
2448 GtkWidget *folder_view,
2449 GtkWidget **tree_view)
2451 GtkWidget *dialog, *scroll;
2453 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2455 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2457 GTK_RESPONSE_ACCEPT,
2459 GTK_RESPONSE_REJECT,
2462 /* Create scrolled window */
2463 scroll = gtk_scrolled_window_new (NULL, NULL);
2464 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2465 GTK_POLICY_AUTOMATIC,
2466 GTK_POLICY_AUTOMATIC);
2468 /* Create folder view */
2469 *tree_view = modest_folder_view_new (NULL);
2470 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2471 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2472 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2474 /* Add scroll to dialog */
2475 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2476 scroll, FALSE, FALSE, 0);
2478 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2484 * Returns TRUE if at least one of the headers of the list belongs to
2485 * a message that has been fully retrieved.
2488 has_retrieved_msgs (TnyList *list)
2491 gboolean found = FALSE;
2493 iter = tny_list_create_iterator (list);
2494 while (tny_iterator_is_done (iter) && !found) {
2496 TnyHeaderFlags flags;
2498 header = TNY_HEADER (tny_iterator_get_current (iter));
2499 flags = tny_header_get_flags (header);
2500 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2504 tny_iterator_next (iter);
2506 g_object_unref (iter);
2512 * Shows a confirmation dialog to the user when we're moving messages
2513 * from a remote server to the local storage. Returns the dialog
2514 * response. If it's other kind of movement the it always returns
2518 msgs_move_to_confirmation (GtkWindow *win,
2519 TnyFolder *dest_folder,
2522 gint response = GTK_RESPONSE_OK;
2524 /* If the destination is a local folder */
2525 if (modest_tny_folder_is_local_folder (dest_folder)) {
2526 TnyFolder *src_folder;
2530 /* Get source folder */
2531 iter = tny_list_create_iterator (headers);
2532 header = TNY_HEADER (tny_iterator_get_current (iter));
2533 src_folder = tny_header_get_folder (header);
2534 g_object_unref (header);
2535 g_object_unref (iter);
2537 /* If the source is a remote folder */
2538 if (!modest_tny_folder_is_local_folder (src_folder)) {
2539 const gchar *message;
2541 if (tny_list_get_length (headers) == 1)
2542 if (has_retrieved_msgs (headers))
2543 message = _("mcen_nc_move_retrieve");
2545 message = _("mcen_nc_move_header");
2547 if (has_retrieved_msgs (headers))
2548 message = _("mcen_nc_move_retrieves");
2550 message = _("mcen_nc_move_headers");
2552 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2553 (const gchar *) message);
2555 g_object_unref (src_folder);
2562 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2564 ModestMsgViewWindow *self = NULL;
2565 gboolean found = FALSE;
2567 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2568 self = MODEST_MSG_VIEW_WINDOW (object);
2570 found = modest_msg_view_window_select_first_message (self);
2571 g_return_if_fail (found);
2575 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2578 GObject *win = modest_mail_operation_get_source (mail_op);
2580 /* TODO: show error message */
2581 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2582 _("mail_in_ui_folder_move_target_error"));
2586 * UI handler for the "Move to" action when invoked from the
2590 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2591 ModestMainWindow *win)
2593 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2594 GtkWidget *header_view = NULL;
2596 TnyFolderStore *folder_store = NULL;
2597 ModestMailOperation *mail_op = NULL;
2599 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2601 /* Get the folder view */
2602 folder_view = modest_main_window_get_child_widget (win,
2603 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2605 /* Get header view */
2606 header_view = modest_main_window_get_child_widget (win,
2607 MODEST_WIDGET_TYPE_HEADER_VIEW);
2609 /* Create and run the dialog */
2610 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2611 result = gtk_dialog_run (GTK_DIALOG(dialog));
2612 g_object_ref (tree_view);
2614 /* We do this to save an indentation level ;-) */
2615 if (result != GTK_RESPONSE_ACCEPT)
2618 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2620 if (TNY_IS_ACCOUNT (folder_store))
2623 /* Get folder or messages to transfer */
2624 if (gtk_widget_is_focus (folder_view)) {
2625 TnyFolderStore *src_folder;
2626 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2628 /* Clean folder on header view before moving it */
2629 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2631 if (TNY_IS_FOLDER (src_folder)) {
2633 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2635 modest_ui_actions_move_folder_error_handler,
2637 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2639 modest_mail_operation_xfer_folder (mail_op,
2640 TNY_FOLDER (src_folder),
2643 /* Unref mail operation */
2644 g_object_unref (G_OBJECT (mail_op));
2648 g_object_unref (G_OBJECT (src_folder));
2650 if (gtk_widget_is_focus (header_view)) {
2654 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2656 /* Ask for user confirmation */
2657 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2658 TNY_FOLDER (folder_store),
2661 /* Transfer messages */
2662 if (response == GTK_RESPONSE_OK) {
2663 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2664 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2667 modest_mail_operation_xfer_msgs (mail_op,
2669 TNY_FOLDER (folder_store),
2674 g_object_unref (G_OBJECT (mail_op));
2676 g_object_unref (headers);
2679 g_object_unref (folder_store);
2681 gtk_widget_destroy (dialog);
2686 * UI handler for the "Move to" action when invoked from the
2687 * ModestMsgViewWindow
2690 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2691 ModestMsgViewWindow *win)
2693 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2695 ModestMainWindow *main_window;
2699 /* Get the folder view */
2700 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2701 folder_view = modest_main_window_get_child_widget (main_window,
2702 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2704 /* Create and run the dialog */
2705 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2706 result = gtk_dialog_run (GTK_DIALOG(dialog));
2707 g_object_ref (tree_view);
2709 if (result == GTK_RESPONSE_ACCEPT) {
2710 TnyFolderStore *folder_store;
2713 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2715 /* Create header list */
2716 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2717 headers = tny_simple_list_new ();
2718 tny_list_prepend (headers, G_OBJECT (header));
2719 g_object_unref (header);
2721 /* Ask user for confirmation. MSG-NOT404 */
2722 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2723 TNY_FOLDER (folder_store),
2726 /* Transfer current msg */
2727 if (response == GTK_RESPONSE_OK) {
2728 ModestMailOperation *mail_op;
2730 /* Create mail op */
2731 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2732 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2735 /* Transfer messages */
2736 modest_mail_operation_xfer_msgs (mail_op,
2738 TNY_FOLDER (folder_store),
2740 tranasfer_msgs_from_viewer_cb,
2742 g_object_unref (G_OBJECT (mail_op));
2744 g_object_unref (headers);
2745 g_object_unref (folder_store);
2747 gtk_widget_destroy (dialog);
2751 modest_ui_actions_on_move_to (GtkAction *action,
2754 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2755 MODEST_IS_MSG_VIEW_WINDOW (win));
2757 if (MODEST_IS_MAIN_WINDOW (win))
2758 modest_ui_actions_on_main_window_move_to (action,
2759 MODEST_MAIN_WINDOW (win));
2761 modest_ui_actions_on_msg_view_window_move_to (action,
2762 MODEST_MSG_VIEW_WINDOW (win));
2766 * Calls #HeadersFunc for each header already selected in the main
2767 * window or the message currently being shown in the msg view window
2770 do_headers_action (ModestWindow *win,
2774 TnyList *headers_list;
2778 headers_list = get_selected_headers (win);
2782 /* Call the function for each header */
2783 iter = tny_list_create_iterator (headers_list);
2784 while (!tny_iterator_is_done (iter)) {
2787 header = TNY_HEADER (tny_iterator_get_current (iter));
2788 func (header, win, user_data);
2789 g_object_unref (header);
2790 tny_iterator_next (iter);
2792 g_object_unref (iter);
2793 g_object_unref (headers_list);
2797 modest_ui_actions_view_attachment (GtkAction *action,
2798 ModestWindow *window)
2800 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2801 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2803 /* not supported window for this action */
2804 g_return_if_reached ();
2809 modest_ui_actions_save_attachments (GtkAction *action,
2810 ModestWindow *window)
2812 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2813 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2815 /* not supported window for this action */
2816 g_return_if_reached ();
2821 modest_ui_actions_remove_attachments (GtkAction *action,
2822 ModestWindow *window)
2824 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2825 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2827 /* not supported window for this action */
2828 g_return_if_reached ();
2833 modest_ui_actions_on_settings (GtkAction *action,
2838 dialog = modest_platform_get_global_settings_dialog ();
2839 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2840 gtk_widget_show (dialog);
2842 gtk_dialog_run (GTK_DIALOG (dialog));
2844 gtk_widget_destroy (dialog);
2848 modest_ui_actions_on_help (GtkAction *action,
2851 const gchar *help_id = NULL;
2853 if (MODEST_IS_MAIN_WINDOW (win)) {
2854 const gchar *action_name;
2855 action_name = gtk_action_get_name (action);
2857 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2858 !strcmp (action_name, "HeaderViewCSMHelp")) {
2859 GtkWidget *folder_view;
2860 TnyFolderStore *folder_store;
2861 /* Get selected folder */
2862 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2863 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2864 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2866 /* Switch help_id */
2867 if (TNY_IS_FOLDER (folder_store)) {
2868 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2869 case TNY_FOLDER_TYPE_NORMAL:
2870 help_id = "applications_email_userfolder";
2872 case TNY_FOLDER_TYPE_INBOX:
2873 help_id = "applications_email_inbox";
2875 case TNY_FOLDER_TYPE_OUTBOX:
2876 help_id = "applications_email_outbox";
2878 case TNY_FOLDER_TYPE_SENT:
2879 help_id = "applications_email_sent";
2881 case TNY_FOLDER_TYPE_DRAFTS:
2882 help_id = "applications_email_drafts";
2884 case TNY_FOLDER_TYPE_ARCHIVE:
2885 help_id = "applications_email_archive";
2892 help_id = "applications_email_mainview";
2894 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2895 help_id = "applications_email_viewer";
2896 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2897 help_id = "applications_email_editor";
2899 modest_platform_show_help (GTK_WINDOW (win), help_id);
2903 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2904 ModestWindow *window)
2906 ModestMailOperation *mail_op;
2910 headers = get_selected_headers (window);
2914 /* Create mail operation */
2915 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2917 modest_ui_actions_get_msgs_full_error_handler,
2919 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2920 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2923 g_object_unref (headers);
2924 g_object_unref (mail_op);
2928 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2929 ModestWindow *window)
2931 g_return_if_fail (MODEST_IS_WINDOW (window));
2934 modest_window_check_dimming_rules (window);
2938 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2939 ModestWindow *window)
2941 g_return_if_fail (MODEST_IS_WINDOW (window));
2944 modest_window_check_dimming_rules (window);
2948 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2949 ModestWindow *window)
2951 g_return_if_fail (MODEST_IS_WINDOW (window));
2954 modest_window_check_dimming_rules (window);
2958 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2959 ModestWindow *window)
2961 g_return_if_fail (MODEST_IS_WINDOW (window));
2964 modest_window_check_dimming_rules (window);
2968 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2969 ModestWindow *window)
2971 g_return_if_fail (MODEST_IS_WINDOW (window));
2974 modest_window_check_dimming_rules (window);