/*
 * GNOME panel drawer module.
 * (C) 1997 The Free Software Foundation
 *
 * Authors: Miguel de Icaza
 *          Federico Mena
 *          George Lebl
 */

#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>

#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>

#include "drawer.h"

#include "applet.h"
#include "button-widget.h"
#include "panel-config-global.h"
#include "panel-gconf.h"
#include "panel-profile.h"
#include "panel-util.h"
#include "xstuff.h"
#include "panel-globals.h"
#include "panel-lockdown.h"
#include "panel-icon-names.h"

static void
drawer_click (GtkWidget *w, Drawer *drawer)
{
	if (!panel_toplevel_get_is_hidden (drawer->toplevel))
		panel_toplevel_hide (drawer->toplevel, FALSE, -1);
	else 
		panel_toplevel_unhide (drawer->toplevel);
}

static void
toplevel_destroyed (GtkWidget *widget,
		    Drawer    *drawer)
{
	drawer->toplevel = NULL;
	gtk_widget_destroy (drawer->button);
}

static void
destroy_drawer (GtkWidget *widget,
		Drawer    *drawer)
{
	GConfClient *client;
	int          i;

	client = panel_gconf_get_client ();

	for (i = 0; i < PANEL_DRAWER_N_LISTENERS; i++) {
		if (drawer->listeners [i])
			gconf_client_notify_remove (client, drawer->listeners [i]);
		drawer->listeners [i] = 0;
	}

	if (drawer->toplevel)
		gtk_widget_destroy (GTK_WIDGET (drawer->toplevel));
	drawer->toplevel = NULL;

	if (drawer->close_timeout_id)
		g_source_remove (drawer->close_timeout_id);
	drawer->close_timeout_id = 0;
}

static void
drawer_focus_panel_widget (Drawer           *drawer,
			   GtkDirectionType  direction)
{
	PanelWidget *panel_widget;

	panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);

	gtk_window_present (GTK_WINDOW (drawer->toplevel));
	gtk_container_set_focus_child (GTK_CONTAINER (panel_widget), NULL);
	gtk_widget_child_focus (GTK_WIDGET (panel_widget), direction);
}

static gboolean
key_press_drawer (GtkWidget   *widget,
		  GdkEventKey *event,
		  Drawer      *drawer)
{
	gboolean retval = TRUE;
	GtkOrientation orient;

	if (event->state & gtk_accelerator_get_default_mod_mask ())
		return FALSE;

	orient = PANEL_WIDGET (drawer->button->parent)->orient;

	switch (event->keyval) {
	case GDK_Up:
	case GDK_KP_Up:
		if (orient == GTK_ORIENTATION_HORIZONTAL) {
			if (!panel_toplevel_get_is_hidden (drawer->toplevel))
				drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD);
		} else {
			/* let default focus movement happen */
			retval = FALSE;
		}
		break;
	case GDK_Left:
	case GDK_KP_Left:
		if (orient == GTK_ORIENTATION_VERTICAL) {
			if (!panel_toplevel_get_is_hidden (drawer->toplevel))
				drawer_focus_panel_widget (drawer, GTK_DIR_TAB_BACKWARD);
		} else {
			/* let default focus movement happen */
			retval = FALSE;
		}
		break;
	case GDK_Down:
	case GDK_KP_Down:
		if (orient == GTK_ORIENTATION_HORIZONTAL) {
			if (!panel_toplevel_get_is_hidden (drawer->toplevel))
				drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD);
		} else {
			/* let default focus movement happen */
			retval = FALSE;
		}
		break;
	case GDK_Right:
	case GDK_KP_Right:
		if (orient == GTK_ORIENTATION_VERTICAL) {
			if (!panel_toplevel_get_is_hidden (drawer->toplevel))
				drawer_focus_panel_widget (drawer, GTK_DIR_TAB_FORWARD);
		} else {
			/* let default focus movement happen */
			retval = FALSE;
		}
		break;
	case GDK_Escape:
		panel_toplevel_hide (drawer->toplevel, FALSE, -1);
		break;
	default:
		retval = FALSE;
		break;
	}

	return retval;
}

