/***************************************************************************
                          misc_gtk.c  -  description
                             -------------------
    begin                : Fri Nov 29 2002
    copyright            : (C) 2002 by Tim-Philipp Müller
    email                : t.i.m@orange.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "global.h"
#include "icons.h"
#include "mainwindow.h"
#include "misc_gtk.h"
#include "misc_strings.h"

#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

#include "glade.h"

#include <gtk/gtk.h>

#define MENU_ITEM_SPACING 2

static GdkPixbuf	*hlbuf = NULL;


/******************************************************************************
 *
 *   misc_gtk_ok_dialog
 *
 ***/

void
misc_gtk_ok_dialog (GtkMessageType type, const gchar *txt)
{
	gchar *utf8; 
	GtkWidget *dialog;

	g_return_if_fail ( txt != NULL );

	utf8 = TO_UTF8(txt);

	dialog = gtk_message_dialog_new ( GTK_WINDOW(window),
	                                  GTK_DIALOG_DESTROY_WITH_PARENT,
	                                  type, GTK_BUTTONS_OK, "%s", utf8 );

	(void) gtk_dialog_run (GTK_DIALOG(dialog));

	gtk_widget_destroy (dialog);

	FREE_UTF8(utf8);
}



/******************************************************************************
 *
 *   new_button_pack_and_signal_connect
 *
 *    - creates a new button with a label
 *    - adds it to a pack box at the start or end (pack_start_flag = 1/0)
 *    - connects its 'clicked' signal with a function
 *    - and makes it visible
 *
 ***/

void
new_button_pack_and_signal_connect ( GtkWidget **button_ptr,
                                     GtkWidget *hbox,
                                     const gchar *label,
                                     void *click_func,
                                     gpointer func_data,
                                     gint pack_start_flag)
{
	gchar *utf8;

	g_return_if_fail (button_ptr!=NULL);
	g_return_if_fail (hbox!=NULL);
	g_return_if_fail (click_func!=NULL);
	g_return_if_fail (label!=NULL);

	utf8 = TO_UTF8(label);

	*button_ptr = gtk_button_new_with_label (utf8);

	/* connect button to function */

	g_signal_connect (G_OBJECT(*button_ptr), "clicked",
	                  G_CALLBACK(click_func), func_data);

	if (pack_start_flag)
	{
		gtk_box_pack_start (GTK_BOX (hbox), *button_ptr, FALSE, TRUE, 2);
	}
	else
	{
		gtk_box_pack_end   (GTK_BOX (hbox), *button_ptr, FALSE, TRUE, 2);
	}

	FREE_UTF8(utf8);
	gtk_widget_show (*button_ptr);
}


/******************************************************************************
 *
 *   new_icon_button_pack_and_signal_connect
 *
 ***/

void
new_icon_button_pack_and_signal_connect ( GtkWidget **button_ptr,
                                          GtkWidget *hbox,
                                          const gchar *text,
                                          void *click_func,
                                          gpointer func_data,
                                          gint pack_start_flag,
                                          IconName icon)
{
	g_return_if_fail (button_ptr != NULL);
	g_return_if_fail (hbox != NULL);
	g_return_if_fail (text != NULL);
	g_return_if_fail (click_func != NULL);

	*button_ptr = gtk_button_new ();

	gtk_container_add (GTK_CONTAINER(*button_ptr), make_icon_and_label_hbox(text,icon));

	g_signal_connect ( G_OBJECT(*button_ptr), "clicked", G_CALLBACK(click_func), func_data);

	if (pack_start_flag)
	{
		gtk_box_pack_start (GTK_BOX (hbox), *button_ptr, FALSE, TRUE, 2);
	}
	else
	{
		gtk_box_pack_end (GTK_BOX (hbox), *button_ptr, FALSE, TRUE, 2);
	}

	gtk_widget_show (*button_ptr);
}






/******************************************************************************
 *
 *   add_new_entry_widget_to_box
 *
 ***/

