/*
** 1998-07-30 -	Configuration of the shortcuts I implemented yesterday. I feel kind of guilty
**		here, because I know this GUI will look much like the one used for UserCommands,
**		but still there is no code reuse taking place. Sometimes I guess I should just
**		be taken out and shot. Or at least sued.
** 1998-09-12 -	Extended the separator modes.
** 1998-12-25 -	Major changes in order to accomodate the new shortcuts module.
*/

#include "gentoo.h"
#include "guiutil.h"
#include "xmlutil.h"
#include "shortcuts.h"

#include "cfg_gui.h"
#include "cfg_module.h"

#include "cfg_shortcuts.h"

#define	NODE	"ShortcutBanks"

/* ----------------------------------------------------------------------------------------- */

/* BUG:	This really should be in some dedicated module or some such. */
void	rebuild_bottom(MainInfo *min);

/* ----------------------------------------------------------------------------------------- */

typedef struct {
	GtkWidget	*vbox;

	GtkWidget	*tophbox;	/* Topmost hbox. Various frames. */

	GtkWidget	*dplframe;	/* Display frame. */
	GtkWidget	*dplhbox;	/* Hbox for the display options. */
	GtkWidget	*dplvis;	/* Visibility checkbox. */
	GSList		*dplpadgroup;	/* The list that holds the pad radios together. */
	GtkWidget	*dplpad[3];	/* Padding radio buttons (none, static, pane). */

	GtkWidget	*posframe;	/* Frame for shortcut position selection. */
	GtkWidget	*poshbox;	/* Shortcuts positions hbox. */
	GSList		*posgroup;	/* The group. */
	GtkWidget	*pos[2];	/* Left or right, dude? */

	GtkWidget	*scwin;		/* A scrolling window for the main clist. */
	GtkWidget	*clist;		/* Main clist, holds all defined shortcuts. */
	GtkWidget	*table;		/* Table containing the two entry widgets etc. */
	GtkWidget	*label;		/* A place to enter a shortcut's label in. */
	GtkWidget	*path;		/* Entry widget for path ... entry. */
	GtkWidget	*hbox;		/* This holds two frames; pane and flag controls. */
	GtkWidget	*pframe;	/* Frame for pane selection. */
	GtkWidget	*pane[4];	/* One radio button for each pane mode. */
	GtkWidget	*ptable;	/* Table that holds the pane radio buttons. */
	GSList		*pgroup;	/* The grouping list for the pane radio buttons. */
	GtkWidget	*fframe;	/* Frame for various flags. */
	GtkWidget	*ftooltip;	/* "Show tooltip" flag. */

	GtkWidget	*bhbox;		/* This one holds the "Add" & "Delete" buttons. */
	GtkWidget	*badd, *bdel;	/* Button widgets for add and delete. */
	GtkWidget	*bup, *bdown;	/* Up and down buttons. */

	ShortcutBank	*bank;		/* The bank we're editing. A copy, of course. */
	Shortcut	*shc;		/* Currently selected shortcut. */
	gint		row;		/* Index in clist for currently selected row. */
} P_Shortcuts;

static P_Shortcuts	the_page;

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Reset the widgets to their most idle-looking state. */
static void reset_widgets(P_Shortcuts *page)
{
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->dplvis), page->bank->visible);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->dplpad[page->bank->sep_mode]), TRUE);
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->pos[1]), page->bank->right);

	gtk_entry_set_text(GTK_ENTRY(page->label), "");
	gtk_entry_set_text(GTK_ENTRY(page->path), "");

	gtk_widget_set_sensitive(page->table, FALSE);

	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->ftooltip), FALSE);
	gtk_widget_set_sensitive(page->fframe, FALSE);

	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->pane[0]), TRUE);
	gtk_widget_set_sensitive(page->hbox, FALSE);
	gtk_widget_set_sensitive(page->bdel, FALSE);
}