/*
 * This function implements Esc moving focus from the drawer to the drawer
 * icon and closing the drawer and Shift+Esc moving focus from the drawer
 * to the drawer icon without closing the drawer when focus is in the drawer.
 */
static gboolean
key_press_drawer_widget (GtkWidget   *widget,
			 GdkEventKey *event,
			 Drawer      *drawer)
{
	PanelWidget *panel_widget;

	if (event->keyval != GDK_Escape)
		return FALSE;

	panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);

	gtk_window_present (GTK_WINDOW (panel_widget->toplevel));

	if ((event->state & gtk_accelerator_get_default_mod_mask ()) == GDK_SHIFT_MASK ||
	    panel_toplevel_get_is_hidden (drawer->toplevel))
		return TRUE;

	panel_toplevel_hide (drawer->toplevel, FALSE, -1);

	return TRUE;
}

static void 
drag_data_received_cb (GtkWidget          *widget,
		       GdkDragContext     *context,
		       gint                x,
		       gint                y,
		       GtkSelectionData   *selection_data,
		       guint               info,
		       guint               time_,
		       Drawer             *drawer)
{
	PanelWidget *panel_widget;

	if (!panel_check_dnd_target_data (widget, context, &info, NULL)) {
		gtk_drag_finish (context, FALSE, FALSE, time_);
		return;
	}

	panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);

	panel_receive_dnd_data (
		panel_widget, info, -1, selection_data, context, time_);
}

static gboolean
drag_motion_cb (GtkWidget          *widget,
		GdkDragContext     *context,
		int                 x,
		int                 y,
		guint               time_,
		Drawer             *drawer)
{
	PanelWidget *panel_widget;
	guint        info = 0;

	if (!panel_check_dnd_target_data (widget, context, &info, NULL))
		return FALSE;

	panel_widget = panel_toplevel_get_panel_widget (drawer->toplevel);

	if (!panel_check_drop_forbidden (panel_widget, context, info, time_))
		return FALSE;

	if (drawer->close_timeout_id)
		g_source_remove (drawer->close_timeout_id);
	drawer->close_timeout_id = 0;

	button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), TRUE);

	if (panel_toplevel_get_is_hidden (drawer->toplevel)) {
		panel_toplevel_unhide (drawer->toplevel);
		drawer->opened_for_drag = TRUE;
	}

	return TRUE;
}

static gboolean
close_drawer_in_idle (gpointer data)
{
	Drawer *drawer = (Drawer *) data;

	drawer->close_timeout_id = 0;

	if (drawer->opened_for_drag) {
		panel_toplevel_hide (drawer->toplevel, FALSE, -1);
		drawer->opened_for_drag = FALSE;
	}

	return FALSE;
}

static void
queue_drawer_close_for_drag (Drawer *drawer)
{
	if (!drawer->close_timeout_id)
		drawer->close_timeout_id =
			g_timeout_add_seconds (1, close_drawer_in_idle, drawer);
}

static void
drag_leave_cb (GtkWidget      *widget,
	       GdkDragContext *context,
	       guint           time_,
	       Drawer         *drawer)
{
	queue_drawer_close_for_drag (drawer);

	button_widget_set_dnd_highlight (BUTTON_WIDGET (widget), FALSE);
}

static gboolean
drag_drop_cb (GtkWidget      *widget,
	      GdkDragContext *context,
	      int             x,
	      int             y,
	      guint           time_,
	      Drawer         *drawer)
{
	GdkAtom atom = NULL;

	if (!panel_check_dnd_target_data (widget, context, NULL, &atom))
		return FALSE;

	gtk_drag_get_data (widget, context, atom, time_);

	return TRUE;
}

