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"
52 #ifdef MODEST_HAVE_EASYSETUP
53 #include "easysetup/modest-easysetup-wizard.h"
54 #endif /*MODEST_HAVE_EASYSETUP*/
56 #include <modest-widget-memory.h>
57 #include <tny-error.h>
58 #include <tny-simple-list.h>
59 #include <tny-msg-view.h>
60 #include <tny-device.h>
63 typedef struct _GetMsgAsyncHelper {
70 typedef enum _ReplyForwardAction {
76 typedef struct _ReplyForwardHelper {
77 guint reply_forward_type;
78 ReplyForwardAction action;
83 static void reply_forward_func (gpointer data, gpointer user_data);
84 static void read_msg_func (gpointer data, gpointer user_data);
85 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
87 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
88 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
92 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
95 const gchar *authors[] = {
96 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
99 about = gtk_about_dialog_new ();
100 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
101 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
102 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
103 _("Copyright (c) 2006, Nokia Corporation\n"
104 "All rights reserved."));
105 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
106 _("a modest e-mail client\n\n"
107 "design and implementation: Dirk-Jan C. Binnema\n"
108 "contributions from the fine people at KernelConcepts and Igalia\n"
109 "uses the tinymail email framework written by Philip van Hoof"));
110 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
111 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
113 gtk_dialog_run (GTK_DIALOG (about));
114 gtk_widget_destroy(about);
119 get_selected_headers (ModestWindow *win)
121 if (MODEST_IS_MAIN_WINDOW(win)) {
122 GtkWidget *header_view;
124 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
125 MODEST_WIDGET_TYPE_HEADER_VIEW);
126 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
128 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
129 /* for MsgViewWindows, we simply return a list with one element */
132 TnyList *list = NULL;
134 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
136 header = tny_msg_get_header (msg);
137 list = tny_simple_list_new ();
138 tny_list_prepend (list, G_OBJECT(header));
139 g_object_unref (G_OBJECT(header));
148 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
150 TnyList *header_list;
153 g_return_if_fail (MODEST_IS_WINDOW(win));
155 header_list = get_selected_headers (win);
158 iter = tny_list_create_iterator (header_list);
161 ModestMailOperation *mail_op;
163 header = TNY_HEADER (tny_iterator_get_current (iter));
164 /* TODO: thick grain mail operation involving
165 a list of objects. Composite pattern ??? */
166 /* TODO: add confirmation dialog */
167 mail_op = modest_mail_operation_new ();
168 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
171 /* Always delete. TODO: Move to trash still not supported */
172 modest_mail_operation_remove_msg (mail_op, header, FALSE);
175 g_object_unref (G_OBJECT (mail_op));
176 g_object_unref (G_OBJECT (header));
178 tny_iterator_next (iter);
180 } while (!tny_iterator_is_done (iter));
183 g_object_unref (G_OBJECT (iter));
189 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
191 /* FIXME: save size of main window */
192 /* save_sizes (main_window); */
193 gtk_widget_destroy (GTK_WIDGET (win));
197 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
199 GtkClipboard *clipboard = NULL;
200 gchar *selection = NULL;
202 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
203 selection = gtk_clipboard_wait_for_text (clipboard);
205 modest_address_book_add_address (selection);
210 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
212 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
214 gboolean accounts_exist = account_names != NULL;
215 g_slist_free (account_names);
217 /* This is currently only implemented for Maemo,
218 * because it requires a providers preset file which is not publically available.
220 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
221 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
222 if (!accounts_exist) {
223 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
224 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
225 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
226 gtk_dialog_run (GTK_DIALOG (wizard));
227 gtk_widget_destroy (GTK_WIDGET (wizard));
231 /* Show the list of accounts: */
232 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
233 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
234 gtk_dialog_run (account_win);
235 gtk_widget_destroy (GTK_WIDGET(account_win));
238 GtkWidget *dialog, *label;
240 /* Create the widgets */
242 dialog = gtk_dialog_new_with_buttons ("Message",
244 GTK_DIALOG_DESTROY_WITH_PARENT,
248 label = gtk_label_new ("Hello World!");
250 /* Ensure that the dialog box is destroyed when the user responds. */
252 g_signal_connect_swapped (dialog, "response",
253 G_CALLBACK (gtk_widget_destroy),
256 /* Add the label, and show everything we've added to the dialog. */
258 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
260 gtk_widget_show_all (dialog);
261 #endif /* MODEST_PLATFORM_MAEMO */
265 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
267 ModestWindow *msg_win;
269 TnyFolder *folder = NULL;
270 gchar *account_name = NULL;
271 gchar *from_str = NULL;
275 account_name = g_strdup(modest_window_get_active_account (win));
277 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
279 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
281 TNY_ACCOUNT_TYPE_STORE);
283 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
287 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
289 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
291 g_printerr ("modest: failed to create new msg\n");
295 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
297 g_printerr ("modest: failed to find Drafts folder\n");
301 tny_folder_add_msg (folder, msg, &err);
303 g_printerr ("modest: error adding msg to Drafts folder: %s",
309 msg_win = modest_msg_edit_window_new (msg, account_name);
311 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
313 gtk_widget_show_all (GTK_WIDGET (msg_win));
316 g_free (account_name);
319 g_object_unref (G_OBJECT(account));
321 g_object_unref (G_OBJECT(msg));
323 g_object_unref (G_OBJECT(folder));
328 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
330 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
336 reply_forward_func (gpointer data, gpointer user_data)
338 TnyMsg *msg, *new_msg;
339 GetMsgAsyncHelper *helper;
340 ReplyForwardHelper *rf_helper;
341 ModestWindow *msg_win;
342 ModestEditType edit_type;
345 TnyFolder *folder = NULL;
346 TnyAccount *account = NULL;
348 msg = TNY_MSG (data);
349 helper = (GetMsgAsyncHelper *) user_data;
350 rf_helper = (ReplyForwardHelper *) helper->user_data;
352 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
353 rf_helper->account_name);
354 /* Create reply mail */
355 switch (rf_helper->action) {
358 modest_tny_msg_create_reply_msg (msg, from,
359 rf_helper->reply_forward_type,
360 MODEST_TNY_MSG_REPLY_MODE_SENDER);
362 case ACTION_REPLY_TO_ALL:
364 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
365 MODEST_TNY_MSG_REPLY_MODE_ALL);
366 edit_type = MODEST_EDIT_TYPE_REPLY;
370 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
371 edit_type = MODEST_EDIT_TYPE_FORWARD;
374 g_return_if_reached ();
379 g_printerr ("modest: failed to create message\n");
383 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
384 rf_helper->account_name,
385 TNY_ACCOUNT_TYPE_STORE);
387 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
391 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
393 g_printerr ("modest: failed to find Drafts folder\n");
397 tny_folder_add_msg (folder, msg, &err);
399 g_printerr ("modest: error adding msg to Drafts folder: %s",
405 /* Show edit window */
406 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
407 gtk_widget_show_all (GTK_WIDGET (msg_win));
411 g_object_unref (G_OBJECT (new_msg));
413 g_object_unref (G_OBJECT (folder));
415 g_object_unref (G_OBJECT (account));
417 g_free (rf_helper->account_name);
418 g_slice_free (ReplyForwardHelper, rf_helper);
421 * Common code for the reply and forward actions
424 reply_forward (ReplyForwardAction action, ModestWindow *win)
426 TnyList *header_list;
427 guint reply_forward_type;
430 GetMsgAsyncHelper *helper;
431 ReplyForwardHelper *rf_helper;
433 g_return_if_fail (MODEST_IS_WINDOW(win));
435 header_list = get_selected_headers (win);
439 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
440 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
442 /* We assume that we can only select messages of the
443 same folder and that we reply all of them from the
444 same account. In fact the interface currently only
445 allows single selection */
448 rf_helper = g_slice_new0 (ReplyForwardHelper);
449 rf_helper->reply_forward_type = reply_forward_type;
450 rf_helper->action = action;
452 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
453 if (!rf_helper->account_name)
454 rf_helper->account_name =
455 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
457 helper = g_slice_new0 (GetMsgAsyncHelper);
458 helper->window = win;
459 helper->func = reply_forward_func;
460 helper->iter = tny_list_create_iterator (header_list);
461 helper->user_data = rf_helper;
463 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
465 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
467 g_printerr ("modest: no message found\n");
470 reply_forward_func (msg, helper);
472 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
473 folder = tny_header_get_folder (header);
475 /* The callback will call it per each header */
476 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
477 g_object_unref (G_OBJECT (folder));
479 g_printerr ("modest: no folder for header\n");
482 g_object_unref (G_OBJECT (header));
488 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
490 g_return_if_fail (MODEST_IS_WINDOW(win));
492 reply_forward (ACTION_REPLY, win);
496 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
498 g_return_if_fail (MODEST_IS_WINDOW(win));
500 reply_forward (ACTION_FORWARD, win);
504 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
506 g_return_if_fail (MODEST_IS_WINDOW(win));
508 reply_forward (ACTION_REPLY_TO_ALL, win);
512 modest_ui_actions_on_next (GtkAction *action,
513 ModestMainWindow *main_window)
515 GtkWidget *header_view;
516 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
518 header_view = modest_main_window_get_child_widget (main_window,
519 MODEST_WIDGET_TYPE_HEADER_VIEW);
523 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
527 modest_ui_actions_on_prev (GtkAction *action,
528 ModestMainWindow *main_window)
530 GtkWidget *header_view;
531 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
533 header_view = modest_main_window_get_child_widget (main_window,
534 MODEST_WIDGET_TYPE_HEADER_VIEW);
538 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
543 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
546 TnyAccount *tny_account;
547 ModestTnySendQueue *send_queue;
548 ModestMailOperation *mail_op;
551 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
553 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
555 g_printerr ("modest: cannot get account\n");
560 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
562 TNY_ACCOUNT_TYPE_TRANSPORT);
564 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
567 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
569 g_object_unref (G_OBJECT(tny_account));
570 g_printerr ("modest: cannot get send queue for %s\n", account_name);
573 //modest_tny_send_queue_flush (send_queue);
575 g_object_unref (G_OBJECT(send_queue));
576 g_object_unref (G_OBJECT(tny_account));
579 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
581 TNY_ACCOUNT_TYPE_STORE);
583 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
587 /* Create the mail operation */
588 mail_op = modest_mail_operation_new ();
589 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
590 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
593 g_object_unref (G_OBJECT (tny_account));
594 g_object_unref (G_OBJECT (mail_op));
600 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
603 GtkWidget *header_view;
605 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
607 header_view = modest_main_window_get_child_widget (main_window,
608 MODEST_WIDGET_TYPE_HEADER_VIEW);
612 conf = modest_runtime_get_conf ();
614 /* what is saved/restored is depending on the style; thus; we save with
615 * old style, then update the style, and restore for this new style
617 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
619 if (modest_header_view_get_style
620 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
621 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
622 MODEST_HEADER_VIEW_STYLE_TWOLINES);
624 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
625 MODEST_HEADER_VIEW_STYLE_DETAILS);
627 modest_widget_memory_restore (conf, G_OBJECT(header_view),
634 * Marks a message as read and passes it to the msg preview widget
637 read_msg_func (gpointer data, gpointer user_data)
641 GetMsgAsyncHelper *helper;
642 TnyHeaderFlags header_flags;
643 GtkWidget *msg_preview;
645 msg = TNY_MSG (data);
646 helper = (GetMsgAsyncHelper *) user_data;
648 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
649 MODEST_WIDGET_TYPE_MSG_PREVIEW);
653 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
654 header_flags = tny_header_get_flags (header);
655 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
656 g_object_unref (G_OBJECT (header));
658 /* Set message on msg view */
659 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
663 * This function is a generic handler for the tny_folder_get_msg_async
664 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
665 * contains a user provided function that is called inside this
666 * method. This will allow us to use this callback in many different
667 * places. This callback performs the common actions for the
668 * get_msg_async call, more specific actions will be done by the user
672 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
674 GetMsgAsyncHelper *helper;
676 helper = (GetMsgAsyncHelper *) user_data;
678 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
679 modest_ui_actions_on_item_not_found (NULL,
680 MODEST_ITEM_TYPE_MESSAGE,
685 /* Call user function */
686 helper->func (msg, user_data);
688 /* Process next element (if exists) */
689 tny_iterator_next (helper->iter);
690 if (tny_iterator_is_done (helper->iter)) {
692 headers = tny_iterator_get_list (helper->iter);
694 g_object_unref (G_OBJECT (headers));
695 g_object_unref (G_OBJECT (helper->iter));
696 g_slice_free (GetMsgAsyncHelper, helper);
699 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
700 tny_folder_get_msg_async (folder, header,
702 g_object_unref (G_OBJECT(header));
707 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
709 ModestMainWindow *main_window)
711 GtkWidget *msg_preview;
713 GetMsgAsyncHelper *helper;
716 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
718 msg_preview = modest_main_window_get_child_widget(main_window,
719 MODEST_WIDGET_TYPE_MSG_PREVIEW);
723 /* when there's no header, clear the msgview */
725 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
729 folder = tny_header_get_folder (TNY_HEADER(header));
732 list = tny_simple_list_new ();
733 tny_list_prepend (list, G_OBJECT (header));
735 /* Fill helper data */
736 helper = g_slice_new0 (GetMsgAsyncHelper);
737 helper->window = MODEST_WINDOW (main_window);
738 helper->iter = tny_list_create_iterator (list);
739 helper->func = read_msg_func;
741 tny_folder_get_msg_async (TNY_FOLDER(folder),
746 g_object_unref (G_OBJECT (folder));
752 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
753 ModestMainWindow *main_window)
756 TnyFolder *folder = NULL;
758 gchar *account = NULL;
760 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
765 folder = tny_header_get_folder (header);
767 g_printerr ("modest: cannot get folder for header\n");
771 /* FIXME: make async?; check error */
772 msg = tny_folder_get_msg (folder, header, NULL);
774 g_printerr ("modest: cannot get msg for header\n");
778 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
780 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
782 win = modest_msg_view_window_new (msg, account);
783 gtk_window_set_transient_for (GTK_WINDOW (win),
784 GTK_WINDOW (main_window));
786 gtk_widget_show_all (GTK_WIDGET(win));
792 g_object_unref (G_OBJECT (folder));
794 g_object_unref (G_OBJECT (msg));
798 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
801 ModestMainWindow *main_window)
805 GtkWidget *header_view;
807 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
809 header_view = modest_main_window_get_child_widget(main_window,
810 MODEST_WIDGET_TYPE_HEADER_VIEW);
814 conf = modest_runtime_get_conf ();
816 if (!selected) { /* the folder was unselected; save it's settings */
817 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
818 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
819 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
820 } else { /* the folder was selected */
821 if (folder) { /* folder may be NULL */
825 num = tny_folder_get_all_count (folder);
826 unread = tny_folder_get_unread_count (folder);
828 title = g_strdup_printf ("Modest: %s",
829 tny_folder_get_name (folder));
831 gtk_window_set_title (GTK_WINDOW(main_window), title);
834 txt = g_strdup_printf (_("%d %s, %d unread"),
835 num, num==1 ? _("item") : _("items"), unread);
836 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
839 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
840 modest_widget_memory_restore (conf, G_OBJECT(header_view),
846 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
853 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
855 if (g_main_depth > 0)
856 gdk_threads_enter ();
857 online = tny_device_is_online (modest_runtime_get_device());
860 /* already online -- the item is simply not there... */
861 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
865 _("The %s you selected cannot be found"),
867 gtk_dialog_run (GTK_DIALOG(dialog));
869 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
877 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
878 "Do you want to get online?"), item);
879 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
880 gtk_label_new (txt), FALSE, FALSE, 0);
881 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
884 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
885 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
886 // tny_device_force_online (modest_runtime_get_device());
889 gtk_widget_destroy (dialog);
890 if (g_main_depth > 0)
891 gdk_threads_leave ();
895 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
898 g_message (__FUNCTION__);
903 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
906 g_message (__FUNCTION__);
910 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
913 g_message (__FUNCTION__);
918 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
919 const gchar *address,
922 g_message ("%s %s", __FUNCTION__, address);
926 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
928 TnyTransportAccount *transport_account;
929 ModestMailOperation *mail_operation;
931 gchar *account_name, *from;
932 ModestAccountMgr *account_mgr;
934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
936 data = modest_msg_edit_window_get_msg_data (edit_window);
938 /* FIXME: Code added just for testing. The final version will
939 use the send queue provided by tinymail and some
941 account_mgr = modest_runtime_get_account_mgr();
942 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
944 account_name = modest_account_mgr_get_default_account (account_mgr);
946 g_printerr ("modest: no account found\n");
947 modest_msg_edit_window_free_msg_data (edit_window, data);
951 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
952 (modest_runtime_get_account_store(),
954 TNY_ACCOUNT_TYPE_TRANSPORT));
955 if (!transport_account) {
956 g_printerr ("modest: no transport account found for '%s'\n", account_name);
957 g_free (account_name);
958 modest_msg_edit_window_free_msg_data (edit_window, data);
961 from = modest_account_mgr_get_from_string (account_mgr, account_name);
963 /* Create the mail operation */
964 mail_operation = modest_mail_operation_new ();
965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
967 modest_mail_operation_send_new_mail (mail_operation,
979 g_free (account_name);
980 g_object_unref (G_OBJECT (transport_account));
981 g_object_unref (G_OBJECT (mail_operation));
983 modest_msg_edit_window_free_msg_data (edit_window, data);
985 /* Save settings and close the window */
986 gtk_widget_destroy (GTK_WIDGET (edit_window));
990 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
991 ModestMsgEditWindow *window)
993 ModestMsgEditFormatState *format_state = NULL;
995 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
996 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
998 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1001 format_state = modest_msg_edit_window_get_format_state (window);
1002 g_return_if_fail (format_state != NULL);
1004 format_state->bold = gtk_toggle_action_get_active (action);
1005 modest_msg_edit_window_set_format_state (window, format_state);
1006 g_free (format_state);
1011 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1012 ModestMsgEditWindow *window)
1014 ModestMsgEditFormatState *format_state = NULL;
1016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1017 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1019 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1022 format_state = modest_msg_edit_window_get_format_state (window);
1023 g_return_if_fail (format_state != NULL);
1025 format_state->italics = gtk_toggle_action_get_active (action);
1026 modest_msg_edit_window_set_format_state (window, format_state);
1027 g_free (format_state);
1032 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1033 ModestMsgEditWindow *window)
1035 ModestMsgEditFormatState *format_state = NULL;
1037 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1038 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1040 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1043 format_state = modest_msg_edit_window_get_format_state (window);
1044 g_return_if_fail (format_state != NULL);
1046 format_state->bullet = gtk_toggle_action_get_active (action);
1047 modest_msg_edit_window_set_format_state (window, format_state);
1048 g_free (format_state);
1053 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1054 GtkRadioAction *selected,
1055 ModestMsgEditWindow *window)
1057 ModestMsgEditFormatState *format_state = NULL;
1058 GtkJustification value;
1060 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1062 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1065 value = gtk_radio_action_get_current_value (selected);
1067 format_state = modest_msg_edit_window_get_format_state (window);
1068 g_return_if_fail (format_state != NULL);
1070 format_state->justification = value;
1071 modest_msg_edit_window_set_format_state (window, format_state);
1072 g_free (format_state);
1076 modest_ui_actions_on_select_editor_color (GtkAction *action,
1077 ModestMsgEditWindow *window)
1079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1080 g_return_if_fail (GTK_IS_ACTION (action));
1082 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1085 modest_msg_edit_window_select_color (window);
1089 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1090 ModestMsgEditWindow *window)
1092 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1093 g_return_if_fail (GTK_IS_ACTION (action));
1095 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1098 modest_msg_edit_window_select_background_color (window);
1102 modest_ui_actions_on_insert_image (GtkAction *action,
1103 ModestMsgEditWindow *window)
1105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1106 g_return_if_fail (GTK_IS_ACTION (action));
1108 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1111 modest_msg_edit_window_insert_image (window);
1115 * Shows a dialog with an entry that asks for some text. The returned
1116 * value must be freed by the caller. The dialog window title will be
1120 ask_for_folder_name (GtkWindow *parent_window,
1123 GtkWidget *dialog, *entry;
1124 gchar *folder_name = NULL;
1126 /* Ask for folder name */
1127 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1131 GTK_RESPONSE_REJECT,
1133 GTK_RESPONSE_ACCEPT,
1135 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1136 gtk_label_new(title),
1139 entry = gtk_entry_new_with_max_length (40);
1140 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1144 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1146 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1147 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1149 gtk_widget_destroy (dialog);
1155 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1157 TnyFolder *parent_folder;
1158 GtkWidget *folder_view;
1160 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1162 folder_view = modest_main_window_get_child_widget (main_window,
1163 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1167 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1169 if (parent_folder) {
1172 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1173 _("Please enter a name for the new folder"));
1175 if (folder_name != NULL && strlen (folder_name) > 0) {
1176 TnyFolder *new_folder;
1177 ModestMailOperation *mail_op;
1179 mail_op = modest_mail_operation_new ();
1180 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1183 new_folder = modest_mail_operation_create_folder (mail_op,
1184 TNY_FOLDER_STORE (parent_folder),
1185 (const gchar *) folder_name);
1187 g_object_unref (new_folder);
1188 g_object_unref (mail_op);
1189 g_free (folder_name);
1191 g_object_unref (parent_folder);
1196 modest_ui_actions_on_rename_folder (GtkAction *action,
1197 ModestMainWindow *main_window)
1200 GtkWidget *folder_view;
1202 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1204 folder_view = modest_main_window_get_child_widget (main_window,
1205 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1209 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1213 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1214 _("Please enter a new name for the folder"));
1216 if (folder_name != NULL && strlen (folder_name) > 0) {
1217 ModestMailOperation *mail_op;
1219 mail_op = modest_mail_operation_new ();
1220 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1223 modest_mail_operation_rename_folder (mail_op,
1225 (const gchar *) folder_name);
1227 g_object_unref (mail_op);
1228 g_free (folder_name);
1230 g_object_unref (folder);
1235 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1238 ModestMailOperation *mail_op;
1239 GtkWidget *folder_view;
1241 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1243 folder_view = modest_main_window_get_child_widget (main_window,
1244 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1248 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1250 mail_op = modest_mail_operation_new ();
1251 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1253 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1255 g_object_unref (G_OBJECT (mail_op));
1256 g_object_unref (G_OBJECT (folder));
1260 modest_ui_actions_on_delete_folder (GtkAction *action,
1261 ModestMainWindow *main_window)
1263 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1265 delete_folder (main_window, FALSE);
1269 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1271 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1273 delete_folder (main_window, TRUE);
1277 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1278 const gchar* account_name,
1282 ModestMainWindow *main_window)
1285 GtkWidget *dialog, *entry, *remember_pass_check;
1287 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1291 GTK_RESPONSE_REJECT,
1293 GTK_RESPONSE_ACCEPT,
1295 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1297 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1298 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1302 entry = gtk_entry_new_with_max_length (40);
1303 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1304 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1306 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1309 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1310 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1313 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1315 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1316 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1323 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1328 gtk_widget_destroy (dialog);
1332 modest_ui_actions_on_cut (GtkAction *action,
1333 ModestWindow *window)
1335 GtkWidget *focused_widget;
1337 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1338 if (GTK_IS_EDITABLE (focused_widget)) {
1339 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1340 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1341 GtkTextBuffer *buffer;
1342 GtkClipboard *clipboard;
1344 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1345 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1346 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1351 modest_ui_actions_on_copy (GtkAction *action,
1352 ModestWindow *window)
1354 GtkClipboard *clipboard;
1355 GtkWidget *focused_widget;
1357 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1358 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1359 if (GTK_IS_LABEL (focused_widget)) {
1360 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1361 } else if (GTK_IS_EDITABLE (focused_widget)) {
1362 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1363 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1364 GtkTextBuffer *buffer;
1366 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1367 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1372 modest_ui_actions_on_paste (GtkAction *action,
1373 ModestWindow *window)
1375 GtkWidget *focused_widget;
1377 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1378 if (GTK_IS_EDITABLE (focused_widget)) {
1379 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1380 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1381 GtkTextBuffer *buffer;
1382 GtkClipboard *clipboard;
1384 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1385 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1386 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1391 modest_ui_actions_on_select_all (GtkAction *action,
1392 ModestWindow *window)
1394 GtkWidget *focused_widget;
1396 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1397 if (GTK_IS_LABEL (focused_widget)) {
1398 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1399 } else if (GTK_IS_EDITABLE (focused_widget)) {
1400 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1401 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1402 GtkTextBuffer *buffer;
1403 GtkTextIter start, end;
1405 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1406 gtk_text_buffer_get_start_iter (buffer, &start);
1407 gtk_text_buffer_get_end_iter (buffer, &end);
1408 gtk_text_buffer_select_range (buffer, &start, &end);