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