static void  
drag_data_get_cb (GtkWidget          *widget,
		  GdkDragContext     *context,
		  GtkSelectionData   *selection_data,
		  guint               info,
		  guint               time,
		  Drawer             *drawer)
{
	char *foo;

	foo = g_strdup_printf ("DRAWER:%d", panel_find_applet_index (widget));

	gtk_selection_data_set (selection_data,
				selection_data->target, 8, (guchar *)foo,
				strlen (foo));

	g_free (foo);
}

static void
set_tooltip_and_name (Drawer     *drawer,
		      const char *tooltip)
{
	g_return_if_fail (drawer != NULL);
	g_return_if_fail (tooltip != NULL);

	if (tooltip && !tooltip [0])
		tooltip = NULL;

	panel_toplevel_set_name (drawer->toplevel, tooltip);
	panel_util_set_tooltip_text (drawer->button, tooltip);
}

static Drawer *
create_drawer_applet (PanelToplevel    *toplevel,
		      PanelToplevel    *parent_toplevel,
		      const char       *tooltip,
		      const char       *custom_icon,
		      gboolean          use_custom_icon,
		      PanelOrientation  orientation)
{
	Drawer *drawer;
	AtkObject *atk_obj;
	
	drawer = g_new0 (Drawer, 1);

	drawer->toplevel = toplevel;

	if (!use_custom_icon || !custom_icon || !custom_icon [0]) {
		drawer->button = button_widget_new (PANEL_ICON_DRAWER, TRUE,
						    orientation);
	} else {
		drawer->button = button_widget_new (custom_icon, TRUE,
						    orientation);
	}

	if (!drawer->button) {
		g_free (drawer);
		return NULL;
	}
	atk_obj = gtk_widget_get_accessible (drawer->button);
	atk_object_set_name (atk_obj, _("Drawer")); 

	set_tooltip_and_name (drawer, tooltip);

	gtk_drag_dest_set (drawer->button, 0, NULL, 0, 0); 

	g_signal_connect (drawer->button, "drag_data_get",
			  G_CALLBACK (drag_data_get_cb), drawer);
	g_signal_connect (drawer->button, "drag_data_received",
			  G_CALLBACK (drag_data_received_cb), drawer);
	g_signal_connect (drawer->button, "drag_motion",
			  G_CALLBACK (drag_motion_cb), drawer);
	g_signal_connect (drawer->button, "drag_leave",
			  G_CALLBACK (drag_leave_cb), drawer);
	g_signal_connect (drawer->button, "drag_drop",
			  G_CALLBACK (drag_drop_cb), drawer);

	g_signal_connect (drawer->button, "clicked",
			  G_CALLBACK (drawer_click), drawer);
	g_signal_connect (drawer->button, "destroy",
			  G_CALLBACK (destroy_drawer), drawer);
	g_signal_connect (drawer->button, "key_press_event",
			  G_CALLBACK (key_press_drawer), drawer);
	g_signal_connect (toplevel, "destroy",
			  G_CALLBACK (toplevel_destroyed), drawer);

	gtk_widget_show (drawer->button);

	g_signal_connect (drawer->toplevel, "key_press_event",
			  G_CALLBACK (key_press_drawer_widget), drawer);

	panel_toplevel_attach_to_widget (
		toplevel, parent_toplevel, GTK_WIDGET (drawer->button));

	return drawer;
}

static PanelToplevel *
create_drawer_toplevel (const char *drawer_id)
{
	PanelToplevel *toplevel;
	GConfClient   *client;
	const char    *key;
	char          *toplevel_id;

	client  = panel_gconf_get_client ();

	toplevel_id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);
	
	toplevel = panel_profile_load_toplevel (client, PANEL_CONFIG_DIR,
						PANEL_GCONF_TOPLEVELS, toplevel_id);

	if (!toplevel) {
		g_free (toplevel_id);
		return NULL;
	}

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "attached_toplevel_id");
	gconf_client_set_string (client, key, toplevel_id, NULL);
	g_free (toplevel_id);

	panel_profile_set_toplevel_enable_buttons (toplevel, TRUE);
	panel_profile_set_toplevel_enable_arrows (toplevel, TRUE);

	return toplevel;
}

