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 const 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 if (!accounts_exist) {
217 printf ("debug: modest_account_mgr_account_names() returned NULL.\n");
218 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
219 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
220 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
221 gtk_dialog_run (GTK_DIALOG (wizard));
222 gtk_widget_destroy (GTK_WIDGET (wizard));
226 /* Show the list of accounts: */
227 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
228 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
229 gtk_dialog_run (account_win);
230 gtk_widget_destroy (GTK_WIDGET(account_win));
233 GtkWidget *dialog, *label;
235 /* Create the widgets */
237 dialog = gtk_dialog_new_with_buttons ("Message",
239 GTK_DIALOG_DESTROY_WITH_PARENT,
243 label = gtk_label_new ("Hello World!");
245 /* Ensure that the dialog box is destroyed when the user responds. */
247 g_signal_connect_swapped (dialog, "response",
248 G_CALLBACK (gtk_widget_destroy),
251 /* Add the label, and show everything we've added to the dialog. */
253 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
255 gtk_widget_show_all (dialog);
256 #endif /* MODEST_PLATFORM_MAEMO */
260 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
262 ModestWindow *msg_win;
264 TnyFolder *folder = NULL;
265 gchar *account_name = NULL;
266 gchar *from_str = NULL;
270 account_name = g_strdup(modest_window_get_active_account (win));
272 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
274 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
276 TNY_ACCOUNT_TYPE_STORE);
278 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
282 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
284 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
286 g_printerr ("modest: failed to create new msg\n");
290 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
292 g_printerr ("modest: failed to find Drafts folder\n");
296 tny_folder_add_msg (folder, msg, &err);
298 g_printerr ("modest: error adding msg to Drafts folder: %s",
304 msg_win = modest_msg_edit_window_new (msg, account_name);
306 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
308 gtk_widget_show_all (GTK_WIDGET (msg_win));
311 g_free (account_name);
314 g_object_unref (G_OBJECT(account));
316 g_object_unref (G_OBJECT(msg));
318 g_object_unref (G_OBJECT(folder));
323 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
325 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
331 reply_forward_func (gpointer data, gpointer user_data)
333 TnyMsg *msg, *new_msg;
334 GetMsgAsyncHelper *helper;
335 ReplyForwardHelper *rf_helper;
336 ModestWindow *msg_win;
337 ModestEditType edit_type;
340 TnyFolder *folder = NULL;
341 TnyAccount *account = NULL;
343 msg = TNY_MSG (data);
344 helper = (GetMsgAsyncHelper *) user_data;
345 rf_helper = (ReplyForwardHelper *) helper->user_data;
347 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
348 rf_helper->account_name);
349 /* Create reply mail */
350 switch (rf_helper->action) {
353 modest_tny_msg_create_reply_msg (msg, from,
354 rf_helper->reply_forward_type,
355 MODEST_TNY_MSG_REPLY_MODE_SENDER);
357 case ACTION_REPLY_TO_ALL:
359 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
360 MODEST_TNY_MSG_REPLY_MODE_ALL);
361 edit_type = MODEST_EDIT_TYPE_REPLY;
365 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
366 edit_type = MODEST_EDIT_TYPE_FORWARD;
369 g_return_if_reached ();
374 g_printerr ("modest: failed to create message\n");
378 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
379 rf_helper->account_name,
380 TNY_ACCOUNT_TYPE_STORE);
382 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
386 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
388 g_printerr ("modest: failed to find Drafts folder\n");
392 tny_folder_add_msg (folder, msg, &err);
394 g_printerr ("modest: error adding msg to Drafts folder: %s",
400 /* Show edit window */
401 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
402 gtk_widget_show_all (GTK_WIDGET (msg_win));
406 g_object_unref (G_OBJECT (new_msg));
408 g_object_unref (G_OBJECT (folder));
410 g_object_unref (G_OBJECT (account));
412 g_free (rf_helper->account_name);
413 g_slice_free (ReplyForwardHelper, rf_helper);
416 * Common code for the reply and forward actions
419 reply_forward (ReplyForwardAction action, ModestWindow *win)
421 TnyList *header_list;
422 guint reply_forward_type;
425 GetMsgAsyncHelper *helper;
426 ReplyForwardHelper *rf_helper;
428 g_return_if_fail (MODEST_IS_WINDOW(win));
430 header_list = get_selected_headers (win);
434 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
435 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
437 /* We assume that we can only select messages of the
438 same folder and that we reply all of them from the
439 same account. In fact the interface currently only
440 allows single selection */
443 rf_helper = g_slice_new0 (ReplyForwardHelper);
444 rf_helper->reply_forward_type = reply_forward_type;
445 rf_helper->action = action;
447 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
448 if (!rf_helper->account_name)
449 rf_helper->account_name =
450 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
452 helper = g_slice_new0 (GetMsgAsyncHelper);
453 helper->window = win;
454 helper->func = reply_forward_func;
455 helper->iter = tny_list_create_iterator (header_list);
456 helper->user_data = rf_helper;
458 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
460 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
462 g_printerr ("modest: no message found\n");
465 reply_forward_func (msg, helper);
467 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
468 folder = tny_header_get_folder (header);
470 /* The callback will call it per each header */
471 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
472 g_object_unref (G_OBJECT (folder));
474 g_printerr ("modest: no folder for header\n");
477 g_object_unref (G_OBJECT (header));
483 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
485 g_return_if_fail (MODEST_IS_WINDOW(win));
487 reply_forward (ACTION_REPLY, win);
491 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
493 g_return_if_fail (MODEST_IS_WINDOW(win));
495 reply_forward (ACTION_FORWARD, win);
499 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
501 g_return_if_fail (MODEST_IS_WINDOW(win));
503 reply_forward (ACTION_REPLY_TO_ALL, win);
507 modest_ui_actions_on_next (GtkAction *action,
508 ModestMainWindow *main_window)
510 GtkWidget *header_view;
511 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
513 header_view = modest_main_window_get_child_widget (main_window,
514 MODEST_WIDGET_TYPE_HEADER_VIEW);
518 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
522 modest_ui_actions_on_prev (GtkAction *action,
523 ModestMainWindow *main_window)
525 GtkWidget *header_view;
526 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
528 header_view = modest_main_window_get_child_widget (main_window,
529 MODEST_WIDGET_TYPE_HEADER_VIEW);
533 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
538 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
541 TnyAccount *tny_account;
542 ModestTnySendQueue *send_queue;
543 ModestMailOperation *mail_op;
546 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
548 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
550 g_printerr ("modest: cannot get account\n");
555 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
557 TNY_ACCOUNT_TYPE_TRANSPORT);
559 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
562 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
564 g_object_unref (G_OBJECT(tny_account));
565 g_printerr ("modest: cannot get send queue for %s\n", account_name);
568 //modest_tny_send_queue_flush (send_queue);
570 g_object_unref (G_OBJECT(send_queue));
571 g_object_unref (G_OBJECT(tny_account));
574 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
576 TNY_ACCOUNT_TYPE_STORE);
578 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
582 /* Create the mail operation */
583 mail_op = modest_mail_operation_new ();
584 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
585 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
588 g_object_unref (G_OBJECT (tny_account));
589 g_object_unref (G_OBJECT (mail_op));
595 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
598 GtkWidget *header_view;
600 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
602 header_view = modest_main_window_get_child_widget (main_window,
603 MODEST_WIDGET_TYPE_HEADER_VIEW);
607 conf = modest_runtime_get_conf ();
609 /* what is saved/restored is depending on the style; thus; we save with
610 * old style, then update the style, and restore for this new style
612 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
614 if (modest_header_view_get_style
615 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
616 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
617 MODEST_HEADER_VIEW_STYLE_TWOLINES);
619 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
620 MODEST_HEADER_VIEW_STYLE_DETAILS);
622 modest_widget_memory_restore (conf, G_OBJECT(header_view),
629 * Marks a message as read and passes it to the msg preview widget
632 read_msg_func (gpointer data, gpointer user_data)
636 GetMsgAsyncHelper *helper;
637 TnyHeaderFlags header_flags;
638 GtkWidget *msg_preview;
640 msg = TNY_MSG (data);
641 helper = (GetMsgAsyncHelper *) user_data;
643 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
644 MODEST_WIDGET_TYPE_MSG_PREVIEW);
648 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
649 header_flags = tny_header_get_flags (header);
650 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
651 g_object_unref (G_OBJECT (header));
653 /* Set message on msg view */
654 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
658 * This function is a generic handler for the tny_folder_get_msg_async
659 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
660 * contains a user provided function that is called inside this
661 * method. This will allow us to use this callback in many different
662 * places. This callback performs the common actions for the
663 * get_msg_async call, more specific actions will be done by the user
667 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
669 GetMsgAsyncHelper *helper;
671 helper = (GetMsgAsyncHelper *) user_data;
673 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
674 modest_ui_actions_on_item_not_found (NULL,
675 MODEST_ITEM_TYPE_MESSAGE,
680 /* Call user function */
681 helper->func (msg, user_data);
683 /* Process next element (if exists) */
684 tny_iterator_next (helper->iter);
685 if (tny_iterator_is_done (helper->iter)) {
687 headers = tny_iterator_get_list (helper->iter);
689 g_object_unref (G_OBJECT (headers));
690 g_object_unref (G_OBJECT (helper->iter));
691 g_slice_free (GetMsgAsyncHelper, helper);
694 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
695 tny_folder_get_msg_async (folder, header,
697 g_object_unref (G_OBJECT(header));
702 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
704 ModestMainWindow *main_window)
706 GtkWidget *msg_preview;
708 GetMsgAsyncHelper *helper;
711 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
713 msg_preview = modest_main_window_get_child_widget(main_window,
714 MODEST_WIDGET_TYPE_MSG_PREVIEW);
718 /* when there's no header, clear the msgview */
720 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
724 folder = tny_header_get_folder (TNY_HEADER(header));
727 list = tny_simple_list_new ();
728 tny_list_prepend (list, G_OBJECT (header));
730 /* Fill helper data */
731 helper = g_slice_new0 (GetMsgAsyncHelper);
732 helper->window = MODEST_WINDOW (main_window);
733 helper->iter = tny_list_create_iterator (list);
734 helper->func = read_msg_func;
736 tny_folder_get_msg_async (TNY_FOLDER(folder),
741 g_object_unref (G_OBJECT (folder));
747 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
748 ModestMainWindow *main_window)
751 TnyFolder *folder = NULL;
753 gchar *account = NULL;
755 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
760 folder = tny_header_get_folder (header);
762 g_printerr ("modest: cannot get folder for header\n");
766 /* FIXME: make async?; check error */
767 msg = tny_folder_get_msg (folder, header, NULL);
769 g_printerr ("modest: cannot get msg for header\n");
773 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
775 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
777 win = modest_msg_view_window_new (msg, account);
778 gtk_window_set_transient_for (GTK_WINDOW (win),
779 GTK_WINDOW (main_window));
781 gtk_widget_show_all (GTK_WIDGET(win));
787 g_object_unref (G_OBJECT (folder));
789 g_object_unref (G_OBJECT (msg));
793 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
796 ModestMainWindow *main_window)
800 GtkWidget *header_view;
802 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
804 header_view = modest_main_window_get_child_widget(main_window,
805 MODEST_WIDGET_TYPE_HEADER_VIEW);
809 conf = modest_runtime_get_conf ();
811 if (!selected) { /* the folder was unselected; save it's settings */
812 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
813 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
814 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
815 } else { /* the folder was selected */
816 if (folder) { /* folder may be NULL */
820 num = tny_folder_get_all_count (folder);
821 unread = tny_folder_get_unread_count (folder);
823 title = g_strdup_printf ("Modest: %s",
824 tny_folder_get_name (folder));
826 gtk_window_set_title (GTK_WINDOW(main_window), title);
829 txt = g_strdup_printf (_("%d %s, %d unread"),
830 num, num==1 ? _("item") : _("items"), unread);
831 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
834 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
835 modest_widget_memory_restore (conf, G_OBJECT(header_view),
841 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
848 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
850 if (g_main_depth > 0)
851 gdk_threads_enter ();
852 online = tny_device_is_online (modest_runtime_get_device());
855 /* already online -- the item is simply not there... */
856 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
860 _("The %s you selected cannot be found"),
862 gtk_dialog_run (GTK_DIALOG(dialog));
864 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
872 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
873 "Do you want to get online?"), item);
874 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
875 gtk_label_new (txt), FALSE, FALSE, 0);
876 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
879 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
880 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
881 // tny_device_force_online (modest_runtime_get_device());
884 gtk_widget_destroy (dialog);
885 if (g_main_depth > 0)
886 gdk_threads_leave ();
890 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
893 g_message (__FUNCTION__);
898 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
901 g_message (__FUNCTION__);
905 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
908 g_message (__FUNCTION__);
913 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
914 const gchar *address,
917 g_message ("%s %s", __FUNCTION__, address);
921 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
923 TnyTransportAccount *transport_account;
924 ModestMailOperation *mail_operation;
926 gchar *account_name, *from;
927 ModestAccountMgr *account_mgr;
929 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
931 data = modest_msg_edit_window_get_msg_data (edit_window);
933 /* FIXME: Code added just for testing. The final version will
934 use the send queue provided by tinymail and some
936 account_mgr = modest_runtime_get_account_mgr();
937 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
939 account_name = modest_account_mgr_get_default_account (account_mgr);
941 g_printerr ("modest: no account found\n");
942 modest_msg_edit_window_free_msg_data (edit_window, data);
946 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
947 (modest_runtime_get_account_store(),
949 TNY_ACCOUNT_TYPE_TRANSPORT));
950 if (!transport_account) {
951 g_printerr ("modest: no transport account found for '%s'\n", account_name);
952 g_free (account_name);
953 modest_msg_edit_window_free_msg_data (edit_window, data);
956 from = modest_account_mgr_get_from_string (account_mgr, account_name);
958 /* Create the mail operation */
959 mail_operation = modest_mail_operation_new ();
960 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
962 modest_mail_operation_send_new_mail (mail_operation,
974 g_free (account_name);
975 g_object_unref (G_OBJECT (transport_account));
976 g_object_unref (G_OBJECT (mail_operation));
978 modest_msg_edit_window_free_msg_data (edit_window, data);
980 /* Save settings and close the window */
981 gtk_widget_destroy (GTK_WIDGET (edit_window));
985 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
986 ModestMsgEditWindow *window)
988 ModestMsgEditFormatState *format_state = NULL;
990 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
991 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
993 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
996 format_state = modest_msg_edit_window_get_format_state (window);
997 g_return_if_fail (format_state != NULL);
999 format_state->bold = gtk_toggle_action_get_active (action);
1000 modest_msg_edit_window_set_format_state (window, format_state);
1001 g_free (format_state);
1006 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1007 ModestMsgEditWindow *window)
1009 ModestMsgEditFormatState *format_state = NULL;
1011 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1012 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1014 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1017 format_state = modest_msg_edit_window_get_format_state (window);
1018 g_return_if_fail (format_state != NULL);
1020 format_state->italics = gtk_toggle_action_get_active (action);
1021 modest_msg_edit_window_set_format_state (window, format_state);
1022 g_free (format_state);
1027 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1028 ModestMsgEditWindow *window)
1030 ModestMsgEditFormatState *format_state = NULL;
1032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1033 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1035 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1038 format_state = modest_msg_edit_window_get_format_state (window);
1039 g_return_if_fail (format_state != NULL);
1041 format_state->bullet = gtk_toggle_action_get_active (action);
1042 modest_msg_edit_window_set_format_state (window, format_state);
1043 g_free (format_state);
1048 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1049 GtkRadioAction *selected,
1050 ModestMsgEditWindow *window)
1052 ModestMsgEditFormatState *format_state = NULL;
1053 GtkJustification value;
1055 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1057 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1060 value = gtk_radio_action_get_current_value (selected);
1062 format_state = modest_msg_edit_window_get_format_state (window);
1063 g_return_if_fail (format_state != NULL);
1065 format_state->justification = value;
1066 modest_msg_edit_window_set_format_state (window, format_state);
1067 g_free (format_state);
1071 modest_ui_actions_on_select_editor_color (GtkAction *action,
1072 ModestMsgEditWindow *window)
1074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1075 g_return_if_fail (GTK_IS_ACTION (action));
1077 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1080 modest_msg_edit_window_select_color (window);
1084 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1085 ModestMsgEditWindow *window)
1087 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1088 g_return_if_fail (GTK_IS_ACTION (action));
1090 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1093 modest_msg_edit_window_select_background_color (window);
1097 modest_ui_actions_on_insert_image (GtkAction *action,
1098 ModestMsgEditWindow *window)
1100 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1101 g_return_if_fail (GTK_IS_ACTION (action));
1103 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1106 modest_msg_edit_window_insert_image (window);
1110 * Shows a dialog with an entry that asks for some text. The returned
1111 * value must be freed by the caller. The dialog window title will be
1115 ask_for_folder_name (GtkWindow *parent_window,
1118 GtkWidget *dialog, *entry;
1119 gchar *folder_name = NULL;
1121 /* Ask for folder name */
1122 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1126 GTK_RESPONSE_REJECT,
1128 GTK_RESPONSE_ACCEPT,
1130 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1131 gtk_label_new(title),
1134 entry = gtk_entry_new_with_max_length (40);
1135 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1139 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1141 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1142 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1144 gtk_widget_destroy (dialog);
1150 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1152 TnyFolder *parent_folder;
1153 GtkWidget *folder_view;
1155 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1157 folder_view = modest_main_window_get_child_widget (main_window,
1158 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1162 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1164 if (parent_folder) {
1167 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1168 _("Please enter a name for the new folder"));
1170 if (folder_name != NULL && strlen (folder_name) > 0) {
1171 TnyFolder *new_folder;
1172 ModestMailOperation *mail_op;
1174 mail_op = modest_mail_operation_new ();
1175 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1178 new_folder = modest_mail_operation_create_folder (mail_op,
1179 TNY_FOLDER_STORE (parent_folder),
1180 (const gchar *) folder_name);
1182 g_object_unref (new_folder);
1183 g_object_unref (mail_op);
1184 g_free (folder_name);
1186 g_object_unref (parent_folder);
1191 modest_ui_actions_on_rename_folder (GtkAction *action,
1192 ModestMainWindow *main_window)
1195 GtkWidget *folder_view;
1197 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1199 folder_view = modest_main_window_get_child_widget (main_window,
1200 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1204 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1208 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1209 _("Please enter a new name for the folder"));
1211 if (folder_name != NULL && strlen (folder_name) > 0) {
1212 ModestMailOperation *mail_op;
1214 mail_op = modest_mail_operation_new ();
1215 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1218 modest_mail_operation_rename_folder (mail_op,
1220 (const gchar *) folder_name);
1222 g_object_unref (mail_op);
1223 g_free (folder_name);
1225 g_object_unref (folder);
1230 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1233 ModestMailOperation *mail_op;
1234 GtkWidget *folder_view;
1236 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1238 folder_view = modest_main_window_get_child_widget (main_window,
1239 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1243 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1245 mail_op = modest_mail_operation_new ();
1246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1248 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1250 g_object_unref (G_OBJECT (mail_op));
1251 g_object_unref (G_OBJECT (folder));
1255 modest_ui_actions_on_delete_folder (GtkAction *action,
1256 ModestMainWindow *main_window)
1258 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1260 delete_folder (main_window, FALSE);
1264 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1266 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1268 delete_folder (main_window, TRUE);
1272 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1273 const gchar* account_name,
1277 ModestMainWindow *main_window)
1280 GtkWidget *dialog, *entry, *remember_pass_check;
1282 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1286 GTK_RESPONSE_REJECT,
1288 GTK_RESPONSE_ACCEPT,
1290 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1292 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1293 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1297 entry = gtk_entry_new_with_max_length (40);
1298 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1299 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1301 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1304 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1305 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1308 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1310 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1311 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1318 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1323 gtk_widget_destroy (dialog);
1327 modest_ui_actions_on_cut (GtkAction *action,
1328 ModestWindow *window)
1330 GtkWidget *focused_widget;
1332 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1333 if (GTK_IS_EDITABLE (focused_widget)) {
1334 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1335 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1336 GtkTextBuffer *buffer;
1337 GtkClipboard *clipboard;
1339 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1340 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1341 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1346 modest_ui_actions_on_copy (GtkAction *action,
1347 ModestWindow *window)
1349 GtkClipboard *clipboard;
1350 GtkWidget *focused_widget;
1352 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1353 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1354 if (GTK_IS_LABEL (focused_widget)) {
1355 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1356 } else if (GTK_IS_EDITABLE (focused_widget)) {
1357 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1358 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1359 GtkTextBuffer *buffer;
1361 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1362 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1367 modest_ui_actions_on_paste (GtkAction *action,
1368 ModestWindow *window)
1370 GtkWidget *focused_widget;
1372 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1373 if (GTK_IS_EDITABLE (focused_widget)) {
1374 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1375 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1376 GtkTextBuffer *buffer;
1377 GtkClipboard *clipboard;
1379 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1380 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1381 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1386 modest_ui_actions_on_select_all (GtkAction *action,
1387 ModestWindow *window)
1389 GtkWidget *focused_widget;
1391 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1392 if (GTK_IS_LABEL (focused_widget)) {
1393 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1394 } else if (GTK_IS_EDITABLE (focused_widget)) {
1395 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1396 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1397 GtkTextBuffer *buffer;
1398 GtkTextIter start, end;
1400 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1401 gtk_text_buffer_get_start_iter (buffer, &start);
1402 gtk_text_buffer_get_end_iter (buffer, &end);
1403 gtk_text_buffer_select_range (buffer, &start, &end);