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.
10  *
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.
15  *
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
19  */
20 
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
27  *
28  */
29 
30 #include <config.h>
31 #include <gtk/gtk.h>
32 #include <libanjuta/anjuta-status.h>
33 #include <libanjuta/anjuta-utils.h>
34 #include <libanjuta/anjuta-debug.h>
35 #include <libanjuta/resources.h>
36 #include <libanjuta/e-splash.h>
37 
38 struct _AnjutaStatusPriv
39 {
40 	GHashTable *default_status_items;
41 	gint busy_count;
42 	GHashTable *widgets;
43 
44 	/* Status bar */
45 	GtkWidget *status_bar;
46 	guint status_message;
47 	guint push_message;
48 	GList *push_values;
49 
50 	/* Progress bar */
51 	GtkWidget *progress_bar;
52 	gint total_ticks;
53 	gint current_ticks;
54 
55 	/* Splash */
56 	GtkWidget *splash;
57 	gboolean disable_splash;
58 	gchar *splash_file;
59 	gint splash_progress_position;
60 
61 	/* Title window */
62 	GtkWindow *window;
63 };
64 
65 enum {
66 	BUSY,
67 	LAST_SIGNAL
68 };
69 
70 static gpointer parent_class = NULL;
71 static guint status_signals[LAST_SIGNAL] = { 0 };
72 
73 static void on_widget_destroy (AnjutaStatus *status, GObject *widget);
74 
75 static void
anjuta_status_finalize(GObject * widget)76 anjuta_status_finalize (GObject *widget)
77 {
78 	g_free(ANJUTA_STATUS(widget)->priv);
79 	G_OBJECT_CLASS (parent_class)->finalize (widget);
80 }
81 
82 static void
foreach_widget_unref(gpointer key,gpointer value,gpointer data)83 foreach_widget_unref (gpointer key, gpointer value, gpointer data)
84 {
85 	g_object_weak_unref (G_OBJECT (key), (GWeakNotify) on_widget_destroy, data);
86 }
87 
88 static void
anjuta_status_dispose(GObject * widget)89 anjuta_status_dispose (GObject *widget)
90 {
91 	AnjutaStatus *status;
92 
93 	status = ANJUTA_STATUS (widget);
94 
95 	if (status->priv->default_status_items)
96 	{
97 		g_hash_table_destroy (status->priv->default_status_items);
98 		status->priv->default_status_items = NULL;
99 	}
100 	if (status->priv->splash != NULL) {
101 		gtk_widget_destroy (status->priv->splash);
102 		status->priv->splash = NULL;
103 	}
104 	if (status->priv->splash_file)
105 	{
106 		g_free (status->priv->splash_file);
107 		status->priv->splash_file = NULL;
108 	}
109 	if (status->priv->push_values)
110 	{
111 		g_list_free (status->priv->push_values);
112 		status->priv->push_values = NULL;
113 	}
114 	if (status->priv->widgets)
115 	{
116 		g_hash_table_foreach (status->priv->widgets,
117 							  foreach_widget_unref, widget);
118 		g_hash_table_destroy (status->priv->widgets);
119 		status->priv->widgets = NULL;
120 	}
121 	if (status->priv->window)
122 	{
123 		g_object_remove_weak_pointer (G_OBJECT (status->priv->window),
124 						   (gpointer*)(gpointer)&status->priv->window);
125 		status->priv->window = NULL;
126 	}
127 	if (status->priv->progress_bar)
128 	{
129 		g_object_remove_weak_pointer (G_OBJECT (status->priv->progress_bar),
130 							(gpointer)&status->priv->progress_bar);
131 		gtk_widget_destroy (status->priv->progress_bar);
132 		status->priv->progress_bar = NULL;
133 	}
134 	if (status->priv->status_bar)
135 	{
136 		g_object_remove_weak_pointer (G_OBJECT (status->priv->status_bar),
137 							(gpointer)&status->priv->status_bar);
138 		gtk_widget_destroy (status->priv->status_bar);
139 		status->priv->status_bar = NULL;
140 	}
141 
142 	G_OBJECT_CLASS (parent_class)->dispose (widget);
143 }
144 
145 static void
anjuta_status_instance_init(AnjutaStatus * status)146 anjuta_status_instance_init (AnjutaStatus *status)
147 {
148 	status->priv = g_new0 (AnjutaStatusPriv, 1);
149 	status->priv->progress_bar = gtk_progress_bar_new ();
150 	gtk_box_pack_start (GTK_BOX (status), status->priv->progress_bar, FALSE, TRUE, 0);
151 	gtk_widget_show (status->priv->progress_bar);
152 	g_object_add_weak_pointer (G_OBJECT (status->priv->progress_bar),
153 							   (gpointer)&status->priv->progress_bar);
154 	status->priv->status_bar = gtk_statusbar_new ();
155 	gtk_box_pack_start (GTK_BOX (status), status->priv->status_bar, TRUE, TRUE, 0);
156 	gtk_widget_show (status->priv->status_bar);
157 	g_object_add_weak_pointer (G_OBJECT(status->priv->status_bar),
158 							   (gpointer)&status->priv->status_bar);
159 	status->priv->status_message = gtk_statusbar_get_context_id (GTK_STATUSBAR (status->priv->status_bar),
160 																 "status-message");
161 	status->priv->push_message = gtk_statusbar_get_context_id (GTK_STATUSBAR (status->priv->status_bar),
162 															   "push-message");
163 	status->priv->push_values = NULL;
164 	status->priv->splash_file = NULL;
165 	status->priv->splash_progress_position = 0;
166 	status->priv->disable_splash = FALSE;
167 	status->priv->total_ticks = 0;
168 	status->priv->current_ticks = 0;
169 	status->priv->splash = NULL;
170 	status->priv->default_status_items =
171 		g_hash_table_new_full (g_str_hash, g_str_equal,
172 							   g_free, g_free);
173 }
174 
175 static void
anjuta_status_class_init(AnjutaStatusClass * class)176 anjuta_status_class_init (AnjutaStatusClass *class)
177 {
178 	GObjectClass *object_class;
179 
180 	parent_class = g_type_class_peek_parent (class);
181 	object_class = (GObjectClass*) class;
182 	object_class->finalize = anjuta_status_finalize;
183 	object_class->dispose = anjuta_status_dispose;
184 
185 	status_signals[BUSY] =
186 		g_signal_new ("busy",
187 				  ANJUTA_TYPE_STATUS,
188 				  G_SIGNAL_RUN_LAST,
189 				  G_STRUCT_OFFSET (AnjutaStatusClass, busy),
190 				  NULL, NULL,
191 				  g_cclosure_marshal_VOID__BOOLEAN,
192 				  G_TYPE_NONE, 1,
193 				  G_TYPE_BOOLEAN);
194 }
195 
196 GtkWidget *
anjuta_status_new(void)197 anjuta_status_new (void)
198 {
199 	GtkWidget *status;
200 
201 	status = GTK_WIDGET (g_object_new (ANJUTA_TYPE_STATUS, NULL));
202 	return status;
203 }
204 
205 void
anjuta_status_set(AnjutaStatus * status,const gchar * mesg,...)206 anjuta_status_set (AnjutaStatus *status, const gchar * mesg, ...)
207 {
208 	gchar* message;
209 	va_list args;
210 
211 	g_return_if_fail (ANJUTA_IS_STATUS (status));
212 	g_return_if_fail (mesg != NULL);
213 
214 	va_start (args, mesg);
215 	message = g_strdup_vprintf (mesg, args);
216 	va_end (args);
217 	gtk_statusbar_pop (GTK_STATUSBAR (status->priv->status_bar),
218 					   status->priv->status_message);
219 	gtk_statusbar_push (GTK_STATUSBAR (status->priv->status_bar),
220 						status->priv->status_message, message);
221 	g_free(message);
222 }
223 
224 void
anjuta_status_push(AnjutaStatus * status,const gchar * mesg,...)225 anjuta_status_push (AnjutaStatus *status, const gchar * mesg, ...)
226 {
227 	gchar* message;
228 	va_list args;
229 	guint value;
230 
231 	g_return_if_fail (ANJUTA_IS_STATUS (status));
232 	g_return_if_fail (mesg != NULL);
233 
234 	va_start (args, mesg);
235 	message = g_strdup_vprintf (mesg, args);
236 	va_end (args);
237 
238 	value = gtk_statusbar_push (GTK_STATUSBAR (status->priv->status_bar),
239 								status->priv->push_message, message);
240 	status->priv->push_values = g_list_prepend (status->priv->push_values,
241 												GUINT_TO_POINTER (value));
242 	g_free(message);
243 }
244 
245 void
anjuta_status_pop(AnjutaStatus * status)246 anjuta_status_pop (AnjutaStatus *status)
247 {
248 	g_return_if_fail (ANJUTA_IS_STATUS (status));
249 
250 	/* This can be called on a time out when the status object is destroyed */
251 	if (status->priv->status_bar != NULL)
252 	{
253 		gtk_statusbar_pop (GTK_STATUSBAR (status->priv->status_bar),
254 						   status->priv->push_message);
255 	}
256 
257 	status->priv->push_values = g_list_remove_link (status->priv->push_values,
258 													status->priv->push_values);
259 }
260 
261 void
anjuta_status_clear_stack(AnjutaStatus * status)262 anjuta_status_clear_stack (AnjutaStatus *status)
263 {
264 	GList *l;
265 	g_return_if_fail (ANJUTA_IS_STATUS (status));
266 
267 	for (l = status->priv->push_values; l != NULL; l = g_list_next (l))
268 	{
269 		guint value = GPOINTER_TO_UINT (l->data);
270 		gtk_statusbar_remove (GTK_STATUSBAR (status->priv->status_bar),
271 							  status->priv->push_message, value);
272 	}
273 	g_list_free (status->priv->push_values);
274 	status->priv->push_values = NULL;
275 }
276 
277 static void
foreach_widget_set_cursor(gpointer widget,gpointer value,gpointer cursor)278 foreach_widget_set_cursor (gpointer widget, gpointer value, gpointer cursor)
279 {
280 	GdkWindow *window;
281 
282 	window = gtk_widget_get_window (widget);
283 	if (window)
284 		gdk_window_set_cursor (window, (GdkCursor*)cursor);
285 }
286 
287 void
anjuta_status_busy_push(AnjutaStatus * status)288 anjuta_status_busy_push (AnjutaStatus *status)
289 {
290 	GtkWidget *top;
291 	GdkCursor *cursor;
292 	GdkWindow *window;
293 	GdkDisplay *display;
294 
295 	g_return_if_fail (ANJUTA_IS_STATUS (status));
296 
297 	top = gtk_widget_get_toplevel (GTK_WIDGET (status));
298 	if (top == NULL)
299 		return;
300 
301 	status->priv->busy_count++;
302 
303 	DEBUG_PRINT ("Busy status: %d", status->priv->busy_count);
304 
305 	if (status->priv->busy_count > 1)
306 		return;
307 	display = gtk_widget_get_display (top);
308 	cursor = gdk_cursor_new_for_display (display, GDK_WATCH);
309 	window = gtk_widget_get_window (top);
310 	if (window)
311 		gdk_window_set_cursor (window, cursor);
312 	if (status->priv->widgets)
313 		g_hash_table_foreach (status->priv->widgets,
314 							  foreach_widget_set_cursor, cursor);
315 	g_object_unref (cursor);
316 	gdk_flush ();
317 	g_signal_emit_by_name (G_OBJECT (status), "busy", TRUE);
318 }
319 
320 void
anjuta_status_busy_pop(AnjutaStatus * status)321 anjuta_status_busy_pop (AnjutaStatus *status)
322 {
323 	GtkWidget *top;
324 	GdkWindow *window;
325 
326 	g_return_if_fail (ANJUTA_IS_STATUS (status));
327 
328 	top = gtk_widget_get_toplevel (GTK_WIDGET (status));
329 	if (top == NULL)
330 		return;
331 
332 	status->priv->busy_count--;
333 	DEBUG_PRINT ("Busy status: %d", status->priv->busy_count);
334 
335 	if (status->priv->busy_count > 0)
336 		return;
337 
338 	status->priv->busy_count = 0;
339 	window = gtk_widget_get_window (top);
340 	if (window)
341 		gdk_window_set_cursor (window, NULL);
342 	if (status->priv->widgets)
343 		g_hash_table_foreach (status->priv->widgets,
344 							  foreach_widget_set_cursor, NULL);
345 	g_signal_emit_by_name (G_OBJECT (status), "busy", FALSE);
346 }
347 
348 static void
foreach_hash(gpointer key,gpointer value,gpointer userdata)349 foreach_hash (gpointer key, gpointer value, gpointer userdata)
350 {
351 	GString *str = (GString*)(userdata);
352 	const gchar *divider = ": ";
353 	const gchar *separator = "    ";
354 
355 	g_string_append (str, separator);
356 	g_string_append (str, (const gchar*)key);
357 	g_string_append (str, divider);
358 	g_string_append (str, (const gchar*)value);
359 }
360 
361 void
anjuta_status_set_default(AnjutaStatus * status,const gchar * label,const gchar * value_format,...)362 anjuta_status_set_default (AnjutaStatus *status, const gchar *label,
363 						   const gchar *value_format, ...)
364 {
365 	GString *str;
366 	gchar *status_str;
367 
368 	g_return_if_fail (ANJUTA_IS_STATUS (status));
369 	g_return_if_fail (label != NULL);
370 
371 	if (value_format)
372 	{
373 		gchar* value;
374 		va_list args;
375 
376 		va_start (args, value_format);
377 		value = g_strdup_vprintf (value_format, args);
378 		va_end (args);
379 		g_hash_table_replace (status->priv->default_status_items,
380 							  g_strdup (label), value);
381 	}
382 	else
383 	{
384 		if (g_hash_table_lookup (status->priv->default_status_items, label))
385 		{
386 			g_hash_table_remove (status->priv->default_status_items, label);
387 		}
388 	}
389 
390 	/* Update default status */
391 	str = g_string_new (NULL);
392 	g_hash_table_foreach (status->priv->default_status_items, foreach_hash, str);
393 	status_str = g_string_free (str, FALSE);
394 	anjuta_status_set (status, status_str, NULL);
395 	g_free (status_str);
396 }
397 
398 static void
on_widget_destroy(AnjutaStatus * status,GObject * widget)399 on_widget_destroy (AnjutaStatus *status, GObject *widget)
400 {
401 	if (g_hash_table_lookup (status->priv->widgets, widget))
402 		g_hash_table_remove (status->priv->widgets, widget);
403 }
404 
405 void
anjuta_status_add_widget(AnjutaStatus * status,GtkWidget * widget)406 anjuta_status_add_widget (AnjutaStatus *status, GtkWidget *widget)
407 {
408 	g_return_if_fail (ANJUTA_IS_STATUS (status));
409 	g_return_if_fail (GTK_IS_WIDGET (widget));
410 
411 	if (status->priv->widgets == NULL)
412 		status->priv->widgets =
413 			g_hash_table_new (g_direct_hash, g_direct_equal);
414 
415 	g_hash_table_insert (status->priv->widgets, widget, widget);
416 	g_object_weak_ref (G_OBJECT (widget),
417 					   (GWeakNotify) (on_widget_destroy), status);
418 }
419 
420 void
anjuta_status_set_splash(AnjutaStatus * status,const gchar * splash_file,gint splash_progress_position)421 anjuta_status_set_splash (AnjutaStatus *status, const gchar *splash_file,
422 						  gint splash_progress_position)
423 {
424 	g_return_if_fail (ANJUTA_IS_STATUS (status));
425 	g_return_if_fail (splash_file != NULL);
426 	g_return_if_fail (splash_progress_position >= 0);
427 	if (status->priv->splash_file)
428 		g_free (status->priv->splash_file);
429 	status->priv->splash_file = g_strdup (splash_file);
430 	status->priv->splash_progress_position = splash_progress_position;
431 }
432 
433 void
anjuta_status_disable_splash(AnjutaStatus * status,gboolean disable_splash)434 anjuta_status_disable_splash (AnjutaStatus *status,
435 							  gboolean disable_splash)
436 {
437 	g_return_if_fail (ANJUTA_IS_STATUS (status));
438 
439 	status->priv->disable_splash = disable_splash;
440 	if (status->priv->splash)
441 	{
442 		gtk_widget_destroy (status->priv->splash);
443 		status->priv->splash = NULL;
444 		anjuta_status_progress_add_ticks (status, 0);
445 	}
446 }
447 
448 void
anjuta_status_progress_add_ticks(AnjutaStatus * status,gint ticks)449 anjuta_status_progress_add_ticks (AnjutaStatus *status, gint ticks)
450 {
451 	gfloat percentage;
452 
453 	g_return_if_fail (ANJUTA_IS_STATUS (status));
454 	g_return_if_fail (ticks >= 0);
455 
456 	status->priv->total_ticks += ticks;
457 	if (!gtk_widget_get_realized (GTK_WIDGET (status)))
458 	{
459 		if (status->priv->splash == NULL &&
460 			status->priv->splash_file &&
461 			!status->priv->disable_splash)
462 		{
463 			status->priv->splash = e_splash_new (status->priv->splash_file, 100);
464 			if (status->priv->splash)
465 					gtk_widget_show (status->priv->splash);
466 		}
467 	}
468 	percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
469 	if (status->priv->splash)
470 	{
471 		e_splash_set (E_SPLASH(status->priv->splash), NULL, NULL, NULL,
472 					  percentage);
473 		while (g_main_context_iteration(NULL, FALSE));
474 	}
475 	else
476 	{
477 		if (status->priv->progress_bar && status->priv->status_bar)
478 		{
479 			GdkWindow *progressbar_window, *statusbar_window;
480 
481 			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (status->priv->progress_bar),
482 										   percentage);
483 			gtk_widget_queue_draw (GTK_WIDGET (status->priv->status_bar));
484 			gtk_widget_queue_draw (GTK_WIDGET (status->priv->progress_bar));
485 			progressbar_window = gtk_widget_get_window (GTK_WIDGET(status->priv->progress_bar));
486 			statusbar_window = gtk_widget_get_window (GTK_WIDGET(status->priv->status_bar));
487 			if (progressbar_window != NULL)
488 				gdk_window_process_updates (progressbar_window, TRUE);
489 			if (statusbar_window != NULL)
490 				gdk_window_process_updates (statusbar_window, TRUE);
491 		}
492 	}
493 }
494 
495 void
anjuta_status_progress_pulse(AnjutaStatus * status,const gchar * text)496 anjuta_status_progress_pulse (AnjutaStatus *status, const gchar *text)
497 {
498 	GtkProgressBar *progressbar;
499 	GtkWidget *statusbar;
500 	GdkWindow *progressbar_window, *statusbar_window;
501 
502 	progressbar = GTK_PROGRESS_BAR (status->priv->progress_bar);
503 	statusbar = status->priv->status_bar;
504 
505 	if (text)
506 		anjuta_status_push (status, "%s", text);
507 
508 	gtk_progress_bar_pulse (progressbar);
509 
510 	gtk_widget_queue_draw (GTK_WIDGET (statusbar));
511 	gtk_widget_queue_draw (GTK_WIDGET (progressbar));
512 	progressbar_window = gtk_widget_get_window (GTK_WIDGET (progressbar));
513 	if (progressbar_window != NULL)
514 		gdk_window_process_updates (progressbar_window, TRUE);
515 	statusbar_window = gtk_widget_get_window (GTK_WIDGET (statusbar));
516 	if (statusbar_window != NULL)
517 		gdk_window_process_updates (statusbar_window, TRUE);
518 }
519 
520 void
anjuta_status_progress_tick(AnjutaStatus * status,GdkPixbuf * icon,const gchar * text)521 anjuta_status_progress_tick (AnjutaStatus *status,
522 							 GdkPixbuf *icon, const gchar *text)
523 {
524 	gfloat percentage;
525 
526 	g_return_if_fail (ANJUTA_IS_STATUS (status));
527 	g_return_if_fail (status->priv->total_ticks != 0);
528 
529 	status->priv->current_ticks++;
530 	percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
531 
532 	if (status->priv->splash)
533 	{
534 		e_splash_set (E_SPLASH(status->priv->splash), icon, text, NULL, percentage);
535 	}
536 	else
537 	{
538 		GtkProgressBar *progressbar;
539 		GtkWidget *statusbar;
540 		GdkWindow *progressbar_window, *statusbar_window;
541 
542 		if (text)
543 			anjuta_status_set (status, "%s", text);
544 		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (status->priv->progress_bar),
545 									   percentage);
546 		progressbar = GTK_PROGRESS_BAR (status->priv->progress_bar);
547 		statusbar = status->priv->status_bar;
548 		gtk_widget_queue_draw (GTK_WIDGET (statusbar));
549 		gtk_widget_queue_draw (GTK_WIDGET (progressbar));
550 		progressbar_window = gtk_widget_get_window (GTK_WIDGET (progressbar));
551 		if (progressbar_window != NULL)
552 			gdk_window_process_updates (progressbar_window, TRUE);
553 		statusbar_window = gtk_widget_get_window (GTK_WIDGET (statusbar));
554 		if (statusbar_window != NULL)
555 			gdk_window_process_updates (statusbar_window, TRUE);
556 	}
557 	if (status->priv->current_ticks >= status->priv->total_ticks)
558 		anjuta_status_progress_reset (status);
559 }
560 
561 void
anjuta_status_progress_increment_ticks(AnjutaStatus * status,gint ticks,const gchar * text)562 anjuta_status_progress_increment_ticks (AnjutaStatus *status, gint ticks,
563 										const gchar *text)
564 {
565 	gfloat percentage;
566 	GdkWindow *progressbar_window, *statusbar_window;
567 
568 	g_return_if_fail (ANJUTA_IS_STATUS (status));
569 	g_return_if_fail (status->priv->total_ticks != 0);
570 
571 	status->priv->current_ticks += ticks;
572 	percentage = ((gfloat)status->priv->current_ticks)/status->priv->total_ticks;
573 
574 	GtkProgressBar *progressbar;
575 	GtkWidget *statusbar;
576 
577 	if (text)
578 		anjuta_status_set (status, "%s", text);
579 	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (status->priv->progress_bar),
580 									   percentage);
581 	progressbar = GTK_PROGRESS_BAR (status->priv->progress_bar);
582 	statusbar = status->priv->status_bar;
583 	gtk_widget_queue_draw (GTK_WIDGET (statusbar));
584 	gtk_widget_queue_draw (GTK_WIDGET (progressbar));
585 	progressbar_window = gtk_widget_get_window (GTK_WIDGET(progressbar));
586 	if (progressbar_window != NULL)
587 		gdk_window_process_updates (progressbar_window, TRUE);
588 	statusbar_window = gtk_widget_get_window (GTK_WIDGET(statusbar));
589 	if (statusbar_window != NULL)
590 		gdk_window_process_updates (statusbar_window, TRUE);
591 
592 	if (status->priv->current_ticks >= status->priv->total_ticks)
593 		anjuta_status_progress_reset (status);
594 }
595 
596 void
anjuta_status_progress_reset(AnjutaStatus * status)597 anjuta_status_progress_reset (AnjutaStatus *status)
598 {
599 	g_return_if_fail (ANJUTA_IS_STATUS (status));
600 
601 	if (status->priv->splash)
602 	{
603 		gtk_widget_destroy (status->priv->splash);
604 		status->priv->splash = NULL;
605 	}
606 	status->priv->current_ticks = 0;
607 	status->priv->total_ticks = 0;
608 	gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (status->priv->progress_bar), 0);
609 	anjuta_status_clear_stack (status);
610 }
611 
612 static gboolean
anjuta_status_timeout(AnjutaStatus * status)613 anjuta_status_timeout (AnjutaStatus *status)
614 {
615 	anjuta_status_pop (status);
616 	g_object_unref (status);
617 
618 	return FALSE;
619 }
620 
621 /**
622  * anjuta_status: (skip)
623  * Display message in status until timeout (seconds)
624  */
625 void
anjuta_status(AnjutaStatus * status,const gchar * mesg,gint timeout)626 anjuta_status (AnjutaStatus *status, const gchar *mesg, gint timeout)
627 {
628 	g_return_if_fail (ANJUTA_IS_STATUS (status));
629 	g_return_if_fail (mesg != NULL);
630 	anjuta_status_push (status, "%s", mesg);
631 	g_timeout_add_seconds (timeout, (void*) anjuta_status_timeout, g_object_ref (status));
632 }
633 
634 void
anjuta_status_set_title_window(AnjutaStatus * status,GtkWidget * window)635 anjuta_status_set_title_window (AnjutaStatus *status, GtkWidget *window)
636 {
637 	g_return_if_fail (ANJUTA_IS_STATUS (status));
638 	g_return_if_fail (GTK_IS_WINDOW (window));
639 	status->priv->window = GTK_WINDOW (window);
640 	g_object_add_weak_pointer (G_OBJECT (window),
641 							   (gpointer*)(gpointer)&status->priv->window);
642 }
643 
644 void
anjuta_status_set_title(AnjutaStatus * status,const gchar * title)645 anjuta_status_set_title (AnjutaStatus *status, const gchar *title)
646 {
647 	g_return_if_fail (ANJUTA_IS_STATUS (status));
648 
649 	if (!status->priv->window)
650 		return;
651 
652 	const gchar *app_name = g_get_application_name();
653 	if (title)
654 	{
655 		gchar* str = g_strconcat (title, " - ", app_name, NULL);
656 		gtk_window_set_title (status->priv->window, str);
657 		g_free (str);
658 	}
659 	else
660 	{
661 		gtk_window_set_title (status->priv->window, app_name);
662 	}
663 }
664 
665 ANJUTA_TYPE_BEGIN(AnjutaStatus, anjuta_status, GTK_TYPE_BOX);
666 ANJUTA_TYPE_END;
667