static void insert_shortcut(gpointer data, gpointer user)
{
	char		*line[] = {NULL, NULL};
	Shortcut	*shc = (Shortcut *) data;
	gint		row;

	if(shc != NULL)
	{
		line[0] = shc->label;
		line[1] = shc->path;
		row = gtk_clist_append(GTK_CLIST(((P_Shortcuts *) user)->clist), line);
		gtk_clist_set_row_data(GTK_CLIST(((P_Shortcuts *) user)->clist), row, shc);
	}
}

/* 1998-07-30 -	Populate the column list with the current (copied) shortcuts. */
static void populate_clist(P_Shortcuts *page)
{
	gtk_clist_clear(GTK_CLIST(page->clist));
	g_list_foreach(page->bank->shortcut, insert_shortcut, (gpointer) page);
	page->shc = NULL;
	page->row = -1;
}

/* ----------------------------------------------------------------------------------------- */

static gint evt_visible_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	page->bank->visible = GTK_TOGGLE_BUTTON(wid)->active;

	return TRUE;
}

/* 1998-09-12 -	Rewritten since there are now three separator modes rather than just two. */
static gint evt_sep_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(!GTK_TOGGLE_BUTTON(wid)->active)
		return TRUE;
	page->bank->sep_mode = (int) gtk_object_get_user_data(GTK_OBJECT(wid));

	return TRUE;
}

static gint evt_position_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	page->bank->right = (wid == page->pos[1]);

	return TRUE;
}

/* 1998-07-30 -	Someone just clicked on something in the clist. React! */
static gint evt_clist_select(GtkWidget *wid, gint row, gint column, GdkEventButton *evt)
{
	P_Shortcuts	*page = (P_Shortcuts *) gtk_object_get_user_data(GTK_OBJECT(wid));

	if((page->shc = gtk_clist_get_row_data(GTK_CLIST(page->clist), row)) != NULL)
	{
		page->row = row;
		gtk_entry_set_text(GTK_ENTRY(page->label), page->shc->label);
		gtk_entry_set_text(GTK_ENTRY(page->path),  page->shc->path);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->pane[page->shc->pane]), TRUE);
		gtk_widget_set_sensitive(page->table, TRUE);
		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(page->ftooltip), page->shc->show_tooltip);
		gtk_widget_set_sensitive(page->fframe, TRUE);
		gtk_widget_set_sensitive(page->hbox, TRUE);
		gtk_widget_set_sensitive(page->bdel, TRUE);
	}
	return TRUE;
}

/* 1998-07-30 -	Row in clist got unselected; react to that, too. */
static gint evt_clist_unselect(GtkWidget *wid, gint row, gint column, GdkEventButton *evt)
{
	P_Shortcuts	*page = (P_Shortcuts *) gtk_object_get_user_data(GTK_OBJECT(wid));

	page->shc = NULL;
	page->row = -1;
	reset_widgets(page);	

	return TRUE;
}

/* 1998-07-30 -	Text in label entry changed, so copy it into the shortcut being edited. */
static gint evt_label_changed(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
	{
		strcpy(page->shc->label, gtk_entry_get_text(GTK_ENTRY(wid)));
		gtk_clist_set_text(GTK_CLIST(page->clist), page->row, 0, page->shc->label);
	}

	return TRUE;
}

/* 1998-07-30 -	Text in path entry changed. We'd better grab that. */
static gint evt_path_changed(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
	{
		strcpy(page->shc->path, gtk_entry_get_text(GTK_ENTRY(wid)));
		gtk_clist_set_text(GTK_CLIST(page->clist), page->row, 1, page->shc->path);
	}

	return TRUE;
}

/* 1998-07-30 -	User clicked on one of the four "Pane" radio buttons. Copy that. */
static gint evt_pane_changed(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
		page->shc->pane = (ShcPane) gtk_object_get_user_data(GTK_OBJECT(wid));

	return TRUE;
}

