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>
36 #include <modest-runtime.h>
37 #include <modest-tny-msg.h>
38 #include <modest-tny-account.h>
39 #include <modest-address-book.h>
41 #include "modest-ui-actions.h"
43 #include "modest-tny-platform-factory.h"
45 #include <widgets/modest-main-window.h>
46 #include <widgets/modest-msg-view-window.h>
47 #include <widgets/modest-account-view-window.h>
49 #include "modest-account-mgr-helpers.h"
50 #include "modest-mail-operation.h"
51 #include "easysetup/modest-easysetup-wizard.h"
52 #include <modest-widget-memory.h>
53 #include <tny-error.h>
54 #include <tny-simple-list.h>
55 #include <tny-msg-view.h>
56 #include <tny-device.h>
59 typedef struct _GetMsgAsyncHelper {
66 typedef enum _ReplyForwardAction {
72 typedef struct _ReplyForwardHelper {
73 guint reply_forward_type;
74 ReplyForwardAction action;
79 static void reply_forward_func (gpointer data, gpointer user_data);
80 static void read_msg_func (gpointer data, gpointer user_data);
81 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
83 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
84 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
88 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
91 const gchar *authors[] = {
92 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
95 about = gtk_about_dialog_new ();
96 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
97 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
98 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
99 _("Copyright (c) 2006, Nokia Corporation\n"
100 "All rights reserved."));
101 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
102 _("a modest e-mail client\n\n"
103 "design and implementation: Dirk-Jan C. Binnema\n"
104 "contributions from the fine people at KernelConcepts and Igalia\n"
105 "uses the tinymail email framework written by Philip van Hoof"));
106 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
107 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
109 gtk_dialog_run (GTK_DIALOG (about));
110 gtk_widget_destroy(about);
115 get_selected_headers (ModestWindow *win)
117 if (MODEST_IS_MAIN_WINDOW(win)) {
118 GtkWidget *header_view;
120 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
121 MODEST_WIDGET_TYPE_HEADER_VIEW);
122 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
124 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
125 /* for MsgViewWindows, we simply return a list with one element */
128 TnyList *list = NULL;
130 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
132 header = tny_msg_get_header (msg);
133 list = tny_simple_list_new ();
134 tny_list_prepend (list, G_OBJECT(header));
135 g_object_unref (G_OBJECT(header));
144 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
146 TnyList *header_list;
149 g_return_if_fail (MODEST_IS_WINDOW(win));
151 header_list = get_selected_headers (win);
154 iter = tny_list_create_iterator (header_list);
157 ModestMailOperation *mail_op;
159 header = TNY_HEADER (tny_iterator_get_current (iter));
160 /* TODO: thick grain mail operation involving
161 a list of objects. Composite pattern ??? */
162 /* TODO: add confirmation dialog */
163 mail_op = modest_mail_operation_new ();
164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
167 /* Always delete. TODO: Move to trash still not supported */
168 modest_mail_operation_remove_msg (mail_op, header, FALSE);
171 g_object_unref (G_OBJECT (mail_op));
172 g_object_unref (G_OBJECT (header));
174 tny_iterator_next (iter);
176 } while (!tny_iterator_is_done (iter));
179 g_object_unref (G_OBJECT (iter));
185 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
187 /* FIXME: save size of main window */
188 /* save_sizes (main_window); */
189 gtk_widget_destroy (GTK_WIDGET (win));
193 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
195 GtkClipboard *clipboard = NULL;
196 gchar *selection = NULL;
198 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
199 selection = gtk_clipboard_wait_for_text (clipboard);
201 modest_address_book_add_address (selection);
206 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
208 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
211 GSList *account_names = modest_account_mgr_search_server_accounts (
212 modest_runtime_get_account_mgr(),
213 NULL /* account_name, any */,
214 MODEST_PROTOCOL_TYPE_UNKNOWN /* type */,
215 MODEST_PROTOCOL_UNKNOWN /* proto */);
218 gboolean accounts_exist = account_names != NULL;
219 g_slist_free (account_names);
221 /* This is currently only implemented for Maemo,
222 * because it requires a providers preset file which is not publically available.
224 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
225 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
226 if (!accounts_exist) {
227 printf ("debug: modest_account_mgr_account_names() returned NULL.\n");
228 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
229 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
230 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
231 gtk_dialog_run (GTK_DIALOG (wizard));
232 gtk_widget_destroy (GTK_WIDGET (wizard));
236 /* Show the list of accounts: */
237 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
238 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
239 gtk_dialog_run (account_win);
240 gtk_widget_destroy (GTK_WIDGET(account_win));
243 GtkWidget *dialog, *label;
245 /* Create the widgets */
247 dialog = gtk_dialog_new_with_buttons ("Message",
249 GTK_DIALOG_DESTROY_WITH_PARENT,
253 label = gtk_label_new ("Hello World!");
255 /* Ensure that the dialog box is destroyed when the user responds. */
257 g_signal_connect_swapped (dialog, "response",
258 G_CALLBACK (gtk_widget_destroy),
261 /* Add the label, and show everything we've added to the dialog. */
263 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
265 gtk_widget_show_all (dialog);
266 #endif /* MODEST_PLATFORM_MAEMO */
270 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
272 ModestWindow *msg_win;
274 TnyFolder *folder = NULL;
275 gchar *account_name = NULL;
276 gchar *from_str = NULL;
280 account_name = g_strdup(modest_window_get_active_account (win));
282 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
284 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
286 TNY_ACCOUNT_TYPE_STORE);
288 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
292 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
294 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
296 g_printerr ("modest: failed to create new msg\n");
300 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
302 g_printerr ("modest: failed to find Drafts folder\n");
306 tny_folder_add_msg (folder, msg, &err);
308 g_printerr ("modest: error adding msg to Drafts folder: %s",
314 msg_win = modest_msg_edit_window_new (msg, account_name);
316 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
318 gtk_widget_show_all (GTK_WIDGET (msg_win));
321 g_free (account_name);
324 g_object_unref (G_OBJECT(account));
326 g_object_unref (G_OBJECT(msg));
328 g_object_unref (G_OBJECT(folder));
333 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
335 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
341 reply_forward_func (gpointer data, gpointer user_data)
343 TnyMsg *msg, *new_msg;
344 GetMsgAsyncHelper *helper;
345 ReplyForwardHelper *rf_helper;
346 ModestWindow *msg_win;
347 ModestEditType edit_type;
350 TnyFolder *folder = NULL;
351 TnyAccount *account = NULL;
353 msg = TNY_MSG (data);
354 helper = (GetMsgAsyncHelper *) user_data;
355 rf_helper = (ReplyForwardHelper *) helper->user_data;
357 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
358 rf_helper->account_name);
359 /* Create reply mail */
360 switch (rf_helper->action) {
363 modest_tny_msg_create_reply_msg (msg, from,
364 rf_helper->reply_forward_type,
365 MODEST_TNY_MSG_REPLY_MODE_SENDER);
367 case ACTION_REPLY_TO_ALL:
369 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
370 MODEST_TNY_MSG_REPLY_MODE_ALL);
371 edit_type = MODEST_EDIT_TYPE_REPLY;
375 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
376 edit_type = MODEST_EDIT_TYPE_FORWARD;
379 g_return_if_reached ();
384 g_printerr ("modest: failed to create message\n");
388 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
389 rf_helper->account_name,
390 TNY_ACCOUNT_TYPE_STORE);
392 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
396 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
398 g_printerr ("modest: failed to find Drafts folder\n");
402 tny_folder_add_msg (folder, msg, &err);
404 g_printerr ("modest: error adding msg to Drafts folder: %s",
410 /* Show edit window */
411 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
412 gtk_widget_show_all (GTK_WIDGET (msg_win));
416 g_object_unref (G_OBJECT (new_msg));
418 g_object_unref (G_OBJECT (folder));
420 g_object_unref (G_OBJECT (account));
422 g_free (rf_helper->account_name);
423 g_slice_free (ReplyForwardHelper, rf_helper);
426 * Common code for the reply and forward actions
429 reply_forward (ReplyForwardAction action, ModestWindow *win)
431 TnyList *header_list;
432 guint reply_forward_type;
435 GetMsgAsyncHelper *helper;
436 ReplyForwardHelper *rf_helper;
438 g_return_if_fail (MODEST_IS_WINDOW(win));
440 header_list = get_selected_headers (win);
444 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
445 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
447 /* We assume that we can only select messages of the
448 same folder and that we reply all of them from the
449 same account. In fact the interface currently only
450 allows single selection */
453 rf_helper = g_slice_new0 (ReplyForwardHelper);
454 rf_helper->reply_forward_type = reply_forward_type;
455 rf_helper->action = action;
457 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
458 if (!rf_helper->account_name)
459 rf_helper->account_name =
460 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
462 helper = g_slice_new0 (GetMsgAsyncHelper);
463 helper->window = win;
464 helper->func = reply_forward_func;
465 helper->iter = tny_list_create_iterator (header_list);
466 helper->user_data = rf_helper;
468 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
470 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
472 g_printerr ("modest: no message found\n");
475 reply_forward_func (msg, helper);
477 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
478 folder = tny_header_get_folder (header);
480 /* The callback will call it per each header */
481 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
482 g_object_unref (G_OBJECT (folder));
484 g_printerr ("modest: no folder for header\n");
487 g_object_unref (G_OBJECT (header));
493 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
495 g_return_if_fail (MODEST_IS_WINDOW(win));
497 reply_forward (ACTION_REPLY, win);
501 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
503 g_return_if_fail (MODEST_IS_WINDOW(win));
505 reply_forward (ACTION_FORWARD, win);
509 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
511 g_return_if_fail (MODEST_IS_WINDOW(win));
513 reply_forward (ACTION_REPLY_TO_ALL, win);
517 modest_ui_actions_on_next (GtkAction *action,
518 ModestMainWindow *main_window)
520 GtkWidget *header_view;
521 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
523 header_view = modest_main_window_get_child_widget (main_window,
524 MODEST_WIDGET_TYPE_HEADER_VIEW);
528 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
532 modest_ui_actions_on_prev (GtkAction *action,
533 ModestMainWindow *main_window)
535 GtkWidget *header_view;
536 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
538 header_view = modest_main_window_get_child_widget (main_window,
539 MODEST_WIDGET_TYPE_HEADER_VIEW);
543 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
548 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
551 TnyAccount *tny_account;
552 ModestTnySendQueue *send_queue;
553 ModestMailOperation *mail_op;
556 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
558 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
560 g_printerr ("modest: cannot get account\n");
565 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
567 TNY_ACCOUNT_TYPE_TRANSPORT);
569 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
572 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
574 g_object_unref (G_OBJECT(tny_account));
575 g_printerr ("modest: cannot get send queue for %s\n", account_name);
578 //modest_tny_send_queue_flush (send_queue);
580 g_object_unref (G_OBJECT(send_queue));
581 g_object_unref (G_OBJECT(tny_account));
584 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
586 TNY_ACCOUNT_TYPE_STORE);
588 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
592 /* Create the mail operation */
593 mail_op = modest_mail_operation_new ();
594 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
595 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
598 g_object_unref (G_OBJECT (tny_account));
599 g_object_unref (G_OBJECT (mail_op));
605 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
608 GtkWidget *header_view;
610 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
612 header_view = modest_main_window_get_child_widget (main_window,
613 MODEST_WIDGET_TYPE_HEADER_VIEW);
617 conf = modest_runtime_get_conf ();
619 /* what is saved/restored is depending on the style; thus; we save with
620 * old style, then update the style, and restore for this new style
622 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
624 if (modest_header_view_get_style
625 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
626 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
627 MODEST_HEADER_VIEW_STYLE_TWOLINES);
629 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
630 MODEST_HEADER_VIEW_STYLE_DETAILS);
632 modest_widget_memory_restore (conf, G_OBJECT(header_view),
639 * Marks a message as read and passes it to the msg preview widget
642 read_msg_func (gpointer data, gpointer user_data)
646 GetMsgAsyncHelper *helper;
647 TnyHeaderFlags header_flags;
648 GtkWidget *msg_preview;
650 msg = TNY_MSG (data);
651 helper = (GetMsgAsyncHelper *) user_data;
653 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
654 MODEST_WIDGET_TYPE_MSG_PREVIEW);
658 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
659 header_flags = tny_header_get_flags (header);
660 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
661 g_object_unref (G_OBJECT (header));
663 /* Set message on msg view */
664 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
668 * This function is a generic handler for the tny_folder_get_msg_async
669 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
670 * contains a user provided function that is called inside this
671 * method. This will allow us to use this callback in many different
672 * places. This callback performs the common actions for the
673 * get_msg_async call, more specific actions will be done by the user
677 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
679 GetMsgAsyncHelper *helper;
681 helper = (GetMsgAsyncHelper *) user_data;
683 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
684 modest_ui_actions_on_item_not_found (NULL,
685 MODEST_ITEM_TYPE_MESSAGE,
690 /* Call user function */
691 helper->func (msg, user_data);
693 /* Process next element (if exists) */
694 tny_iterator_next (helper->iter);
695 if (tny_iterator_is_done (helper->iter)) {
697 headers = tny_iterator_get_list (helper->iter);
699 g_object_unref (G_OBJECT (headers));
700 g_object_unref (G_OBJECT (helper->iter));
701 g_slice_free (GetMsgAsyncHelper, helper);
704 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
705 tny_folder_get_msg_async (folder, header,
707 g_object_unref (G_OBJECT(header));
712 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
714 ModestMainWindow *main_window)
716 GtkWidget *msg_preview;
718 GetMsgAsyncHelper *helper;
721 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
723 msg_preview = modest_main_window_get_child_widget(main_window,
724 MODEST_WIDGET_TYPE_MSG_PREVIEW);
728 /* when there's no header, clear the msgview */
730 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
734 folder = tny_header_get_folder (TNY_HEADER(header));
737 list = tny_simple_list_new ();
738 tny_list_prepend (list, G_OBJECT (header));
740 /* Fill helper data */
741 helper = g_slice_new0 (GetMsgAsyncHelper);
742 helper->window = MODEST_WINDOW (main_window);
743 helper->iter = tny_list_create_iterator (list);
744 helper->func = read_msg_func;
746 tny_folder_get_msg_async (TNY_FOLDER(folder),
751 g_object_unref (G_OBJECT (folder));
757 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
758 ModestMainWindow *main_window)
761 TnyFolder *folder = NULL;
763 gchar *account = NULL;
765 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
770 folder = tny_header_get_folder (header);
772 g_printerr ("modest: cannot get folder for header\n");
776 /* FIXME: make async?; check error */
777 msg = tny_folder_get_msg (folder, header, NULL);
779 g_printerr ("modest: cannot get msg for header\n");
783 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
785 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
787 win = modest_msg_view_window_new (msg, account);
788 gtk_window_set_transient_for (GTK_WINDOW (win),
789 GTK_WINDOW (main_window));
791 gtk_widget_show_all (GTK_WIDGET(win));
797 g_object_unref (G_OBJECT (folder));
799 g_object_unref (G_OBJECT (msg));
803 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
806 ModestMainWindow *main_window)
810 GtkWidget *header_view;
812 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
814 header_view = modest_main_window_get_child_widget(main_window,
815 MODEST_WIDGET_TYPE_HEADER_VIEW);
819 conf = modest_runtime_get_conf ();
821 if (!selected) { /* the folder was unselected; save it's settings */
822 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
823 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
824 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
825 } else { /* the folder was selected */
826 if (folder) { /* folder may be NULL */
830 num = tny_folder_get_all_count (folder);
831 unread = tny_folder_get_unread_count (folder);
833 title = g_strdup_printf ("Modest: %s",
834 tny_folder_get_name (folder));
836 gtk_window_set_title (GTK_WINDOW(main_window), title);
839 txt = g_strdup_printf (_("%d %s, %d unread"),
840 num, num==1 ? _("item") : _("items"), unread);
841 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
844 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
845 modest_widget_memory_restore (conf, G_OBJECT(header_view),
851 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
858 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
860 if (g_main_depth > 0)
861 gdk_threads_enter ();
862 online = tny_device_is_online (modest_runtime_get_device());
865 /* already online -- the item is simply not there... */
866 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
870 _("The %s you selected cannot be found"),
872 gtk_dialog_run (GTK_DIALOG(dialog));
874 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
882 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
883 "Do you want to get online?"), item);
884 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
885 gtk_label_new (txt), FALSE, FALSE, 0);
886 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
889 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
890 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
891 // tny_device_force_online (modest_runtime_get_device());
894 gtk_widget_destroy (dialog);
895 if (g_main_depth > 0)
896 gdk_threads_leave ();
900 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
903 g_message (__FUNCTION__);
908 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
911 g_message (__FUNCTION__);
915 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
918 g_message (__FUNCTION__);
923 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
924 const gchar *address,
927 g_message ("%s %s", __FUNCTION__, address);
931 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
933 TnyTransportAccount *transport_account;
934 ModestMailOperation *mail_operation;
936 gchar *account_name, *from;
937 ModestAccountMgr *account_mgr;
939 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
941 data = modest_msg_edit_window_get_msg_data (edit_window);
943 /* FIXME: Code added just for testing. The final version will
944 use the send queue provided by tinymail and some
946 account_mgr = modest_runtime_get_account_mgr();
947 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
949 account_name = modest_account_mgr_get_default_account (account_mgr);
951 g_printerr ("modest: no account found\n");
952 modest_msg_edit_window_free_msg_data (edit_window, data);
956 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
957 (modest_runtime_get_account_store(),
959 TNY_ACCOUNT_TYPE_TRANSPORT));
960 if (!transport_account) {
961 g_printerr ("modest: no transport account found for '%s'\n", account_name);
962 g_free (account_name);
963 modest_msg_edit_window_free_msg_data (edit_window, data);
966 from = modest_account_mgr_get_from_string (account_mgr, account_name);
968 /* Create the mail operation */
969 mail_operation = modest_mail_operation_new ();
970 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
972 modest_mail_operation_send_new_mail (mail_operation,
984 g_free (account_name);
985 g_object_unref (G_OBJECT (transport_account));
986 g_object_unref (G_OBJECT (mail_operation));
988 modest_msg_edit_window_free_msg_data (edit_window, data);
990 /* Save settings and close the window */
991 gtk_widget_destroy (GTK_WIDGET (edit_window));
995 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
996 ModestMsgEditWindow *window)
998 ModestMsgEditFormatState *format_state = NULL;
1000 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1001 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1003 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1006 format_state = modest_msg_edit_window_get_format_state (window);
1007 g_return_if_fail (format_state != NULL);
1009 format_state->bold = gtk_toggle_action_get_active (action);
1010 modest_msg_edit_window_set_format_state (window, format_state);
1011 g_free (format_state);
1016 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1017 ModestMsgEditWindow *window)
1019 ModestMsgEditFormatState *format_state = NULL;
1021 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1022 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1024 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1027 format_state = modest_msg_edit_window_get_format_state (window);
1028 g_return_if_fail (format_state != NULL);
1030 format_state->italics = gtk_toggle_action_get_active (action);
1031 modest_msg_edit_window_set_format_state (window, format_state);
1032 g_free (format_state);
1037 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1038 ModestMsgEditWindow *window)
1040 ModestMsgEditFormatState *format_state = NULL;
1042 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1043 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1045 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1048 format_state = modest_msg_edit_window_get_format_state (window);
1049 g_return_if_fail (format_state != NULL);
1051 format_state->bullet = gtk_toggle_action_get_active (action);
1052 modest_msg_edit_window_set_format_state (window, format_state);
1053 g_free (format_state);
1058 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1059 GtkRadioAction *selected,
1060 ModestMsgEditWindow *window)
1062 ModestMsgEditFormatState *format_state = NULL;
1063 GtkJustification value;
1065 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1067 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1070 value = gtk_radio_action_get_current_value (selected);
1072 format_state = modest_msg_edit_window_get_format_state (window);
1073 g_return_if_fail (format_state != NULL);
1075 format_state->justification = value;
1076 modest_msg_edit_window_set_format_state (window, format_state);
1077 g_free (format_state);
1081 modest_ui_actions_on_select_editor_color (GtkAction *action,
1082 ModestMsgEditWindow *window)
1084 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1085 g_return_if_fail (GTK_IS_ACTION (action));
1087 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1090 modest_msg_edit_window_select_color (window);
1094 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1095 ModestMsgEditWindow *window)
1097 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1098 g_return_if_fail (GTK_IS_ACTION (action));
1100 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1103 modest_msg_edit_window_select_background_color (window);
1107 modest_ui_actions_on_insert_image (GtkAction *action,
1108 ModestMsgEditWindow *window)
1110 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1111 g_return_if_fail (GTK_IS_ACTION (action));
1113 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1116 modest_msg_edit_window_insert_image (window);
1120 * Shows a dialog with an entry that asks for some text. The returned
1121 * value must be freed by the caller. The dialog window title will be
1125 ask_for_folder_name (GtkWindow *parent_window,
1128 GtkWidget *dialog, *entry;
1129 gchar *folder_name = NULL;
1131 /* Ask for folder name */
1132 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1136 GTK_RESPONSE_REJECT,
1138 GTK_RESPONSE_ACCEPT,
1140 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1141 gtk_label_new(title),
1144 entry = gtk_entry_new_with_max_length (40);
1145 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1149 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1151 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1152 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1154 gtk_widget_destroy (dialog);
1160 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1162 TnyFolder *parent_folder;
1163 GtkWidget *folder_view;
1165 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1167 folder_view = modest_main_window_get_child_widget (main_window,
1168 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1172 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1174 if (parent_folder) {
1177 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1178 _("Please enter a name for the new folder"));
1180 if (folder_name != NULL && strlen (folder_name) > 0) {
1181 TnyFolder *new_folder;
1182 ModestMailOperation *mail_op;
1184 mail_op = modest_mail_operation_new ();
1185 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1188 new_folder = modest_mail_operation_create_folder (mail_op,
1189 TNY_FOLDER_STORE (parent_folder),
1190 (const gchar *) folder_name);
1192 g_object_unref (new_folder);
1193 g_object_unref (mail_op);
1194 g_free (folder_name);
1196 g_object_unref (parent_folder);
1201 modest_ui_actions_on_rename_folder (GtkAction *action,
1202 ModestMainWindow *main_window)
1205 GtkWidget *folder_view;
1207 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1209 folder_view = modest_main_window_get_child_widget (main_window,
1210 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1214 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1218 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1219 _("Please enter a new name for the folder"));
1221 if (folder_name != NULL && strlen (folder_name) > 0) {
1222 ModestMailOperation *mail_op;
1224 mail_op = modest_mail_operation_new ();
1225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1228 modest_mail_operation_rename_folder (mail_op,
1230 (const gchar *) folder_name);
1232 g_object_unref (mail_op);
1233 g_free (folder_name);
1235 g_object_unref (folder);
1240 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1243 ModestMailOperation *mail_op;
1244 GtkWidget *folder_view;
1246 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1248 folder_view = modest_main_window_get_child_widget (main_window,
1249 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1253 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1255 mail_op = modest_mail_operation_new ();
1256 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1258 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1260 g_object_unref (G_OBJECT (mail_op));
1261 g_object_unref (G_OBJECT (folder));
1265 modest_ui_actions_on_delete_folder (GtkAction *action,
1266 ModestMainWindow *main_window)
1268 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1270 delete_folder (main_window, FALSE);
1274 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1276 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1278 delete_folder (main_window, TRUE);
1282 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1283 const gchar* account_name,
1287 ModestMainWindow *main_window)
1290 GtkWidget *dialog, *entry, *remember_pass_check;
1292 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1296 GTK_RESPONSE_REJECT,
1298 GTK_RESPONSE_ACCEPT,
1300 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1302 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1303 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1307 entry = gtk_entry_new_with_max_length (40);
1308 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1309 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1311 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1314 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1315 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1318 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1320 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1321 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1328 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1333 gtk_widget_destroy (dialog);
1337 modest_ui_actions_on_cut (GtkAction *action,
1338 ModestWindow *window)
1340 GtkWidget *focused_widget;
1342 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1343 if (GTK_IS_EDITABLE (focused_widget)) {
1344 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1345 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1346 GtkTextBuffer *buffer;
1347 GtkClipboard *clipboard;
1349 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1350 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1351 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1356 modest_ui_actions_on_copy (GtkAction *action,
1357 ModestWindow *window)
1359 GtkClipboard *clipboard;
1360 GtkWidget *focused_widget;
1362 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1363 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1364 if (GTK_IS_LABEL (focused_widget)) {
1365 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1366 } else if (GTK_IS_EDITABLE (focused_widget)) {
1367 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1368 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1369 GtkTextBuffer *buffer;
1371 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1372 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1377 modest_ui_actions_on_paste (GtkAction *action,
1378 ModestWindow *window)
1380 GtkWidget *focused_widget;
1382 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1383 if (GTK_IS_EDITABLE (focused_widget)) {
1384 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1385 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1386 GtkTextBuffer *buffer;
1387 GtkClipboard *clipboard;
1389 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1390 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1391 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1396 modest_ui_actions_on_select_all (GtkAction *action,
1397 ModestWindow *window)
1399 GtkWidget *focused_widget;
1401 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1402 if (GTK_IS_LABEL (focused_widget)) {
1403 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1404 } else if (GTK_IS_EDITABLE (focused_widget)) {
1405 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1406 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1407 GtkTextBuffer *buffer;
1408 GtkTextIter start, end;
1410 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1411 gtk_text_buffer_get_start_iter (buffer, &start);
1412 gtk_text_buffer_get_end_iter (buffer, &end);
1413 gtk_text_buffer_select_range (buffer, &start, &end);