* support main- and edt-toolbars
[modest] / src / modest-widget-factory.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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.
16  *
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.
28  */
29
30 #include "modest-widget-factory.h"
31 #include <tny-account-store-iface.h>
32 #include <tny-device-iface.h>
33
34 /* 'private'/'protected' functions */
35 static void modest_widget_factory_class_init    (ModestWidgetFactoryClass *klass);
36 static void modest_widget_factory_init          (ModestWidgetFactory *obj);
37 static void modest_widget_factory_finalize      (GObject *obj);
38
39
40 /* callbacks */
41 static void on_folder_selected         (ModestFolderView *folder_view,
42                                         TnyFolderIface *folder,
43                                         ModestWidgetFactory *self);
44 static void on_message_selected        (ModestHeaderView *header_view, TnyMsgIface *msg,
45                                         ModestWidgetFactory *self);
46 static void on_header_status_update    (ModestHeaderView *header_view, const gchar *msg,
47                                         gint status_id, ModestWidgetFactory *self);
48 static void on_msg_link_hover          (ModestMsgView *msgview, const gchar* link,
49                                         ModestWidgetFactory *self);
50 static void on_msg_link_clicked        (ModestMsgView *msgview, const gchar* link,
51                                         ModestWidgetFactory *self);
52 static void on_msg_attachment_clicked  (ModestMsgView *msgview, int index,
53                                         ModestWidgetFactory *self);
54
55 static void on_connection_changed (TnyDeviceIface *device, gboolean online,
56                                    ModestWidgetFactory *self);
57 static void on_online_toggle_toggled (GtkToggleButton *toggle, ModestWidgetFactory *factory);
58
59 static void on_main_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id, 
60                                             ModestWidgetFactory *self);
61 static void on_password_requested (ModestTnyAccountStore *account_store, const gchar* account_name,
62                                    gchar **password, gboolean *cancel, ModestWidgetFactory *self);
63
64 static void on_item_not_found     (ModestHeaderView* header_view, ModestItemType type,
65                                    ModestWidgetFactory *self);
66
67
68 /* list my signals */
69 enum {
70         /* MY_SIGNAL_1, */
71         /* MY_SIGNAL_2, */
72         LAST_SIGNAL
73 };
74
75 typedef struct _ModestWidgetFactoryPrivate ModestWidgetFactoryPrivate;
76 struct _ModestWidgetFactoryPrivate {
77         
78         ModestTnyAccountStore *account_store;
79         ModestAccountMgr      *account_mgr;
80         ModestConf            *conf;
81         
82         ModestHeaderView      *header_view;
83         ModestFolderView      *folder_view;
84         ModestMsgView         *msg_preview;
85         ModestToolbar         *main_toolbar, *edit_toolbar;
86
87         GtkWidget             *progress_bar;
88         GtkWidget             *status_bar;
89         GtkWidget             *folder_info_label;
90
91         GtkWidget             *online_toggle;
92 };
93 #define MODEST_WIDGET_FACTORY_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
94                                                    MODEST_TYPE_WIDGET_FACTORY, \
95                                                    ModestWidgetFactoryPrivate))
96 /* globals */
97 static GObjectClass *parent_class = NULL;
98
99 /* uncomment the following if you have defined any signals */
100 /* static guint signals[LAST_SIGNAL] = {0}; */
101
102 GType
103 modest_widget_factory_get_type (void)
104 {
105         static GType my_type = 0;
106         if (!my_type) {
107                 static const GTypeInfo my_info = {
108                         sizeof(ModestWidgetFactoryClass),
109                         NULL,           /* base init */
110                         NULL,           /* base finalize */
111                         (GClassInitFunc) modest_widget_factory_class_init,
112                         NULL,           /* class finalize */
113                         NULL,           /* class data */
114                         sizeof(ModestWidgetFactory),
115                         1,              /* n_preallocs */
116                         (GInstanceInitFunc) modest_widget_factory_init,
117                         NULL
118                 };
119                 my_type = g_type_register_static (G_TYPE_OBJECT,
120                                                   "ModestWidgetFactory",
121                                                   &my_info, 0);
122         }
123         return my_type;
124 }
125
126 static void
127 modest_widget_factory_class_init (ModestWidgetFactoryClass *klass)
128 {
129         GObjectClass *gobject_class;
130         gobject_class = (GObjectClass*) klass;
131
132         parent_class            = g_type_class_peek_parent (klass);
133         gobject_class->finalize = modest_widget_factory_finalize;
134
135         g_type_class_add_private (gobject_class, sizeof(ModestWidgetFactoryPrivate));
136 }
137
138 static void
139 modest_widget_factory_init (ModestWidgetFactory *obj)
140 {
141         ModestWidgetFactoryPrivate *priv;
142         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(obj);
143
144         priv->conf          = NULL;
145         priv->account_mgr   = NULL;
146         priv->account_store = NULL;
147         
148         priv->progress_bar = gtk_progress_bar_new ();
149         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(priv->progress_bar),
150                                        1.0);
151         priv->status_bar   = gtk_statusbar_new ();
152         gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(priv->status_bar),
153                                            FALSE);
154 }
155
156 static void
157 modest_widget_factory_finalize (GObject *obj)
158 {
159         ModestWidgetFactoryPrivate *priv;
160         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(obj);
161
162         if (priv->account_mgr) {
163                 g_object_unref (G_OBJECT(priv->account_mgr));
164                 priv->account_mgr = NULL;
165         }
166
167         if (priv->conf) {
168                 g_object_unref (G_OBJECT(priv->conf));
169                 priv->conf = NULL;
170         }
171
172         if (priv->account_store) {
173                 g_object_unref (G_OBJECT(priv->account_store));
174                 priv->account_store = NULL;
175         }
176 }
177
178
179
180 static void
181 init_signals (ModestWidgetFactory *self)
182 {
183         
184         TnyDeviceIface *device;
185         ModestWidgetFactoryPrivate *priv;
186         
187         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
188
189         /* folder view */
190         g_signal_connect (G_OBJECT(priv->folder_view), "folder_selected",
191                           G_CALLBACK(on_folder_selected), self);
192
193         /* header view */
194         g_signal_connect (G_OBJECT(priv->header_view), "status_update",
195                           G_CALLBACK(on_header_status_update), self);
196         g_signal_connect (G_OBJECT(priv->header_view), "message_selected",
197                           G_CALLBACK(on_message_selected), self);
198         g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
199                           G_CALLBACK(on_item_not_found), self);
200
201         
202         /* msg preview */
203         g_signal_connect (G_OBJECT(priv->msg_preview), "link_clicked",
204                           G_CALLBACK(on_msg_link_clicked), self);
205         g_signal_connect (G_OBJECT(priv->msg_preview), "link_hover",
206                           G_CALLBACK(on_msg_link_hover), self);
207         g_signal_connect (G_OBJECT(priv->msg_preview), "attachment_clicked",
208                           G_CALLBACK(on_msg_attachment_clicked), self);
209
210         /* account store */     
211         g_signal_connect (G_OBJECT(priv->account_store), "password_requested",
212                           G_CALLBACK(on_password_requested), self);     
213
214         /* FIXME: const casting is evil ==> tinymail */
215         device = (TnyDeviceIface*)tny_account_store_iface_get_device
216                 (TNY_ACCOUNT_STORE_IFACE(priv->account_store));
217         if (device) {
218                 g_signal_connect (G_OBJECT(device), "connection_changed",
219                                   G_CALLBACK(on_connection_changed), self);
220                 g_signal_connect (G_OBJECT(priv->online_toggle), "toggled",
221                                   G_CALLBACK(on_online_toggle_toggled), self);
222                 
223                 /* init toggle in correct state */
224                 on_connection_changed (device,
225                                        tny_device_iface_is_online (device),
226                                        self);
227         }
228 }
229
230 static gboolean
231 init_widgets (ModestWidgetFactory *self)
232 {
233         ModestWidgetFactoryPrivate *priv;
234         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
235
236         /* folder view */
237         if (!(priv->folder_view =
238               MODEST_FOLDER_VIEW(modest_folder_view_new (priv->account_store)))) {
239                 g_printerr ("modest: cannot instantiate folder view\n");
240                 return FALSE;
241         }
242
243         /* header view */
244         if (!(priv->header_view =
245               MODEST_HEADER_VIEW(modest_header_view_new
246                                  (NULL, NULL,MODEST_HEADER_VIEW_STYLE_NORMAL)))) {
247                 g_printerr ("modest: cannot instantiate header view\n");
248                 return FALSE;
249         }
250         
251         
252         /* msg preview */
253         if (!(priv->msg_preview = MODEST_MSG_VIEW(modest_msg_view_new (NULL)))) {
254                 g_printerr ("modest: cannot instantiate header view\n");
255                 return FALSE;
256         }
257
258
259
260         /* online/offline combo */
261         priv->online_toggle = gtk_toggle_button_new ();
262
263         /* label with number of items, unread items for 
264            the current folder */
265         priv->folder_info_label = gtk_label_new (NULL);
266         
267         init_signals (self);
268         
269         return TRUE;
270 }
271
272
273 ModestWidgetFactory*
274 modest_widget_factory_new (ModestConf *conf,
275                            ModestTnyAccountStore *account_store,
276                            ModestAccountMgr *account_mgr)
277 {
278         GObject *obj;
279         ModestWidgetFactoryPrivate *priv;
280
281         g_return_val_if_fail (account_store, NULL);
282         g_return_val_if_fail (account_mgr, NULL);
283         g_return_val_if_fail (conf, NULL);
284         
285         obj  = g_object_new(MODEST_TYPE_WIDGET_FACTORY, NULL);  
286         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(obj);
287
288         g_object_ref (G_OBJECT(conf));
289         priv->conf = conf;
290         
291         g_object_ref (G_OBJECT(account_mgr));
292         priv->account_mgr = account_mgr;
293         
294         g_object_ref (G_OBJECT(account_store));
295         priv->account_store = account_store;
296
297         if (!init_widgets (MODEST_WIDGET_FACTORY(obj))) {
298                 g_printerr ("modest: widget factory failed to init widgets\n");
299                 g_object_unref (obj);
300                 return NULL;
301         }
302         
303         return MODEST_WIDGET_FACTORY(obj);
304 }
305
306
307
308
309 ModestFolderView*
310 modest_widget_factory_get_folder_view (ModestWidgetFactory *self)
311 {
312         g_return_val_if_fail (self, NULL);
313         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->folder_view;
314 }
315
316
317 ModestHeaderView*
318 modest_widget_factory_get_header_view (ModestWidgetFactory *self)
319 {
320         g_return_val_if_fail (self, NULL);
321         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->header_view;
322 }
323
324
325 ModestMsgView*
326 modest_widget_factory_get_msg_preview (ModestWidgetFactory *self)
327 {
328         g_return_val_if_fail (self, NULL);
329         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->msg_preview;
330 }
331
332
333 ModestAccountView*
334 modest_widget_factory_get_account_view (ModestWidgetFactory *self)
335 {
336         ModestWidgetFactoryPrivate *priv;
337         
338         g_return_val_if_fail (self, NULL);
339         priv =  MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
340         
341         return modest_account_view_new (priv->account_mgr);
342 }
343
344
345
346 GtkWidget*
347 modest_widget_factory_get_progress_bar (ModestWidgetFactory *self)
348 {
349         g_return_val_if_fail (self, NULL);
350         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->progress_bar;
351 }
352
353
354 GtkWidget*
355 modest_widget_factory_get_status_bar (ModestWidgetFactory *self)
356 {
357         g_return_val_if_fail (self, NULL);
358         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->status_bar;
359 }
360
361
362 GtkWidget*
363 modest_widget_factory_get_combo_box (ModestWidgetFactory *self, ModestComboBoxType type)
364 {
365         GtkWidget *combo_box;
366         const gchar **protos, **cursor; 
367
368         g_return_val_if_fail (self, NULL);
369
370         combo_box = gtk_combo_box_new_text ();
371         
372         switch (type) {
373         case MODEST_COMBO_BOX_TYPE_STORE_PROTOS:
374                 cursor = protos = modest_proto_store_protos ();
375                 break;
376         case MODEST_COMBO_BOX_TYPE_TRANSPORT_PROTOS:
377                 cursor = protos = modest_proto_transport_protos ();
378                 break;
379         case MODEST_COMBO_BOX_TYPE_SECURITY_PROTOS:
380                 cursor = protos = modest_proto_security_protos ();
381                 break;
382         case MODEST_COMBO_BOX_TYPE_AUTH_PROTOS:
383                 cursor = protos = modest_proto_auth_protos ();
384                 break;
385         default:
386                 g_assert_not_reached ();
387         }
388         while (cursor && *cursor) {
389                 gtk_combo_box_append_text (GTK_COMBO_BOX(combo_box),
390                                            (const gchar*)*cursor);
391                 ++cursor;
392         }
393         gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), 0);
394         
395         return combo_box;
396 }
397
398
399
400
401 GtkWidget*
402 modest_widget_factory_get_online_toggle (ModestWidgetFactory *self)
403 {
404         g_return_val_if_fail (self, NULL);
405         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->online_toggle;
406 }
407
408
409
410 GtkWidget*
411 modest_widget_factory_get_folder_info_label (ModestWidgetFactory *self)
412 {
413         g_return_val_if_fail (self, NULL);
414         return MODEST_WIDGET_FACTORY_GET_PRIVATE(self)->folder_info_label;
415 }
416
417
418
419
420 ModestToolbar*
421 modest_widget_factory_get_main_toolbar (ModestWidgetFactory *self, 
422                                         GSList *items)
423 {
424         ModestWidgetFactoryPrivate *priv;
425         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
426
427         if (priv->main_toolbar)
428                 return priv->main_toolbar;
429
430         priv->main_toolbar = modest_toolbar_new (items);
431         if (!priv->main_toolbar) {
432                 g_printerr ("modest: failed to create main toolbar\n");
433                 return NULL;
434         }
435         
436         g_signal_connect (G_OBJECT(priv->main_toolbar), "button_clicked",
437                           G_CALLBACK(on_main_toolbar_button_clicked), self);
438         
439         return priv->main_toolbar;
440 }
441
442
443 ModestToolbar*
444 modest_widget_factory_get_edit_toolbar (ModestWidgetFactory *self, 
445                                         GSList *items)
446 {
447         return modest_toolbar_new (items);
448 }
449
450
451
452 static void
453 on_folder_selected (ModestFolderView *folder_view, TnyFolderIface *folder,
454                     ModestWidgetFactory *self)
455 {
456         ModestWidgetFactoryPrivate *priv;
457         gchar *txt;
458
459         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
460         
461         modest_header_view_set_folder (priv->header_view, folder);
462         
463         if (folder) {
464                 guint num, unread;
465                 
466                 num    = tny_folder_iface_get_all_count    (folder);
467                 unread = tny_folder_iface_get_unread_count (folder); 
468
469                 txt = g_strdup_printf (_("%d %s, %d unread"),
470                                        num, num==1 ? _("item") : _("items"), unread);
471                 
472                 gtk_label_set_label (GTK_LABEL(priv->folder_info_label), txt);
473                 g_free (txt);
474         } else
475                 gtk_label_set_label (GTK_LABEL(priv->folder_info_label), "");   
476 }
477
478
479 static void
480 on_message_selected (ModestHeaderView *folder_view, TnyMsgIface *msg,
481                      ModestWidgetFactory *self)
482 {       
483         ModestWidgetFactoryPrivate *priv;
484         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
485         
486         modest_msg_view_set_message (priv->msg_preview, msg);
487 }
488
489
490 /*
491  * below some stuff to clearup statusbar messages after 1,5 seconds....
492  */
493 typedef struct {
494         GtkWidget *status_bar;
495         GtkWidget *progress_bar;
496         guint     msg_id;
497 } StatusRemoveData;
498
499
500 static gboolean
501 on_statusbar_remove_msg (StatusRemoveData *data)
502 {
503         /* we need to test types, as this callback maybe called after the
504          * widgets have been destroyed
505          */
506         if (GTK_IS_STATUSBAR(data->status_bar)) 
507                 gtk_statusbar_remove (GTK_STATUSBAR(data->status_bar),
508                                       0, data->msg_id);
509         if (GTK_IS_PROGRESS_BAR(data->progress_bar))
510                 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(data->progress_bar),
511                                                1.0);
512         g_free (data);
513         return FALSE;
514 }
515
516
517 static void
518 statusbar_push (ModestWidgetFactory *self, guint context_id, const gchar *msg)
519 {
520         guint id;
521         StatusRemoveData *data;
522         ModestWidgetFactoryPrivate *priv;
523         
524         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
525         
526         if (!msg)
527                 return;
528         
529         id = gtk_statusbar_push (GTK_STATUSBAR(priv->status_bar), 0, msg);
530
531         data = g_new (StatusRemoveData, 1);
532         data->status_bar   = priv->status_bar;
533         data->progress_bar = priv->progress_bar;
534         data->msg_id     = id;
535
536         g_timeout_add (1500, (GSourceFunc)on_statusbar_remove_msg, data);
537 }
538 /****************************************************************************/
539
540
541 static void
542 on_header_status_update (ModestHeaderView *header_view, const gchar *msg,
543                          gint status_id, ModestWidgetFactory *self)
544 {
545         ModestWidgetFactoryPrivate *priv;
546         
547         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
548                         
549         gtk_progress_bar_pulse (GTK_PROGRESS_BAR(priv->progress_bar));
550         statusbar_push (self, 0, msg);
551 }
552
553
554 static void
555 on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
556                    ModestWidgetFactory *self)
557 {
558         ModestWidgetFactoryPrivate *priv;
559         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
560         
561         statusbar_push (self, 0, link);
562
563 }       
564
565
566 static void
567 on_msg_link_clicked  (ModestMsgView *msgview, const gchar* link,
568                       ModestWidgetFactory *self)
569 {
570         gchar *msg;
571         msg = g_strdup_printf (_("Opening %s..."), link);
572         statusbar_push (self, 0, msg);
573         g_free (msg);
574 }
575
576 static void
577 on_msg_attachment_clicked  (ModestMsgView *msgview, int index,
578                             ModestWidgetFactory *self)
579 {
580         gchar *msg;
581         
582         msg = g_strdup_printf (_("Opening attachment %d..."), index);
583         statusbar_push (self, 0, msg);
584         
585         g_free (msg);
586 }
587
588
589 static void
590 on_connection_changed (TnyDeviceIface *device, gboolean online,
591                        ModestWidgetFactory *self)
592 {
593         ModestWidgetFactoryPrivate *priv;
594         priv = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
595
596         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(priv->online_toggle),
597                                       online);
598         gtk_button_set_label (GTK_BUTTON(priv->online_toggle),
599                               online ? _("Online") : _("Offline"));
600
601         statusbar_push (self, 0, online ? _("Modest went online") : _("Modest went offline"));
602 }
603
604
605 static void
606 on_online_toggle_toggled (GtkToggleButton *toggle, ModestWidgetFactory *self)
607 {
608         gboolean online;
609         const TnyDeviceIface *device;
610         ModestWidgetFactoryPrivate *priv;
611         
612         priv    = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
613         online  = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(priv->online_toggle));
614         device  = tny_account_store_iface_get_device
615                 (TNY_ACCOUNT_STORE_IFACE(priv->account_store)); 
616
617         /* FIXME: const casting should not be necessary ==> tinymail */
618         if (online)  /* we're moving to online state */
619                 tny_device_iface_force_online ((TnyDeviceIface*)device);
620         else  /* we're moving to offline state */
621                 tny_device_iface_force_offline ((TnyDeviceIface*)device);
622 }
623
624
625 static void on_item_not_found     (ModestHeaderView* header_view, ModestItemType type,
626                                    ModestWidgetFactory *self)
627 {
628         /* FIXME ==> ask from UI... */
629         GtkWidget *dialog;
630         gchar *txt;
631         gboolean online;
632         gchar *item = type == MODEST_ITEM_TYPE_FOLDER ? "folder" : "message";
633         
634         TnyDeviceIface *device;
635         ModestWidgetFactoryPrivate *priv;
636         
637         priv    = MODEST_WIDGET_FACTORY_GET_PRIVATE(self);
638         device  = tny_account_store_iface_get_device
639                 (TNY_ACCOUNT_STORE_IFACE(priv->account_store));
640         
641         online = tny_device_iface_is_online (device);
642         if (online) {
643                 /* already online -- the item is simply not there... */
644                 dialog = gtk_message_dialog_new (NULL,
645                                                  GTK_DIALOG_MODAL,
646                                                  GTK_MESSAGE_WARNING,
647                                                  GTK_BUTTONS_OK,
648                                                  _("The %s you selected cannot be found"),
649                                                  item);
650                 gtk_dialog_run (GTK_DIALOG(dialog));
651         } else {
652
653                 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
654                                                       NULL,
655                                                       GTK_DIALOG_MODAL,
656                                                       GTK_STOCK_CANCEL,
657                                                       GTK_RESPONSE_REJECT,
658                                                       GTK_STOCK_OK,
659                                                       GTK_RESPONSE_ACCEPT,
660                                                       NULL);
661
662                 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
663                                          "Do you want to get online?"), item);
664                 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), 
665                                     gtk_label_new (txt), FALSE, FALSE, 0);
666                 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
667                 g_free (txt);
668
669                 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
670                 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
671                         tny_device_iface_force_online (device);
672         }
673         gtk_widget_destroy (dialog);
674 }
675
676
677 static void
678 on_main_toolbar_button_clicked (ModestToolbar *toolbar, ModestToolbarButton button_id, 
679                                 ModestWidgetFactory *self)
680 {
681         g_printerr ("modest: button %d clicked\n", button_id);
682 }
683
684
685 static void
686 on_password_requested (ModestTnyAccountStore *account_store, const gchar* account_name,
687                        gchar **password, gboolean *cancel, ModestWidgetFactory *self)
688 {
689         gchar *txt;
690         GtkWidget *dialog, *entry;
691         
692         dialog = gtk_dialog_new_with_buttons (_("Password requested"),
693                                               NULL,
694                                               GTK_DIALOG_MODAL,
695                                               GTK_STOCK_CANCEL,
696                                               GTK_RESPONSE_REJECT,
697                                               GTK_STOCK_OK,
698                                               GTK_RESPONSE_ACCEPT,
699                                               NULL);
700
701         txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
702         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
703                             FALSE, FALSE, 0);
704         g_free (txt);   
705
706         entry = gtk_entry_new_with_max_length (40);
707         gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
708         gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
709         
710         gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
711                             TRUE, FALSE, 0);    
712         
713         gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
714         
715         if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
716                 *password = g_strdup(gtk_entry_get_text (GTK_ENTRY(entry)));
717                 *cancel   = FALSE;
718         } else {
719                 *password = NULL;
720                 *cancel   = TRUE;
721         }       
722         gtk_widget_destroy (dialog);
723 }
724