static gint evt_tooltip_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
		page->shc->show_tooltip = GTK_TOGGLE_BUTTON(page->ftooltip)->active;
	return TRUE;
}

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Add a new shortcut to the list. */
static gint evt_add_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;
	Shortcut	*shc;
	char		*line[] = { "(Name)", "(Path" };
	gint		row;

	if((shc = shc_shortcut_new()) != NULL)
	{
		shc_shortcutbank_add_shortcut(page->bank, shc);
		gtk_widget_grab_focus(page->label);
		gtk_clist_freeze(GTK_CLIST(page->clist));
		row = gtk_clist_append(GTK_CLIST(page->clist), line);
		gtk_clist_set_row_data(GTK_CLIST(page->clist), row, (gpointer) shc);
		gtk_clist_select_row(GTK_CLIST(page->clist), row, 0);
		gtk_clist_thaw(GTK_CLIST(page->clist));
	}
	return TRUE;
}

/* 1998-07-30 -	User clicked on the "Delete" button; better smack something. */
static gint evt_del_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
	{
		shc_shortcutbank_kill_shortcut(page->bank, page->shc);
		gtk_clist_remove(GTK_CLIST(page->clist), page->row);
	}

	return TRUE;
}

/* ----------------------------------------------------------------------------------------- */

static void move_shortcut(P_Shortcuts *page, int delta)
{
	char		*line[2] = { NULL, NULL };
	gint		row = page->row, nrow;
	Shortcut	*shc;

	if((shc = page->shc) != NULL)
	{
		if((nrow = shc_shortcutbank_move_shortcut(page->bank, shc, delta)) >= 0)
		{
			gtk_clist_remove(GTK_CLIST(page->clist), row);
			line[0] = shc->label;
			line[1] = shc->path;
			gtk_clist_insert(GTK_CLIST(page->clist), nrow, line);
			gtk_clist_set_row_data(GTK_CLIST(page->clist), nrow, shc);
			gtk_clist_select_row(GTK_CLIST(page->clist), nrow, 0);
		}
	}
}

/* 1998-09-20 -	User clicked the up button (between Add and Delete). Move current shortcut upwards. */
static gint evt_up_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
		move_shortcut(page, -1);
	return TRUE;
}