void
add_new_entry_widget_to_box ( GtkWidget *box,
                              GtkWidget **entrywidget,
                              const gchar *entrylabel,
                              guint16 max_length )
{
	GtkWidget *hbox;
	GtkWidget *label, *dummy;

	hbox = gtk_hbox_new ( FALSE, 0 );

	label = gtk_label_new ( UTF8_SHORT_PRINTF("%s", entrylabel) );
	gtk_misc_set_padding (GTK_MISC (label), 0, 2);
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
	gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
	gtk_widget_show (label);

	*entrywidget = gtk_entry_new();
	gtk_entry_set_max_length(GTK_ENTRY(*entrywidget), max_length);
	gtk_box_pack_start (GTK_BOX (hbox), *entrywidget, FALSE, FALSE, 0);
	gtk_widget_show (*entrywidget);

	dummy = gtk_label_new ("     ");
	gtk_box_pack_start (GTK_BOX (hbox), dummy, FALSE, FALSE, 5);
	gtk_widget_show (dummy);

	gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 0);	/* orig: FALSE FALSE --- add hbox to vbox */
	gtk_widget_show (hbox);
}




/******************************************************************************
 *
 *   make_icon_and_label_hbox
 *
 ***/

GtkWidget *
make_icon_and_label_hbox (const gchar *text, IconName icon)
{
	GtkWidget *hbox, *pix, *label;

	g_return_val_if_fail ( text   != NULL, NULL);
	g_return_val_if_fail ( window != NULL, NULL);

	hbox = gtk_hbox_new ( FALSE, 0 );

	if ( hbox == NULL )
		return NULL;

	pix = gtk_image_new_from_pixbuf (get_icon (icon));

	if (pix)
	{
		gtk_widget_show(pix);
		gtk_box_pack_start (GTK_BOX(hbox), pix, FALSE,FALSE,0);
	}

	if ( text != NULL  &&  *text != 0x00 )
	{
		label = gtk_label_new ("");
		gtk_label_set_use_markup (GTK_LABEL(label), TRUE);
		gtk_label_set_markup (GTK_LABEL(label), UTF8_SHORT_PRINTF("%s", text) );
		gtk_widget_show(label);
		gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE,0);
	}

	gtk_widget_show(hbox);

	return hbox;
}


/******************************************************************************
 *
 *   do_colorshift
 *
 *   (code taken from gnome-panel)
 *
 ***/

static void 
do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
{
	gint i, j;
	gint width, height, has_alpha, srcrowstride, destrowstride;
	guchar *target_pixels;
	guchar *original_pixels;
	guchar *pixsrc;
	guchar *pixdest;
	gint val;
	guchar r,g,b;

	has_alpha = gdk_pixbuf_get_has_alpha (src);
	width = gdk_pixbuf_get_width (src);
	height = gdk_pixbuf_get_height (src);
	srcrowstride = gdk_pixbuf_get_rowstride (src);
	destrowstride = gdk_pixbuf_get_rowstride (dest);
	target_pixels = gdk_pixbuf_get_pixels (dest);
	original_pixels = gdk_pixbuf_get_pixels (src);

	for (i = 0; i < height; i++)
	{
		pixdest = target_pixels + i*destrowstride;
		pixsrc = original_pixels + i*srcrowstride;

		for (j = 0; j < width; j++)
		{
			r = *(pixsrc++);
			g = *(pixsrc++);
			b = *(pixsrc++);
			val = r + shift;
			*(pixdest++) = CLAMP(val, 0, 255);
			val = g + shift;
			*(pixdest++) = CLAMP(val, 0, 255);
			val = b + shift;
			*(pixdest++) = CLAMP(val, 0, 255);
			if (has_alpha)
				*(pixdest++) = *(pixsrc++);
		}
	}
}


/******************************************************************************
 *
 *   make_hc_pixbuf
 *
 *   (code taken from gnome-panel)
 *
 ***/