static void
drawer_button_size_allocated (GtkWidget     *widget,
			      GtkAllocation *alloc,
			      Drawer        *drawer)
{
	if (!gtk_widget_get_realized (widget))
		return;

	gtk_widget_queue_resize (GTK_WIDGET (drawer->toplevel));

	g_object_set_data (G_OBJECT (widget), "allocated", GINT_TO_POINTER (TRUE));
}

static void
panel_drawer_use_custom_icon_changed (GConfClient *client,
				      guint        cnxn_id,
				      GConfEntry  *entry,
				      Drawer      *drawer)
{
	gboolean  use_custom_icon;
	char     *custom_icon = NULL;

	if (!entry->value || entry->value->type != GCONF_VALUE_BOOL)
		return;

	use_custom_icon = gconf_value_get_bool (entry->value);

	if (use_custom_icon) {
		const char *key;

		key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "custom_icon");
		custom_icon = gconf_client_get_string (client, key, NULL);
	}

	button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon);

	g_free (custom_icon);
}

static void
panel_drawer_custom_icon_changed (GConfClient *client,
				  guint        cnxn_id,
				  GConfEntry  *entry,
				  Drawer      *drawer)
{
	const char *custom_icon;

	if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
		return;

	custom_icon = gconf_value_get_string (entry->value);

	if (custom_icon && custom_icon [0]) {
		const char *key;
		gboolean    use_custom_icon;

		key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "use_custom_icon");
		use_custom_icon = gconf_client_get_bool (client, key, NULL);
		if (use_custom_icon)
			button_widget_set_icon_name (BUTTON_WIDGET (drawer->button), custom_icon);
	}
}

static void
panel_drawer_tooltip_changed (GConfClient *client,
			      guint        cnxn_id,
			      GConfEntry  *entry,
			      Drawer      *drawer)
{
	if (!entry->value || entry->value->type != GCONF_VALUE_STRING)
		return;

	set_tooltip_and_name (drawer,
			      gconf_value_get_string (entry->value));
}

static void
panel_drawer_connect_to_gconf (Drawer *drawer)
{
	GConfClient *client;
	const char  *key;
	int          i = 0;

	client  = panel_gconf_get_client ();
	
	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "use_custom_icon");
        drawer->listeners [i++] =
		gconf_client_notify_add (client, key,
					 (GConfClientNotifyFunc) panel_drawer_use_custom_icon_changed,
					 drawer, NULL, NULL);

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "custom_icon");
        drawer->listeners [i++] =
		gconf_client_notify_add (client, key,
					 (GConfClientNotifyFunc) panel_drawer_custom_icon_changed,
					 drawer, NULL, NULL);

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer->info->id, "tooltip");
        drawer->listeners [i++] =
		gconf_client_notify_add (client, key,
					 (GConfClientNotifyFunc) panel_drawer_tooltip_changed,
					 drawer, NULL, NULL);

	g_assert (i == PANEL_DRAWER_N_LISTENERS);
}

static gboolean
drawer_changes_enabled (void)
{
  return !panel_lockdown_get_locked_down ();
}