/* 1998-09-20 -	User clicked the down button (between Add and Delete). Move current shortcut downwards. */
static gint evt_down_clicked(GtkWidget *wid, gpointer data)
{
	P_Shortcuts	*page = (P_Shortcuts *) data;

	if(page->shc != NULL)
		move_shortcut(page, 1);
	return TRUE;
}

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Build the GUI for configuring shortcuts. As stated above, this will look a
**		lot like the UserCommands page. Surely, that's good? Zero code reuse, though. :(
*/
static GtkWidget * csc_init(MainInfo *min, char **name)
{
	P_Shortcuts	*page = &the_page;
	GtkWidget	*label;
	const gchar	*title[] = { "Label", "Path" }, *plabel[] = {"Current", "Other", "Left", "Right"},
			*padlabel[] = { "No Padding", "Static", "Paned" },
			*poslabel[] = {"Left of Buttons", "Right of Buttons"};
	gint		sepmode[] = { SSM_NONE, SSM_SIMPLE, SSM_PANED };
	gint		i;

	if(name == NULL)
		return NULL;

	*name = "Shortcuts";

	page->vbox = gtk_vbox_new(FALSE, 0);

	page->tophbox = gtk_hbox_new(FALSE, 0);
	page->dplframe = gtk_frame_new("Display Options");
	page->dplhbox = gtk_hbox_new(FALSE, 0);
	page->dplvis = gtk_check_button_new_with_label("Visible?");
	gtk_signal_connect(GTK_OBJECT(page->dplvis), "clicked", GTK_SIGNAL_FUNC(evt_visible_clicked), (gpointer) page);
	gtk_box_pack_start(GTK_BOX(page->dplhbox), page->dplvis, FALSE, FALSE, 0);
	gtk_widget_show(page->dplvis);
	page->dplpadgroup = gui_radio_group_new(3, padlabel, page->dplpad);
	for(i = 0; i < 3; i++)
	{
		gtk_object_set_user_data(GTK_OBJECT(page->dplpad[i]), (gpointer) sepmode[i]);
		gtk_signal_connect(GTK_OBJECT(page->dplpad[i]), "clicked", GTK_SIGNAL_FUNC(evt_sep_clicked), (gpointer) page);
		gtk_box_pack_start(GTK_BOX(page->dplhbox), page->dplpad[i], FALSE, FALSE, 0);
		gtk_widget_show(page->dplpad[i]);
	}
	gtk_container_add(GTK_CONTAINER(page->dplframe), page->dplhbox);
	gtk_widget_show(page->dplhbox);
	gtk_box_pack_start(GTK_BOX(page->tophbox), page->dplframe, FALSE, FALSE, 0);
	gtk_widget_show(page->dplframe);

	page->posframe = gtk_frame_new("Position");
	page->poshbox = gtk_hbox_new(FALSE, 0);
	page->posgroup = gui_radio_group_new(2, poslabel, page->pos);
	for(i = 0; i < 2; i++)
	{
		gtk_signal_connect(GTK_OBJECT(page->pos[i]), "clicked", GTK_SIGNAL_FUNC(evt_position_clicked), (gpointer) page);
		gtk_box_pack_start(GTK_BOX(page->poshbox), page->pos[i], FALSE, FALSE, 0);
		gtk_widget_show(page->pos[i]);
	}

	gtk_container_add(GTK_CONTAINER(page->posframe), page->poshbox);
	gtk_widget_show(page->poshbox);

	gtk_box_pack_start(GTK_BOX(page->tophbox), page->posframe, TRUE, TRUE, 5);
	gtk_widget_show(page->posframe);
	gtk_box_pack_start(GTK_BOX(page->vbox), page->tophbox, FALSE, FALSE, 5);
	gtk_widget_show(page->tophbox);

	page->scwin = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(page->scwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	page->clist = gtk_clist_new_with_titles(2, (gchar **) title);
	gtk_object_set_user_data(GTK_OBJECT(page->clist), (gpointer) page);
	gtk_signal_connect(GTK_OBJECT(page->clist), "select_row", GTK_SIGNAL_FUNC(evt_clist_select), NULL);
	gtk_signal_connect(GTK_OBJECT(page->clist), "unselect_row", GTK_SIGNAL_FUNC(evt_clist_unselect), NULL);
	gtk_clist_set_column_width(GTK_CLIST(page->clist), 0, 80);
	gtk_clist_column_titles_passive(GTK_CLIST(page->clist));

	gtk_container_add(GTK_CONTAINER(page->scwin), page->clist);
	gtk_widget_show(page->clist);
	gtk_box_pack_start(GTK_BOX(page->vbox), page->scwin, TRUE, TRUE, 0);
	gtk_widget_show(page->scwin);

	page->table = gtk_table_new(2, 3, FALSE);
	label = gtk_label_new("Label");
	gtk_table_attach(GTK_TABLE(page->table), label, 0, 1, 0, 1,  0,0,0,0);
	gtk_widget_show(label);
	page->label = gtk_entry_new_with_max_length(BTN_LABEL_MAX - 1);
	gtk_signal_connect(GTK_OBJECT(page->label), "changed", GTK_SIGNAL_FUNC(evt_label_changed), (gpointer) page);
	gtk_table_attach_defaults(GTK_TABLE(page->table), page->label, 1, 3, 0, 1);
	gtk_widget_show(page->label);

	label = gtk_label_new("Path");
	gtk_table_attach(GTK_TABLE(page->table), label, 0, 1, 1, 2,  0,0,0,0);
	gtk_widget_show(label);
	page->path = gtk_entry_new_with_max_length(PATH_MAX - 1);
	gtk_signal_connect(GTK_OBJECT(page->path), "changed", GTK_SIGNAL_FUNC(evt_path_changed), (gpointer) page);
	gtk_table_attach_defaults(GTK_TABLE(page->table), page->path, 1, 2, 1, 2);
	gtk_widget_show(page->path);

	gtk_widget_set_sensitive(page->table, FALSE);
	gtk_box_pack_start(GTK_BOX(page->vbox), page->table, FALSE, FALSE, 0);
	gtk_widget_show(page->table);

	page->hbox = gtk_hbox_new(FALSE, 0);
	page->pframe = gtk_frame_new("Pane");

	page->ptable = gtk_table_new(2, 2, FALSE);
	if((page->pgroup = gui_radio_group_new(4, plabel, page->pane)) != NULL)
	{
		for(i = 0; i < 4; i++)
		{
			gtk_object_set_user_data(GTK_OBJECT(page->pane[i]), (gpointer) i);
			gtk_signal_connect(GTK_OBJECT(page->pane[i]), "clicked", GTK_SIGNAL_FUNC(evt_pane_changed), (gpointer) page);
			gtk_table_attach(GTK_TABLE(page->ptable), page->pane[i], i / 2, i / 2 + 1, i % 2, i % 2 + 1, GTK_EXPAND|GTK_FILL,0,0,0);
			gtk_widget_show(page->pane[i]);
		}
	}
	gtk_container_add(GTK_CONTAINER(page->pframe), page->ptable);
	gtk_widget_show(page->ptable);
	gtk_box_pack_start(GTK_BOX(page->hbox), page->pframe, FALSE, FALSE, 0);
	gtk_widget_show(page->pframe);

	page->fframe = gtk_frame_new("Flags");
	page->ftooltip = gtk_check_button_new_with_label("Show Path as Tooltip?");
	gtk_signal_connect(GTK_OBJECT(page->ftooltip), "clicked", GTK_SIGNAL_FUNC(evt_tooltip_clicked), (gpointer) page);
	gtk_container_add(GTK_CONTAINER(page->fframe), page->ftooltip);
	gtk_widget_show(page->ftooltip);
	gtk_box_pack_start(GTK_BOX(page->hbox), page->fframe, TRUE, TRUE, 0);
	gtk_widget_show(page->fframe);

	gtk_widget_set_sensitive(page->hbox, FALSE);
	gtk_box_pack_start(GTK_BOX(page->vbox), page->hbox, FALSE, FALSE, 0);
	gtk_widget_show(page->hbox);

	page->bhbox = gtk_hbox_new(FALSE, 0);
	page->badd = gtk_button_new_with_label("Add");
	gtk_signal_connect(GTK_OBJECT(page->badd), "clicked", GTK_SIGNAL_FUNC(evt_add_clicked), (gpointer) page);
	gtk_box_pack_start(GTK_BOX(page->bhbox), page->badd, TRUE, TRUE, 5);
	gtk_widget_show(page->badd);

	page->bup = gui_arrow_button_new(GTK_ARROW_UP);
	gtk_signal_connect(GTK_OBJECT(page->bup), "clicked", GTK_SIGNAL_FUNC(evt_up_clicked), (gpointer) page);
	gtk_box_pack_start(GTK_BOX(page->bhbox), page->bup, FALSE, FALSE, 0);
	gtk_widget_show(page->bup);

	page->bdown = gui_arrow_button_new(GTK_ARROW_DOWN);
	gtk_signal_connect(GTK_OBJECT(page->bdown), "clicked", GTK_SIGNAL_FUNC(evt_down_clicked), (gpointer) page);
	gtk_box_pack_start(GTK_BOX(page->bhbox), page->bdown, FALSE, FALSE, 0);
	gtk_widget_show(page->bdown);

	page->bdel = gtk_button_new_with_label("Delete");
	gtk_widget_set_sensitive(page->bdel, FALSE);
	gtk_signal_connect(GTK_OBJECT(page->bdel), "clicked", GTK_SIGNAL_FUNC(evt_del_clicked), (gpointer) page);
	gtk_box_pack_start(GTK_BOX(page->bhbox), page->bdel, TRUE, TRUE, 5);
	gtk_widget_show(page->bdel);

	gtk_box_pack_start(GTK_BOX(page->vbox), page->bhbox, FALSE, FALSE, 5);
	gtk_widget_show(page->bhbox);

	gtk_widget_show(page->vbox);
	return page->vbox;
}

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Update entire GUI since display is pending. */
static void csc_update(MainInfo *min)
{
	the_page.bank = shc_shortcutbank_copy(min->cfg.shortcutbank);
	populate_clist(&the_page);
	reset_widgets(&the_page);
}

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Accept the current shortcut config, and store it. */
static void csc_accept(MainInfo *min)
{
	shc_shortcutbank_destroy(min->cfg.shortcutbank);
	min->cfg.shortcutbank = the_page.bank;
	the_page.bank = NULL;
	cfg_set_flags(CFLG_REBUILD_BOTTOM);
}

/* ----------------------------------------------------------------------------------------- */

/* 1998-07-30 -	Write out a shortcut definition to the config file.
** BUG BUG BUG	Doesn't bother to encode the pane textually.
*/
static void save_shortcut(gpointer data, gpointer user)
{
	Shortcut	*shc = (Shortcut *) data;
	FILE		*out = (FILE *) user;

	if(shc != NULL)
	{
		xml_put_node_open(out, "Shortcut");
		xml_put_text(out, "label", shc->label);
		xml_put_text(out, "path", shc->path);
		xml_put_integer(out, "pane", shc->pane);
		xml_put_boolean(out, "show_tooltip", shc->show_tooltip);
		xml_put_node_close(out, "Shortcut");
	}
}

/* 1998-07-30 -	Save out a bank of shortcuts. Very serious. */
static void save_shortcutbank(FILE *out, ShortcutBank *bank)
{
	xml_put_node_open(out, "ShortcutBank");
	xml_put_boolean(out, "visible", bank->visible);
	xml_put_integer(out, "sep_mode", bank->sep_mode);
	xml_put_boolean(out, "right", bank->right);
	xml_put_node_open(out, "Shortcuts");
	g_list_foreach(bank->shortcut, save_shortcut, (gpointer) out);
	xml_put_node_close(out, "Shortcuts");
	xml_put_node_close(out, "ShortcutBank");
}

/* 1998-07-30 -	Save out the current shortcut settings. Nice and simple. */
static gint csc_save(MainInfo *min, FILE *out)
{
	xml_put_node_open(out, NODE);
	save_shortcutbank(out, min->cfg.shortcutbank);
	xml_put_node_close(out, NODE);

	return 1;
}

/* ----------------------------------------------------------------------------------------- */

static void load_shortcut(XmlNode *node, gpointer user)
{
	ShortcutBank	*bank = (ShortcutBank *) user;
	Shortcut	*shc;
	gint		tmp = FALSE;

	if((shc = shc_shortcut_new()) != NULL)
	{
		xml_get_text_copy(node, "label", shc->label, sizeof shc->label);
		xml_get_text_copy(node, "path",  shc->path,  sizeof shc->path);
		xml_get_integer(node, "pane", (gint *) &shc->pane);
		xml_get_boolean(node, "show_tooltip", &tmp);
		shc->show_tooltip = tmp;
		shc_shortcutbank_add_shortcut(bank, shc);
	}
}

static void load_shortcutbank(XmlNode *node, gpointer user)
{
	MainInfo	*min = (MainInfo *) user;
	XmlNode		*data;
	gint		tmp;

	if(xml_get_boolean(node, "visible", &tmp))
		min->cfg.shortcutbank->visible = tmp;
	xml_get_integer(node, "sep_mode", (gint *) &min->cfg.shortcutbank->sep_mode);
	if(xml_get_boolean(node, "right", &tmp))
		min->cfg.shortcutbank->right = tmp;
	if((data = xml_tree_search(node, "Shortcuts")) != NULL)
	{
		shc_shortcutbank_clear(min->cfg.shortcutbank);
		xml_node_visit_children(data, load_shortcut, min->cfg.shortcutbank);
	}
}

/* 1998-07-30 -	Load in the shortcut data from given tree. */
static void csc_load(MainInfo *min, XmlNode *node)
{
	xml_node_visit_children(node, load_shortcutbank, (gpointer) min);
}

/* ----------------------------------------------------------------------------------------- */

CfgPage * csc_describe(MainInfo *min)
{
	static CfgPage	desc = { NODE, csc_init, csc_update, csc_accept, csc_save, csc_load, NULL };

	return &desc;
}