static GdkPixbuf *
make_hc_pixbuf (GdkPixbuf *pb)
{
	GdkPixbuf *new;

	if(!pb)
		return NULL;

	new = gdk_pixbuf_new ( gdk_pixbuf_get_colorspace(pb),
	                       gdk_pixbuf_get_has_alpha (pb),
	                       gdk_pixbuf_get_bits_per_sample (pb),
	                       gdk_pixbuf_get_width (pb),
	                       gdk_pixbuf_get_height (pb));

	do_colorshift (new, pb, 30);

	return new;
}



/******************************************************************************
 *
 *   flash_widget
 *
 *   Highlights the image in WIDGET, which must be a GtkImage.
 *   Original pixbuf is stored to restore it later with
 *   unflash_widget().
 *
 *   Code inspired by gnome-panel.
 *
 ***/

static void 
flash_widget (GtkWidget *widget)
{
	GdkPixbuf *pb;

	if (hlbuf) 
	{
		g_object_unref(hlbuf);
	}

	hlbuf = gdk_pixbuf_copy(gtk_image_get_pixbuf(GTK_IMAGE(widget)));
	pb = make_hc_pixbuf(hlbuf);
	gtk_image_set_from_pixbuf(GTK_IMAGE(widget), pb);
	g_object_unref(pb);
}



/******************************************************************************
 *
 *   unflash_widget
 *
 *   Restores last flashed widget to original state.
 *   Note that only the last flashed widget is saved, so calling
 *   flash_widget() on 2 different widgets without calling unflash first
 *   will result in the first widget being lost forever (will not happen
 *   unless we forget to set the leave event on a widget).
 *
 ***/

static void
unflash_widget (GtkWidget *widget)
{
	if (!hlbuf)
		return;

	gtk_image_set_from_pixbuf(GTK_IMAGE(widget), hlbuf);
	g_object_unref(hlbuf);
	hlbuf = NULL;
}


/******************************************************************************
 *
 *   misc_highlight_enter
 *
 ***/

static gboolean
misc_highlight_enter (GtkWidget *widget,  GdkEventCrossing *ev, gpointer baz)
{
	flash_widget (baz);
	return FALSE;
}

/******************************************************************************
 *
 *   misc_highlight_leave
 *
 ***/

static gboolean
misc_highlight_leave (GtkWidget *widget,  GdkEventCrossing *ev, gpointer baz)
{
	unflash_widget (baz);
	return FALSE;
}


/******************************************************************************
 *
 *   new_highlight_button_pack_and_signal_connect
 *
 ***/

void
new_highlight_button_pack_and_signal_connect ( GtkWidget **box,
                                               IconName icon,
                                               void *click_func,
                                               gpointer func_data )
{
	GtkWidget *img;

	*box = gtk_button_new ();

	gtk_button_set_relief(GTK_BUTTON(*box), GTK_RELIEF_NONE);

	img = gtk_image_new_from_pixbuf (get_icon (icon));

	if (!img)
	{
		gtk_widget_destroy (*box);
		*box = NULL;
		return;
	}

	gtk_container_add (GTK_CONTAINER(*box), img);

	g_signal_connect (G_OBJECT (*box), "enter_notify_event", G_CALLBACK (misc_highlight_enter), img);
	g_signal_connect (G_OBJECT (*box), "leave_notify_event", G_CALLBACK (misc_highlight_leave), img);

	 /* note [Tim]: func_data is not handed over to callback for some reason. maybe we need
	  * to use g_signal_connect_swapped() or something? */

	// FIXME: this is because the callbacks are missing the GdkEvent parameter, which should not
	//        be necessary any longer with the "clicked" signal

	g_signal_connect (G_OBJECT (*box), "button-press-event", G_CALLBACK (click_func), func_data);

	gtk_widget_show_all (*box);
}


/*******************************************************************************
 *
 *  misc_gtk_new_tooltip_label_in_flat_button_box
 *
 *******************************************************************************/

