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());
209 gboolean accounts_exist = account_names != NULL;
210 g_slist_free (account_names);
212 /* This is currently only implemented for Maemo,
213 * because it requires a providers preset file which is not publically available.
215 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
216 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
217 if (!accounts_exist) {
218 printf ("debug: modest_account_mgr_account_names() returned NULL.");
219 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
220 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
221 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
222 gtk_dialog_run (GTK_DIALOG (wizard));
223 gtk_widget_destroy (GTK_WIDGET (wizard));
227 /* Show the list of accounts: */
228 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
229 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
230 gtk_dialog_run (account_win);
231 gtk_widget_destroy (GTK_WIDGET(account_win));
234 GtkWidget *dialog, *label;
236 /* Create the widgets */
238 dialog = gtk_dialog_new_with_buttons ("Message",
240 GTK_DIALOG_DESTROY_WITH_PARENT,
244 label = gtk_label_new ("Hello World!");
246 /* Ensure that the dialog box is destroyed when the user responds. */
248 g_signal_connect_swapped (dialog, "response",
249 G_CALLBACK (gtk_widget_destroy),
252 /* Add the label, and show everything we've added to the dialog. */
254 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
256 gtk_widget_show_all (dialog);
257 #endif /* MODEST_PLATFORM_MAEMO */
261 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
263 ModestWindow *msg_win;
265 TnyFolder *folder = NULL;
266 gchar *account_name = NULL;
267 gchar *from_str = NULL;
271 account_name = g_strdup(modest_window_get_active_account (win));
273 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
275 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
277 TNY_ACCOUNT_TYPE_STORE);
279 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
283 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
285 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
287 g_printerr ("modest: failed to create new msg\n");
291 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
293 g_printerr ("modest: failed to find Drafts folder\n");
297 tny_folder_add_msg (folder, msg, &err);
299 g_printerr ("modest: error adding msg to Drafts folder: %s",
305 msg_win = modest_msg_edit_window_new (msg, account_name);
307 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
309 gtk_widget_show_all (GTK_WIDGET (msg_win));
312 g_free (account_name);
315 g_object_unref (G_OBJECT(account));
317 g_object_unref (G_OBJECT(msg));
319 g_object_unref (G_OBJECT(folder));
324 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
326 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
332 reply_forward_func (gpointer data, gpointer user_data)
334 TnyMsg *msg, *new_msg;
335 GetMsgAsyncHelper *helper;
336 ReplyForwardHelper *rf_helper;
337 ModestWindow *msg_win;
338 ModestEditType edit_type;
341 TnyFolder *folder = NULL;
342 TnyAccount *account = NULL;
344 msg = TNY_MSG (data);
345 helper = (GetMsgAsyncHelper *) user_data;
346 rf_helper = (ReplyForwardHelper *) helper->user_data;
348 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
349 rf_helper->account_name);
350 /* Create reply mail */
351 switch (rf_helper->action) {
354 modest_tny_msg_create_reply_msg (msg, from,
355 rf_helper->reply_forward_type,
356 MODEST_TNY_MSG_REPLY_MODE_SENDER);
358 case ACTION_REPLY_TO_ALL:
360 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
361 MODEST_TNY_MSG_REPLY_MODE_ALL);
362 edit_type = MODEST_EDIT_TYPE_REPLY;
366 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
367 edit_type = MODEST_EDIT_TYPE_FORWARD;
370 g_return_if_reached ();
375 g_printerr ("modest: failed to create message\n");
379 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
380 rf_helper->account_name,
381 TNY_ACCOUNT_TYPE_STORE);
383 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
387 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
389 g_printerr ("modest: failed to find Drafts folder\n");
393 tny_folder_add_msg (folder, msg, &err);
395 g_printerr ("modest: error adding msg to Drafts folder: %s",
401 /* Show edit window */
402 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
403 gtk_widget_show_all (GTK_WIDGET (msg_win));
407 g_object_unref (G_OBJECT (new_msg));
409 g_object_unref (G_OBJECT (folder));
411 g_object_unref (G_OBJECT (account));
413 g_free (rf_helper->account_name);
414 g_slice_free (ReplyForwardHelper, rf_helper);
417 * Common code for the reply and forward actions
420 reply_forward (ReplyForwardAction action, ModestWindow *win)
422 TnyList *header_list;
423 guint reply_forward_type;
426 GetMsgAsyncHelper *helper;
427 ReplyForwardHelper *rf_helper;
429 g_return_if_fail (MODEST_IS_WINDOW(win));
431 header_list = get_selected_headers (win);
435 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
436 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
438 /* We assume that we can only select messages of the
439 same folder and that we reply all of them from the
440 same account. In fact the interface currently only
441 allows single selection */
444 rf_helper = g_slice_new0 (ReplyForwardHelper);
445 rf_helper->reply_forward_type = reply_forward_type;
446 rf_helper->action = action;
448 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
449 if (!rf_helper->account_name)
450 rf_helper->account_name =
451 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
453 helper = g_slice_new0 (GetMsgAsyncHelper);
454 helper->window = win;
455 helper->func = reply_forward_func;
456 helper->iter = tny_list_create_iterator (header_list);
457 helper->user_data = rf_helper;
459 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
461 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
463 g_printerr ("modest: no message found\n");
466 reply_forward_func (msg, helper);
468 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
469 folder = tny_header_get_folder (header);
471 /* The callback will call it per each header */
472 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
473 g_object_unref (G_OBJECT (folder));
475 g_printerr ("modest: no folder for header\n");
478 g_object_unref (G_OBJECT (header));
484 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
486 g_return_if_fail (MODEST_IS_WINDOW(win));
488 reply_forward (ACTION_REPLY, win);
492 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
494 g_return_if_fail (MODEST_IS_WINDOW(win));
496 reply_forward (ACTION_FORWARD, win);
500 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
502 g_return_if_fail (MODEST_IS_WINDOW(win));
504 reply_forward (ACTION_REPLY_TO_ALL, win);
508 modest_ui_actions_on_next (GtkAction *action,
509 ModestMainWindow *main_window)
511 GtkWidget *header_view;
512 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
514 header_view = modest_main_window_get_child_widget (main_window,
515 MODEST_WIDGET_TYPE_HEADER_VIEW);
519 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
523 modest_ui_actions_on_prev (GtkAction *action,
524 ModestMainWindow *main_window)
526 GtkWidget *header_view;
527 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
529 header_view = modest_main_window_get_child_widget (main_window,
530 MODEST_WIDGET_TYPE_HEADER_VIEW);
534 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
539 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
542 TnyAccount *tny_account;
543 ModestTnySendQueue *send_queue;
544 ModestMailOperation *mail_op;
547 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
549 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
551 g_printerr ("modest: cannot get account\n");
556 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
558 TNY_ACCOUNT_TYPE_TRANSPORT);
560 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
563 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
565 g_object_unref (G_OBJECT(tny_account));
566 g_printerr ("modest: cannot get send queue for %s\n", account_name);
569 //modest_tny_send_queue_flush (send_queue);
571 g_object_unref (G_OBJECT(send_queue));
572 g_object_unref (G_OBJECT(tny_account));
575 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
577 TNY_ACCOUNT_TYPE_STORE);
579 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
583 /* Create the mail operation */
584 mail_op = modest_mail_operation_new ();
585 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
586 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
589 g_object_unref (G_OBJECT (tny_account));
590 g_object_unref (G_OBJECT (mail_op));
596 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
599 GtkWidget *header_view;
601 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
603 header_view = modest_main_window_get_child_widget (main_window,
604 MODEST_WIDGET_TYPE_HEADER_VIEW);
608 conf = modest_runtime_get_conf ();
610 /* what is saved/restored is depending on the style; thus; we save with
611 * old style, then update the style, and restore for this new style
613 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
615 if (modest_header_view_get_style
616 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
617 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
618 MODEST_HEADER_VIEW_STYLE_TWOLINES);
620 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
621 MODEST_HEADER_VIEW_STYLE_DETAILS);
623 modest_widget_memory_restore (conf, G_OBJECT(header_view),
630 * Marks a message as read and passes it to the msg preview widget
633 read_msg_func (gpointer data, gpointer user_data)
637 GetMsgAsyncHelper *helper;
638 TnyHeaderFlags header_flags;
639 GtkWidget *msg_preview;
641 msg = TNY_MSG (data);
642 helper = (GetMsgAsyncHelper *) user_data;
644 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
645 MODEST_WIDGET_TYPE_MSG_PREVIEW);
649 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
650 header_flags = tny_header_get_flags (header);
651 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
652 g_object_unref (G_OBJECT (header));
654 /* Set message on msg view */
655 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
659 * This function is a generic handler for the tny_folder_get_msg_async
660 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
661 * contains a user provided function that is called inside this
662 * method. This will allow us to use this callback in many different
663 * places. This callback performs the common actions for the
664 * get_msg_async call, more specific actions will be done by the user
668 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
670 GetMsgAsyncHelper *helper;
672 helper = (GetMsgAsyncHelper *) user_data;
674 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
675 modest_ui_actions_on_item_not_found (NULL,
676 MODEST_ITEM_TYPE_MESSAGE,
681 /* Call user function */
682 helper->func (msg, user_data);
684 /* Process next element (if exists) */
685 tny_iterator_next (helper->iter);
686 if (tny_iterator_is_done (helper->iter)) {
688 headers = tny_iterator_get_list (helper->iter);
690 g_object_unref (G_OBJECT (headers));
691 g_object_unref (G_OBJECT (helper->iter));
692 g_slice_free (GetMsgAsyncHelper, helper);
695 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
696 tny_folder_get_msg_async (folder, header,
698 g_object_unref (G_OBJECT(header));
703 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
705 ModestMainWindow *main_window)
707 GtkWidget *msg_preview;
709 GetMsgAsyncHelper *helper;
712 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
714 msg_preview = modest_main_window_get_child_widget(main_window,
715 MODEST_WIDGET_TYPE_MSG_PREVIEW);
719 /* when there's no header, clear the msgview */
721 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
725 folder = tny_header_get_folder (TNY_HEADER(header));
728 list = tny_simple_list_new ();
729 tny_list_prepend (list, G_OBJECT (header));
731 /* Fill helper data */
732 helper = g_slice_new0 (GetMsgAsyncHelper);
733 helper->window = MODEST_WINDOW (main_window);
734 helper->iter = tny_list_create_iterator (list);
735 helper->func = read_msg_func;
737 tny_folder_get_msg_async (TNY_FOLDER(folder),
742 g_object_unref (G_OBJECT (folder));
748 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
749 ModestMainWindow *main_window)
752 TnyFolder *folder = NULL;
754 gchar *account = NULL;
756 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
761 folder = tny_header_get_folder (header);
763 g_printerr ("modest: cannot get folder for header\n");
767 /* FIXME: make async?; check error */
768 msg = tny_folder_get_msg (folder, header, NULL);
770 g_printerr ("modest: cannot get msg for header\n");
774 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
776 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
778 win = modest_msg_view_window_new (msg, account);
779 gtk_window_set_transient_for (GTK_WINDOW (win),
780 GTK_WINDOW (main_window));
782 gtk_widget_show_all (GTK_WIDGET(win));
788 g_object_unref (G_OBJECT (folder));
790 g_object_unref (G_OBJECT (msg));
794 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
797 ModestMainWindow *main_window)
801 GtkWidget *header_view;
803 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
805 header_view = modest_main_window_get_child_widget(main_window,
806 MODEST_WIDGET_TYPE_HEADER_VIEW);
810 conf = modest_runtime_get_conf ();
812 if (!selected) { /* the folder was unselected; save it's settings */
813 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
814 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
815 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
816 } else { /* the folder was selected */
817 if (folder) { /* folder may be NULL */
821 num = tny_folder_get_all_count (folder);
822 unread = tny_folder_get_unread_count (folder);
824 title = g_strdup_printf ("Modest: %s",
825 tny_folder_get_name (folder));
827 gtk_window_set_title (GTK_WINDOW(main_window), title);
830 txt = g_strdup_printf (_("%d %s, %d unread"),
831 num, num==1 ? _("item") : _("items"), unread);
832 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
835 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
836 modest_widget_memory_restore (conf, G_OBJECT(header_view),
842 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
849 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
851 if (g_main_depth > 0)
852 gdk_threads_enter ();
853 online = tny_device_is_online (modest_runtime_get_device());
856 /* already online -- the item is simply not there... */
857 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
861 _("The %s you selected cannot be found"),
863 gtk_dialog_run (GTK_DIALOG(dialog));
865 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
873 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
874 "Do you want to get online?"), item);
875 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
876 gtk_label_new (txt), FALSE, FALSE, 0);
877 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
880 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
881 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
882 // tny_device_force_online (modest_runtime_get_device());
885 gtk_widget_destroy (dialog);
886 if (g_main_depth > 0)
887 gdk_threads_leave ();
891 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
894 g_message (__FUNCTION__);
899 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
902 g_message (__FUNCTION__);
906 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
909 g_message (__FUNCTION__);
914 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
915 const gchar *address,
918 g_message ("%s %s", __FUNCTION__, address);
922 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
924 TnyTransportAccount *transport_account;
925 ModestMailOperation *mail_operation;
927 gchar *account_name, *from;
928 ModestAccountMgr *account_mgr;
930 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
932 data = modest_msg_edit_window_get_msg_data (edit_window);
934 /* FIXME: Code added just for testing. The final version will
935 use the send queue provided by tinymail and some
937 account_mgr = modest_runtime_get_account_mgr();
938 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
940 account_name = modest_account_mgr_get_default_account (account_mgr);
942 g_printerr ("modest: no account found\n");
943 modest_msg_edit_window_free_msg_data (edit_window, data);
947 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
948 (modest_runtime_get_account_store(),
950 TNY_ACCOUNT_TYPE_TRANSPORT));
951 if (!transport_account) {
952 g_printerr ("modest: no transport account found for '%s'\n", account_name);
953 g_free (account_name);
954 modest_msg_edit_window_free_msg_data (edit_window, data);
957 from = modest_account_mgr_get_from_string (account_mgr, account_name);
959 /* Create the mail operation */
960 mail_operation = modest_mail_operation_new ();
961 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
963 modest_mail_operation_send_new_mail (mail_operation,
975 g_free (account_name);
976 g_object_unref (G_OBJECT (transport_account));
977 g_object_unref (G_OBJECT (mail_operation));
979 modest_msg_edit_window_free_msg_data (edit_window, data);
981 /* Save settings and close the window */
982 gtk_widget_destroy (GTK_WIDGET (edit_window));
986 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
987 ModestMsgEditWindow *window)
989 ModestMsgEditFormatState *format_state = NULL;
991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
992 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
994 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
997 format_state = modest_msg_edit_window_get_format_state (window);
998 g_return_if_fail (format_state != NULL);
1000 format_state->bold = gtk_toggle_action_get_active (action);
1001 modest_msg_edit_window_set_format_state (window, format_state);
1002 g_free (format_state);
1007 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1008 ModestMsgEditWindow *window)
1010 ModestMsgEditFormatState *format_state = NULL;
1012 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1013 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1015 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1018 format_state = modest_msg_edit_window_get_format_state (window);
1019 g_return_if_fail (format_state != NULL);
1021 format_state->italics = gtk_toggle_action_get_active (action);
1022 modest_msg_edit_window_set_format_state (window, format_state);
1023 g_free (format_state);
1028 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1029 ModestMsgEditWindow *window)
1031 ModestMsgEditFormatState *format_state = NULL;
1033 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1034 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1036 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1039 format_state = modest_msg_edit_window_get_format_state (window);
1040 g_return_if_fail (format_state != NULL);
1042 format_state->bullet = gtk_toggle_action_get_active (action);
1043 modest_msg_edit_window_set_format_state (window, format_state);
1044 g_free (format_state);
1049 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1050 GtkRadioAction *selected,
1051 ModestMsgEditWindow *window)
1053 ModestMsgEditFormatState *format_state = NULL;
1054 GtkJustification value;
1056 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1058 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1061 value = gtk_radio_action_get_current_value (selected);
1063 format_state = modest_msg_edit_window_get_format_state (window);
1064 g_return_if_fail (format_state != NULL);
1066 format_state->justification = value;
1067 modest_msg_edit_window_set_format_state (window, format_state);
1068 g_free (format_state);
1072 modest_ui_actions_on_select_editor_color (GtkAction *action,
1073 ModestMsgEditWindow *window)
1075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1076 g_return_if_fail (GTK_IS_ACTION (action));
1078 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1081 modest_msg_edit_window_select_color (window);
1085 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1086 ModestMsgEditWindow *window)
1088 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1089 g_return_if_fail (GTK_IS_ACTION (action));
1091 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1094 modest_msg_edit_window_select_background_color (window);
1098 modest_ui_actions_on_insert_image (GtkAction *action,
1099 ModestMsgEditWindow *window)
1101 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1102 g_return_if_fail (GTK_IS_ACTION (action));
1104 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1107 modest_msg_edit_window_insert_image (window);
1111 * Shows a dialog with an entry that asks for some text. The returned
1112 * value must be freed by the caller. The dialog window title will be
1116 ask_for_folder_name (GtkWindow *parent_window,
1119 GtkWidget *dialog, *entry;
1120 gchar *folder_name = NULL;
1122 /* Ask for folder name */
1123 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1127 GTK_RESPONSE_REJECT,
1129 GTK_RESPONSE_ACCEPT,
1131 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1132 gtk_label_new(title),
1135 entry = gtk_entry_new_with_max_length (40);
1136 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1140 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1142 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1143 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1145 gtk_widget_destroy (dialog);
1151 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1153 TnyFolder *parent_folder;
1154 GtkWidget *folder_view;
1156 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1158 folder_view = modest_main_window_get_child_widget (main_window,
1159 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1163 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1165 if (parent_folder) {
1168 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1169 _("Please enter a name for the new folder"));
1171 if (folder_name != NULL && strlen (folder_name) > 0) {
1172 TnyFolder *new_folder;
1173 ModestMailOperation *mail_op;
1175 mail_op = modest_mail_operation_new ();
1176 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1179 new_folder = modest_mail_operation_create_folder (mail_op,
1180 TNY_FOLDER_STORE (parent_folder),
1181 (const gchar *) folder_name);
1183 g_object_unref (new_folder);
1184 g_object_unref (mail_op);
1185 g_free (folder_name);
1187 g_object_unref (parent_folder);
1192 modest_ui_actions_on_rename_folder (GtkAction *action,
1193 ModestMainWindow *main_window)
1196 GtkWidget *folder_view;
1198 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1200 folder_view = modest_main_window_get_child_widget (main_window,
1201 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1205 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1209 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1210 _("Please enter a new name for the folder"));
1212 if (folder_name != NULL && strlen (folder_name) > 0) {
1213 ModestMailOperation *mail_op;
1215 mail_op = modest_mail_operation_new ();
1216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1219 modest_mail_operation_rename_folder (mail_op,
1221 (const gchar *) folder_name);
1223 g_object_unref (mail_op);
1224 g_free (folder_name);
1226 g_object_unref (folder);
1231 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1234 ModestMailOperation *mail_op;
1235 GtkWidget *folder_view;
1237 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1239 folder_view = modest_main_window_get_child_widget (main_window,
1240 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1244 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1246 mail_op = modest_mail_operation_new ();
1247 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1249 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1251 g_object_unref (G_OBJECT (mail_op));
1252 g_object_unref (G_OBJECT (folder));
1256 modest_ui_actions_on_delete_folder (GtkAction *action,
1257 ModestMainWindow *main_window)
1259 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1261 delete_folder (main_window, FALSE);
1265 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1267 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1269 delete_folder (main_window, TRUE);
1273 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1274 const gchar* account_name,
1278 ModestMainWindow *main_window)
1281 GtkWidget *dialog, *entry, *remember_pass_check;
1283 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1287 GTK_RESPONSE_REJECT,
1289 GTK_RESPONSE_ACCEPT,
1291 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1293 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1294 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1298 entry = gtk_entry_new_with_max_length (40);
1299 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1300 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1302 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1305 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1306 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1309 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1311 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1312 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1319 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1324 gtk_widget_destroy (dialog);
1328 modest_ui_actions_on_cut (GtkAction *action,
1329 ModestWindow *window)
1331 GtkWidget *focused_widget;
1333 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1334 if (GTK_IS_EDITABLE (focused_widget)) {
1335 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1336 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1337 GtkTextBuffer *buffer;
1338 GtkClipboard *clipboard;
1340 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1341 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1342 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1347 modest_ui_actions_on_copy (GtkAction *action,
1348 ModestWindow *window)
1350 GtkClipboard *clipboard;
1351 GtkWidget *focused_widget;
1353 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1354 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1355 if (GTK_IS_LABEL (focused_widget)) {
1356 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1357 } else if (GTK_IS_EDITABLE (focused_widget)) {
1358 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1359 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1360 GtkTextBuffer *buffer;
1362 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1363 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1368 modest_ui_actions_on_paste (GtkAction *action,
1369 ModestWindow *window)
1371 GtkWidget *focused_widget;
1373 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1374 if (GTK_IS_EDITABLE (focused_widget)) {
1375 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1376 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1377 GtkTextBuffer *buffer;
1378 GtkClipboard *clipboard;
1380 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1381 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1382 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1387 modest_ui_actions_on_select_all (GtkAction *action,
1388 ModestWindow *window)
1390 GtkWidget *focused_widget;
1392 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1393 if (GTK_IS_LABEL (focused_widget)) {
1394 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1395 } else if (GTK_IS_EDITABLE (focused_widget)) {
1396 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1397 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1398 GtkTextBuffer *buffer;
1399 GtkTextIter start, end;
1401 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1402 gtk_text_buffer_get_start_iter (buffer, &start);
1403 gtk_text_buffer_get_end_iter (buffer, &end);
1404 gtk_text_buffer_select_range (buffer, &start, &end);