Updated Spanish translation
[anjuta-git-plugin.git] / libanjuta / anjuta-status.c
blob2f977a3c150779bf454d6101edadfc37768c6d84
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-status.c
4 * Copyright (C) 2004 Naba Kumar <naba@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc., 59
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 /**
22 * SECTION:anjuta-status
23 * @short_description: Program status such as status message, progress etc.
24 * @see_also:
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-status.h
30 #include <config.h>
31 #include <gtk/gtkwindow.h>
32 #include <libanjuta/anjuta-status.h>
33 #include <libanjuta/anjuta-utils.h>
34 #include <libanjuta/resources.h>
35 #include <libanjuta/e-splash.h>
37 struct _AnjutaStatusPriv
39 GHashTable *default_status_items;
40 gint busy_count;
41 GHashTable *widgets;
43 /* Progress bar */
44 gint total_ticks;
45 gint current_ticks;
47 /* Splash */
48 GtkWidget *splash;
49 gboolean disable_splash;
50 gchar *splash_file;
51 gint splash_progress_position;
53 /* Title window */
54 GtkWindow *window;
57 enum {
58 BUSY,
59 LAST_SIGNAL
62 static gpointer parent_class = NULL;
63 static guint status_signals[LAST_SIGNAL] = { 0 };
65 static void on_widget_destroy (AnjutaStatus *status, GObject *widget);
67 static void
68 anjuta_status_finalize (GObject *widget)
70 g_free(ANJUTA_STATUS(widget)->priv);
71 GNOME_CALL_PARENT(G_OBJECT_CLASS, finalize, (widget));
74 static void
75 foreach_widget_unref (gpointer key, gpointer value, gpointer data)
77 g_object_weak_unref (G_OBJECT (key), (GWeakNotify) on_widget_destroy, data);
80 static void
81 anjuta_status_dispose (GObject *widget)
83 AnjutaStatus *status;
85 status = ANJUTA_STATUS (widget);
87 if (status->priv->default_status_items)
89 g_hash_table_destroy (status->priv->default_status_items);
90 status->priv->default_status_items = NULL;
92 if (status->priv->splash != NULL) {
93 gtk_widget_destroy (status->priv->splash);
94 status->priv->splash = NULL;
96 if (status->priv->splash_file)
98 g_free (status->priv->splash_file);
99 status->priv->splash_file = NULL;
101 if (status->priv->widgets)
103 g_hash_table_foreach (status->priv->widgets,
104 foreach_widget_unref, widget);
105 g_hash_table_destroy (status->priv->widgets);
106 status->priv->widgets = NULL;
109 GNOME_CALL_PARENT(G_OBJECT_CLASS, dispose, (widget));
112 static void
113 anjuta_status_instance_init (AnjutaStatus *status)
115 status->priv = g_new0 (AnjutaStatusPriv, 1);
116 status->priv->splash_file = NULL;
117 status->priv->splash_progress_position = 0;
118 status->priv->disable_splash = FALSE;
119 status->priv->total_ticks = 0;
120 status->priv->current_ticks = 0;
121 status->priv->splash = NULL;
122 status->priv->default_status_items =
123 g_hash_table_new_full (g_str_hash, g_str_equal,
124 g_free, g_free);
127 static void
128 anjuta_status_class_init (AnjutaStatusClass *class)
130 GObjectClass *object_class;
132 parent_class = g_type_class_peek_parent (class);
133 object_class = (GObjectClass*) class;
134 object_class->finalize = anjuta_status_finalize;
135 object_class->dispose = anjuta_status_dispose;
137 status_signals[BUSY] =
138 g_signal_new ("busy",
139 ANJUTA_TYPE_STATUS,
140 G_SIGNAL_RUN_LAST,
141 G_STRUCT_OFFSET (AnjutaStatusClass, busy),
142 NULL, NULL,
143 g_cclosure_marshal_VOID__BOOLEAN,
144 G_TYPE_NONE, 1,
145 G_TYPE_BOOLEAN);
148 GtkWidget *
149 anjuta_status_new (void)
151 GtkWidget *status;
153 status = GTK_WIDGET (g_object_new (ANJUTA_TYPE_STATUS,
154 "has-progress", TRUE, "has-status", TRUE,
155 "interactivity", GNOME_PREFERENCES_NEVER, NULL));
156 return status;
159 void
160 anjuta_status_set (AnjutaStatus *status, const gchar * mesg, ...)
162 gchar* message;
163 va_list args;
165 g_return_if_fail (ANJUTA_IS_STATUS (status));
166 g_return_if_fail (mesg != NULL);
168 va_start (args, mesg);
169 message = g_strdup_vprintf (mesg, args);
170 va_end (args);
171 gnome_appbar_set_status (GNOME_APPBAR (status), message);
172 g_free(message);
175 void
176 anjuta_status_push (AnjutaStatus *status, const gchar * mesg, ...)
178 gchar* message;
179 va_list args;
181 g_return_if_fail (ANJUTA_IS_STATUS (status));
182 g_return_if_fail (mesg != NULL);
184 va_start (args, mesg);
185 message = g_strdup_vprintf (mesg, args);
186 va_end (args);
187 gnome_appbar_push (GNOME_APPBAR (status), message);
188 g_free(message);
191 static void
192 foreach_widget_set_cursor (gpointer widget, gpointer value, gpointer cursor)
194 if (GTK_WIDGET (widget)->window)
195 gdk_window_set_cursor (GTK_WIDGET (widget)->window, (GdkCursor*)cursor);
198 void
199 anjuta_status_busy_push (AnjutaStatus *status)
201 GtkWidget *top;
202 GdkCursor *cursor;
204 g_return_if_fail (ANJUTA_IS_STATUS (status));
206 top = gtk_widget_get_toplevel (GTK_WIDGET (status));
207 if (top == NULL)
208 return;
210 status->priv->busy_count++;
211 if (status->priv->busy_count > 1)
212 return;
213 cursor = gdk_cursor_new (GDK_WATCH);
214 if (GTK_WIDGET (top)->window)
215 gdk_window_set_cursor (GTK_WIDGET (top)->window, cursor);
216 if (status->priv->widgets)
217 g_hash_table_foreach (status->priv->widgets,
218 foreach_widget_set_cursor, cursor);
219 gdk_cursor_unref (cursor);
220 gdk_flush ();
221 g_signal_emit_by_name (G_OBJECT (status), "busy", TRUE);
224 void
225 anjuta_status_busy_pop (AnjutaStatus *status)
227 GtkWidget *top;
229 g_return_if_fail (ANJUTA_IS_STATUS (status));
231 top = gtk_widget_get_toplevel (GTK_WIDGET (status));
232 if (top == NULL)
233 return;
235 status->priv->busy_count--;
236 if (status->priv->busy_count > 0)
237 return;
239 status->priv->busy_count = 0;
240 if (GTK_WIDGET (top)->window)
241 gdk_window_set_cursor (GTK_WIDGET (top)->window, NULL);
242 if (status->priv->widgets)
243 g_hash_table_foreach (status->priv->widgets,
244 foreach_widget_set_cursor, NULL);
245 g_signal_emit_by_name (G_OBJECT (status), "busy", FALSE);
248 static void
249 foreach_hash (gpointer key, gpointer value, gpointer userdata)
251 GString *str = (GString*)(userdata);
252 const gchar *divider = ": ";
253 const gchar *separator = " ";
255 g_string_append (str, separator);
256 g_string_append (str, (const gchar*)key);
257 g_string_append (str, divider);
258 g_string_append (str, (const gchar*)value);
261 void
262 anjuta_status_set_default (AnjutaStatus *status, const gchar *label,
263 const gchar *value_format, ...)
265 GString *str;
266 gchar *status_str;
268 g_return_if_fail (ANJUTA_IS_STATUS (status));
269 g_return_if_fail (label != NULL);
271 if (value_format)
273 gchar* value;
274 va_list args;
276 va_start (args, value_format);
277 value = g_strdup_vprintf (value_format, args);
278 va_end (args);
279 g_hash_table_replace (status->priv->default_status_items,
280 g_strdup (label), value);
282 else
284 if (g_hash_table_lookup (status->priv->default_status_items, label))
286 g_hash_table_remove (status->priv->default_status_items, label);
290 /* Update default status */
291 str = g_string_new (NULL);
292 g_hash_table_foreach (status->priv->default_status_items, foreach_hash, str);
293 status_str = g_string_free (str, FALSE);
294 gnome_appbar_set_default (GNOME_APPBAR (status), status_str);
295 g_free (status_str);
298 static void
299 on_widget_destroy (AnjutaStatus *status, GObject *widget)
301 if (g_hash_table_lookup (status->priv->widgets, widget))
302 g_hash_table_remove (status->priv->widgets, widget);
305 void
306 anjuta_status_add_widget (AnjutaStatus *status, GtkWidget *widget)
308 g_return_if_fail (ANJUTA_IS_STATUS (status));
309 g_return_if_fail (GTK_IS_WIDGET (widget));
311 if (status->priv->widgets == NULL)
312 status->priv->widgets =
313 g_hash_table_new (g_direct_hash, g_direct_equal);
315 g_hash_table_insert (status->priv->widgets, widget, widget);
316 g_object_weak_ref (G_OBJECT (widget),
317 (GWeakNotify) (on_widget_destroy), status);
320 void
321 anjuta_status_set_splash (AnjutaStatus *status, const gchar *splash_file,
322 gint splash_progress_position)
324 g_return_if_fail (ANJUTA_IS_STATUS (status));
325 g_return_if_fail (splash_file != NULL);
326 g_return_if_fail (splash_progress_position >= 0);
327 if (status->priv->splash_file)
328 g_free (status->priv->splash_file);
329 status->priv->splash_file = g_strdup (splash_file);
330 status->priv->splash_progress_position = splash_progress_position;
333 void
334 anjuta_status_disable_splash (AnjutaStatus *status,
335 gboolean disable_splash)
337 g_return_if_fail (ANJUTA_IS_STATUS (status));
339 status->priv->disable_splash = disable_splash;
340 if (status->priv->splash)
342 gtk_widget_destroy (status->priv->splash);
343 status->priv->splash = NULL;
344 anjuta_status_progress_add_ticks (status, 0);
348 void
349 anjuta_status_progress_add_ticks (AnjutaStatus *status, gint ticks)
351 gfloat percentage;
353 g_return_if_fail (ANJUTA_IS_STATUS (status));
354 g_return_if_fail (ticks >= 0);
356 status->priv->total_ticks += ticks;
357 if (!GTK_WIDGET_REALIZED (status))
359 if (status->priv->splash == NULL &&
360 status->priv->splash_file &&
361 !status->priv->disable_splash)
363 status->priv->splash = e_splash_new (status->priv->splash_file, 100);
364 if (status->priv->splash)
365 gtk_widget_show (status->priv->splash);
368 percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
369 if (status->priv->splash)
371 e_splash_set (E_SPLASH(status->priv->splash), NULL, NULL, NULL,
372 percentage);
373 while (g_main_context_iteration(NULL, FALSE));
375 else
377 GtkProgressBar *progressbar;
378 GtkWidget *statusbar;
380 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status),
381 percentage);
382 progressbar = gnome_appbar_get_progress (GNOME_APPBAR (status));
383 statusbar = gnome_appbar_get_status (GNOME_APPBAR (status));
384 gtk_widget_queue_draw (GTK_WIDGET (statusbar));
385 gtk_widget_queue_draw (GTK_WIDGET (progressbar));
386 if (GTK_WIDGET(progressbar)->window != NULL &&
387 GDK_IS_WINDOW(GTK_WIDGET(progressbar)->window))
388 gdk_window_process_updates (GTK_WIDGET(progressbar)->window, TRUE);
389 if (GTK_WIDGET(statusbar)->window != NULL &&
390 GDK_IS_WINDOW(GTK_WIDGET(statusbar)->window))
391 gdk_window_process_updates (GTK_WIDGET(statusbar)->window, TRUE);
395 void
396 anjuta_status_progress_tick (AnjutaStatus *status,
397 GdkPixbuf *icon, const gchar *text)
399 gfloat percentage;
401 g_return_if_fail (ANJUTA_IS_STATUS (status));
402 g_return_if_fail (status->priv->total_ticks != 0);
404 status->priv->current_ticks++;
405 percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
407 if (status->priv->splash)
409 e_splash_set (E_SPLASH(status->priv->splash), icon, text, NULL, percentage);
410 while (g_main_context_iteration(NULL, FALSE));
412 else
414 GtkProgressBar *progressbar;
415 GtkWidget *statusbar;
417 if (text)
418 anjuta_status_set (status, "%s", text);
419 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status),
420 percentage);
421 progressbar = gnome_appbar_get_progress (GNOME_APPBAR (status));
422 statusbar = gnome_appbar_get_status (GNOME_APPBAR (status));
423 gtk_widget_queue_draw (GTK_WIDGET (statusbar));
424 gtk_widget_queue_draw (GTK_WIDGET (progressbar));
425 if (GTK_WIDGET(progressbar)->window != NULL &&
426 GDK_IS_WINDOW(GTK_WIDGET(progressbar)->window))
427 gdk_window_process_updates (GTK_WIDGET(progressbar)->window, TRUE);
428 if (GTK_WIDGET(statusbar)->window != NULL &&
429 GDK_IS_WINDOW(GTK_WIDGET(statusbar)->window))
430 gdk_window_process_updates (GTK_WIDGET(statusbar)->window, TRUE);
432 if (status->priv->current_ticks >= status->priv->total_ticks)
433 anjuta_status_progress_reset (status);
436 void
437 anjuta_status_progress_reset (AnjutaStatus *status)
439 g_return_if_fail (ANJUTA_IS_STATUS (status));
440 if (status->priv->splash)
442 gtk_widget_destroy (status->priv->splash);
443 status->priv->splash = NULL;
445 status->priv->current_ticks = 0;
446 status->priv->total_ticks = 0;
447 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status), 0);
448 gnome_appbar_refresh (GNOME_APPBAR(status));
451 static gboolean
452 anjuta_status_timeout (AnjutaStatus *status)
454 anjuta_status_pop (status);
455 return FALSE;
458 /* Display message in status until timeout (secondes) */
459 void
460 anjuta_status (AnjutaStatus *status, const gchar *mesg, gint timeout)
462 g_return_if_fail (ANJUTA_IS_STATUS (status));
463 g_return_if_fail (mesg != NULL);
464 anjuta_status_push (status, "%s", mesg);
465 g_timeout_add (timeout * 1000, (void*) anjuta_status_timeout, status);
468 void
469 anjuta_status_set_title_window (AnjutaStatus *status, GtkWidget *window)
471 g_return_if_fail (ANJUTA_IS_STATUS (status));
472 g_return_if_fail (GTK_IS_WINDOW (window));
473 status->priv->window = GTK_WINDOW (window);
474 g_object_add_weak_pointer (G_OBJECT (window),
475 (gpointer*)(gpointer)&status->priv->window);
478 void
479 anjuta_status_set_title (AnjutaStatus *status, const gchar *title)
481 g_return_if_fail (ANJUTA_IS_STATUS (status));
483 if (!status->priv->window)
484 return;
486 const gchar *app_name = g_get_application_name();
487 if (title)
489 gchar* str = g_strconcat (app_name, " - ", title, NULL);
490 gtk_window_set_title (status->priv->window, str);
491 g_free (str);
493 else
495 gtk_window_set_title (status->priv->window, app_name);
499 ANJUTA_TYPE_BEGIN(AnjutaStatus, anjuta_status, GNOME_TYPE_APPBAR);
500 ANJUTA_TYPE_END;