static gboolean
onLabelButtonPressEvent (GtkWidget *button, GdkEvent *event, gpointer baz)
{
	return TRUE; /* do not invoke other handlers */
}

GtkWidget *
misc_gtk_new_tooltip_label_in_flat_button_box (GtkWidget **label, const gchar *tiptext_utf8)
{
	GtkWidget *button;

	button = gtk_button_new();
	gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
	g_signal_connect(button, "button-press-event", G_CALLBACK(onLabelButtonPressEvent), NULL);
	g_signal_connect(button, "enter-notify-event", G_CALLBACK(onLabelButtonPressEvent), NULL);
	GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
	GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_DEFAULT);

	*label = gtk_label_new(NULL);
	gtk_label_set_justify (GTK_LABEL(*label), GTK_JUSTIFY_LEFT);

	gtk_container_add (GTK_CONTAINER(button), *label);

	if (tiptext_utf8)
	{
		static GtkTooltips *tooltips; /* NULL */

		if (tooltips == NULL)
			tooltips = gtk_tooltips_new();

		gtk_tooltips_set_tip(tooltips, button, tiptext_utf8, NULL);
	}

	gtk_widget_show_all(button);

	return button;
}



/*******************************************************************************
 *
 *   misc_gtk_tree_selection_count_selected_rows
 *
 *   The function 'gtk_tree_selection_count_selected_rows' is only in
 *     gtk+-2.2, but not in gtk+-2.0, so let's re-implement it here. We could
 *     use #ifdefs of course, but then the whole thing would only work properly
 *     when compiling from source. We need to use this reimplementation at all
 *     places in order to make sure that a binary package created on a developer's
 *     machine with gtk+-2.2 will work on a user's machine with gtk+-2.0  *sigh*
 *
 ***/

static void
misc_gtk_tree_selection_count_selected_rows_foreach_helper (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
	gint *count = (gint*)data;

	g_return_if_fail ( count != NULL);

	*count = *count + 1;
}

gint
misc_gtk_tree_selection_count_selected_rows (GtkTreeSelection *selection)
{
	gint counter = 0;

	g_return_val_if_fail ( selection != NULL, 0 );

	gtk_tree_selection_selected_foreach ( selection, misc_gtk_tree_selection_count_selected_rows_foreach_helper, &counter );

	return counter;
}


/******************************************************************************
 *
 *   misc_gtk_attach_new_check_button_to_table
 *
 *   Used by the options page.
 *
 *   Returns new check button widget
 *
 ***/

GtkWidget *
misc_gtk_attach_new_check_button_to_table ( GtkWidget *table,
                                            const gchar *checktxt,
                                            GtkTooltips *tooltips,
                                            const gchar *tooltxt,
                                            guint row,
                                            guint col )
{
	GtkWidget    *checkbutton;
	const gchar  *checktxt_utf8; 

	checktxt_utf8 = UTF8_SHORT_PRINTF(checktxt);

	checkbutton = gtk_check_button_new_with_label (checktxt_utf8);

	gtk_widget_show (checkbutton);

	if (tooltxt)
	{
		gchar *tooltxt_utf8 = TO_UTF8(tooltxt);

		gtk_tooltips_set_tip (tooltips, checkbutton, tooltxt_utf8, NULL);

		FREE_UTF8(tooltxt_utf8);
	}

	gtk_table_attach (GTK_TABLE(table), checkbutton, row, (row+1), col, (col+1),
					(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
					(GtkAttachOptions) (0), 0, 0);

	return checkbutton;
}

/***************************************************************************
 *
 *   misc_gtk_add_menu_header
 *
 *   Adds an inactive menu item with a follow-up separator to the menu.
 *
 ***************************************************************************/

void
misc_gtk_add_menu_header (GtkWidget *menu, const gchar *text, const gchar *stock_id)
{
  GtkWidget   *item, *label, *icon;
	const gchar *utf8;
  gchar       *markup;

  g_return_if_fail ( menu != NULL );
  g_return_if_fail ( text != NULL );

	/* we need to check this here, otherwise be might get cases where
	 * UTF8_SHORT_PRINTF() is called with a buffer from UTF8_SHORT_PRINTF().. */

	utf8 = text;
	if (g_utf8_validate(text, -1, NULL) == FALSE)
		utf8 = UTF8_SHORT_PRINTF("%s", text);

  label = gtk_label_new(NULL);

  /* we'll just assume that the text in utf8 won't need escaping */
  markup = g_strconcat("<span color='black' weight='ultrabold'> <b>", utf8, "</b></span>", NULL);

  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.50);
  gtk_label_set_markup(GTK_LABEL(label), markup);

  gtk_widget_show(label);

  item = gtk_image_menu_item_new();

  if (stock_id)
  {
    icon = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_MENU);
    gtk_widget_show (icon);
    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), icon);
  }

  gtk_container_add(GTK_CONTAINER(item), label);

  if (gtk_check_version(2,4,0) == NULL)
  	gtk_container_set_border_width (GTK_CONTAINER(item), MENU_ITEM_SPACING);

  gtk_widget_set_sensitive (item, FALSE);

  gtk_widget_show(item);

  gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);

  misc_gtk_add_menu_separator (menu);

  g_free(markup);
}


