1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include "modest-ui-priv.h"
36 #include "modest-ui.h"
37 #include "modest-ui-actions.h"
38 #include "modest-icon-names.h"
39 #include "modest-tny-platform-factory.h"
40 #include "modest-account-view-window.h"
41 #include "modest-main-window.h"
42 #include <modest-widget-memory.h>
43 #include <tny-error.h>
44 #include <tny-simple-list.h>
46 #define MODEST_UI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
50 typedef struct _GetMsgAsyncHelper {
51 ModestMainWindow *main_window;
57 typedef enum _ReplyForwardAction {
63 typedef struct _ReplyForwardHelper {
64 guint reply_forward_type;
65 ReplyForwardAction action;
70 static GObjectClass *parent_class = NULL;
72 /* 'private'/'protected' functions */
73 static void modest_ui_class_init (ModestUIClass *klass);
74 static void modest_ui_init (ModestUI *obj);
75 static void modest_ui_finalize (GObject *obj);
77 static void register_stock_icons ();
78 static void connect_signals (ModestUI *self);
79 /* static GtkUIManager *create_ui_manager (); */
81 static void reply_forward_func (gpointer data, gpointer user_data);
82 static void read_msg_func (gpointer data, gpointer user_data);
83 static void get_msg_cb (TnyFolder *folder,
88 static void reply_forward (GtkWidget *widget,
89 ReplyForwardAction action,
90 ModestMainWindow *main_window);
92 static void _modest_ui_actions_on_password_requested (ModestTnyAccountStore *account_store,
93 const gchar* account_name,
97 ModestMainWindow *main_window);
100 modest_ui_get_type (void)
102 static GType my_type = 0;
104 static const GTypeInfo my_info = {
105 sizeof(ModestUIClass),
106 NULL, /* base init */
107 NULL, /* base finalize */
108 (GClassInitFunc) modest_ui_class_init,
109 NULL, /* class finalize */
110 NULL, /* class data */
113 (GInstanceInitFunc) modest_ui_init,
116 my_type = g_type_register_static (G_TYPE_OBJECT,
125 modest_ui_class_init (ModestUIClass *klass)
127 GObjectClass *gobject_class;
128 gobject_class = (GObjectClass*) klass;
130 parent_class = g_type_class_peek_parent (klass);
131 gobject_class->finalize = modest_ui_finalize;
133 g_type_class_add_private (gobject_class, sizeof(ModestUIPrivate));
139 modest_ui_init (ModestUI *obj)
141 ModestUIPrivate *priv;
143 priv = MODEST_UI_GET_PRIVATE(obj);
145 priv->widget_factory = NULL;
146 priv->main_window = NULL;
147 priv->account_store = NULL;
152 modest_ui_finalize (GObject *obj)
155 ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
157 if (priv->widget_factory) {
158 g_object_unref (G_OBJECT(priv->widget_factory));
159 priv->widget_factory = NULL;
162 if (priv->ui_manager) {
163 g_object_unref (G_OBJECT(priv->ui_manager));
164 priv->ui_manager = NULL;
167 G_OBJECT_CLASS(parent_class)->finalize (obj);
172 modest_ui_new (TnyAccountStore *account_store)
175 ModestUIPrivate *priv;
176 TnyPlatformFactory *fact;
177 ModestAccountMgr *account_mgr;
179 obj = g_object_new(MODEST_TYPE_UI, NULL);
180 priv = MODEST_UI_GET_PRIVATE(obj);
182 /* Get the platform-dependent instances */
183 fact = modest_tny_platform_factory_get_instance ();
185 priv->account_store = account_store;
187 account_mgr = modest_tny_platform_factory_get_account_mgr_instance
188 (MODEST_TNY_PLATFORM_FACTORY(fact));
190 g_printerr ("modest: could not create ModestAccountMgr instance\n");
191 g_object_unref (obj);
195 priv->widget_factory = modest_widget_factory_new ();
196 if (!priv->widget_factory) {
197 g_printerr ("modest: could not initialize widget factory\n");
201 /* Register our own icons as stock icons in order to
202 use them with the UI manager */
203 register_stock_icons ();
205 return MODEST_UI(obj);
209 on_main_window_destroy (GtkObject *widget, ModestUI *self)
211 /* FIXME: check if there any viewer/editing windows opened */
218 modest_ui_main_window (ModestUI *self)
220 ModestUIPrivate *priv;
222 g_return_val_if_fail (self, NULL);
223 priv = MODEST_UI_GET_PRIVATE(self);
225 if (!priv->main_window) {
227 /* Create main window */
228 priv->main_window = modest_main_window_new (priv->widget_factory,
229 priv->account_store);
231 connect_signals (self);
234 if (!priv->main_window)
235 g_printerr ("modest: could not create main window\n");
237 return priv->main_window;
241 modest_ui_edit_window (ModestUI *self, ModestEditType edit_type)
243 ModestUIPrivate *priv;
244 ModestWindow *edit_window;
246 g_return_val_if_fail (self, NULL);
247 priv = MODEST_UI_GET_PRIVATE(self);
250 edit_window = modest_edit_msg_window_new (priv->widget_factory,
254 /* Connect Edit Window signals */
255 /* connect_edit_window_signals (self); */
261 * This function registers our custom toolbar icons, so they can be
262 * themed. The idea of this function was taken from the gtk-demo
265 register_stock_icons ()
267 static gboolean registered = FALSE;
271 GtkIconFactory *factory;
274 static GtkStockItem items[] = {
275 { MODEST_STOCK_MAIL_SEND, "send mail", 0, 0, NULL },
276 { MODEST_STOCK_NEW_MAIL, "new mail", 0, 0, NULL },
277 { MODEST_STOCK_SEND_RECEIVE, "send receive", 0, 0, NULL },
278 { MODEST_STOCK_REPLY, "reply", 0, 0, NULL },
279 { MODEST_STOCK_REPLY_ALL, "reply all", 0, 0, NULL },
280 { MODEST_STOCK_FORWARD, "forward", 0, 0, NULL },
281 { MODEST_STOCK_DELETE, "delete", 0, 0, NULL },
282 { MODEST_STOCK_NEXT, "next", 0, 0, NULL },
283 { MODEST_STOCK_PREV, "prev", 0, 0, NULL },
284 { MODEST_STOCK_STOP, "stop", 0, 0, NULL }
287 static gchar *items_names [] = {
288 MODEST_TOOLBAR_ICON_MAIL_SEND,
289 MODEST_TOOLBAR_ICON_NEW_MAIL,
290 MODEST_TOOLBAR_ICON_SEND_RECEIVE,
291 MODEST_TOOLBAR_ICON_REPLY,
292 MODEST_TOOLBAR_ICON_REPLY_ALL,
293 MODEST_TOOLBAR_ICON_FORWARD,
294 MODEST_TOOLBAR_ICON_DELETE,
295 MODEST_TOOLBAR_ICON_NEXT,
296 MODEST_TOOLBAR_ICON_PREV,
297 MODEST_TOOLBAR_ICON_STOP
302 /* Register our stock items */
303 gtk_stock_add (items, G_N_ELEMENTS (items));
305 /* Add our custom icon factory to the list of defaults */
306 factory = gtk_icon_factory_new ();
307 gtk_icon_factory_add_default (factory);
309 /* Register icons to accompany stock items */
310 for (i = 0; i < G_N_ELEMENTS (items); i++) {
312 pixbuf = gdk_pixbuf_new_from_file (items_names[i], NULL);
314 if (pixbuf != NULL) {
315 GtkIconSet *icon_set;
316 GdkPixbuf *transparent;
318 transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);
320 icon_set = gtk_icon_set_new_from_pixbuf (transparent);
321 gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
322 gtk_icon_set_unref (icon_set);
323 g_object_unref (pixbuf);
324 g_object_unref (transparent);
327 g_warning ("failed to load %s icon", items_names[i]);
329 /* Drop our reference to the factory, GTK will hold a reference. */
330 g_object_unref (factory);
334 /* FIXME: uninit these as well */
336 connect_signals (ModestUI *self)
339 ModestUIPrivate *priv;
340 ModestFolderView *folder_view;
341 ModestHeaderView *header_view;
342 ModestMsgView *msg_view;
345 priv = MODEST_UI_GET_PRIVATE(self);
347 folder_view = modest_widget_factory_get_folder_view (priv->widget_factory);
348 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
349 msg_view = modest_widget_factory_get_msg_preview (priv->widget_factory);
350 toggle = modest_widget_factory_get_online_toggle (priv->widget_factory);
351 device = tny_account_store_get_device (priv->account_store);
354 g_signal_connect (G_OBJECT(folder_view), "folder_selection_changed",
355 G_CALLBACK(_modest_ui_actions_on_folder_selection_changed),
357 /* g_signal_connect (G_OBJECT(folder_view), "key-press-event", */
358 /* G_CALLBACK(on_folder_key_press_event), priv->widget_factory); */
361 g_signal_connect (G_OBJECT(header_view), "status_update",
362 G_CALLBACK(_modest_ui_actions_on_header_status_update),
364 g_signal_connect (G_OBJECT(header_view), "header_selected",
365 G_CALLBACK(_modest_ui_actions_on_header_selected),
367 g_signal_connect (G_OBJECT(header_view), "item_not_found",
368 G_CALLBACK(_modest_ui_actions_on_item_not_found),
373 g_signal_connect (G_OBJECT(msg_view), "link_clicked",
374 G_CALLBACK(_modest_ui_actions_on_msg_link_clicked),
376 g_signal_connect (G_OBJECT(msg_view), "link_hover",
377 G_CALLBACK(_modest_ui_actions_on_msg_link_hover),
379 g_signal_connect (G_OBJECT(msg_view), "attachment_clicked",
380 G_CALLBACK(_modest_ui_actions_on_msg_attachment_clicked),
384 g_signal_connect (G_OBJECT(device), "connection_changed",
385 G_CALLBACK(_modest_ui_actions_on_connection_changed),
387 g_signal_connect (G_OBJECT(toggle), "toggled",
388 G_CALLBACK(_modest_ui_actions_on_online_toggle_toggled),
392 g_signal_connect (G_OBJECT (priv->account_store),
393 "password_requested",
394 G_CALLBACK(_modest_ui_actions_on_password_requested),
398 g_signal_connect (G_OBJECT(priv->main_window),
400 G_CALLBACK(on_main_window_destroy),
404 /* Init toggle in correct state */
405 _modest_ui_actions_on_connection_changed (device,
406 tny_device_is_online (device),
407 MODEST_MAIN_WINDOW (priv->main_window));
411 /* ***************************************************************** */
412 /* M O D E S T U I A C T I O N S */
413 /* ***************************************************************** */
415 _modest_ui_actions_on_about (GtkWidget *widget,
416 ModestMainWindow *main_window)
419 const gchar *authors[] = {
420 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
423 about = gtk_about_dialog_new ();
424 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
425 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
426 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
427 _("Copyright (c) 2006, Nokia Corporation\n"
428 "All rights reserved."));
429 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
430 _("a modest e-mail client\n\n"
431 "design and implementation: Dirk-Jan C. Binnema\n"
432 "contributions from the fine people at KernelConcepts and Igalia\n"
433 "uses the tinymail email framework written by Philip van Hoof"));
434 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
435 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
437 gtk_dialog_run (GTK_DIALOG (about));
438 gtk_widget_destroy(about);
442 _modest_ui_actions_on_delete (GtkWidget *widget,
443 ModestMainWindow *main_window)
445 ModestWidgetFactory *widget_factory;
446 ModestHeaderView *header_view;
447 TnyList *header_list;
451 widget_factory = modest_main_window_get_widget_factory (main_window);
452 header_view = modest_widget_factory_get_header_view (widget_factory);
453 header_list = modest_header_view_get_selected_headers (header_view);
454 g_object_unref (G_OBJECT(widget_factory));
457 iter = tny_list_create_iterator (header_list);
458 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
459 if (GTK_IS_TREE_MODEL_SORT (model))
460 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model));
463 ModestMailOperation *mail_op;
465 header = TNY_HEADER (tny_iterator_get_current (iter));
466 /* TODO: thick grain mail operation involving
467 a list of objects. Composite pattern ??? */
468 mail_op = modest_mail_operation_new ();
470 /* TODO: add confirmation dialog */
473 modest_mail_operation_remove_msg (mail_op, header, TRUE);
475 /* Remove from tree model */
476 if (modest_mail_operation_get_status (mail_op) ==
477 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
478 tny_list_remove (TNY_LIST (model), G_OBJECT (header));
480 /* TODO: error handling management */
482 error = modest_mail_operation_get_error (mail_op);
483 g_warning (error->message);
486 g_object_unref (G_OBJECT (mail_op));
487 g_object_unref (header);
488 tny_iterator_next (iter);
490 } while (!tny_iterator_is_done (iter));
495 _modest_ui_actions_on_quit (GtkWidget *widget,
496 ModestMainWindow *main_window)
498 /* FIXME: save size of main window */
499 /* save_sizes (main_window); */
500 gtk_widget_destroy (GTK_WIDGET (main_window));
504 _modest_ui_actions_on_accounts (GtkWidget *widget,
505 ModestMainWindow *main_window)
507 GtkWidget *account_win;
508 ModestWidgetFactory *widget_factory;
510 widget_factory = modest_main_window_get_widget_factory (main_window);
511 account_win = modest_account_view_window_new (widget_factory);
512 g_object_unref (G_OBJECT(widget_factory));
514 gtk_window_set_transient_for (GTK_WINDOW (account_win),
515 GTK_WINDOW (main_window));
517 gtk_widget_show (account_win);
521 _modest_ui_actions_on_new_msg (GtkWidget *widget,
522 ModestMainWindow *main_window)
524 ModestWindow *msg_win;
525 ModestWidgetFactory *widget_factory;
526 TnyAccountStore *account_store;
528 widget_factory = modest_main_window_get_widget_factory (main_window);
529 account_store = modest_main_window_get_account_store (main_window);
530 msg_win = modest_edit_msg_window_new (widget_factory,
532 MODEST_EDIT_TYPE_NEW);
533 g_object_unref (G_OBJECT (widget_factory));
534 g_object_unref (G_OBJECT (account_store));
536 gtk_widget_show (GTK_WIDGET (msg_win));
540 reply_forward_func (gpointer data, gpointer user_data)
542 ModestWidgetFactory *widget_factory;
543 TnyHeader *new_header;
544 TnyMsg *msg, *new_msg;
545 TnyAccountStore *account_store;
546 GetMsgAsyncHelper *helper;
547 ReplyForwardHelper *rf_helper;
549 ModestEditType edit_type;
551 msg = TNY_MSG (data);
552 helper = (GetMsgAsyncHelper *) user_data;
553 rf_helper = (ReplyForwardHelper *) helper->user_data;
555 /* Create reply mail */
556 switch (rf_helper->action) {
559 modest_mail_operation_create_reply_mail (msg,
561 rf_helper->reply_forward_type,
562 MODEST_MAIL_OPERATION_REPLY_MODE_SENDER);
563 case ACTION_REPLY_TO_ALL:
565 modest_mail_operation_create_reply_mail (msg, rf_helper->from, rf_helper->reply_forward_type,
566 MODEST_MAIL_OPERATION_REPLY_MODE_ALL);
567 edit_type = MODEST_EDIT_TYPE_REPLY;
571 modest_mail_operation_create_forward_mail (msg, rf_helper->from, rf_helper->reply_forward_type);
572 edit_type = MODEST_EDIT_TYPE_FORWARD;
577 new_header = tny_msg_get_header (new_msg);
578 tny_header_set_from (new_header, rf_helper->from);
579 g_object_unref (G_OBJECT (new_header));
581 /* Show edit window */
582 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
583 account_store = modest_main_window_get_account_store (helper->main_window);
584 msg_win = modest_edit_msg_window_new (widget_factory,
586 MODEST_EDIT_TYPE_NEW);
587 g_object_unref (G_OBJECT (widget_factory));
588 g_object_unref (G_OBJECT (account_store));
589 modest_edit_msg_window_set_msg (MODEST_EDIT_MSG_WINDOW (msg_win),
591 gtk_widget_show (GTK_WIDGET (msg_win));
594 g_object_unref (G_OBJECT (new_msg));
595 g_free (rf_helper->from);
596 g_slice_free (ReplyForwardHelper, rf_helper);
600 * Common code for the reply and forward actions
603 reply_forward (GtkWidget *widget,
604 ReplyForwardAction action,
605 ModestMainWindow *main_window)
607 ModestHeaderView *header_view;
608 ModestWidgetFactory *widget_factory;
609 TnyList *header_list;
610 guint reply_forward_type;
612 TnyPlatformFactory *plat_factory;
616 GetMsgAsyncHelper *helper;
617 ReplyForwardHelper *rf_helper;
620 plat_factory = modest_tny_platform_factory_get_instance ();
621 conf = modest_tny_platform_factory_get_conf_instance
622 (MODEST_TNY_PLATFORM_FACTORY(plat_factory));
624 /* Get reply or forward type */
625 key = g_strdup_printf ("%s/%s", MODEST_CONF_NAMESPACE,
626 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE);
627 reply_forward_type = modest_conf_get_int (conf, key, NULL);
630 /* Get the list of headers */
631 widget_factory = modest_main_window_get_widget_factory (main_window);
632 header_view = modest_widget_factory_get_header_view (widget_factory);
633 header_list = modest_header_view_get_selected_headers (header_view);
634 g_object_unref (G_OBJECT(widget_factory));
639 /* We assume that we can only select messages of the
640 same folder and that we reply all of them from the
641 same account. In fact the interface currently only
642 allows single selection */
644 /* TODO: get the from string from account */
645 from = g_strdup ("Invalid");
648 rf_helper = g_slice_new0 (ReplyForwardHelper);
649 rf_helper->reply_forward_type = reply_forward_type;
650 rf_helper->action = action;
651 rf_helper->from = from;
653 helper = g_slice_new0 (GetMsgAsyncHelper);
654 helper->main_window = main_window;
655 helper->func = reply_forward_func;
656 helper->iter = tny_list_create_iterator (header_list);
657 helper->user_data = rf_helper;
659 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
660 folder = tny_header_get_folder (header);
662 /* The callback will call it per each header */
663 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
666 g_object_unref (G_OBJECT (folder));
670 _modest_ui_actions_on_reply (GtkWidget *widget,
671 ModestMainWindow *main_window)
673 reply_forward (widget, ACTION_REPLY, main_window);
677 _modest_ui_actions_on_forward (GtkWidget *widget,
678 ModestMainWindow *main_window)
680 reply_forward (widget, ACTION_FORWARD, main_window);
684 _modest_ui_actions_on_reply_all (GtkWidget *widget,
685 ModestMainWindow *main_window)
687 reply_forward (widget, ACTION_REPLY_TO_ALL, main_window);
691 _modest_ui_actions_on_next (GtkWidget *widget,
692 ModestMainWindow *main_window)
694 ModestHeaderView *header_view;
695 ModestWidgetFactory *widget_factory;
697 widget_factory = modest_main_window_get_widget_factory (main_window);
698 header_view = modest_widget_factory_get_header_view (widget_factory);
699 g_object_unref (G_OBJECT(widget_factory));
701 modest_header_view_select_next (header_view);
706 * Marks a message as read and passes it to the msg preview widget
709 read_msg_func (gpointer data, gpointer user_data)
711 ModestMsgView *msg_view;
712 ModestWidgetFactory *widget_factory;
715 GetMsgAsyncHelper *helper;
716 TnyHeaderFlags header_flags;
718 msg = TNY_MSG (data);
719 helper = (GetMsgAsyncHelper *) user_data;
721 /* mark message as seen; _set_flags crashes, bug in tinymail? */
722 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
723 header_flags = tny_header_get_flags (header);
724 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
725 g_object_unref (G_OBJECT (header));
727 /* Set message on msg view */
728 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
729 msg_view = modest_widget_factory_get_msg_preview (widget_factory);
730 g_object_unref (G_OBJECT(widget_factory));
731 modest_msg_view_set_message (msg_view, msg);
735 * This function is a generic handler for the tny_folder_get_msg_async
736 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
737 * contains a user provided function that is called inside this
738 * method. This will allow us to use this callback in many different
739 * places. This callback performs the common actions for the
740 * get_msg_async call, more specific actions will be done by the user
744 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
746 GetMsgAsyncHelper *helper;
748 helper = (GetMsgAsyncHelper *) user_data;
750 if (*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) {
751 ModestHeaderView *header_view;
752 ModestWidgetFactory *widget_factory;
754 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
755 header_view = modest_widget_factory_get_header_view (widget_factory);
756 g_object_unref (G_OBJECT (widget_factory));
757 _modest_ui_actions_on_item_not_found (header_view,
758 MODEST_ITEM_TYPE_MESSAGE,
759 helper->main_window);
766 /* Call user function */
767 helper->func (msg, user_data);
769 /* Process next element (if exists) */
770 tny_iterator_next (helper->iter);
771 if (tny_iterator_is_done (helper->iter)) {
773 headers = tny_iterator_get_list (helper->iter);
775 g_object_unref (G_OBJECT (headers));
776 g_object_unref (G_OBJECT (helper->iter));
777 g_slice_free (GetMsgAsyncHelper, helper);
779 tny_folder_get_msg_async (folder,
780 TNY_HEADER (tny_iterator_get_current (helper->iter)),
785 _modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
787 ModestMainWindow *main_window)
790 GetMsgAsyncHelper *helper;
796 folder = tny_header_get_folder (TNY_HEADER(header));
799 list = tny_simple_list_new ();
800 tny_list_prepend (list, G_OBJECT (header));
802 /* Fill helper data */
803 helper = g_slice_new0 (GetMsgAsyncHelper);
804 helper->main_window = main_window;
805 helper->iter = tny_list_create_iterator (list);
806 helper->func = read_msg_func;
808 tny_folder_get_msg_async (TNY_FOLDER(folder),
814 g_object_unref (G_OBJECT (folder));
818 _modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
821 ModestMainWindow *main_window)
823 GtkLabel *folder_info_label;
824 TnyPlatformFactory *factory;
827 ModestHeaderView *header_view;
828 ModestWidgetFactory *widget_factory;
830 widget_factory = modest_main_window_get_widget_factory (main_window);
832 GTK_LABEL (modest_widget_factory_get_folder_info_label (widget_factory));
835 gtk_label_set_label (GTK_LABEL(folder_info_label), "");
839 factory = modest_tny_platform_factory_get_instance ();
840 header_view = modest_widget_factory_get_header_view (widget_factory);
841 conf = modest_tny_platform_factory_get_conf_instance
842 (MODEST_TNY_PLATFORM_FACTORY(factory));
843 g_object_unref (G_OBJECT (widget_factory));
845 if (!selected) { /* the folder was unselected; save it's settings */
846 modest_widget_memory_save (conf, G_OBJECT (header_view),
848 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
849 } else { /* the folder was selected */
852 num = tny_folder_get_all_count (folder);
853 unread = tny_folder_get_unread_count (folder);
855 title = g_strdup_printf ("Modest: %s",
856 tny_folder_get_name (folder));
858 gtk_window_set_title (GTK_WINDOW(main_window), title);
861 txt = g_strdup_printf (_("%d %s, %d unread"),
862 num, num==1 ? _("item") : _("items"), unread);
863 gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
866 modest_header_view_set_folder (header_view, folder);
867 modest_widget_memory_restore (conf, G_OBJECT(header_view),
873 _modest_ui_actions_on_password_requested (ModestTnyAccountStore *account_store,
874 const gchar* account_name,
878 ModestMainWindow *main_window)
881 GtkWidget *dialog, *entry, *remember_pass_check;
883 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
884 GTK_WINDOW (main_window),
892 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
893 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
897 entry = gtk_entry_new_with_max_length (40);
898 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
899 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
901 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
904 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
905 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
908 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
910 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
911 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
918 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
923 gtk_widget_destroy (dialog);
925 while (gtk_events_pending ())
926 gtk_main_iteration ();
929 /****************************************************/
931 * below some stuff to clearup statusbar messages after 1,5 seconds....
934 GtkWidget *status_bar;
935 GtkWidget *progress_bar;
940 on_statusbar_remove_msg (StatusRemoveData *data)
942 /* we need to test types, as this callback maybe called after the
943 * widgets have been destroyed
945 if (GTK_IS_STATUSBAR(data->status_bar))
946 gtk_statusbar_remove (GTK_STATUSBAR(data->status_bar),
948 if (GTK_IS_PROGRESS_BAR(data->progress_bar))
949 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(data->progress_bar),
956 statusbar_push (ModestWidgetFactory *factory, guint context_id, const gchar *msg)
959 StatusRemoveData *data;
960 GtkWidget *status_bar, *progress_bar;
965 progress_bar = modest_widget_factory_get_progress_bar (factory);
966 status_bar = modest_widget_factory_get_status_bar (factory);
968 id = gtk_statusbar_push (GTK_STATUSBAR(status_bar), 0, msg);
970 data = g_new (StatusRemoveData, 1);
971 data->status_bar = status_bar;
972 data->progress_bar = progress_bar;
975 g_timeout_add (1500, (GSourceFunc)on_statusbar_remove_msg, data);
977 /****************************************************************************/
980 _modest_ui_actions_on_connection_changed (TnyDevice *device,
982 ModestMainWindow *main_window)
984 GtkWidget *online_toggle;
985 ModestHeaderView *header_view;
986 ModestWidgetFactory *widget_factory;
988 widget_factory = modest_main_window_get_widget_factory (main_window);
989 header_view = modest_widget_factory_get_header_view (widget_factory);
990 online_toggle = modest_widget_factory_get_online_toggle (widget_factory);
992 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(online_toggle),
994 gtk_button_set_label (GTK_BUTTON(online_toggle),
995 online ? _("Online") : _("Offline"));
997 statusbar_push (widget_factory, 0,
998 online ? _("Modest went online") : _("Modest went offline"));
999 g_object_unref (G_OBJECT (widget_factory));
1001 /* If Modest has became online and the header view has a
1002 header selected then show it */
1004 GtkTreeSelection *selected;
1006 selected = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1007 _modest_header_view_change_selection (selected, header_view);
1012 _modest_ui_actions_on_online_toggle_toggled (GtkToggleButton *toggle,
1013 ModestMainWindow *main_window)
1017 TnyPlatformFactory *factory;
1018 TnyAccountStore *account_store;
1020 /* Get device. Do not ask the platform factory for it, because
1021 it returns always a new one */
1022 factory = modest_tny_platform_factory_get_instance ();
1023 account_store = tny_platform_factory_new_account_store (factory);
1024 device = tny_account_store_get_device (account_store);
1026 online = gtk_toggle_button_get_active (toggle);
1029 tny_device_force_online (device);
1031 tny_device_force_offline (device);
1035 _modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,
1036 ModestItemType type,
1037 ModestMainWindow *main_window)
1043 TnyPlatformFactory *factory;
1044 TnyAccountStore *account_store;
1046 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1048 /* Get device. Do not ask the platform factory for it, because
1049 it returns always a new one */
1050 factory = modest_tny_platform_factory_get_instance ();
1051 account_store = tny_platform_factory_new_account_store (factory);
1052 device = tny_account_store_get_device (account_store);
1054 gdk_threads_enter ();
1055 online = tny_device_is_online (device);
1058 /* already online -- the item is simply not there... */
1059 dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
1061 GTK_MESSAGE_WARNING,
1063 _("The %s you selected cannot be found"),
1065 gtk_dialog_run (GTK_DIALOG(dialog));
1068 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1069 GTK_WINDOW (main_window),
1072 GTK_RESPONSE_REJECT,
1074 GTK_RESPONSE_ACCEPT,
1077 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1078 "Do you want to get online?"), item);
1079 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1080 gtk_label_new (txt), FALSE, FALSE, 0);
1081 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1084 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1085 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1086 tny_device_force_online (device);
1089 gtk_widget_destroy (dialog);
1090 gdk_threads_leave ();
1094 _modest_ui_actions_on_header_status_update (ModestHeaderView *header_view,
1098 ModestMainWindow *main_window)
1100 GtkWidget *progress_bar;
1101 ModestWidgetFactory *widget_factory;
1103 widget_factory = modest_main_window_get_widget_factory (main_window);
1104 progress_bar = modest_widget_factory_get_progress_bar (widget_factory);
1107 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar),
1108 (gdouble)num/(gdouble)total);
1110 gtk_progress_bar_pulse (GTK_PROGRESS_BAR(progress_bar));
1112 statusbar_push (widget_factory, 0, msg);
1115 g_object_unref (G_OBJECT (widget_factory));
1120 _modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview,
1122 ModestMainWindow *main_window)
1124 ModestWidgetFactory *widget_factory;
1126 widget_factory = modest_main_window_get_widget_factory (main_window);
1127 statusbar_push (widget_factory, 0, link);
1128 g_object_unref (G_OBJECT (widget_factory));
1130 /* TODO: do something */
1135 _modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview,
1137 ModestMainWindow *main_window)
1140 ModestWidgetFactory *widget_factory;
1142 msg = g_strdup_printf (_("Opening %s..."), link);
1143 widget_factory = modest_main_window_get_widget_factory (main_window);
1144 statusbar_push (widget_factory, 0, msg);
1146 g_object_unref (G_OBJECT (widget_factory));
1150 /* TODO: do something */
1154 _modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview,
1156 ModestMainWindow *main_window)
1159 ModestWidgetFactory *widget_factory;
1161 msg = g_strdup_printf (_("Opening attachment %d..."), index);
1162 widget_factory = modest_main_window_get_widget_factory (main_window);
1163 statusbar_push (widget_factory, 0, msg);
1166 g_object_unref (G_OBJECT (widget_factory));
1167 /* TODO: do something */
1171 _modest_ui_actions_on_send (GtkWidget *widget,
1172 ModestEditMsgWindow *edit_window)
1174 TnyTransportAccount *transport_account;
1175 ModestMailOperation *mail_operation;
1178 data = modest_edit_msg_window_get_msg_data (edit_window);
1180 /* FIXME: Code added just for testing. The final version will
1181 use the send queue provided by tinymail and some
1186 TnyAccountStore *account_store;
1188 accounts = TNY_LIST(tny_simple_list_new ());
1189 account_store = modest_edit_msg_window_get_account_store (edit_window);
1190 tny_account_store_get_accounts (account_store, accounts,
1191 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
1192 g_object_unref (G_OBJECT (account_store));
1194 iter = tny_list_create_iterator(accounts);
1195 tny_iterator_first (iter);
1196 if (tny_iterator_is_done (iter)) {
1197 /* FIXME: Add error handling through mail operation */
1198 g_printerr("modest: no transport accounts defined\n");
1199 modest_edit_msg_window_free_msg_data (edit_window, data);
1202 transport_account = TNY_TRANSPORT_ACCOUNT (tny_iterator_get_current(iter));
1203 g_object_ref (transport_account);
1205 tny_list_foreach (accounts, (GFunc) g_object_unref, NULL);
1206 g_object_unref (G_OBJECT (accounts));
1207 g_object_unref (G_OBJECT (iter));
1210 mail_operation = modest_mail_operation_new ();
1212 modest_mail_operation_send_new_mail (mail_operation,
1222 g_object_unref (G_OBJECT (mail_operation));
1223 g_object_unref (G_OBJECT (transport_account));
1224 modest_edit_msg_window_free_msg_data (edit_window, data);
1226 /* Save settings and close the window */
1227 /* save_settings (edit_window) */
1228 gtk_widget_destroy (GTK_WIDGET (edit_window));