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"));
1178 /* Update toolbar dimming state */
1179 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1183 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1185 ModestMainWindow *main_window)
1189 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1194 headers = tny_simple_list_new ();
1195 tny_list_prepend (headers, G_OBJECT (header));
1197 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1199 g_object_unref (headers);
1203 set_active_account_from_tny_account (TnyAccount *account,
1204 ModestWindow *window)
1206 const gchar *server_acc_name = tny_account_get_id (account);
1208 /* We need the TnyAccount provided by the
1209 account store because that is the one that
1210 knows the name of the Modest account */
1211 TnyAccount *modest_server_account = modest_server_account =
1212 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1215 const gchar *modest_acc_name =
1216 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1217 modest_window_set_active_account (window, modest_acc_name);
1218 g_object_unref (modest_server_account);
1222 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1223 TnyFolderStore *folder_store,
1225 ModestMainWindow *main_window)
1228 GtkWidget *header_view;
1230 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1232 header_view = modest_main_window_get_child_widget(main_window,
1233 MODEST_WIDGET_TYPE_HEADER_VIEW);
1237 conf = modest_runtime_get_conf ();
1239 if (TNY_IS_ACCOUNT (folder_store)) {
1240 /* Update active account */
1241 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1242 /* Show account details */
1243 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1244 } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) {
1245 //TODO: Set the virtual folder store as the "active account" somehow:
1246 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1248 if (TNY_IS_FOLDER (folder_store) && selected) {
1250 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1251 /* Update the active account */
1252 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store));
1253 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1254 g_object_unref (account);
1257 /* Set folder on header view */
1258 modest_main_window_set_contents_style (main_window,
1259 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1260 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1261 TNY_FOLDER (folder_store));
1262 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1263 MODEST_CONF_HEADER_VIEW_KEY);
1265 /* Update the active account */
1266 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1267 /* Do not show folder */
1268 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1269 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1273 /* Update toolbar dimming state */
1274 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1278 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1285 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1287 if (g_main_depth > 0)
1288 gdk_threads_enter ();
1289 online = tny_device_is_online (modest_runtime_get_device());
1292 /* already online -- the item is simply not there... */
1293 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1295 GTK_MESSAGE_WARNING,
1297 _("The %s you selected cannot be found"),
1299 gtk_dialog_run (GTK_DIALOG(dialog));
1301 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1305 GTK_RESPONSE_REJECT,
1307 GTK_RESPONSE_ACCEPT,
1309 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1310 "Do you want to get online?"), item);
1311 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1312 gtk_label_new (txt), FALSE, FALSE, 0);
1313 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1316 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1317 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1318 // modest_platform_connect_and_wait ();;
1321 gtk_widget_destroy (dialog);
1322 if (g_main_depth > 0)
1323 gdk_threads_leave ();
1327 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1330 /* g_message ("%s %s", __FUNCTION__, link); */
1335 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1338 modest_platform_activate_uri (link);
1342 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1345 modest_platform_show_uri_popup (link);
1349 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1352 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1356 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1357 const gchar *address,
1360 /* g_message ("%s %s", __FUNCTION__, address); */
1364 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1366 TnyTransportAccount *transport_account;
1367 ModestMailOperation *mail_operation;
1369 gchar *account_name, *from;
1370 ModestAccountMgr *account_mgr;
1372 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1374 data = modest_msg_edit_window_get_msg_data (edit_window);
1376 account_mgr = modest_runtime_get_account_mgr();
1377 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1379 account_name = modest_account_mgr_get_default_account (account_mgr);
1380 if (!account_name) {
1381 g_printerr ("modest: no account found\n");
1382 modest_msg_edit_window_free_msg_data (edit_window, data);
1386 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1387 (modest_runtime_get_account_store(),
1389 TNY_ACCOUNT_TYPE_TRANSPORT));
1390 if (!transport_account) {
1391 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1392 g_free (account_name);
1393 modest_msg_edit_window_free_msg_data (edit_window, data);
1396 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1398 /* Create the mail operation */
1399 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1400 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1402 modest_mail_operation_save_to_drafts (mail_operation,
1412 data->priority_flags);
1415 g_free (account_name);
1416 g_object_unref (G_OBJECT (transport_account));
1417 g_object_unref (G_OBJECT (mail_operation));
1419 modest_msg_edit_window_free_msg_data (edit_window, data);
1421 /* Save settings and close the window */
1422 gtk_widget_destroy (GTK_WIDGET (edit_window));
1425 /* For instance, when clicking the Send toolbar button when editing a message: */
1427 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1429 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1431 if (!modest_msg_edit_window_check_names (edit_window))
1434 /* FIXME: Code added just for testing. The final version will
1435 use the send queue provided by tinymail and some
1437 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1438 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1440 account_name = modest_account_mgr_get_default_account (account_mgr);
1442 if (!account_name) {
1443 g_printerr ("modest: no account found\n");
1447 /* Get the currently-active transport account for this modest account: */
1448 TnyTransportAccount *transport_account =
1449 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1450 (modest_runtime_get_account_store(),
1452 if (!transport_account) {
1453 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1454 g_free (account_name);
1458 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1460 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1462 /* mail content checks and dialogs */
1463 if (data->subject == NULL || data->subject[0] == '\0') {
1464 GtkResponseType response;
1465 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1466 _("mcen_nc_subject_is_empty_send"));
1467 if (response == GTK_RESPONSE_CANCEL) {
1468 g_free (account_name);
1473 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1474 GtkResponseType response;
1475 gchar *note_message;
1476 gchar *note_subject = data->subject;
1477 if (note_subject == NULL || note_subject[0] == '\0')
1478 note_subject = _("mail_va_no_subject");
1479 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1480 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1482 g_free (note_message);
1483 if (response == GTK_RESPONSE_CANCEL) {
1484 g_free (account_name);
1489 /* Create the mail operation */
1490 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1491 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1493 modest_mail_operation_send_new_mail (mail_operation,
1503 data->priority_flags);
1507 g_free (account_name);
1508 g_object_unref (G_OBJECT (transport_account));
1509 g_object_unref (G_OBJECT (mail_operation));
1511 modest_msg_edit_window_free_msg_data (edit_window, data);
1513 /* Save settings and close the window: */
1514 gtk_widget_destroy (GTK_WIDGET (edit_window));
1518 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1519 ModestMsgEditWindow *window)
1521 ModestMsgEditFormatState *format_state = NULL;
1523 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1524 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1526 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1529 format_state = modest_msg_edit_window_get_format_state (window);
1530 g_return_if_fail (format_state != NULL);
1532 format_state->bold = gtk_toggle_action_get_active (action);
1533 modest_msg_edit_window_set_format_state (window, format_state);
1534 g_free (format_state);
1539 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1540 ModestMsgEditWindow *window)
1542 ModestMsgEditFormatState *format_state = NULL;
1544 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1545 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1547 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1550 format_state = modest_msg_edit_window_get_format_state (window);
1551 g_return_if_fail (format_state != NULL);
1553 format_state->italics = gtk_toggle_action_get_active (action);
1554 modest_msg_edit_window_set_format_state (window, format_state);
1555 g_free (format_state);
1560 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1561 ModestMsgEditWindow *window)
1563 ModestMsgEditFormatState *format_state = NULL;
1565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1566 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1568 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1571 format_state = modest_msg_edit_window_get_format_state (window);
1572 g_return_if_fail (format_state != NULL);
1574 format_state->bullet = gtk_toggle_action_get_active (action);
1575 modest_msg_edit_window_set_format_state (window, format_state);
1576 g_free (format_state);
1581 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1582 GtkRadioAction *selected,
1583 ModestMsgEditWindow *window)
1585 ModestMsgEditFormatState *format_state = NULL;
1586 GtkJustification value;
1588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1590 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1593 value = gtk_radio_action_get_current_value (selected);
1595 format_state = modest_msg_edit_window_get_format_state (window);
1596 g_return_if_fail (format_state != NULL);
1598 format_state->justification = value;
1599 modest_msg_edit_window_set_format_state (window, format_state);
1600 g_free (format_state);
1604 modest_ui_actions_on_select_editor_color (GtkAction *action,
1605 ModestMsgEditWindow *window)
1607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1608 g_return_if_fail (GTK_IS_ACTION (action));
1610 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1613 modest_msg_edit_window_select_color (window);
1617 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1618 ModestMsgEditWindow *window)
1620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1621 g_return_if_fail (GTK_IS_ACTION (action));
1623 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1626 modest_msg_edit_window_select_background_color (window);
1630 modest_ui_actions_on_insert_image (GtkAction *action,
1631 ModestMsgEditWindow *window)
1633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1634 g_return_if_fail (GTK_IS_ACTION (action));
1636 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1639 modest_msg_edit_window_insert_image (window);
1643 modest_ui_actions_on_attach_file (GtkAction *action,
1644 ModestMsgEditWindow *window)
1646 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1647 g_return_if_fail (GTK_IS_ACTION (action));
1649 modest_msg_edit_window_attach_file (window);
1653 modest_ui_actions_on_remove_attachments (GtkAction *action,
1654 ModestMsgEditWindow *window)
1656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1657 g_return_if_fail (GTK_IS_ACTION (action));
1659 modest_msg_edit_window_remove_attachments (window, NULL);
1663 * Shows a dialog with an entry that asks for some text. The returned
1664 * value must be freed by the caller. The dialog window title will be
1668 ask_for_folder_name (GtkWindow *parent_window,
1671 GtkWidget *dialog, *entry;
1672 gchar *folder_name = NULL;
1674 /* Ask for folder name */
1675 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1679 GTK_RESPONSE_REJECT,
1681 GTK_RESPONSE_ACCEPT,
1683 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1684 gtk_label_new(title),
1687 entry = gtk_entry_new_with_max_length (40);
1688 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1692 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1694 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1695 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1697 gtk_widget_destroy (dialog);
1703 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1705 TnyFolderStore *parent_folder;
1706 GtkWidget *folder_view;
1708 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1710 folder_view = modest_main_window_get_child_widget (main_window,
1711 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1715 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1717 if (parent_folder) {
1718 gboolean finished = FALSE;
1720 gchar *folder_name = NULL, *suggested_name = NULL;
1722 /* Run the new folder dialog */
1724 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1729 if (result == GTK_RESPONSE_REJECT) {
1732 ModestMailOperation *mail_op;
1733 TnyFolder *new_folder = NULL;
1735 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1736 G_OBJECT(main_window));
1737 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1739 new_folder = modest_mail_operation_create_folder (mail_op,
1741 (const gchar *) folder_name);
1743 g_object_unref (new_folder);
1746 g_object_unref (mail_op);
1748 g_free (folder_name);
1752 g_object_unref (parent_folder);
1757 modest_ui_actions_on_rename_folder (GtkAction *action,
1758 ModestMainWindow *main_window)
1760 TnyFolderStore *folder;
1761 GtkWidget *folder_view;
1762 GtkWidget *header_view;
1764 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1766 folder_view = modest_main_window_get_child_widget (main_window,
1767 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1771 header_view = modest_main_window_get_child_widget (main_window,
1772 MODEST_WIDGET_TYPE_HEADER_VIEW);
1777 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1779 if (folder && TNY_IS_FOLDER (folder)) {
1781 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1782 _("Please enter a new name for the folder"));
1784 if (folder_name != NULL && strlen (folder_name) > 0) {
1785 ModestMailOperation *mail_op;
1787 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1788 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1791 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1793 modest_mail_operation_rename_folder (mail_op,
1794 TNY_FOLDER (folder),
1795 (const gchar *) folder_name);
1797 g_object_unref (mail_op);
1798 g_free (folder_name);
1800 g_object_unref (folder);
1805 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1808 GObject *win = modest_mail_operation_get_source (mail_op);
1810 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1811 _("mail_in_ui_folder_delete_error"));
1815 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1817 TnyFolderStore *folder;
1818 GtkWidget *folder_view;
1822 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1824 folder_view = modest_main_window_get_child_widget (main_window,
1825 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1829 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1831 /* Show an error if it's an account */
1832 if (!TNY_IS_FOLDER (folder)) {
1833 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1834 _("mail_in_ui_folder_delete_error"));
1839 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1840 tny_folder_get_name (TNY_FOLDER (folder)));
1841 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1842 (const gchar *) message);
1845 if (response == GTK_RESPONSE_OK) {
1846 ModestMailOperation *mail_op =
1847 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1848 G_OBJECT(main_window),
1849 modest_ui_actions_delete_folder_error_handler,
1852 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1854 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1855 g_object_unref (G_OBJECT (mail_op));
1858 g_object_unref (G_OBJECT (folder));
1862 modest_ui_actions_on_delete_folder (GtkAction *action,
1863 ModestMainWindow *main_window)
1865 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1867 delete_folder (main_window, FALSE);
1871 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1873 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1875 delete_folder (main_window, TRUE);
1879 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1880 const gchar* server_account_name,
1885 ModestMainWindow *main_window)
1887 g_return_if_fail(server_account_name);
1888 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1890 /* Initalize output parameters: */
1897 #ifdef MODEST_PLATFORM_MAEMO
1898 /* Maemo uses a different (awkward) button order,
1899 * It should probably just use gtk_alternative_dialog_button_order ().
1901 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1905 GTK_RESPONSE_ACCEPT,
1907 GTK_RESPONSE_REJECT,
1910 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1914 GTK_RESPONSE_REJECT,
1916 GTK_RESPONSE_ACCEPT,
1918 #endif /* MODEST_PLATFORM_MAEMO */
1920 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1922 gchar *server_name = modest_server_account_get_hostname (
1923 modest_runtime_get_account_mgr(), server_account_name);
1925 /* This causes a warning because the logical ID has no %s in it,
1926 * though the translation does, but there is not much we can do about that: */
1927 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1928 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1931 g_free (server_name);
1935 gchar *initial_username = modest_server_account_get_username (
1936 modest_runtime_get_account_mgr(), server_account_name);
1938 GtkWidget *entry_username = gtk_entry_new ();
1939 if (initial_username)
1940 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1941 /* Dim this if a connection has ever succeeded with this username,
1942 * as per the UI spec: */
1943 const gboolean username_known =
1944 modest_server_account_get_username_has_succeeded(
1945 modest_runtime_get_account_mgr(), server_account_name);
1946 gtk_widget_set_sensitive (entry_username, !username_known);
1948 #ifdef MODEST_PLATFORM_MAEMO
1949 /* Auto-capitalization is the default, so let's turn it off: */
1950 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1952 /* Create a size group to be used by all captions.
1953 * Note that HildonCaption does not create a default size group if we do not specify one.
1954 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1955 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1957 GtkWidget *caption = hildon_caption_new (sizegroup,
1958 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1959 gtk_widget_show (entry_username);
1960 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1961 FALSE, FALSE, MODEST_MARGIN_HALF);
1962 gtk_widget_show (caption);
1964 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1966 #endif /* MODEST_PLATFORM_MAEMO */
1969 GtkWidget *entry_password = gtk_entry_new ();
1970 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1971 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
1973 #ifdef MODEST_PLATFORM_MAEMO
1974 /* Auto-capitalization is the default, so let's turn it off: */
1975 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
1976 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
1978 caption = hildon_caption_new (sizegroup,
1979 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
1980 gtk_widget_show (entry_password);
1981 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1982 FALSE, FALSE, MODEST_MARGIN_HALF);
1983 gtk_widget_show (caption);
1984 g_object_unref (sizegroup);
1986 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
1988 #endif /* MODEST_PLATFORM_MAEMO */
1990 /* This is not in the Maemo UI spec:
1991 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1992 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1996 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1998 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2000 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2002 modest_server_account_set_username (
2003 modest_runtime_get_account_mgr(), server_account_name,
2006 const gboolean username_was_changed =
2007 (strcmp (*username, initial_username) != 0);
2008 if (username_was_changed) {
2009 /* To actually use a changed username,
2010 * we must reset the connection, according to pvanhoof.
2011 * This _might_ be a sensible way to do that: */
2012 TnyDevice *device = modest_runtime_get_device();
2013 tny_device_force_offline (device);
2014 tny_device_force_online (device);
2019 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2021 /* We do not save the password in the configuration,
2022 * because this function is only called for passwords that should
2023 * not be remembered:
2024 modest_server_account_set_password (
2025 modest_runtime_get_account_mgr(), server_account_name,
2044 /* This is not in the Maemo UI spec:
2045 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2051 gtk_widget_destroy (dialog);
2053 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2057 modest_ui_actions_on_cut (GtkAction *action,
2058 ModestWindow *window)
2060 GtkWidget *focused_widget;
2062 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2063 if (GTK_IS_EDITABLE (focused_widget)) {
2064 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2065 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2066 GtkTextBuffer *buffer;
2067 GtkClipboard *clipboard;
2069 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2070 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2071 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2076 modest_ui_actions_on_copy (GtkAction *action,
2077 ModestWindow *window)
2079 GtkClipboard *clipboard;
2080 GtkWidget *focused_widget;
2082 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2083 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2084 if (GTK_IS_LABEL (focused_widget)) {
2085 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2086 } else if (GTK_IS_EDITABLE (focused_widget)) {
2087 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2088 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2089 GtkTextBuffer *buffer;
2091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2092 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2097 modest_ui_actions_on_undo (GtkAction *action,
2098 ModestWindow *window)
2100 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2101 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2103 g_return_if_reached ();
2108 modest_ui_actions_on_paste (GtkAction *action,
2109 ModestWindow *window)
2111 GtkWidget *focused_widget;
2113 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2114 if (GTK_IS_EDITABLE (focused_widget)) {
2115 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2116 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2117 GtkTextBuffer *buffer;
2118 GtkClipboard *clipboard;
2120 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2121 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2122 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2127 modest_ui_actions_on_select_all (GtkAction *action,
2128 ModestWindow *window)
2130 GtkWidget *focused_widget;
2132 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2133 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2134 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2135 } else if (GTK_IS_LABEL (focused_widget)) {
2136 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2137 } else if (GTK_IS_EDITABLE (focused_widget)) {
2138 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2139 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2140 GtkTextBuffer *buffer;
2141 GtkTextIter start, end;
2143 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2144 gtk_text_buffer_get_start_iter (buffer, &start);
2145 gtk_text_buffer_get_end_iter (buffer, &end);
2146 gtk_text_buffer_select_range (buffer, &start, &end);
2148 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2149 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2151 GtkTreeSelection *selection = NULL;
2153 /* Get header view */
2154 GtkWidget *header_view = focused_widget;
2155 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2156 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2157 MODEST_WIDGET_TYPE_HEADER_VIEW);
2159 /* Select all messages */
2160 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2161 gtk_tree_selection_select_all (selection);
2166 modest_ui_actions_on_mark_as_read (GtkAction *action,
2167 ModestWindow *window)
2169 g_return_if_fail (MODEST_IS_WINDOW(window));
2171 /* Mark each header as read */
2172 do_headers_action (window, headers_action_mark_as_read, NULL);
2176 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2177 ModestWindow *window)
2179 g_return_if_fail (MODEST_IS_WINDOW(window));
2181 /* Mark each header as read */
2182 do_headers_action (window, headers_action_mark_as_unread, NULL);
2186 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2187 GtkRadioAction *selected,
2188 ModestWindow *window)
2192 value = gtk_radio_action_get_current_value (selected);
2193 if (MODEST_IS_WINDOW (window)) {
2194 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2198 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2199 GtkRadioAction *selected,
2200 ModestWindow *window)
2202 TnyHeaderFlags flags;
2203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 flags = gtk_radio_action_get_current_value (selected);
2206 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2209 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2210 GtkRadioAction *selected,
2211 ModestWindow *window)
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2217 file_format = gtk_radio_action_get_current_value (selected);
2218 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2223 modest_ui_actions_on_zoom_plus (GtkAction *action,
2224 ModestWindow *window)
2226 g_return_if_fail (MODEST_IS_WINDOW (window));
2228 modest_window_zoom_plus (MODEST_WINDOW (window));
2232 modest_ui_actions_on_zoom_minus (GtkAction *action,
2233 ModestWindow *window)
2235 g_return_if_fail (MODEST_IS_WINDOW (window));
2237 modest_window_zoom_minus (MODEST_WINDOW (window));
2241 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2242 ModestWindow *window)
2244 ModestWindowMgr *mgr;
2245 gboolean fullscreen, active;
2246 g_return_if_fail (MODEST_IS_WINDOW (window));
2248 mgr = modest_runtime_get_window_mgr ();
2250 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2251 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2253 if (active != fullscreen) {
2254 modest_window_mgr_set_fullscreen_mode (mgr, active);
2255 gtk_window_present (GTK_WINDOW (window));
2260 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2261 ModestWindow *window)
2263 ModestWindowMgr *mgr;
2264 gboolean fullscreen;
2266 g_return_if_fail (MODEST_IS_WINDOW (window));
2268 mgr = modest_runtime_get_window_mgr ();
2269 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2270 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2272 gtk_window_present (GTK_WINDOW (window));
2276 * Used by modest_ui_actions_on_details to call do_headers_action
2279 headers_action_show_details (TnyHeader *header,
2280 ModestWindow *window,
2287 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2290 gtk_widget_show_all (dialog);
2291 gtk_dialog_run (GTK_DIALOG (dialog));
2293 gtk_widget_destroy (dialog);
2297 * Show the folder details in a ModestDetailsDialog widget
2300 show_folder_details (TnyFolder *folder,
2306 dialog = modest_details_dialog_new_with_folder (window, folder);
2309 gtk_widget_show_all (dialog);
2310 gtk_dialog_run (GTK_DIALOG (dialog));
2312 gtk_widget_destroy (dialog);
2316 * Show the header details in a ModestDetailsDialog widget
2319 modest_ui_actions_on_details (GtkAction *action,
2322 TnyList * headers_list;
2326 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2329 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2332 g_object_unref (msg);
2334 headers_list = get_selected_headers (win);
2338 iter = tny_list_create_iterator (headers_list);
2340 header = TNY_HEADER (tny_iterator_get_current (iter));
2341 headers_action_show_details (header, win, NULL);
2342 g_object_unref (header);
2344 g_object_unref (iter);
2345 g_object_unref (headers_list);
2347 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2348 GtkWidget *folder_view, *header_view;
2350 /* Check which widget has the focus */
2351 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2352 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2353 if (gtk_widget_is_focus (folder_view)) {
2356 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2358 /* Show only when it's a folder */
2359 if (!folder || !TNY_IS_FOLDER (folder))
2362 show_folder_details (folder, GTK_WINDOW (win));
2365 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2366 MODEST_WIDGET_TYPE_HEADER_VIEW);
2367 /* Show details of each header */
2368 do_headers_action (win, headers_action_show_details, header_view);
2374 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2375 ModestMsgEditWindow *window)
2377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2379 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2383 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2384 ModestMsgEditWindow *window)
2386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2388 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2392 modest_ui_actions_toggle_folders_view (GtkAction *action,
2393 ModestMainWindow *main_window)
2397 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2399 conf = modest_runtime_get_conf ();
2401 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2402 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2404 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2408 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2409 ModestWindow *window)
2411 gboolean active, fullscreen = FALSE;
2412 ModestWindowMgr *mgr;
2414 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2416 /* Check if we want to toggle the toolbar vuew in fullscreen
2418 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2419 "ViewShowToolbarFullScreen")) {
2423 /* Toggle toolbar */
2424 mgr = modest_runtime_get_window_mgr ();
2425 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2429 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2430 ModestMsgEditWindow *window)
2432 modest_msg_edit_window_select_font (window);
2436 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2437 const gchar *display_name,
2440 /* Do not change the application name if the widget has not
2441 the focus. This callback could be called even if the folder
2442 view has not the focus, because the handled signal could be
2443 emitted when the folder view is redrawn */
2444 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2446 gtk_window_set_title (window, display_name);
2448 gtk_window_set_title (window, " ");
2453 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2455 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2456 modest_msg_edit_window_select_contacts (window);
2460 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2462 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2463 modest_msg_edit_window_check_names (window);
2468 create_move_to_dialog (ModestWindow *win,
2469 GtkWidget *folder_view,
2470 GtkWidget **tree_view)
2472 GtkWidget *dialog, *scroll;
2474 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2476 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2478 GTK_RESPONSE_ACCEPT,
2480 GTK_RESPONSE_REJECT,
2483 /* Create scrolled window */
2484 scroll = gtk_scrolled_window_new (NULL, NULL);
2485 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2486 GTK_POLICY_AUTOMATIC,
2487 GTK_POLICY_AUTOMATIC);
2489 /* Create folder view */
2490 *tree_view = modest_folder_view_new (NULL);
2491 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2492 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2493 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2495 /* Add scroll to dialog */
2496 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2497 scroll, FALSE, FALSE, 0);
2499 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2505 * Returns TRUE if at least one of the headers of the list belongs to
2506 * a message that has been fully retrieved.
2509 has_retrieved_msgs (TnyList *list)
2512 gboolean found = FALSE;
2514 iter = tny_list_create_iterator (list);
2515 while (tny_iterator_is_done (iter) && !found) {
2517 TnyHeaderFlags flags;
2519 header = TNY_HEADER (tny_iterator_get_current (iter));
2520 flags = tny_header_get_flags (header);
2521 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2525 tny_iterator_next (iter);
2527 g_object_unref (iter);
2533 * Shows a confirmation dialog to the user when we're moving messages
2534 * from a remote server to the local storage. Returns the dialog
2535 * response. If it's other kind of movement the it always returns
2539 msgs_move_to_confirmation (GtkWindow *win,
2540 TnyFolder *dest_folder,
2543 gint response = GTK_RESPONSE_OK;
2545 /* If the destination is a local folder */
2546 if (modest_tny_folder_is_local_folder (dest_folder)) {
2547 TnyFolder *src_folder;
2551 /* Get source folder */
2552 iter = tny_list_create_iterator (headers);
2553 header = TNY_HEADER (tny_iterator_get_current (iter));
2554 src_folder = tny_header_get_folder (header);
2555 g_object_unref (header);
2556 g_object_unref (iter);
2558 /* If the source is a remote folder */
2559 if (!modest_tny_folder_is_local_folder (src_folder)) {
2560 const gchar *message;
2562 if (tny_list_get_length (headers) == 1)
2563 if (has_retrieved_msgs (headers))
2564 message = _("mcen_nc_move_retrieve");
2566 message = _("mcen_nc_move_header");
2568 if (has_retrieved_msgs (headers))
2569 message = _("mcen_nc_move_retrieves");
2571 message = _("mcen_nc_move_headers");
2573 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2574 (const gchar *) message);
2576 g_object_unref (src_folder);
2583 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2585 ModestMsgViewWindow *self = NULL;
2586 gboolean found = FALSE;
2588 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2589 self = MODEST_MSG_VIEW_WINDOW (object);
2591 found = modest_msg_view_window_select_first_message (self);
2592 g_return_if_fail (found);
2596 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2599 GObject *win = modest_mail_operation_get_source (mail_op);
2601 /* TODO: show error message */
2602 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2603 _("mail_in_ui_folder_move_target_error"));
2607 * UI handler for the "Move to" action when invoked from the
2611 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2612 ModestMainWindow *win)
2614 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2615 GtkWidget *header_view = NULL;
2617 TnyFolderStore *folder_store = NULL;
2618 ModestMailOperation *mail_op = NULL;
2620 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2622 /* Get the folder view */
2623 folder_view = modest_main_window_get_child_widget (win,
2624 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2626 /* Get header view */
2627 header_view = modest_main_window_get_child_widget (win,
2628 MODEST_WIDGET_TYPE_HEADER_VIEW);
2630 /* Create and run the dialog */
2631 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2632 result = gtk_dialog_run (GTK_DIALOG(dialog));
2633 g_object_ref (tree_view);
2635 /* We do this to save an indentation level ;-) */
2636 if (result != GTK_RESPONSE_ACCEPT)
2639 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2641 if (TNY_IS_ACCOUNT (folder_store))
2644 /* Get folder or messages to transfer */
2645 if (gtk_widget_is_focus (folder_view)) {
2646 TnyFolderStore *src_folder;
2647 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2649 /* Clean folder on header view before moving it */
2650 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2652 if (TNY_IS_FOLDER (src_folder)) {
2654 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2656 modest_ui_actions_move_folder_error_handler,
2658 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2660 modest_mail_operation_xfer_folder (mail_op,
2661 TNY_FOLDER (src_folder),
2664 /* Unref mail operation */
2665 g_object_unref (G_OBJECT (mail_op));
2669 g_object_unref (G_OBJECT (src_folder));
2671 if (gtk_widget_is_focus (header_view)) {
2675 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2677 /* Ask for user confirmation */
2678 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2679 TNY_FOLDER (folder_store),
2682 /* Transfer messages */
2683 if (response == GTK_RESPONSE_OK) {
2684 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2688 modest_mail_operation_xfer_msgs (mail_op,
2690 TNY_FOLDER (folder_store),
2695 g_object_unref (G_OBJECT (mail_op));
2697 g_object_unref (headers);
2700 g_object_unref (folder_store);
2702 gtk_widget_destroy (dialog);
2707 * UI handler for the "Move to" action when invoked from the
2708 * ModestMsgViewWindow
2711 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2712 ModestMsgViewWindow *win)
2714 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2716 ModestMainWindow *main_window;
2720 /* Get the folder view */
2721 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2722 folder_view = modest_main_window_get_child_widget (main_window,
2723 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2725 /* Create and run the dialog */
2726 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2727 result = gtk_dialog_run (GTK_DIALOG(dialog));
2728 g_object_ref (tree_view);
2730 if (result == GTK_RESPONSE_ACCEPT) {
2731 TnyFolderStore *folder_store;
2734 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2736 /* Create header list */
2737 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2738 headers = tny_simple_list_new ();
2739 tny_list_prepend (headers, G_OBJECT (header));
2740 g_object_unref (header);
2742 /* Ask user for confirmation. MSG-NOT404 */
2743 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2744 TNY_FOLDER (folder_store),
2747 /* Transfer current msg */
2748 if (response == GTK_RESPONSE_OK) {
2749 ModestMailOperation *mail_op;
2751 /* Create mail op */
2752 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2753 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2756 /* Transfer messages */
2757 modest_mail_operation_xfer_msgs (mail_op,
2759 TNY_FOLDER (folder_store),
2761 tranasfer_msgs_from_viewer_cb,
2763 g_object_unref (G_OBJECT (mail_op));
2765 g_object_unref (headers);
2766 g_object_unref (folder_store);
2768 gtk_widget_destroy (dialog);
2772 modest_ui_actions_on_move_to (GtkAction *action,
2775 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2776 MODEST_IS_MSG_VIEW_WINDOW (win));
2778 if (MODEST_IS_MAIN_WINDOW (win))
2779 modest_ui_actions_on_main_window_move_to (action,
2780 MODEST_MAIN_WINDOW (win));
2782 modest_ui_actions_on_msg_view_window_move_to (action,
2783 MODEST_MSG_VIEW_WINDOW (win));
2787 * Calls #HeadersFunc for each header already selected in the main
2788 * window or the message currently being shown in the msg view window
2791 do_headers_action (ModestWindow *win,
2795 TnyList *headers_list;
2799 headers_list = get_selected_headers (win);
2803 /* Call the function for each header */
2804 iter = tny_list_create_iterator (headers_list);
2805 while (!tny_iterator_is_done (iter)) {
2808 header = TNY_HEADER (tny_iterator_get_current (iter));
2809 func (header, win, user_data);
2810 g_object_unref (header);
2811 tny_iterator_next (iter);
2813 g_object_unref (iter);
2814 g_object_unref (headers_list);
2818 modest_ui_actions_view_attachment (GtkAction *action,
2819 ModestWindow *window)
2821 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2822 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2824 /* not supported window for this action */
2825 g_return_if_reached ();
2830 modest_ui_actions_save_attachments (GtkAction *action,
2831 ModestWindow *window)
2833 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2834 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2836 /* not supported window for this action */
2837 g_return_if_reached ();
2842 modest_ui_actions_remove_attachments (GtkAction *action,
2843 ModestWindow *window)
2845 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2846 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2848 /* not supported window for this action */
2849 g_return_if_reached ();
2854 modest_ui_actions_on_settings (GtkAction *action,
2859 dialog = modest_platform_get_global_settings_dialog ();
2860 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2861 gtk_widget_show (dialog);
2863 gtk_dialog_run (GTK_DIALOG (dialog));
2865 gtk_widget_destroy (dialog);
2869 modest_ui_actions_on_help (GtkAction *action,
2872 const gchar *help_id = NULL;
2874 if (MODEST_IS_MAIN_WINDOW (win)) {
2875 const gchar *action_name;
2876 action_name = gtk_action_get_name (action);
2878 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2879 !strcmp (action_name, "HeaderViewCSMHelp")) {
2880 GtkWidget *folder_view;
2881 TnyFolderStore *folder_store;
2882 /* Get selected folder */
2883 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2884 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2885 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2887 /* Switch help_id */
2888 if (TNY_IS_FOLDER (folder_store)) {
2889 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2890 case TNY_FOLDER_TYPE_NORMAL:
2891 help_id = "applications_email_userfolder";
2893 case TNY_FOLDER_TYPE_INBOX:
2894 help_id = "applications_email_inbox";
2896 case TNY_FOLDER_TYPE_OUTBOX:
2897 help_id = "applications_email_outbox";
2899 case TNY_FOLDER_TYPE_SENT:
2900 help_id = "applications_email_sent";
2902 case TNY_FOLDER_TYPE_DRAFTS:
2903 help_id = "applications_email_drafts";
2905 case TNY_FOLDER_TYPE_ARCHIVE:
2906 help_id = "applications_email_archive";
2913 help_id = "applications_email_mainview";
2915 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2916 help_id = "applications_email_viewer";
2917 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2918 help_id = "applications_email_editor";
2920 modest_platform_show_help (GTK_WINDOW (win), help_id);
2924 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2925 ModestWindow *window)
2927 ModestMailOperation *mail_op;
2931 headers = get_selected_headers (window);
2935 /* Create mail operation */
2936 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2938 modest_ui_actions_get_msgs_full_error_handler,
2940 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2941 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2944 g_object_unref (headers);
2945 g_object_unref (mail_op);
2949 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2950 ModestWindow *window)
2952 g_return_if_fail (MODEST_IS_WINDOW (window));
2955 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2959 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2960 ModestWindow *window)
2962 g_return_if_fail (MODEST_IS_WINDOW (window));
2965 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2969 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2970 ModestWindow *window)
2972 g_return_if_fail (MODEST_IS_WINDOW (window));
2975 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2979 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
2980 ModestWindow *window)
2982 g_return_if_fail (MODEST_IS_WINDOW (window));
2985 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2989 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
2990 ModestWindow *window)
2992 g_return_if_fail (MODEST_IS_WINDOW (window));
2995 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2999 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3001 g_return_if_fail (MODEST_IS_WINDOW (window));
3004 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");