/******************************************************************************
 *
 *   misc_gtk_add_menu_item
 *
 *   Appends a menu item to the specified menu, ie. an icon with a text.
 *
 ***/

void
misc_gtk_add_menu_item ( GtkWidget *menu,
                         const gchar *text,
                         void *callback_func,
                         gpointer user_data,
                         IconName icon,
                         gboolean is_sensitive )
{
	GtkWidget   *item, *pix;
	const gchar *utf8;

	g_return_if_fail ( menu != NULL );
	g_return_if_fail ( text != NULL );

	/* we need to check this here, otherwise be might get cases where
	 * UTF8_SHORT_PRINTF() is called with a buffer from UTF8_SHORT_PRINTF()..
	 */

	utf8 = text;

	if ( g_utf8_validate(text, -1, NULL) == FALSE )
		utf8 = UTF8_SHORT_PRINTF("%s", text);

	item = gtk_image_menu_item_new_with_label( utf8 );

	if (gtk_check_version(2,4,0) == NULL)
		gtk_container_set_border_width (GTK_CONTAINER(item), MENU_ITEM_SPACING);

	pix = gtk_image_new_from_pixbuf (get_icon((icon < ICON_NUM_ICONS) ? icon : ICON_NONE));

	if (pix)
	{
		gtk_widget_show(pix);
		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(item), pix);
	}

	if (callback_func)
		g_signal_connect (G_OBJECT(item), "activate", G_CALLBACK(callback_func), user_data);

	gtk_widget_show(item);
	gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
	gtk_widget_set_sensitive (item, is_sensitive);
}


/******************************************************************************
 *
 *   misc_gtk_add_submenu
 *
 *   Appends a sub menu item to the specified menu.
 *
 ***/

void
misc_gtk_add_submenu ( GtkWidget *menu,
                       const gchar *text,
                       IconName icon,
                       GtkWidget *submenu,
                       gboolean is_sensitive )
{
	GtkWidget  *item, *pix;

	g_return_if_fail ( menu    != NULL );
	g_return_if_fail ( text    != NULL );
	g_return_if_fail ( submenu != NULL );

	item = gtk_image_menu_item_new_with_label( UTF8_SHORT_PRINTF("%s", text) );
  
	if (gtk_check_version(2,4,0) == NULL)
		gtk_container_set_border_width (GTK_CONTAINER(item), MENU_ITEM_SPACING);

	pix = gtk_image_new_from_pixbuf (get_icon((icon < ICON_NUM_ICONS) ? icon : ICON_NONE));

	if (pix)
	{
		gtk_widget_show(pix);
		gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(item), pix);
	}

	gtk_widget_show(item);
	gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
	gtk_widget_set_sensitive (item, is_sensitive);

	gtk_menu_item_set_submenu (GTK_MENU_ITEM(item), submenu);
}


