1 /* modest-gnome-bar.c */
3 /* insert (c)/licensing information) */
5 #include "modest-gnome-info-bar.h"
6 #include <gtk/gtkprogressbar.h>
7 #include <gtk/gtkstatusbar.h>
8 /* include other impl specific header files */
10 /* 'private'/'protected' functions */
11 static void modest_gnome_info_bar_class_init (ModestGnomeInfoBarClass *klass);
12 static void modest_gnome_info_bar_init (ModestGnomeInfoBar *obj);
13 static void modest_gnome_info_bar_finalize (GObject *obj);
15 static void modest_gnome_info_bar_add_operation (ModestProgressObject *self,
16 ModestMailOperation *mail_op);
18 static void modest_gnome_info_bar_remove_operation (ModestProgressObject *self,
19 ModestMailOperation *mail_op);
21 static void on_progress_changed (ModestMailOperation *mail_op,
22 ModestGnomeInfoBar *self);
24 static gboolean progressbar_clean (GtkProgressBar *bar);
25 static gboolean statusbar_clean (GtkStatusbar *bar);
34 typedef struct _ObservableData ObservableData;
35 struct _ObservableData {
37 ModestMailOperation *mail_op;
40 typedef struct _ModestGnomeInfoBarPrivate ModestGnomeInfoBarPrivate;
41 struct _ModestGnomeInfoBarPrivate {
43 ModestMailOperation *current;
45 GtkWidget *status_bar;
46 GtkWidget *progress_bar;
48 guint status_bar_timeout;
49 guint progress_bar_timeout;
52 #define MODEST_GNOME_INFO_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
53 MODEST_TYPE_GNOME_INFO_BAR, \
54 ModestGnomeInfoBarPrivate))
56 static GtkHBoxClass *parent_class = NULL;
58 /* uncomment the following if you have defined any signals */
59 /* static guint signals[LAST_SIGNAL] = {0}; */
62 modest_progress_object_init (gpointer g, gpointer iface_data)
64 ModestProgressObjectIface *klass = (ModestProgressObjectIface *)g;
66 klass->add_operation_func = modest_gnome_info_bar_add_operation;
67 klass->remove_operation_func = modest_gnome_info_bar_remove_operation;
71 modest_gnome_info_bar_get_type (void)
73 static GType my_type = 0;
75 static const GTypeInfo my_info = {
76 sizeof(ModestGnomeInfoBarClass),
78 NULL, /* base finalize */
79 (GClassInitFunc) modest_gnome_info_bar_class_init,
80 NULL, /* class finalize */
81 NULL, /* class data */
82 sizeof(ModestGnomeInfoBar),
84 (GInstanceInitFunc) modest_gnome_info_bar_init,
88 static const GInterfaceInfo modest_progress_object_info =
90 (GInterfaceInitFunc) modest_progress_object_init, /* interface_init */
91 NULL, /* interface_finalize */
92 NULL /* interface_data */
95 my_type = g_type_register_static (GTK_TYPE_HBOX,
99 g_type_add_interface_static (my_type, MODEST_TYPE_PROGRESS_OBJECT,
100 &modest_progress_object_info);
106 modest_gnome_info_bar_class_init (ModestGnomeInfoBarClass *klass)
108 GObjectClass *gobject_class;
109 gobject_class = (GObjectClass*) klass;
111 parent_class = g_type_class_peek_parent (klass);
112 gobject_class->finalize = modest_gnome_info_bar_finalize;
114 g_type_class_add_private (gobject_class, sizeof(ModestGnomeInfoBarPrivate));
118 modest_gnome_info_bar_init (ModestGnomeInfoBar *obj)
120 ModestGnomeInfoBarPrivate *priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE(obj);
122 priv->observables = NULL;
123 priv->current = NULL;
126 priv->status_bar = gtk_statusbar_new ();
127 gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (priv->status_bar), FALSE);
130 priv->progress_bar = gtk_progress_bar_new ();
131 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress_bar), 1.0);
132 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (priv->progress_bar),
133 PANGO_ELLIPSIZE_END);
136 priv->status_bar_timeout = 0;
137 priv->progress_bar_timeout = 0;
140 gtk_box_pack_start (GTK_BOX (obj), priv->status_bar, TRUE, TRUE, 0);
141 gtk_box_pack_start (GTK_BOX (obj), priv->progress_bar, FALSE, FALSE, 0);
145 destroy_observable_data (ObservableData *data)
147 g_signal_handler_disconnect (data->mail_op, data->signal_handler);
148 g_object_unref (data->mail_op);
152 modest_gnome_info_bar_finalize (GObject *obj)
154 ModestGnomeInfoBarPrivate *priv;
156 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE(obj);
157 if (priv->observables) {
160 for (tmp = priv->observables; tmp; tmp = g_slist_next (tmp)) {
161 destroy_observable_data ((ObservableData *) tmp->data);
164 g_slist_free (priv->observables);
165 priv->observables = NULL;
168 if (priv->status_bar_timeout > 0) {
169 g_source_remove (priv->status_bar_timeout);
170 priv->status_bar_timeout = 0;
173 if (priv->progress_bar_timeout > 0) {
174 g_source_remove (priv->progress_bar_timeout);
175 priv->progress_bar_timeout = 0;
178 G_OBJECT_CLASS(parent_class)->finalize (obj);
182 modest_gnome_info_bar_new (void)
184 return GTK_WIDGET (g_object_new (MODEST_TYPE_GNOME_INFO_BAR, NULL));
188 modest_gnome_info_bar_add_operation (ModestProgressObject *self,
189 ModestMailOperation *mail_op)
191 ModestGnomeInfoBar *me;
192 ObservableData *data;
193 ModestGnomeInfoBarPrivate *priv;
195 me = MODEST_GNOME_INFO_BAR (self);
196 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (me);
198 data = g_malloc0 (sizeof (ObservableData));
199 data->mail_op = g_object_ref (mail_op);
200 data->signal_handler = g_signal_connect (data->mail_op,
202 G_CALLBACK (on_progress_changed),
205 if (priv->observables == NULL) {
206 priv->current = mail_op;
208 priv->observables = g_slist_append (priv->observables, data);
212 compare_observable_data (ObservableData *data1, ObservableData *data2)
214 if (data1->mail_op == data2->mail_op)
221 modest_gnome_info_bar_remove_operation (ModestProgressObject *self,
222 ModestMailOperation *mail_op)
224 ModestGnomeInfoBar *me;
225 ModestGnomeInfoBarPrivate *priv;
228 me = MODEST_GNOME_INFO_BAR (self);
229 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (me);
231 link = g_slist_find_custom (priv->observables,
233 (GCompareFunc) compare_observable_data);
235 /* Remove the item */
237 priv->observables = g_slist_remove_link (priv->observables, link);
238 destroy_observable_data ((ObservableData *) link->data);
241 /* Update the current mail operation */
242 if (priv->current == mail_op) {
243 if (priv->observables)
244 priv->current = ((ObservableData *) priv->observables->data)->mail_op;
246 priv->current = NULL;
248 /* Refresh the view */
249 progressbar_clean (GTK_PROGRESS_BAR (priv->progress_bar));
254 on_progress_changed (ModestMailOperation *mail_op,
255 ModestGnomeInfoBar *self)
257 ModestGnomeInfoBarPrivate *priv;
259 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
261 /* If the mail operation is the currently shown one */
262 if (priv->current == mail_op) {
265 msg = g_strdup_printf ("Mail operation %d of %d",
266 modest_mail_operation_get_task_done (mail_op),
267 modest_mail_operation_get_task_total (mail_op));
268 modest_gnome_info_bar_set_message (self, msg);
274 progressbar_clean (GtkProgressBar *bar)
276 gtk_progress_bar_set_fraction (bar, 0);
277 gtk_progress_bar_set_text (bar, 0);
282 statusbar_clean (GtkStatusbar *bar)
284 gtk_statusbar_push (bar, 0, "");
289 modest_gnome_info_bar_set_message (ModestGnomeInfoBar *self,
290 const gchar *message)
292 ModestGnomeInfoBarPrivate *priv;
294 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
296 /* Set a message. Clean it after 2.5 seconds */
297 gtk_statusbar_push (GTK_STATUSBAR (priv->status_bar), 0, message);
298 priv->status_bar_timeout = g_timeout_add (2500,
299 (GSourceFunc) statusbar_clean,
304 modest_gnome_info_bar_set_progress (ModestGnomeInfoBar *self,
305 const gchar *message,
309 ModestGnomeInfoBarPrivate *priv;
311 priv = MODEST_GNOME_INFO_BAR_GET_PRIVATE (self);
315 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progress_bar),
316 (gdouble)done/(gdouble)total);
318 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progress_bar));
321 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progress_bar), message);