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;
94 GtkWidget *parent_window;
98 * The do_headers_action uses this kind of functions to perform some
99 * action to each member of a list of headers
101 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
104 do_headers_action (ModestWindow *win,
109 static void open_msg_cb (ModestMailOperation *mail_op,
114 static void reply_forward_cb (ModestMailOperation *mail_op,
119 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
121 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
124 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
125 ModestMailOperationState *state,
131 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
134 const gchar *authors[] = {
135 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
138 about = gtk_about_dialog_new ();
139 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
140 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
141 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
142 _("Copyright (c) 2006, Nokia Corporation\n"
143 "All rights reserved."));
144 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
145 _("a modest e-mail client\n\n"
146 "design and implementation: Dirk-Jan C. Binnema\n"
147 "contributions from the fine people at KC and Ig\n"
148 "uses the tinymail email framework written by Philip van Hoof"));
149 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
150 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
152 gtk_dialog_run (GTK_DIALOG (about));
153 gtk_widget_destroy(about);
157 * Gets the list of currently selected messages. If the win is the
158 * main window, then it returns a newly allocated list of the headers
159 * selected in the header view. If win is the msg view window, then
160 * the value returned is a list with just a single header.
162 * The caller of this funcion must free the list.
165 get_selected_headers (ModestWindow *win)
167 if (MODEST_IS_MAIN_WINDOW(win)) {
168 GtkWidget *header_view;
170 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
171 MODEST_WIDGET_TYPE_HEADER_VIEW);
172 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
174 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
175 /* for MsgViewWindows, we simply return a list with one element */
177 TnyList *list = NULL;
179 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
180 if (header != NULL) {
181 list = tny_simple_list_new ();
182 tny_list_prepend (list, G_OBJECT(header));
183 g_object_unref (G_OBJECT(header));
193 headers_action_mark_as_read (TnyHeader *header,
197 TnyHeaderFlags flags;
199 g_return_if_fail (TNY_IS_HEADER(header));
201 flags = tny_header_get_flags (header);
202 if (flags & TNY_HEADER_FLAG_SEEN) return;
203 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
207 headers_action_mark_as_unread (TnyHeader *header,
211 TnyHeaderFlags flags;
213 g_return_if_fail (TNY_IS_HEADER(header));
215 flags = tny_header_get_flags (header);
216 if (flags & TNY_HEADER_FLAG_SEEN) {
217 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
223 headers_action_delete (TnyHeader *header,
227 ModestMailOperation *mail_op = NULL;
229 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
233 /* Always delete. TODO: Move to trash still not supported */
234 modest_mail_operation_remove_msg (mail_op, header, FALSE);
235 g_object_unref (G_OBJECT (mail_op));
239 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
241 TnyList *header_list = NULL;
242 TnyIterator *iter = NULL;
243 TnyHeader *header = NULL;
244 gchar *message = NULL;
248 ModestWindowMgr *mgr;
250 g_return_if_fail (MODEST_IS_WINDOW(win));
252 header_list = get_selected_headers (win);
253 if (!header_list) return;
255 /* Check if any of the headers is already opened */
256 iter = tny_list_create_iterator (header_list);
258 mgr = modest_runtime_get_window_mgr ();
259 while (!tny_iterator_is_done (iter) && !found) {
260 header = TNY_HEADER (tny_iterator_get_current (iter));
261 if (modest_window_mgr_find_window_by_header (mgr, header))
263 g_object_unref (header);
264 tny_iterator_next (iter);
266 g_object_unref (iter);
271 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
272 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
274 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
278 g_object_unref (header_list);
283 if (tny_list_get_length(header_list) > 1)
284 message = g_strdup(_("emev_nc_delete_messages"));
286 iter = tny_list_create_iterator (header_list);
287 header = TNY_HEADER (tny_iterator_get_current (iter));
288 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
289 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
290 g_object_unref (header);
291 g_object_unref (iter);
294 /* Confirmation dialog */
295 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
299 if (response == GTK_RESPONSE_OK) {
300 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
302 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
306 /* Remove each header */
307 do_headers_action (win, headers_action_delete, NULL);
309 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
310 gtk_widget_destroy (GTK_WIDGET(win));
317 g_object_unref (header_list);
322 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
324 #ifdef MODEST_PLATFORM_MAEMO
325 modest_osso_save_state();
326 #endif /* MODEST_PLATFORM_MAEMO */
332 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
334 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
335 gtk_widget_destroy (GTK_WIDGET (win));
336 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
338 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
339 } else if (MODEST_IS_WINDOW (win)) {
340 gtk_widget_destroy (GTK_WIDGET (win));
342 g_return_if_reached ();
347 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
349 GtkClipboard *clipboard = NULL;
350 gchar *selection = NULL;
352 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
353 selection = gtk_clipboard_wait_for_text (clipboard);
355 /* Question: why is the clipboard being used here?
356 * It doesn't really make a lot of sense. */
360 modest_address_book_add_address (selection);
366 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
368 /* This is currently only implemented for Maemo,
369 * because it requires a providers preset file which is not publically available.
371 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
372 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
373 TRUE /* enabled accounts only */);
374 gboolean accounts_exist = account_names != NULL;
375 g_slist_free (account_names);
377 if (!accounts_exist) {
378 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
379 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
380 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
381 gtk_dialog_run (GTK_DIALOG (wizard));
382 gtk_widget_destroy (GTK_WIDGET (wizard));
384 /* Show the list of accounts: */
385 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
386 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
387 gtk_dialog_run (account_win);
388 gtk_widget_destroy (GTK_WIDGET(account_win));
391 GtkWidget *dialog, *label;
393 /* Create the widgets */
395 dialog = gtk_dialog_new_with_buttons ("Message",
397 GTK_DIALOG_DESTROY_WITH_PARENT,
401 label = gtk_label_new ("Hello World!");
403 /* Ensure that the dialog box is destroyed when the user responds. */
405 g_signal_connect_swapped (dialog, "response",
406 G_CALLBACK (gtk_widget_destroy),
409 /* Add the label, and show everything we've added to the dialog. */
411 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
413 gtk_widget_show_all (dialog);
414 #endif /* MODEST_PLATFORM_MAEMO */
418 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
420 ModestWindow *main_window = MODEST_WINDOW (user_data);
422 /* Save any changes. */
423 modest_connection_specific_smtp_window_save_server_accounts (
424 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
425 modest_window_get_active_account (main_window));
426 gtk_widget_destroy (GTK_WIDGET (window));
430 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
432 /* This is currently only implemented for Maemo,
433 * because it requires an API (libconic) to detect different connection
436 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
438 /* Create the window if necessary: */
439 const gchar *active_account_name = modest_window_get_active_account (win);
441 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
442 * or show the default account?
443 * If we show the default account then the account name should be shown in
444 * the window when we show it. */
445 if (!active_account_name) {
446 g_warning ("%s: No account is active.", __FUNCTION__);
450 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
451 modest_connection_specific_smtp_window_fill_with_connections (
452 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
453 modest_runtime_get_account_mgr(),
454 active_account_name);
456 /* Show the window: */
457 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
458 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
459 gtk_widget_show (specific_window);
461 /* Save changes when the window is hidden: */
462 g_signal_connect (specific_window, "hide",
463 G_CALLBACK (on_smtp_servers_window_hide), win);
464 #endif /* MODEST_PLATFORM_MAEMO */
468 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
470 ModestWindow *msg_win;
472 TnyFolder *folder = NULL;
473 gchar *account_name = NULL;
474 gchar *from_str = NULL;
475 /* GError *err = NULL; */
476 TnyAccount *account = NULL;
477 ModestWindowMgr *mgr;
478 gchar *signature = NULL, *blank_and_signature = NULL;
480 account_name = g_strdup(modest_window_get_active_account (win));
482 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
484 g_printerr ("modest: no account found\n");
488 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
490 TNY_ACCOUNT_TYPE_STORE);
492 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
496 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
498 g_printerr ("modest: failed get from string for '%s'\n", account_name);
502 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
503 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
504 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
505 MODEST_ACCOUNT_SIGNATURE, FALSE);
506 blank_and_signature = g_strconcat ("\n", signature, NULL);
509 blank_and_signature = g_strdup ("");
512 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
514 g_printerr ("modest: failed to create new msg\n");
518 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
520 g_printerr ("modest: failed to find Drafts folder\n");
524 /* tny_folder_add_msg (folder, msg, &err); */
526 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
528 /* g_error_free (err); */
532 /* Create and register edit window */
533 /* This is destroyed by TOOD. */
534 msg_win = modest_msg_edit_window_new (msg, account_name);
535 mgr = modest_runtime_get_window_mgr ();
536 modest_window_mgr_register_window (mgr, msg_win);
539 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
541 gtk_widget_show_all (GTK_WIDGET (msg_win));
544 g_free (account_name);
546 g_free (blank_and_signature);
548 g_object_unref (G_OBJECT(account));
550 g_object_unref (G_OBJECT(msg));
552 g_object_unref (G_OBJECT(folder));
556 open_msg_cb (ModestMailOperation *mail_op,
561 ModestWindowMgr *mgr = NULL;
562 ModestWindow *parent_win = NULL;
563 ModestWindow *win = NULL;
564 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
565 gchar *account = NULL;
568 /* TODO: Show an error? (review the specs) */
572 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
573 folder = tny_header_get_folder (header);
575 /* Mark header as read */
576 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
579 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
581 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
583 /* Gets folder type (OUTBOX headers will be opened in edit window */
584 if (modest_tny_folder_is_local_folder (folder))
585 folder_type = modest_tny_folder_get_local_folder_type (folder);
587 /* If the header is in the drafts folder then open the editor,
588 else the message view window */
589 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
590 win = modest_msg_edit_window_new (msg, account);
592 gchar *uid = modest_tny_folder_get_header_unique_id (header);
594 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
595 GtkWidget *header_view;
596 GtkTreeSelection *sel;
597 GList *sel_list = NULL;
600 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
601 MODEST_WIDGET_TYPE_HEADER_VIEW);
603 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
604 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
606 if (sel_list != NULL) {
607 GtkTreeRowReference *row_reference;
609 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
610 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
611 g_list_free (sel_list);
613 win = modest_msg_view_window_new_with_header_model (msg,
618 gtk_tree_row_reference_free (row_reference);
620 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
623 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
628 /* Register and show new window */
630 mgr = modest_runtime_get_window_mgr ();
631 modest_window_mgr_register_window (mgr, win);
632 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
633 gtk_widget_show_all (GTK_WIDGET(win));
638 g_object_unref (msg);
639 g_object_unref (folder);
640 g_object_unref (header);
644 * This function is the error handler of the
645 * modest_mail_operation_get_msgs_full operation
648 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
653 error = modest_mail_operation_get_error (mail_op);
654 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
655 GObject *win = modest_mail_operation_get_source (mail_op);
657 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
663 * This function is used by both modest_ui_actions_on_open and
664 * modest_ui_actions_on_header_activated. This way we always do the
665 * same when trying to open messages.
668 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
670 ModestWindowMgr *mgr;
672 ModestMailOperation *mail_op;
674 /* Look if we already have a message view for each header. If
675 true, then remove the header from the list of headers to
677 mgr = modest_runtime_get_window_mgr ();
678 iter = tny_list_create_iterator (headers);
679 while (!tny_iterator_is_done (iter)) {
680 ModestWindow *window;
683 header = TNY_HEADER (tny_iterator_get_current (iter));
684 window = modest_window_mgr_find_window_by_header (mgr, header);
686 /* Do not open again the message and present
687 the window to the user */
688 tny_list_remove (headers, G_OBJECT (header));
689 gtk_window_present (GTK_WINDOW (window));
692 g_object_unref (header);
693 tny_iterator_next (iter);
696 /* Open each message */
697 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
699 modest_ui_actions_get_msgs_full_error_handler,
701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
702 modest_mail_operation_get_msgs_full (mail_op,
709 g_object_unref(mail_op);
713 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
718 headers = get_selected_headers (win);
723 _modest_ui_actions_open (headers, win);
725 g_object_unref(headers);
730 free_reply_forward_helper (gpointer data)
732 ReplyForwardHelper *helper;
734 helper = (ReplyForwardHelper *) data;
735 g_free (helper->account_name);
736 g_slice_free (ReplyForwardHelper, helper);
740 reply_forward_cb (ModestMailOperation *mail_op,
746 ReplyForwardHelper *rf_helper;
747 ModestWindow *msg_win;
748 ModestEditType edit_type;
750 TnyAccount *account = NULL;
751 ModestWindowMgr *mgr;
752 gchar *signature = NULL;
754 g_return_if_fail (user_data != NULL);
755 rf_helper = (ReplyForwardHelper *) user_data;
757 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
758 rf_helper->account_name);
759 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
760 rf_helper->account_name,
761 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
762 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
763 rf_helper->account_name,
764 MODEST_ACCOUNT_SIGNATURE, FALSE);
767 /* Create reply mail */
768 switch (rf_helper->action) {
771 modest_tny_msg_create_reply_msg (msg, from, signature,
772 rf_helper->reply_forward_type,
773 MODEST_TNY_MSG_REPLY_MODE_SENDER);
775 case ACTION_REPLY_TO_ALL:
777 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
778 MODEST_TNY_MSG_REPLY_MODE_ALL);
779 edit_type = MODEST_EDIT_TYPE_REPLY;
783 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
784 edit_type = MODEST_EDIT_TYPE_FORWARD;
787 g_return_if_reached ();
794 g_printerr ("modest: failed to create message\n");
798 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
799 rf_helper->account_name,
800 TNY_ACCOUNT_TYPE_STORE);
802 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
806 /* Create and register the windows */
807 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
808 mgr = modest_runtime_get_window_mgr ();
809 modest_window_mgr_register_window (mgr, msg_win);
811 if (rf_helper->parent_window != NULL) {
814 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
815 modest_window_set_zoom (msg_win, parent_zoom);
818 /* Show edit window */
819 gtk_widget_show_all (GTK_WIDGET (msg_win));
823 g_object_unref (G_OBJECT (new_msg));
825 g_object_unref (G_OBJECT (account));
826 g_object_unref (msg);
827 g_object_unref (header);
831 * Checks a list of headers. If any of them are not currently
832 * downloaded (CACHED) then it asks the user for permission to
835 * Returns FALSE if the user does not want to download the
836 * messages. Returns TRUE if the user allowed the download or if all
837 * of them are currently downloaded
840 download_uncached_messages (TnyList *header_list, GtkWindow *win)
843 gboolean found, retval;
845 iter = tny_list_create_iterator (header_list);
847 while (!tny_iterator_is_done (iter) && !found) {
849 TnyHeaderFlags flags;
851 header = TNY_HEADER (tny_iterator_get_current (iter));
852 flags = tny_header_get_flags (header);
853 /* TODO: is this the right flag?, it seems that some
854 headers that have been previously downloaded do not
856 found = !(flags & TNY_HEADER_FLAG_CACHED);
857 g_object_unref (header);
858 tny_iterator_next (iter);
860 g_object_unref (iter);
862 /* Ask for user permission to download the messages */
865 GtkResponseType response;
867 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
868 _("mcen_nc_get_multi_msg_txt"));
869 if (response == GTK_RESPONSE_CANCEL)
877 * Common code for the reply and forward actions
880 reply_forward (ReplyForwardAction action, ModestWindow *win)
882 ModestMailOperation *mail_op = NULL;
883 TnyList *header_list = NULL;
884 ReplyForwardHelper *rf_helper = NULL;
885 guint reply_forward_type;
886 gboolean continue_download;
888 g_return_if_fail (MODEST_IS_WINDOW(win));
890 header_list = get_selected_headers (win);
894 /* Check that the messages have been previously downloaded */
895 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
896 if (!continue_download) {
897 g_object_unref (header_list);
902 modest_conf_get_int (modest_runtime_get_conf (),
903 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
905 /* We assume that we can only select messages of the
906 same folder and that we reply all of them from the
907 same account. In fact the interface currently only
908 allows single selection */
911 rf_helper = g_slice_new0 (ReplyForwardHelper);
912 rf_helper->reply_forward_type = reply_forward_type;
913 rf_helper->action = action;
914 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
915 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
916 rf_helper->parent_window = GTK_WIDGET (win);
917 if (!rf_helper->account_name)
918 rf_helper->account_name =
919 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
921 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
924 /* Get header and message. Do not free them here, the
925 reply_forward_cb must do it */
926 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
927 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
928 if (!msg || !header) {
930 g_object_unref (msg);
932 g_object_unref (header);
933 g_printerr ("modest: no message found\n");
936 reply_forward_cb (NULL, header, msg, rf_helper);
938 /* Retrieve messages */
939 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
941 modest_ui_actions_get_msgs_full_error_handler,
943 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
944 modest_mail_operation_get_msgs_full (mail_op,
948 free_reply_forward_helper);
951 g_object_unref(mail_op);
955 g_object_unref (header_list);
959 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
961 g_return_if_fail (MODEST_IS_WINDOW(win));
963 reply_forward (ACTION_REPLY, win);
967 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
969 g_return_if_fail (MODEST_IS_WINDOW(win));
971 reply_forward (ACTION_FORWARD, win);
975 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
977 g_return_if_fail (MODEST_IS_WINDOW(win));
979 reply_forward (ACTION_REPLY_TO_ALL, win);
983 modest_ui_actions_on_next (GtkAction *action,
984 ModestWindow *window)
986 if (MODEST_IS_MAIN_WINDOW (window)) {
987 GtkWidget *header_view;
989 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
990 MODEST_WIDGET_TYPE_HEADER_VIEW);
994 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
995 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
996 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
998 g_return_if_reached ();
1003 modest_ui_actions_on_prev (GtkAction *action,
1004 ModestWindow *window)
1006 g_return_if_fail (MODEST_IS_WINDOW(window));
1008 if (MODEST_IS_MAIN_WINDOW (window)) {
1009 GtkWidget *header_view;
1010 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1011 MODEST_WIDGET_TYPE_HEADER_VIEW);
1015 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1016 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1017 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1019 g_return_if_reached ();
1024 modest_ui_actions_on_sort (GtkAction *action,
1025 ModestWindow *window)
1027 g_return_if_fail (MODEST_IS_WINDOW(window));
1029 if (MODEST_IS_MAIN_WINDOW (window)) {
1030 GtkWidget *header_view;
1031 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1032 MODEST_WIDGET_TYPE_HEADER_VIEW);
1036 /* Show sorting dialog */
1037 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1042 * This function performs the send & receive required actions. The
1043 * window is used to create the mail operation. Typically it should
1044 * always be the main window, but we pass it as argument in order to
1048 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1050 gchar *acc_name = NULL;
1051 ModestMailOperation *mail_op;
1053 /* If no account name was provided then get the current account, and if
1054 there is no current account then pick the default one: */
1055 if (!account_name) {
1056 acc_name = g_strdup (modest_window_get_active_account(win));
1058 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1060 g_printerr ("modest: cannot get default account\n");
1064 acc_name = g_strdup (account_name);
1067 /* Set send/receive operation in progress */
1068 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1070 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1071 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1072 G_CALLBACK (_on_send_receive_progress_changed),
1075 /* Send & receive. */
1076 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1077 /* Receive and then send. The operation is tagged initially as
1078 a receive operation because the account update performs a
1079 receive and then a send. The operation changes its type
1080 internally, so the progress objects will receive the proper
1081 progress information */
1082 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1083 modest_mail_operation_update_account (mail_op, acc_name);
1084 g_object_unref (G_OBJECT (mail_op));
1091 * Refreshes all accounts. This function will be used by automatic
1095 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1097 GSList *account_names, *iter;
1099 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1102 iter = account_names;
1104 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1105 iter = g_slist_next (iter);
1108 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1109 g_slist_free (account_names);
1113 * Handler of the click on Send&Receive button in the main toolbar
1116 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1118 /* Check that at least one account exists: */
1119 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1120 TRUE /* enabled accounts only */);
1121 gboolean accounts_exist = account_names != NULL;
1122 g_slist_free (account_names);
1124 /* If not, allow the user to create an account before trying to send/receive. */
1125 if (!accounts_exist)
1126 modest_ui_actions_on_accounts (NULL, win);
1128 /* Refresh the active account */
1129 modest_ui_actions_do_send_receive (NULL, win);
1134 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1137 GtkWidget *header_view;
1139 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1141 header_view = modest_main_window_get_child_widget (main_window,
1142 MODEST_WIDGET_TYPE_HEADER_VIEW);
1146 conf = modest_runtime_get_conf ();
1148 /* what is saved/restored is depending on the style; thus; we save with
1149 * old style, then update the style, and restore for this new style
1151 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1153 if (modest_header_view_get_style
1154 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1155 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1156 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1158 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1159 MODEST_HEADER_VIEW_STYLE_DETAILS);
1161 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1162 MODEST_CONF_HEADER_VIEW_KEY);
1167 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1169 ModestMainWindow *main_window)
1171 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1173 /* If no header has been selected then exit */
1177 /* Update Main window title */
1178 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1179 const gchar *subject = tny_header_get_subject (header);
1180 if (subject && strcmp (subject, ""))
1181 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1183 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1186 /* Update toolbar dimming state */
1187 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1191 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1193 ModestMainWindow *main_window)
1197 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1202 headers = tny_simple_list_new ();
1203 tny_list_prepend (headers, G_OBJECT (header));
1205 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1207 g_object_unref (headers);
1211 set_active_account_from_tny_account (TnyAccount *account,
1212 ModestWindow *window)
1214 const gchar *server_acc_name = tny_account_get_id (account);
1216 /* We need the TnyAccount provided by the
1217 account store because that is the one that
1218 knows the name of the Modest account */
1219 TnyAccount *modest_server_account = modest_server_account =
1220 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1223 const gchar *modest_acc_name =
1224 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1225 modest_window_set_active_account (window, modest_acc_name);
1226 g_object_unref (modest_server_account);
1230 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1231 TnyFolderStore *folder_store,
1233 ModestMainWindow *main_window)
1236 GtkWidget *header_view;
1237 gboolean folder_empty = FALSE;
1239 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1241 header_view = modest_main_window_get_child_widget(main_window,
1242 MODEST_WIDGET_TYPE_HEADER_VIEW);
1246 conf = modest_runtime_get_conf ();
1248 if (TNY_IS_ACCOUNT (folder_store)) {
1249 /* Update active account */
1250 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1251 /* Show account details */
1252 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1254 if (TNY_IS_FOLDER (folder_store) && selected) {
1256 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1257 /* Update the active account */
1258 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1259 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1260 g_object_unref (account);
1264 /* Set folder on header view */
1265 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1266 TNY_FOLDER (folder_store));
1268 /* Set main view style */
1269 folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1271 modest_main_window_set_contents_style (main_window,
1272 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1275 modest_main_window_set_contents_style (main_window,
1276 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1277 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1278 MODEST_CONF_HEADER_VIEW_KEY);
1281 /* Update the active account */
1282 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1283 /* Do not show folder */
1284 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1285 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1289 /* Update toolbar dimming state */
1290 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1294 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1301 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1303 if (g_main_depth > 0)
1304 gdk_threads_enter ();
1305 online = tny_device_is_online (modest_runtime_get_device());
1308 /* already online -- the item is simply not there... */
1309 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1311 GTK_MESSAGE_WARNING,
1313 _("The %s you selected cannot be found"),
1315 gtk_dialog_run (GTK_DIALOG(dialog));
1317 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1321 GTK_RESPONSE_REJECT,
1323 GTK_RESPONSE_ACCEPT,
1325 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1326 "Do you want to get online?"), item);
1327 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1328 gtk_label_new (txt), FALSE, FALSE, 0);
1329 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1332 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1333 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1334 // modest_platform_connect_and_wait ();;
1337 gtk_widget_destroy (dialog);
1338 if (g_main_depth > 0)
1339 gdk_threads_leave ();
1343 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1346 /* g_message ("%s %s", __FUNCTION__, link); */
1351 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1354 modest_platform_activate_uri (link);
1358 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1361 modest_platform_show_uri_popup (link);
1365 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1368 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1372 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1373 const gchar *address,
1376 /* g_message ("%s %s", __FUNCTION__, address); */
1380 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1382 TnyTransportAccount *transport_account;
1383 ModestMailOperation *mail_operation;
1385 gchar *account_name, *from;
1386 ModestAccountMgr *account_mgr;
1388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1390 data = modest_msg_edit_window_get_msg_data (edit_window);
1392 account_mgr = modest_runtime_get_account_mgr();
1393 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1395 account_name = modest_account_mgr_get_default_account (account_mgr);
1396 if (!account_name) {
1397 g_printerr ("modest: no account found\n");
1398 modest_msg_edit_window_free_msg_data (edit_window, data);
1402 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1403 account_name = g_strdup (data->account_name);
1407 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1408 (modest_runtime_get_account_store(),
1410 TNY_ACCOUNT_TYPE_TRANSPORT));
1411 if (!transport_account) {
1412 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1413 g_free (account_name);
1414 modest_msg_edit_window_free_msg_data (edit_window, data);
1417 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1419 /* Create the mail operation */
1420 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1423 modest_mail_operation_save_to_drafts (mail_operation,
1434 data->priority_flags);
1437 g_free (account_name);
1438 g_object_unref (G_OBJECT (transport_account));
1439 g_object_unref (G_OBJECT (mail_operation));
1441 modest_msg_edit_window_free_msg_data (edit_window, data);
1443 /* Save settings and close the window */
1444 gtk_widget_destroy (GTK_WIDGET (edit_window));
1447 /* For instance, when clicking the Send toolbar button when editing a message: */
1449 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1453 if (!modest_msg_edit_window_check_names (edit_window))
1456 /* FIXME: Code added just for testing. The final version will
1457 use the send queue provided by tinymail and some
1459 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1460 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1462 account_name = modest_account_mgr_get_default_account (account_mgr);
1464 if (!account_name) {
1465 g_printerr ("modest: no account found\n");
1468 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1470 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1471 account_name = g_strdup (data->account_name);
1474 /* Get the currently-active transport account for this modest account: */
1475 TnyTransportAccount *transport_account =
1476 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1477 (modest_runtime_get_account_store(),
1479 if (!transport_account) {
1480 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1481 g_free (account_name);
1482 modest_msg_edit_window_free_msg_data (edit_window, data);
1486 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1488 /* mail content checks and dialogs */
1489 if (data->subject == NULL || data->subject[0] == '\0') {
1490 GtkResponseType response;
1491 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1492 _("mcen_nc_subject_is_empty_send"));
1493 if (response == GTK_RESPONSE_CANCEL) {
1494 g_free (account_name);
1499 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1500 GtkResponseType response;
1501 gchar *note_message;
1502 gchar *note_subject = data->subject;
1503 if (note_subject == NULL || note_subject[0] == '\0')
1504 note_subject = _("mail_va_no_subject");
1505 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1506 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1508 g_free (note_message);
1509 if (response == GTK_RESPONSE_CANCEL) {
1510 g_free (account_name);
1515 /* Create the mail operation */
1516 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1517 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1519 modest_mail_operation_send_new_mail (mail_operation,
1530 data->priority_flags);
1534 g_free (account_name);
1535 g_object_unref (G_OBJECT (transport_account));
1536 g_object_unref (G_OBJECT (mail_operation));
1538 modest_msg_edit_window_free_msg_data (edit_window, data);
1540 /* Save settings and close the window: */
1541 gtk_widget_destroy (GTK_WIDGET (edit_window));
1545 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1546 ModestMsgEditWindow *window)
1548 ModestMsgEditFormatState *format_state = NULL;
1550 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1551 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1553 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1556 format_state = modest_msg_edit_window_get_format_state (window);
1557 g_return_if_fail (format_state != NULL);
1559 format_state->bold = gtk_toggle_action_get_active (action);
1560 modest_msg_edit_window_set_format_state (window, format_state);
1561 g_free (format_state);
1566 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1567 ModestMsgEditWindow *window)
1569 ModestMsgEditFormatState *format_state = NULL;
1571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1572 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1574 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1577 format_state = modest_msg_edit_window_get_format_state (window);
1578 g_return_if_fail (format_state != NULL);
1580 format_state->italics = gtk_toggle_action_get_active (action);
1581 modest_msg_edit_window_set_format_state (window, format_state);
1582 g_free (format_state);
1587 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1588 ModestMsgEditWindow *window)
1590 ModestMsgEditFormatState *format_state = NULL;
1592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1595 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1598 format_state = modest_msg_edit_window_get_format_state (window);
1599 g_return_if_fail (format_state != NULL);
1601 format_state->bullet = gtk_toggle_action_get_active (action);
1602 modest_msg_edit_window_set_format_state (window, format_state);
1603 g_free (format_state);
1608 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1609 GtkRadioAction *selected,
1610 ModestMsgEditWindow *window)
1612 ModestMsgEditFormatState *format_state = NULL;
1613 GtkJustification value;
1615 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1617 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1620 value = gtk_radio_action_get_current_value (selected);
1622 format_state = modest_msg_edit_window_get_format_state (window);
1623 g_return_if_fail (format_state != NULL);
1625 format_state->justification = value;
1626 modest_msg_edit_window_set_format_state (window, format_state);
1627 g_free (format_state);
1631 modest_ui_actions_on_select_editor_color (GtkAction *action,
1632 ModestMsgEditWindow *window)
1634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1635 g_return_if_fail (GTK_IS_ACTION (action));
1637 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1640 modest_msg_edit_window_select_color (window);
1644 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1645 ModestMsgEditWindow *window)
1647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1648 g_return_if_fail (GTK_IS_ACTION (action));
1650 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1653 modest_msg_edit_window_select_background_color (window);
1657 modest_ui_actions_on_insert_image (GtkAction *action,
1658 ModestMsgEditWindow *window)
1660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1661 g_return_if_fail (GTK_IS_ACTION (action));
1663 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1666 modest_msg_edit_window_insert_image (window);
1670 modest_ui_actions_on_attach_file (GtkAction *action,
1671 ModestMsgEditWindow *window)
1673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1674 g_return_if_fail (GTK_IS_ACTION (action));
1676 modest_msg_edit_window_attach_file (window);
1680 modest_ui_actions_on_remove_attachments (GtkAction *action,
1681 ModestMsgEditWindow *window)
1683 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1684 g_return_if_fail (GTK_IS_ACTION (action));
1686 modest_msg_edit_window_remove_attachments (window, NULL);
1690 * Shows a dialog with an entry that asks for some text. The returned
1691 * value must be freed by the caller. The dialog window title will be
1695 ask_for_folder_name (GtkWindow *parent_window,
1698 GtkWidget *dialog, *entry;
1699 gchar *folder_name = NULL;
1701 /* Ask for folder name */
1702 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1706 GTK_RESPONSE_REJECT,
1708 GTK_RESPONSE_ACCEPT,
1710 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1711 gtk_label_new(title),
1714 entry = gtk_entry_new_with_max_length (40);
1715 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1719 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1721 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1722 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1724 gtk_widget_destroy (dialog);
1730 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1732 TnyFolderStore *parent_folder;
1733 GtkWidget *folder_view;
1735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1737 folder_view = modest_main_window_get_child_widget (main_window,
1738 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1742 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1744 if (parent_folder) {
1745 gboolean finished = FALSE;
1747 gchar *folder_name = NULL, *suggested_name = NULL;
1749 /* Run the new folder dialog */
1751 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1756 if (result == GTK_RESPONSE_REJECT) {
1759 ModestMailOperation *mail_op;
1760 TnyFolder *new_folder = NULL;
1762 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1763 G_OBJECT(main_window));
1764 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1766 new_folder = modest_mail_operation_create_folder (mail_op,
1768 (const gchar *) folder_name);
1770 g_object_unref (new_folder);
1773 g_object_unref (mail_op);
1775 g_free (folder_name);
1779 g_object_unref (parent_folder);
1784 modest_ui_actions_on_rename_folder (GtkAction *action,
1785 ModestMainWindow *main_window)
1787 TnyFolderStore *folder;
1788 GtkWidget *folder_view;
1789 GtkWidget *header_view;
1791 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1793 folder_view = modest_main_window_get_child_widget (main_window,
1794 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1798 header_view = modest_main_window_get_child_widget (main_window,
1799 MODEST_WIDGET_TYPE_HEADER_VIEW);
1804 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1806 if (folder && TNY_IS_FOLDER (folder)) {
1808 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1809 _("Please enter a new name for the folder"));
1811 if (folder_name != NULL && strlen (folder_name) > 0) {
1812 ModestMailOperation *mail_op;
1814 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1815 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1818 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1820 modest_mail_operation_rename_folder (mail_op,
1821 TNY_FOLDER (folder),
1822 (const gchar *) folder_name);
1824 g_object_unref (mail_op);
1825 g_free (folder_name);
1827 g_object_unref (folder);
1832 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1835 GObject *win = modest_mail_operation_get_source (mail_op);
1837 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1838 _("mail_in_ui_folder_delete_error"));
1842 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1844 TnyFolderStore *folder;
1845 GtkWidget *folder_view;
1849 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1851 folder_view = modest_main_window_get_child_widget (main_window,
1852 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1856 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1858 /* Show an error if it's an account */
1859 if (!TNY_IS_FOLDER (folder)) {
1860 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1861 _("mail_in_ui_folder_delete_error"));
1866 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1867 tny_folder_get_name (TNY_FOLDER (folder)));
1868 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1869 (const gchar *) message);
1872 if (response == GTK_RESPONSE_OK) {
1873 ModestMailOperation *mail_op =
1874 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1875 G_OBJECT(main_window),
1876 modest_ui_actions_delete_folder_error_handler,
1879 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1881 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1882 g_object_unref (G_OBJECT (mail_op));
1885 g_object_unref (G_OBJECT (folder));
1889 modest_ui_actions_on_delete_folder (GtkAction *action,
1890 ModestMainWindow *main_window)
1892 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1894 delete_folder (main_window, FALSE);
1898 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1900 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1902 delete_folder (main_window, TRUE);
1906 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1907 const gchar* server_account_name,
1912 ModestMainWindow *main_window)
1914 g_return_if_fail(server_account_name);
1915 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1917 /* Initalize output parameters: */
1924 #ifdef MODEST_PLATFORM_MAEMO
1925 /* Maemo uses a different (awkward) button order,
1926 * It should probably just use gtk_alternative_dialog_button_order ().
1928 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1932 GTK_RESPONSE_ACCEPT,
1934 GTK_RESPONSE_REJECT,
1937 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1941 GTK_RESPONSE_REJECT,
1943 GTK_RESPONSE_ACCEPT,
1945 #endif /* MODEST_PLATFORM_MAEMO */
1947 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1949 gchar *server_name = modest_server_account_get_hostname (
1950 modest_runtime_get_account_mgr(), server_account_name);
1952 /* This causes a warning because the logical ID has no %s in it,
1953 * though the translation does, but there is not much we can do about that: */
1954 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1955 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1958 g_free (server_name);
1962 gchar *initial_username = modest_server_account_get_username (
1963 modest_runtime_get_account_mgr(), server_account_name);
1965 GtkWidget *entry_username = gtk_entry_new ();
1966 if (initial_username)
1967 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1968 /* Dim this if a connection has ever succeeded with this username,
1969 * as per the UI spec: */
1970 const gboolean username_known =
1971 modest_server_account_get_username_has_succeeded(
1972 modest_runtime_get_account_mgr(), server_account_name);
1973 gtk_widget_set_sensitive (entry_username, !username_known);
1975 #ifdef MODEST_PLATFORM_MAEMO
1976 /* Auto-capitalization is the default, so let's turn it off: */
1977 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1979 /* Create a size group to be used by all captions.
1980 * Note that HildonCaption does not create a default size group if we do not specify one.
1981 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1982 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1984 GtkWidget *caption = hildon_caption_new (sizegroup,
1985 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1986 gtk_widget_show (entry_username);
1987 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1988 FALSE, FALSE, MODEST_MARGIN_HALF);
1989 gtk_widget_show (caption);
1991 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1993 #endif /* MODEST_PLATFORM_MAEMO */
1996 GtkWidget *entry_password = gtk_entry_new ();
1997 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1998 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2000 #ifdef MODEST_PLATFORM_MAEMO
2001 /* Auto-capitalization is the default, so let's turn it off: */
2002 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2003 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2005 caption = hildon_caption_new (sizegroup,
2006 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2007 gtk_widget_show (entry_password);
2008 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2009 FALSE, FALSE, MODEST_MARGIN_HALF);
2010 gtk_widget_show (caption);
2011 g_object_unref (sizegroup);
2013 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2015 #endif /* MODEST_PLATFORM_MAEMO */
2017 /* This is not in the Maemo UI spec:
2018 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2019 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2023 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2025 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2027 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2029 modest_server_account_set_username (
2030 modest_runtime_get_account_mgr(), server_account_name,
2033 const gboolean username_was_changed =
2034 (strcmp (*username, initial_username) != 0);
2035 if (username_was_changed) {
2036 /* To actually use a changed username,
2037 * we must reset the connection, according to pvanhoof.
2038 * This _might_ be a sensible way to do that: */
2039 TnyDevice *device = modest_runtime_get_device();
2040 tny_device_force_offline (device);
2041 tny_device_force_online (device);
2046 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2048 /* We do not save the password in the configuration,
2049 * because this function is only called for passwords that should
2050 * not be remembered:
2051 modest_server_account_set_password (
2052 modest_runtime_get_account_mgr(), server_account_name,
2071 /* This is not in the Maemo UI spec:
2072 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2078 gtk_widget_destroy (dialog);
2080 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2084 modest_ui_actions_on_cut (GtkAction *action,
2085 ModestWindow *window)
2087 GtkWidget *focused_widget;
2089 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2090 if (GTK_IS_EDITABLE (focused_widget)) {
2091 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2092 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2093 GtkTextBuffer *buffer;
2094 GtkClipboard *clipboard;
2096 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2097 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2098 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2103 modest_ui_actions_on_copy (GtkAction *action,
2104 ModestWindow *window)
2106 GtkClipboard *clipboard;
2107 GtkWidget *focused_widget;
2109 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2110 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2111 if (GTK_IS_LABEL (focused_widget)) {
2112 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2113 } else if (GTK_IS_EDITABLE (focused_widget)) {
2114 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2115 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2116 GtkTextBuffer *buffer;
2118 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2119 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2124 modest_ui_actions_on_undo (GtkAction *action,
2125 ModestWindow *window)
2127 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2128 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2130 g_return_if_reached ();
2135 modest_ui_actions_on_paste (GtkAction *action,
2136 ModestWindow *window)
2138 GtkWidget *focused_widget;
2140 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2141 if (GTK_IS_EDITABLE (focused_widget)) {
2142 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2143 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2144 GtkTextBuffer *buffer;
2145 GtkClipboard *clipboard;
2147 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2148 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2149 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2154 modest_ui_actions_on_select_all (GtkAction *action,
2155 ModestWindow *window)
2157 GtkWidget *focused_widget;
2159 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2160 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2161 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2162 } else if (GTK_IS_LABEL (focused_widget)) {
2163 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2164 } else if (GTK_IS_EDITABLE (focused_widget)) {
2165 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2166 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2167 GtkTextBuffer *buffer;
2168 GtkTextIter start, end;
2170 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2171 gtk_text_buffer_get_start_iter (buffer, &start);
2172 gtk_text_buffer_get_end_iter (buffer, &end);
2173 gtk_text_buffer_select_range (buffer, &start, &end);
2175 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2176 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2178 GtkTreeSelection *selection = NULL;
2180 /* Get header view */
2181 GtkWidget *header_view = focused_widget;
2182 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2183 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2184 MODEST_WIDGET_TYPE_HEADER_VIEW);
2186 /* Select all messages */
2187 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2188 gtk_tree_selection_select_all (selection);
2193 modest_ui_actions_on_mark_as_read (GtkAction *action,
2194 ModestWindow *window)
2196 g_return_if_fail (MODEST_IS_WINDOW(window));
2198 /* Mark each header as read */
2199 do_headers_action (window, headers_action_mark_as_read, NULL);
2203 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2204 ModestWindow *window)
2206 g_return_if_fail (MODEST_IS_WINDOW(window));
2208 /* Mark each header as read */
2209 do_headers_action (window, headers_action_mark_as_unread, NULL);
2213 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2214 GtkRadioAction *selected,
2215 ModestWindow *window)
2219 value = gtk_radio_action_get_current_value (selected);
2220 if (MODEST_IS_WINDOW (window)) {
2221 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2225 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2226 GtkRadioAction *selected,
2227 ModestWindow *window)
2229 TnyHeaderFlags flags;
2230 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2232 flags = gtk_radio_action_get_current_value (selected);
2233 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2236 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2237 GtkRadioAction *selected,
2238 ModestWindow *window)
2242 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2244 file_format = gtk_radio_action_get_current_value (selected);
2245 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2250 modest_ui_actions_on_zoom_plus (GtkAction *action,
2251 ModestWindow *window)
2253 g_return_if_fail (MODEST_IS_WINDOW (window));
2255 modest_window_zoom_plus (MODEST_WINDOW (window));
2259 modest_ui_actions_on_zoom_minus (GtkAction *action,
2260 ModestWindow *window)
2262 g_return_if_fail (MODEST_IS_WINDOW (window));
2264 modest_window_zoom_minus (MODEST_WINDOW (window));
2268 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2269 ModestWindow *window)
2271 ModestWindowMgr *mgr;
2272 gboolean fullscreen, active;
2273 g_return_if_fail (MODEST_IS_WINDOW (window));
2275 mgr = modest_runtime_get_window_mgr ();
2277 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2278 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2280 if (active != fullscreen) {
2281 modest_window_mgr_set_fullscreen_mode (mgr, active);
2282 gtk_window_present (GTK_WINDOW (window));
2287 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2288 ModestWindow *window)
2290 ModestWindowMgr *mgr;
2291 gboolean fullscreen;
2293 g_return_if_fail (MODEST_IS_WINDOW (window));
2295 mgr = modest_runtime_get_window_mgr ();
2296 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2297 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2299 gtk_window_present (GTK_WINDOW (window));
2303 * Used by modest_ui_actions_on_details to call do_headers_action
2306 headers_action_show_details (TnyHeader *header,
2307 ModestWindow *window,
2314 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2317 gtk_widget_show_all (dialog);
2318 gtk_dialog_run (GTK_DIALOG (dialog));
2320 gtk_widget_destroy (dialog);
2324 * Show the folder details in a ModestDetailsDialog widget
2327 show_folder_details (TnyFolder *folder,
2333 dialog = modest_details_dialog_new_with_folder (window, folder);
2336 gtk_widget_show_all (dialog);
2337 gtk_dialog_run (GTK_DIALOG (dialog));
2339 gtk_widget_destroy (dialog);
2343 * Show the header details in a ModestDetailsDialog widget
2346 modest_ui_actions_on_details (GtkAction *action,
2349 TnyList * headers_list;
2353 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2356 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2359 g_object_unref (msg);
2361 headers_list = get_selected_headers (win);
2365 iter = tny_list_create_iterator (headers_list);
2367 header = TNY_HEADER (tny_iterator_get_current (iter));
2368 headers_action_show_details (header, win, NULL);
2369 g_object_unref (header);
2371 g_object_unref (iter);
2372 g_object_unref (headers_list);
2374 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2375 GtkWidget *folder_view, *header_view;
2377 /* Check which widget has the focus */
2378 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2379 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2380 if (gtk_widget_is_focus (folder_view)) {
2383 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2385 /* Show only when it's a folder */
2386 if (!folder || !TNY_IS_FOLDER (folder))
2389 show_folder_details (folder, GTK_WINDOW (win));
2392 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2393 MODEST_WIDGET_TYPE_HEADER_VIEW);
2394 /* Show details of each header */
2395 do_headers_action (win, headers_action_show_details, header_view);
2401 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2402 ModestMsgEditWindow *window)
2404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2406 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2410 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2411 ModestMsgEditWindow *window)
2413 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2415 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2419 modest_ui_actions_toggle_folders_view (GtkAction *action,
2420 ModestMainWindow *main_window)
2424 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2426 conf = modest_runtime_get_conf ();
2428 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2429 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2431 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2435 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2436 ModestWindow *window)
2438 gboolean active, fullscreen = FALSE;
2439 ModestWindowMgr *mgr;
2441 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2443 /* Check if we want to toggle the toolbar vuew in fullscreen
2445 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2446 "ViewShowToolbarFullScreen")) {
2450 /* Toggle toolbar */
2451 mgr = modest_runtime_get_window_mgr ();
2452 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2456 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2457 ModestMsgEditWindow *window)
2459 modest_msg_edit_window_select_font (window);
2463 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2464 const gchar *display_name,
2467 /* Do not change the application name if the widget has not
2468 the focus. This callback could be called even if the folder
2469 view has not the focus, because the handled signal could be
2470 emitted when the folder view is redrawn */
2471 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2473 gtk_window_set_title (window, display_name);
2475 gtk_window_set_title (window, " ");
2480 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2482 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2483 modest_msg_edit_window_select_contacts (window);
2487 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2489 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2490 modest_msg_edit_window_check_names (window);
2495 create_move_to_dialog (ModestWindow *win,
2496 GtkWidget *folder_view,
2497 GtkWidget **tree_view)
2499 GtkWidget *dialog, *scroll;
2501 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2503 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2505 GTK_RESPONSE_ACCEPT,
2507 GTK_RESPONSE_REJECT,
2510 /* Create scrolled window */
2511 scroll = gtk_scrolled_window_new (NULL, NULL);
2512 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2513 GTK_POLICY_AUTOMATIC,
2514 GTK_POLICY_AUTOMATIC);
2516 /* Create folder view */
2517 *tree_view = modest_folder_view_new (NULL);
2518 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2519 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2520 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2522 /* Add scroll to dialog */
2523 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2524 scroll, FALSE, FALSE, 0);
2526 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2532 * Returns TRUE if at least one of the headers of the list belongs to
2533 * a message that has been fully retrieved.
2536 has_retrieved_msgs (TnyList *list)
2539 gboolean found = FALSE;
2541 iter = tny_list_create_iterator (list);
2542 while (tny_iterator_is_done (iter) && !found) {
2544 TnyHeaderFlags flags;
2546 header = TNY_HEADER (tny_iterator_get_current (iter));
2547 flags = tny_header_get_flags (header);
2548 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2552 tny_iterator_next (iter);
2554 g_object_unref (iter);
2560 * Shows a confirmation dialog to the user when we're moving messages
2561 * from a remote server to the local storage. Returns the dialog
2562 * response. If it's other kind of movement the it always returns
2566 msgs_move_to_confirmation (GtkWindow *win,
2567 TnyFolder *dest_folder,
2570 gint response = GTK_RESPONSE_OK;
2572 /* If the destination is a local folder */
2573 if (modest_tny_folder_is_local_folder (dest_folder)) {
2574 TnyFolder *src_folder;
2578 /* Get source folder */
2579 iter = tny_list_create_iterator (headers);
2580 header = TNY_HEADER (tny_iterator_get_current (iter));
2581 src_folder = tny_header_get_folder (header);
2582 g_object_unref (header);
2583 g_object_unref (iter);
2585 /* If the source is a remote folder */
2586 if (!modest_tny_folder_is_local_folder (src_folder)) {
2587 const gchar *message;
2589 if (tny_list_get_length (headers) == 1)
2590 if (has_retrieved_msgs (headers))
2591 message = _("mcen_nc_move_retrieve");
2593 message = _("mcen_nc_move_header");
2595 if (has_retrieved_msgs (headers))
2596 message = _("mcen_nc_move_retrieves");
2598 message = _("mcen_nc_move_headers");
2600 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2601 (const gchar *) message);
2603 g_object_unref (src_folder);
2610 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2612 ModestMsgViewWindow *self = NULL;
2613 gboolean found = FALSE;
2615 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2616 self = MODEST_MSG_VIEW_WINDOW (object);
2618 found = modest_msg_view_window_select_first_message (self);
2619 g_return_if_fail (found);
2623 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2626 GObject *win = modest_mail_operation_get_source (mail_op);
2628 /* TODO: show error message */
2629 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2630 _("mail_in_ui_folder_move_target_error"));
2634 * UI handler for the "Move to" action when invoked from the
2638 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2639 ModestMainWindow *win)
2641 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2642 GtkWidget *header_view = NULL;
2644 TnyFolderStore *folder_store = NULL;
2645 ModestMailOperation *mail_op = NULL;
2647 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2649 /* Get the folder view */
2650 folder_view = modest_main_window_get_child_widget (win,
2651 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2653 /* Get header view */
2654 header_view = modest_main_window_get_child_widget (win,
2655 MODEST_WIDGET_TYPE_HEADER_VIEW);
2657 /* Create and run the dialog */
2658 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2659 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2660 result = gtk_dialog_run (GTK_DIALOG(dialog));
2661 g_object_ref (tree_view);
2663 /* We do this to save an indentation level ;-) */
2664 if (result != GTK_RESPONSE_ACCEPT)
2667 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2669 if (TNY_IS_ACCOUNT (folder_store))
2672 /* Get folder or messages to transfer */
2673 if (gtk_widget_is_focus (folder_view)) {
2674 TnyFolderStore *src_folder;
2675 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2677 /* Clean folder on header view before moving it */
2678 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2680 if (TNY_IS_FOLDER (src_folder)) {
2682 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2684 modest_ui_actions_move_folder_error_handler,
2686 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2688 modest_mail_operation_xfer_folder (mail_op,
2689 TNY_FOLDER (src_folder),
2692 /* Unref mail operation */
2693 g_object_unref (G_OBJECT (mail_op));
2697 g_object_unref (G_OBJECT (src_folder));
2699 if (gtk_widget_is_focus (header_view)) {
2703 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2705 /* Ask for user confirmation */
2706 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2707 TNY_FOLDER (folder_store),
2710 /* Transfer messages */
2711 if (response == GTK_RESPONSE_OK) {
2712 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2713 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2716 modest_mail_operation_xfer_msgs (mail_op,
2718 TNY_FOLDER (folder_store),
2723 g_object_unref (G_OBJECT (mail_op));
2725 g_object_unref (headers);
2728 g_object_unref (folder_store);
2730 gtk_widget_destroy (dialog);
2735 * UI handler for the "Move to" action when invoked from the
2736 * ModestMsgViewWindow
2739 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2740 ModestMsgViewWindow *win)
2742 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2744 ModestMainWindow *main_window;
2748 /* Get the folder view */
2749 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2750 folder_view = modest_main_window_get_child_widget (main_window,
2751 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2753 /* Create and run the dialog */
2754 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2755 result = gtk_dialog_run (GTK_DIALOG(dialog));
2756 g_object_ref (tree_view);
2758 if (result == GTK_RESPONSE_ACCEPT) {
2759 TnyFolderStore *folder_store;
2762 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2764 /* Create header list */
2765 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2766 headers = tny_simple_list_new ();
2767 tny_list_prepend (headers, G_OBJECT (header));
2768 g_object_unref (header);
2770 /* Ask user for confirmation. MSG-NOT404 */
2771 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2772 TNY_FOLDER (folder_store),
2775 /* Transfer current msg */
2776 if (response == GTK_RESPONSE_OK) {
2777 ModestMailOperation *mail_op;
2779 /* Create mail op */
2780 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2781 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2784 /* Transfer messages */
2785 modest_mail_operation_xfer_msgs (mail_op,
2787 TNY_FOLDER (folder_store),
2789 tranasfer_msgs_from_viewer_cb,
2791 g_object_unref (G_OBJECT (mail_op));
2793 g_object_unref (headers);
2794 g_object_unref (folder_store);
2796 gtk_widget_destroy (dialog);
2800 modest_ui_actions_on_move_to (GtkAction *action,
2803 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2804 MODEST_IS_MSG_VIEW_WINDOW (win));
2806 if (MODEST_IS_MAIN_WINDOW (win))
2807 modest_ui_actions_on_main_window_move_to (action,
2808 MODEST_MAIN_WINDOW (win));
2810 modest_ui_actions_on_msg_view_window_move_to (action,
2811 MODEST_MSG_VIEW_WINDOW (win));
2815 * Calls #HeadersFunc for each header already selected in the main
2816 * window or the message currently being shown in the msg view window
2819 do_headers_action (ModestWindow *win,
2823 TnyList *headers_list;
2827 headers_list = get_selected_headers (win);
2831 /* Call the function for each header */
2832 iter = tny_list_create_iterator (headers_list);
2833 while (!tny_iterator_is_done (iter)) {
2836 header = TNY_HEADER (tny_iterator_get_current (iter));
2837 func (header, win, user_data);
2838 g_object_unref (header);
2839 tny_iterator_next (iter);
2841 g_object_unref (iter);
2842 g_object_unref (headers_list);
2846 modest_ui_actions_view_attachment (GtkAction *action,
2847 ModestWindow *window)
2849 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2850 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2852 /* not supported window for this action */
2853 g_return_if_reached ();
2858 modest_ui_actions_save_attachments (GtkAction *action,
2859 ModestWindow *window)
2861 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2862 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2864 /* not supported window for this action */
2865 g_return_if_reached ();
2870 modest_ui_actions_remove_attachments (GtkAction *action,
2871 ModestWindow *window)
2873 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2874 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2876 /* not supported window for this action */
2877 g_return_if_reached ();
2882 modest_ui_actions_on_settings (GtkAction *action,
2887 dialog = modest_platform_get_global_settings_dialog ();
2888 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2889 gtk_widget_show (dialog);
2891 gtk_dialog_run (GTK_DIALOG (dialog));
2893 gtk_widget_destroy (dialog);
2897 modest_ui_actions_on_help (GtkAction *action,
2900 const gchar *help_id = NULL;
2902 if (MODEST_IS_MAIN_WINDOW (win)) {
2903 const gchar *action_name;
2904 action_name = gtk_action_get_name (action);
2906 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2907 !strcmp (action_name, "HeaderViewCSMHelp")) {
2908 GtkWidget *folder_view;
2909 TnyFolderStore *folder_store;
2910 /* Get selected folder */
2911 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2912 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2913 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2915 /* Switch help_id */
2916 if (TNY_IS_FOLDER (folder_store)) {
2917 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2918 case TNY_FOLDER_TYPE_NORMAL:
2919 help_id = "applications_email_userfolder";
2921 case TNY_FOLDER_TYPE_INBOX:
2922 help_id = "applications_email_inbox";
2924 case TNY_FOLDER_TYPE_OUTBOX:
2925 help_id = "applications_email_outbox";
2927 case TNY_FOLDER_TYPE_SENT:
2928 help_id = "applications_email_sent";
2930 case TNY_FOLDER_TYPE_DRAFTS:
2931 help_id = "applications_email_drafts";
2933 case TNY_FOLDER_TYPE_ARCHIVE:
2934 help_id = "applications_email_archive";
2941 help_id = "applications_email_mainview";
2943 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2944 help_id = "applications_email_viewer";
2945 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2946 help_id = "applications_email_editor";
2948 modest_platform_show_help (GTK_WINDOW (win), help_id);
2952 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2953 ModestWindow *window)
2955 ModestMailOperation *mail_op;
2959 headers = get_selected_headers (window);
2963 /* Create mail operation */
2964 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2966 modest_ui_actions_get_msgs_full_error_handler,
2968 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2969 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2972 g_object_unref (headers);
2973 g_object_unref (mail_op);
2977 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2978 ModestWindow *window)
2980 g_return_if_fail (MODEST_IS_WINDOW (window));
2983 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2987 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2988 ModestWindow *window)
2990 g_return_if_fail (MODEST_IS_WINDOW (window));
2993 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2997 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2998 ModestWindow *window)
3000 g_return_if_fail (MODEST_IS_WINDOW (window));
3003 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3007 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3008 ModestWindow *window)
3010 g_return_if_fail (MODEST_IS_WINDOW (window));
3013 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3017 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3018 ModestWindow *window)
3020 g_return_if_fail (MODEST_IS_WINDOW (window));
3023 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3027 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3029 g_return_if_fail (MODEST_IS_WINDOW (window));
3032 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3036 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3038 g_return_if_fail (MODEST_IS_WINDOW (window));
3040 modest_platform_show_search_messages (GTK_WINDOW (window));
3044 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3046 g_return_if_fail (MODEST_IS_WINDOW (win));
3047 modest_platform_show_addressbook (GTK_WINDOW (win));
3052 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3053 ModestWindow *window)
3055 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3057 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3061 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3062 ModestMailOperationState *state,
3065 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3067 /* Set send/receive operation finished */
3068 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3069 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));