/******************************************************************************
 *
 *   misc_gtk_add_separator
 *
 *   Appends a separator to a menu
 *
 ***/

void
misc_gtk_add_menu_separator (GtkWidget *menu)
{
	GtkWidget *item;

	g_return_if_fail ( menu != NULL );

	item = gtk_separator_menu_item_new();

	gtk_widget_show(item);

	gtk_menu_shell_append (GTK_MENU_SHELL(menu), item);
}


/******************************************************************************
 *
 *   misc_gtk_label_new_with_markup
 *
 *   makes a new label, using UTF8_SHORT_PRINTF(markup_template,text_locale),
 *     which means that the template must contain exactly one '%s' format argument.
 *     The point of the template is to separate translation and markup.
 *
 ***/

GtkWidget *
misc_gtk_label_new_with_markup (const gchar *markup_template, const gchar *text_locale)
{
	GtkWidget *label;

	label = gtk_label_new (NULL);

	gtk_widget_show (label);

	if ((markup_template) && (text_locale))
		gtk_label_set_markup (GTK_LABEL(label), UTF8_SHORT_PRINTF(markup_template, text_locale));

	return label;
}




/******************************************************************************
 *
 *   misc_gtk_tree_model_get_iter_from_row_reference
 *
 *   converts a GtkTreeRowPathReference into an GtkTreeIter
 *
 *   returns TRUE if all went fine.
 *
 ***/

gboolean
misc_gtk_tree_model_get_iter_from_row_reference ( GtkTreeModel *model,
                                                  GtkTreeRowReference *ref,
                                                  GtkTreeIter *iter )
{
	GtkTreePath *path;

	g_return_val_if_fail ( ref   != NULL, FALSE);
	g_return_val_if_fail ( iter  != NULL, FALSE);
	g_return_val_if_fail ( model != NULL, FALSE);

	path = gtk_tree_row_reference_get_path(ref);

	g_return_val_if_fail ( path != NULL, FALSE);


	if ( gtk_tree_model_get_iter (model, iter, path) == FALSE )
	{
		gtk_tree_path_free(path);
		g_critical("gtk_tree_model_get_iter() == FALSE");
		return FALSE;
	}

	gtk_tree_path_free(path);

	return TRUE;
}


/******************************************************************************
 *
 *   misc_gtk_tree_model_get_row_reference_from_iter
 *
 *   converts a GtkTreeIter into a new GtkTreeRowReference
 *
 *   returns NULL one erros, otherwise GtkTreeRowReference
 *
 ***/

GtkTreeRowReference *
misc_gtk_tree_model_get_row_reference_from_iter ( GtkTreeModel *model,
                                                  GtkTreeIter *iter )
{
	GtkTreeRowReference *ref;
	GtkTreePath         *path;

	g_return_val_if_fail ( iter  != NULL, NULL);
	g_return_val_if_fail ( model != NULL, NULL);

	path = gtk_tree_model_get_path(model, iter);

	g_return_val_if_fail ( path != NULL, NULL);

	ref = gtk_tree_row_reference_new (model, path);

	g_return_val_if_fail ( ref != NULL, NULL);

	gtk_tree_path_free(path);

	return ref;
}


/*******************************************************************************
 *
 *   misc_gtk_free_row_reference
 *
 ***/

void
misc_gtk_free_row_reference (gpointer data)
{
	if (!data)
		return;

	if (gtk_tree_row_reference_valid((GtkTreeRowReference*)data))
		gtk_tree_row_reference_free((GtkTreeRowReference*)data);
}


/***************************************************************************
 *
 *   utils_ui_retrieve_widget
 *
 ***************************************************************************/

