Updated Spanish translation
[anjuta-git-plugin.git] / libanjuta / anjuta-status.c
blob1fb780929d380747562c5156639f374b06903640
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;
108 if (status->priv->window)
110 g_object_remove_weak_pointer (G_OBJECT (status->priv->window),
111 (gpointer*)(gpointer)&status->priv->window);
112 status->priv->window = NULL;
114 GNOME_CALL_PARENT(G_OBJECT_CLASS, dispose, (widget));
117 static void
118 anjuta_status_instance_init (AnjutaStatus *status)
120 status->priv = g_new0 (AnjutaStatusPriv, 1);
121 status->priv->splash_file = NULL;
122 status->priv->splash_progress_position = 0;
123 status->priv->disable_splash = FALSE;
124 status->priv->total_ticks = 0;
125 status->priv->current_ticks = 0;
126 status->priv->splash = NULL;
127 status->priv->default_status_items =
128 g_hash_table_new_full (g_str_hash, g_str_equal,
129 g_free, g_free);
132 static void
133 anjuta_status_class_init (AnjutaStatusClass *class)
135 GObjectClass *object_class;
137 parent_class = g_type_class_peek_parent (class);
138 object_class = (GObjectClass*) class;
139 object_class->finalize = anjuta_status_finalize;
140 object_class->dispose = anjuta_status_dispose;
142 status_signals[BUSY] =
143 g_signal_new ("busy",
144 ANJUTA_TYPE_STATUS,
145 G_SIGNAL_RUN_LAST,
146 G_STRUCT_OFFSET (AnjutaStatusClass, busy),
147 NULL, NULL,
148 g_cclosure_marshal_VOID__BOOLEAN,
149 G_TYPE_NONE, 1,
150 G_TYPE_BOOLEAN);
153 GtkWidget *
154 anjuta_status_new (void)
156 GtkWidget *status;
158 status = GTK_WIDGET (g_object_new (ANJUTA_TYPE_STATUS,
159 "has-progress", TRUE, "has-status", TRUE,
160 "interactivity", GNOME_PREFERENCES_NEVER, NULL));
161 return status;
164 void
165 anjuta_status_set (AnjutaStatus *status, const gchar * mesg, ...)
167 gchar* message;
168 va_list args;
170 g_return_if_fail (ANJUTA_IS_STATUS (status));
171 g_return_if_fail (mesg != NULL);
173 va_start (args, mesg);
174 message = g_strdup_vprintf (mesg, args);
175 va_end (args);
176 gnome_appbar_set_status (GNOME_APPBAR (status), message);
177 g_free(message);
180 void
181 anjuta_status_push (AnjutaStatus *status, const gchar * mesg, ...)
183 gchar* message;
184 va_list args;
186 g_return_if_fail (ANJUTA_IS_STATUS (status));
187 g_return_if_fail (mesg != NULL);
189 va_start (args, mesg);
190 message = g_strdup_vprintf (mesg, args);
191 va_end (args);
192 gnome_appbar_push (GNOME_APPBAR (status), message);
193 g_free(message);
196 static void
197 foreach_widget_set_cursor (gpointer widget, gpointer value, gpointer cursor)
199 if (GTK_WIDGET (widget)->window)
200 gdk_window_set_cursor (GTK_WIDGET (widget)->window, (GdkCursor*)cursor);
203 void
204 anjuta_status_busy_push (AnjutaStatus *status)
206 GtkWidget *top;
207 GdkCursor *cursor;
209 g_return_if_fail (ANJUTA_IS_STATUS (status));
211 top = gtk_widget_get_toplevel (GTK_WIDGET (status));
212 if (top == NULL)
213 return;
215 status->priv->busy_count++;
216 if (status->priv->busy_count > 1)
217 return;
218 cursor = gdk_cursor_new (GDK_WATCH);
219 if (GTK_WIDGET (top)->window)
220 gdk_window_set_cursor (GTK_WIDGET (top)->window, cursor);
221 if (status->priv->widgets)
222 g_hash_table_foreach (status->priv->widgets,
223 foreach_widget_set_cursor, cursor);
224 gdk_cursor_unref (cursor);
225 gdk_flush ();
226 g_signal_emit_by_name (G_OBJECT (status), "busy", TRUE);
229 void
230 anjuta_status_busy_pop (AnjutaStatus *status)
232 GtkWidget *top;
234 g_return_if_fail (ANJUTA_IS_STATUS (status));
236 top = gtk_widget_get_toplevel (GTK_WIDGET (status));
237 if (top == NULL)
238 return;
240 status->priv->busy_count--;
241 if (status->priv->busy_count > 0)
242 return;
244 status->priv->busy_count = 0;
245 if (GTK_WIDGET (top)->window)
246 gdk_window_set_cursor (GTK_WIDGET (top)->window, NULL);
247 if (status->priv->widgets)
248 g_hash_table_foreach (status->priv->widgets,
249 foreach_widget_set_cursor, NULL);
250 g_signal_emit_by_name (G_OBJECT (status), "busy", FALSE);
253 static void
254 foreach_hash (gpointer key, gpointer value, gpointer userdata)
256 GString *str = (GString*)(userdata);
257 const gchar *divider = ": ";
258 const gchar *separator = " ";
260 g_string_append (str, separator);
261 g_string_append (str, (const gchar*)key);
262 g_string_append (str, divider);
263 g_string_append (str, (const gchar*)value);
266 void
267 anjuta_status_set_default (AnjutaStatus *status, const gchar *label,
268 const gchar *value_format, ...)
270 GString *str;
271 gchar *status_str;
273 g_return_if_fail (ANJUTA_IS_STATUS (status));
274 g_return_if_fail (label != NULL);
276 if (value_format)
278 gchar* value;
279 va_list args;
281 va_start (args, value_format);
282 value = g_strdup_vprintf (value_format, args);
283 va_end (args);
284 g_hash_table_replace (status->priv->default_status_items,
285 g_strdup (label), value);
287 else
289 if (g_hash_table_lookup (status->priv->default_status_items, label))
291 g_hash_table_remove (status->priv->default_status_items, label);
295 /* Update default status */
296 str = g_string_new (NULL);
297 g_hash_table_foreach (status->priv->default_status_items, foreach_hash, str);
298 status_str = g_string_free (str, FALSE);
299 gnome_appbar_set_default (GNOME_APPBAR (status), status_str);
300 g_free (status_str);
303 static void
304 on_widget_destroy (AnjutaStatus *status, GObject *widget)
306 if (g_hash_table_lookup (status->priv->widgets, widget))
307 g_hash_table_remove (status->priv->widgets, widget);
310 void
311 anjuta_status_add_widget (AnjutaStatus *status, GtkWidget *widget)
313 g_return_if_fail (ANJUTA_IS_STATUS (status));
314 g_return_if_fail (GTK_IS_WIDGET (widget));
316 if (status->priv->widgets == NULL)
317 status->priv->widgets =
318 g_hash_table_new (g_direct_hash, g_direct_equal);
320 g_hash_table_insert (status->priv->widgets, widget, widget);
321 g_object_weak_ref (G_OBJECT (widget),
322 (GWeakNotify) (on_widget_destroy), status);
325 void
326 anjuta_status_set_splash (AnjutaStatus *status, const gchar *splash_file,
327 gint splash_progress_position)
329 g_return_if_fail (ANJUTA_IS_STATUS (status));
330 g_return_if_fail (splash_file != NULL);
331 g_return_if_fail (splash_progress_position >= 0);
332 if (status->priv->splash_file)
333 g_free (status->priv->splash_file);
334 status->priv->splash_file = g_strdup (splash_file);
335 status->priv->splash_progress_position = splash_progress_position;
338 void
339 anjuta_status_disable_splash (AnjutaStatus *status,
340 gboolean disable_splash)
342 g_return_if_fail (ANJUTA_IS_STATUS (status));
344 status->priv->disable_splash = disable_splash;
345 if (status->priv->splash)
347 gtk_widget_destroy (status->priv->splash);
348 status->priv->splash = NULL;
349 anjuta_status_progress_add_ticks (status, 0);
353 void
354 anjuta_status_progress_add_ticks (AnjutaStatus *status, gint ticks)
356 gfloat percentage;
358 g_return_if_fail (ANJUTA_IS_STATUS (status));
359 g_return_if_fail (ticks >= 0);
361 status->priv->total_ticks += ticks;
362 if (!GTK_WIDGET_REALIZED (status))
364 if (status->priv->splash == NULL &&
365 status->priv->splash_file &&
366 !status->priv->disable_splash)
368 status->priv->splash = e_splash_new (status->priv->splash_file, 100);
369 if (status->priv->splash)
370 gtk_widget_show (status->priv->splash);
373 percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
374 if (status->priv->splash)
376 e_splash_set (E_SPLASH(status->priv->splash), NULL, NULL, NULL,
377 percentage);
378 while (g_main_context_iteration(NULL, FALSE));
380 else
382 GtkProgressBar *progressbar;
383 GtkWidget *statusbar;
385 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status),
386 percentage);
387 progressbar = gnome_appbar_get_progress (GNOME_APPBAR (status));
388 statusbar = gnome_appbar_get_status (GNOME_APPBAR (status));
389 gtk_widget_queue_draw (GTK_WIDGET (statusbar));
390 gtk_widget_queue_draw (GTK_WIDGET (progressbar));
391 if (GTK_WIDGET(progressbar)->window != NULL &&
392 GDK_IS_WINDOW(GTK_WIDGET(progressbar)->window))
393 gdk_window_process_updates (GTK_WIDGET(progressbar)->window, TRUE);
394 if (GTK_WIDGET(statusbar)->window != NULL &&
395 GDK_IS_WINDOW(GTK_WIDGET(statusbar)->window))
396 gdk_window_process_updates (GTK_WIDGET(statusbar)->window, TRUE);
400 void
401 anjuta_status_progress_pulse (AnjutaStatus *status, const gchar *text)
403 GtkProgressBar *progressbar;
404 GtkWidget *statusbar;
406 progressbar = gnome_appbar_get_progress (GNOME_APPBAR (status));
407 statusbar = gnome_appbar_get_status (GNOME_APPBAR (status));
409 if (text)
410 anjuta_status_set (status, "%s", text);
412 gtk_progress_bar_pulse (progressbar);
414 gtk_widget_queue_draw (GTK_WIDGET (statusbar));
415 gtk_widget_queue_draw (GTK_WIDGET (progressbar));
416 if (GTK_WIDGET(progressbar)->window != NULL &&
417 GDK_IS_WINDOW(GTK_WIDGET(progressbar)->window))
418 gdk_window_process_updates (GTK_WIDGET(progressbar)->window, TRUE);
419 if (GTK_WIDGET(statusbar)->window != NULL &&
420 GDK_IS_WINDOW(GTK_WIDGET(statusbar)->window))
421 gdk_window_process_updates (GTK_WIDGET(statusbar)->window, TRUE);
424 void
425 anjuta_status_progress_tick (AnjutaStatus *status,
426 GdkPixbuf *icon, const gchar *text)
428 gfloat percentage;
430 g_return_if_fail (ANJUTA_IS_STATUS (status));
431 g_return_if_fail (status->priv->total_ticks != 0);
433 status->priv->current_ticks++;
434 percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
436 if (status->priv->splash)
438 e_splash_set (E_SPLASH(status->priv->splash), icon, text, NULL, percentage);
439 while (g_main_context_iteration(NULL, FALSE));
441 else
443 GtkProgressBar *progressbar;
444 GtkWidget *statusbar;
446 if (text)
447 anjuta_status_set (status, "%s", text);
448 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status),
449 percentage);
450 progressbar = gnome_appbar_get_progress (GNOME_APPBAR (status));
451 statusbar = gnome_appbar_get_status (GNOME_APPBAR (status));
452 gtk_widget_queue_draw (GTK_WIDGET (statusbar));
453 gtk_widget_queue_draw (GTK_WIDGET (progressbar));
454 if (GTK_WIDGET(progressbar)->window != NULL &&
455 GDK_IS_WINDOW(GTK_WIDGET(progressbar)->window))
456 gdk_window_process_updates (GTK_WIDGET(progressbar)->window, TRUE);
457 if (GTK_WIDGET(statusbar)->window != NULL &&
458 GDK_IS_WINDOW(GTK_WIDGET(statusbar)->window))
459 gdk_window_process_updates (GTK_WIDGET(statusbar)->window, TRUE);
461 if (status->priv->current_ticks >= status->priv->total_ticks)
462 anjuta_status_progress_reset (status);
465 void
466 anjuta_status_progress_reset (AnjutaStatus *status)
468 g_return_if_fail (ANJUTA_IS_STATUS (status));
469 if (status->priv->splash)
471 gtk_widget_destroy (status->priv->splash);
472 status->priv->splash = NULL;
474 status->priv->current_ticks = 0;
475 status->priv->total_ticks = 0;
476 gnome_appbar_set_progress_percentage (GNOME_APPBAR (status), 0);
477 gnome_appbar_refresh (GNOME_APPBAR(status));
480 static gboolean
481 anjuta_status_timeout (AnjutaStatus *status)
483 anjuta_status_pop (status);
484 return FALSE;
487 /* Display message in status until timeout (secondes) */
488 void
489 anjuta_status (AnjutaStatus *status, const gchar *mesg, gint timeout)
491 g_return_if_fail (ANJUTA_IS_STATUS (status));
492 g_return_if_fail (mesg != NULL);
493 anjuta_status_push (status, "%s", mesg);
494 g_timeout_add (timeout * 1000, (void*) anjuta_status_timeout, status);
497 void
498 anjuta_status_set_title_window (AnjutaStatus *status, GtkWidget *window)
500 g_return_if_fail (ANJUTA_IS_STATUS (status));
501 g_return_if_fail (GTK_IS_WINDOW (window));
502 status->priv->window = GTK_WINDOW (window);
503 g_object_add_weak_pointer (G_OBJECT (window),
504 (gpointer*)(gpointer)&status->priv->window);
507 void
508 anjuta_status_set_title (AnjutaStatus *status, const gchar *title)
510 g_return_if_fail (ANJUTA_IS_STATUS (status));
512 if (!status->priv->window)
513 return;
515 const gchar *app_name = g_get_application_name();
516 if (title)
518 gchar* str = g_strconcat (title, " - ", app_name, NULL);
519 gtk_window_set_title (status->priv->window, str);
520 g_free (str);
522 else
524 gtk_window_set_title (status->priv->window, app_name);
528 ANJUTA_TYPE_BEGIN(AnjutaStatus, anjuta_status, GNOME_TYPE_APPBAR);
529 ANJUTA_TYPE_END;