static void
load_drawer_applet (char          *toplevel_id,
		    const char    *custom_icon,
		    gboolean       use_custom_icon,
		    const char    *tooltip,
		    PanelToplevel *parent_toplevel,
		    gboolean       locked,
		    int            pos,
		    gboolean       exactpos,
		    const char    *id)
{
	PanelOrientation  orientation;
	PanelToplevel    *toplevel = NULL;
	Drawer           *drawer = NULL;
	PanelWidget      *panel_widget;

	orientation = panel_toplevel_get_orientation (parent_toplevel);

	if (toplevel_id)
		toplevel = panel_profile_get_toplevel_by_id (toplevel_id);

	if (!toplevel)
		toplevel = create_drawer_toplevel (id);

	if (toplevel) {
		panel_toplevel_hide (toplevel, FALSE, -1);
		drawer = create_drawer_applet (toplevel,
					       parent_toplevel,
					       tooltip,
					       custom_icon,
					       use_custom_icon,
					       orientation);
	}

	if (!drawer)
		return;

	panel_widget = panel_toplevel_get_panel_widget (parent_toplevel);

	drawer->info = panel_applet_register (drawer->button, drawer,
					      (GDestroyNotify) g_free,
					      panel_widget,
					      locked, pos, exactpos,
					      PANEL_OBJECT_DRAWER, id);

	if (!drawer->info) {
		gtk_widget_destroy (GTK_WIDGET (toplevel));
		return;
	}

	g_signal_connect_after (drawer->button, "size_allocate",
				G_CALLBACK (drawer_button_size_allocated), drawer);

	panel_widget_add_forbidden (panel_toplevel_get_panel_widget (drawer->toplevel));
	panel_widget_set_applet_expandable (panel_widget, GTK_WIDGET (drawer->button), FALSE, TRUE);
	panel_widget_set_applet_size_constrained (panel_widget, GTK_WIDGET (drawer->button), TRUE);

	panel_applet_add_callback (drawer->info,
				   "add",
				   GTK_STOCK_ADD,
				   _("_Add to Drawer..."),
				   drawer_changes_enabled);

	panel_applet_add_callback (drawer->info,
				   "properties",
				   GTK_STOCK_PROPERTIES,
				   _("_Properties"),
				   drawer_changes_enabled);

	panel_applet_add_callback (drawer->info,
				   "help",
				   GTK_STOCK_HELP,
				   _("_Help"),
				   NULL);

	panel_drawer_connect_to_gconf (drawer);
}

static void
panel_drawer_prepare (const char  *drawer_id,
		      const char  *custom_icon,
		      gboolean     use_custom_icon,
		      const char  *tooltip,
		      char       **attached_toplevel_id)
{
	GConfClient *client;
	const char  *key;

	client  = panel_gconf_get_client ();

	if (tooltip) {
		key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "tooltip");
		gconf_client_set_string (client, key, tooltip, NULL);
	}

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "use_custom_icon");
	gconf_client_set_bool (client, key, use_custom_icon, NULL);

	if (custom_icon) {
		key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "custom_icon");
		gconf_client_set_string (client, key, custom_icon, NULL);
	}

	if (attached_toplevel_id) {
		char *toplevel_id;
		char *toplevel_dir;

		toplevel_id = panel_profile_find_new_id (PANEL_GCONF_TOPLEVELS);

		toplevel_dir = g_strdup_printf (PANEL_CONFIG_DIR "/toplevels/%s",
						toplevel_id);
		panel_gconf_associate_schemas_in_dir (client, toplevel_dir, PANEL_SCHEMAS_DIR "/toplevels");
	
		key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, drawer_id, "attached_toplevel_id");
		gconf_client_set_string (client, key, toplevel_id, NULL);
		
		key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, toplevel_id, "enable_buttons");
		gconf_client_set_bool (client, key, TRUE, NULL);

		key = panel_gconf_full_key (PANEL_GCONF_TOPLEVELS, toplevel_id, "enable_arrows");
		gconf_client_set_bool (client, key, TRUE, NULL);

		*attached_toplevel_id = toplevel_id;
	}
}

void
panel_drawer_create (PanelToplevel *toplevel,
		     int            position,
		     const char    *custom_icon,
		     gboolean       use_custom_icon,
		     const char    *tooltip)
{
	char *id;

	id = panel_profile_prepare_object (PANEL_OBJECT_DRAWER, toplevel, position, FALSE);

	panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, NULL);

	panel_profile_add_to_list (PANEL_GCONF_OBJECTS, id);

	g_free (id);
}