static void
utils_ui_retrieve_widget (GladeXML      *xml, 
                          const gchar   *name, 
                          GtkWidget    **p_widget, 
                          gboolean      *p_allok)
{
	g_assert(GLADE_IS_XML(xml) && name && p_widget && p_allok);
	
	*p_widget = glade_xml_get_widget (xml, name);
	
	if (*p_widget == NULL)
	{
		g_warning("Failed to load widget '%s' in '%s'\n", name, xml->filename);
		*p_allok = FALSE;
	}
	
	g_return_if_fail(GTK_IS_WIDGET(*p_widget));

//	g_print("Loaded '%s' of type '%s' ok.\n", widget_name1, g_type_name(G_OBJECT_TYPE(*p_widget1)));
}


/***************************************************************************
 *
 *   misc_gtk_load_interface
 *
 *   returns TRUE if all went fine, FALSE on error 
 *
 *   Expects pairs of widget name string + GtkWidget ** pointers, 
 *    and a NULL parameter as terminator.
 *
 ***************************************************************************/

gboolean
misc_gtk_load_interface (const gchar   *gladefn,  
                         gboolean       autoconnect_signals,
                         const gchar   *widget_name1,
                         GtkWidget    **p_widget1,
                            ...                        )
{
	const gchar  *name;
	GtkWidget   **p_widget;
	GladeXML    *xml;
	gboolean     allok;
	gchar       *fn;
	
	va_list  args;

	g_return_val_if_fail (gladefn      != NULL, FALSE);
	g_return_val_if_fail (widget_name1 != NULL, FALSE);
	g_return_val_if_fail (p_widget1    != NULL, FALSE);

	if (!g_path_is_absolute(gladefn))
		fn = g_build_path(G_DIR_SEPARATOR_S, DATADIR, PACKAGE, "ui", gladefn, NULL);
	else
		fn = g_strdup(gladefn);
	
	xml = glade_xml_new (fn, NULL, PACKAGE);
	
	if (xml == NULL)
	{
		g_warning ("Could not load '%s'\n", fn);
		return FALSE;
	}
	
	allok = TRUE;

	utils_ui_retrieve_widget (xml, widget_name1, p_widget1, &allok);
	
	va_start (args, p_widget1);
	
	do
	{
		name = va_arg (args, const gchar *);
		
		if (name)
		{
			p_widget = va_arg (args, GtkWidget **);

			utils_ui_retrieve_widget (xml, name, p_widget, &allok);
		}
	} while (name != NULL);
	
	va_end (args);

	if (autoconnect_signals)
		glade_xml_signal_autoconnect(xml);

	g_object_unref(xml);
	g_free(fn);
	
	return allok;
}

#if 0
/***************************************************************************
 *
 *   sc_label_set_text
 *
 ***************************************************************************/

void              
sc_label_set_text (gpointer label, const gchar *format, ...)
{
	va_list args;
	gchar   *s;

	g_return_if_fail (GTK_IS_LABEL (label));
	g_return_if_fail (format != NULL);

	if (format == NULL)
	{
		gtk_label_set_text ((GtkLabel*) label, "");
		return;
	}

	va_start (args, format);
	s = g_strdup_vprintf (format, args);
	va_end (args);
	
	gtk_label_set_text ((GtkLabel*) label, s);
	
	g_free (s);
}

/***************************************************************************
 *
 *   sc_label_set_markup
 *
 ***************************************************************************/

void              
sc_label_set_markup (gpointer label, const gchar *format, ...)
{
	va_list args;
	gchar   *s;

	g_return_if_fail (GTK_IS_LABEL (label));
	g_return_if_fail (format != NULL);

	if (format == NULL)
	{
		gtk_label_set_text ((GtkLabel*) label, "");
		return;
	}

	va_start (args, format);
	s = g_markup_vprintf_escaped (format, args);
	va_end (args);
	
	gtk_label_set_markup ((GtkLabel*) label, s);
	
	g_free (s);
}

#endif /* 0 */