char *
panel_drawer_create_with_id (const char    *toplevel_id,
			     int            position,
			     const char    *custom_icon,
			     gboolean       use_custom_icon,
			     const char    *tooltip)
{
	char *id;
	char *attached_toplevel_id = NULL;

	id = panel_profile_prepare_object_with_id (PANEL_OBJECT_DRAWER, toplevel_id, position, FALSE);

	panel_drawer_prepare (id, custom_icon, use_custom_icon, tooltip, &attached_toplevel_id);

	panel_profile_add_to_list (PANEL_GCONF_OBJECTS, id);

	g_free (id);

	return attached_toplevel_id;
}

void
drawer_load_from_gconf (PanelWidget *panel_widget,
			gboolean     locked,
			gint         position,
			const char  *id)
{
	GConfClient *client;
	const char  *key;
	gboolean     use_custom_icon;
	char        *toplevel_id;
	char        *custom_icon;
	char        *tooltip;

	g_return_if_fail (panel_widget != NULL);
	g_return_if_fail (id != NULL);

	client  = panel_gconf_get_client ();

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "attached_toplevel_id");
	toplevel_id = gconf_client_get_string (client, key, NULL);

	panel_profile_load_toplevel (client, PANEL_CONFIG_DIR, PANEL_GCONF_TOPLEVELS, toplevel_id);

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "use_custom_icon");
	use_custom_icon = gconf_client_get_bool (client, key, NULL);
	
	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "custom_icon");
	custom_icon = gconf_client_get_string (client, key, NULL);

	key = panel_gconf_full_key (PANEL_GCONF_OBJECTS, id, "tooltip");
	tooltip = gconf_client_get_string (client, key, NULL);

	load_drawer_applet (toplevel_id,
			    custom_icon,
			    use_custom_icon,
			    tooltip,
			    panel_widget->toplevel,
			    locked,
			    position,
			    TRUE,
			    id);

	g_free (toplevel_id);
	g_free (custom_icon);
	g_free (tooltip);
}

void
panel_drawer_set_dnd_enabled (Drawer   *drawer,
			      gboolean  dnd_enabled)
{
	if (dnd_enabled) {
		static GtkTargetEntry dnd_targets[] = {
			{ "application/x-panel-applet-internal", 0, 0 }
		};

		GTK_WIDGET_UNSET_FLAGS (drawer->button, GTK_NO_WINDOW);
		gtk_drag_source_set (drawer->button,
				     GDK_BUTTON1_MASK,
				     dnd_targets, 1,
				     GDK_ACTION_MOVE);
		//FIXME: we're forgetting the use_custom_icon case, here
		gtk_drag_source_set_icon_name (drawer->button,
					       button_widget_get_icon_name (BUTTON_WIDGET (drawer->button)));

		GTK_WIDGET_SET_FLAGS (drawer->button, GTK_NO_WINDOW);

	} else
		gtk_drag_source_unset (drawer->button);
}

static void
drawer_deletion_response (GtkWidget     *dialog,
                        int            response,
                        Drawer         *drawer)
{
        if (response == GTK_RESPONSE_OK)
		panel_profile_delete_object (drawer->info);

        gtk_widget_destroy (dialog);
}

void 
drawer_query_deletion (Drawer *drawer)
{
	GtkWidget *dialog;

	 if (drawer->toplevel) {
		PanelWidget *panel_widget;

		panel_widget = panel_toplevel_get_panel_widget (
							drawer->toplevel);

		if (!panel_global_config_get_confirm_panel_remove () ||
		    !g_list_length (panel_widget->applet_list)) {
			panel_profile_delete_object (drawer->info);
			return;
		}

		dialog = panel_deletion_dialog (drawer->toplevel);

		g_signal_connect (dialog, "response",
			  	  G_CALLBACK (drawer_deletion_response),
			  	  drawer);

		g_signal_connect_object (drawer->toplevel, "destroy",
					 G_CALLBACK (gtk_widget_destroy),
					 dialog,
					 G_CONNECT_SWAPPED);

        	gtk_widget_show_all (dialog);
	}
}
