#include <stdlib.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>

#include "../include/disk.h"
#include "../include/string.h"

#include "guiutils.h"
#include "csd.h"

#include "pref.h"
#include "prefcb.h"
#include "manedit.h"
#include "maneditcb.h"
#include "messages.h"
#include "config.h"

#include "images/manedit_48x48.xpm"
#include "images/icon_ok_20x20.xpm"
#include "images/icon_select_20x20.xpm"
#include "images/icon_close_20x20.xpm"
#include "images/icon_add_20x20.xpm"
#include "images/icon_properties2_20x20.xpm"
#include "images/icon_remove_20x20.xpm"


GtkWidget *PrefParmGetWidget(pref_struct *pref, gint parameter);
GtkWidget *PrefPanelGetWidget(pref_struct *pref, gint catagory);
gchar *PrefPanelGetBranchText(pref_struct *pref, GtkCTreeNode *branch);

gint PrefParmRecord(
	pref_struct *pref,
	gint parameter,		/* One of MEDIT_PREF_PARM_* */
	GtkWidget *w
);
gint PrefPanelRecord(
	pref_struct *pref,
	gint catagory,		/* One of MEDIT_PREF_CAT_ */
	GtkWidget *w            /* A vbox */
);

gpointer PrefParmGetValueP(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
);
gint PrefParmGetValueI(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
);
float PrefParmGetValueF(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
);
gboolean PrefParmGetValueB(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
);

void PrefBranchSetData(
	GtkCTree *ctree, GtkCTreeNode *branch,
	pref_item_struct *item, GtkDestroyNotify destroy
);
pref_item_struct *PrefBranchGetData(
	GtkCTree *ctree, GtkCTreeNode *branch
);
void PrefSetBusy(pref_struct *pref);
void PrefSetReady(pref_struct *pref);

GtkCTreeNode *PrefAddCatagoryBranch(
	pref_struct *pref,
	const gchar *catagory_name,
	GtkCTreeNode *parent,
	GtkCTreeNode *sibling,
	gboolean is_leaf,
	GtkWidget *panel_vbox,
	gint catagory
);

static void PrefCreateHeading(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label
);
static void PrefCreateColorButton(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label,
	gint label_width,
	gint parameter,
	GdkColor gdk_color
);
static void PrefCreateFontButton(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label,
	const gchar *font_name,
	gint label_width,
	gint entry_width,
	gint parameter
);

static void PrefCreatePanelApperance(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelFonts(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelColors(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelEditor(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelViewer(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelLocations(pref_struct *pref, GtkWidget *parent);
static void PrefCreatePanelConverters(pref_struct *pref, GtkWidget *parent);

static void PrefCreateCatagories(pref_struct *pref);

pref_struct *PrefNew(gpointer core_ptr);
void PrefUpdateMenus(pref_struct *pref);
void PrefReset(pref_struct *pref, gboolean need_unmap);
void PrefMap(pref_struct *pref);
void PrefUnmap(pref_struct *pref);
void PrefDelete(pref_struct *pref);


#define ATOI(s)		(((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)		(((s) != NULL) ? atol(s) : 0)
#define ATOF(s)		(((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)	(((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)	(((a) > (b)) ? (a) : (b))
#define MIN(a,b)	(((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)	(MIN(MAX((a),(l)),(h)))
#define STRLEN(s)	(((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)	(((s) != NULL) ? (*(s) == '\0') : TRUE)

#define PREF_BTN_WIDTH	(100 + (2 * 3))
#define PREF_BTN_HEIGHT	(30 + (2 * 3))


/*
 *	Returns the widget for the given parameter which matches
 *	the index of widgets holding parameter values on the preferences
 *	strcture.
 *
 *	Can return NULL on error.
 */
GtkWidget *PrefParmGetWidget(pref_struct *pref, gint parameter)
{
	if(pref == NULL)
	    return(NULL);
	else if(pref->parm_widget == NULL)
	    return(NULL);
	else if((parameter < 0) || (parameter >= pref->total_parm_widgets))
	    return(NULL);

	return(pref->parm_widget[parameter]);
}

/*
 *      Returns the widget for the given category which matches
 *      the index of panel parent widgets on the preferences structure.
 *
 *      Can return NULL on error.
 */
GtkWidget *PrefPanelGetWidget(pref_struct *pref, gint catagory)
{
	if(pref == NULL)
	    return(NULL);
	else if(pref->panel_parent == NULL)
	    return(NULL);
	else if((catagory < 0) || (catagory >= pref->total_panel_parents))
	    return(NULL);

	return(pref->panel_parent[catagory]);
}


/*
 *	Convience function to return the text of the given branch.
 *
 *	Return is statically allocated, do not delete.
 */
gchar *PrefPanelGetBranchText(pref_struct *pref, GtkCTreeNode *branch)
{
	gchar *text;
	guint8 spacing;
	GdkPixmap *pixmap;
	GdkBitmap *mask;


	if((pref == NULL) || (branch == NULL))
	    return(NULL);

	if(pref->catagory_ctree == NULL)
	    return(NULL);

	if(!gtk_ctree_node_get_pixtext(
	    (GtkCTree *)pref->catagory_ctree,
	    branch, 0,
	    &text, &spacing, &pixmap, &mask
	))
	    text = NULL;

	return((gchar *)text);
}

/*
 *	Records the widget on the preferences structure.
 *
 *	Returns parameter on success or -1 on error.
 */
gint PrefParmRecord(
	pref_struct *pref,
	gint parameter,		/* One of MEDIT_PREF_PARM_* */
	GtkWidget *w
)
{
	if(pref == NULL)
	    return(-1);

	if(pref->total_parm_widgets < 0)
	    pref->total_parm_widgets = 0;

	if(parameter >= pref->total_parm_widgets)
	{
	    /* Need to allocate more pointers */
	    gint i, prev_total = pref->total_parm_widgets;

	    /* Increase total */
	    pref->total_parm_widgets = parameter + 1;

	    /* Reallocate pointer array */
	    pref->parm_widget = (GtkWidget **)g_realloc(
		pref->parm_widget,
		pref->total_parm_widgets * sizeof(GtkWidget *)
	    );
	    if(pref->parm_widget == NULL)
	    {
		pref->total_parm_widgets = 0;
		return(-1);
	    }

	    /* Reset new pointers */
	    for(i = prev_total; i < pref->total_parm_widgets; i++)
		pref->parm_widget[i] = NULL;
	}

	/* Set new pointer */
	if((parameter >= 0) && (parameter < pref->total_parm_widgets))
	{
	    pref->parm_widget[parameter] = w;
	}

	return(parameter);
}

/*
 *      Records the panel parent vbox widget for the given catagory
 *	on the preferences structure.
 *
 *      Returns catagory on success or -1 on error.
 */
gint PrefPanelRecord(
	pref_struct *pref,
	gint catagory,		/* One of MEDIT_PREF_CAT_ */
	GtkWidget *w		/* A vbox */
)
{
	if(pref == NULL)
	    return(-1);

	if(pref->total_panel_parents < 0)
	    pref->total_panel_parents = 0;

	if(catagory >= pref->total_panel_parents)
	{
	    /* Need to allocate more pointers */
	    gint i, prev_total = pref->total_panel_parents;

	    /* Increase total */
	    pref->total_panel_parents = catagory + 1;

	    /* Reallocate pointer array */
	    pref->panel_parent = (GtkWidget **)g_realloc(
		pref->panel_parent,
		pref->total_panel_parents * sizeof(GtkWidget *)
	    );
	    if(pref->panel_parent == NULL)
	    {
		pref->total_panel_parents = 0;
		return(-1);
	    }

	    /* Reset new pointers */
	    for(i = prev_total; i < pref->total_panel_parents; i++)
		pref->panel_parent[i] = NULL;
	}

	/* Set new pointer */
	if((catagory >= 0) && (catagory < pref->total_panel_parents))
	{
	    pref->panel_parent[catagory] = w;
	}

	return(catagory);
}


/*
 *	Returns the buffer pointer of the widget for the parameter
 *	on the preferences widget. Can return NULL on error.
 */
gpointer PrefParmGetValueP(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
)
{
	GtkWidget *w = PrefParmGetWidget(pref, parameter);
	if(w == NULL)
	    return(NULL);

	if(GTK_IS_TOGGLE_BUTTON((GtkObject *)w))
	{
	    return(NULL);
	}
	else if(GTK_IS_ENTRY((GtkObject *)w))
	{
	    gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
	    return((gpointer)s);
	}
	else if(GTK_IS_COMBO((GtkObject *)w))
	{
	    gchar *s;
	    GtkCombo *combo = GTK_COMBO(w);
	    s = gtk_entry_get_text(GTK_ENTRY(combo->entry));
	    return((gpointer)s);
	}

	return(NULL);
}

/*
 *	Gets the value from the widget matching the parameter as an int.
 */
gint PrefParmGetValueI(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
)
{
	GtkWidget *w = PrefParmGetWidget(pref, parameter);
	if(w == NULL)
	    return(0);

	if(GTK_IS_TOGGLE_BUTTON((GtkObject *)w))
	{
	    return((GTK_TOGGLE_BUTTON(w)->active) ? 1 : 0); 
	}
	else if(GTK_IS_ENTRY((GtkObject *)w))
	{
	    gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
	    return((s == NULL) ? 0 : atoi(s));
	}
	else if(GTK_IS_COMBO((GtkObject *)w))
	{
	    gchar *s;
	    GtkCombo *combo = GTK_COMBO(w);
	    s = gtk_entry_get_text(GTK_ENTRY(combo->entry));
	    return((s == NULL) ? 0 : atoi(s));
	}

	return(0);
}

/*
 *      Gets the value from the widget matching the parameter as a float.
 */
float PrefParmGetValueF(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
)
{
	GtkWidget *w = PrefParmGetWidget(pref, parameter);
	if(w == NULL)
	    return(0.0);

	if(GTK_IS_TOGGLE_BUTTON((GtkObject *)w))
	{
	    return((GTK_TOGGLE_BUTTON(w)->active) ? 1.0 : 0.0);
	}
	else if(GTK_IS_ENTRY((GtkObject *)w))
	{
	    gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
	    return((s == NULL) ? 0.0 : atof(s));
	}
	else if(GTK_IS_COMBO((GtkObject *)w))
	{
	    gchar *s;
	    GtkCombo *combo = GTK_COMBO(w);
	    s = gtk_entry_get_text(GTK_ENTRY(combo->entry));
	    return((s == NULL) ? 0.0 : atof(s));
	}

	return(0.0);
}

/*
 *      Gets the value from the widget matching the parameter as a boolean.
 */
gboolean PrefParmGetValueB(
	pref_struct *pref,
	gint parameter		/* One of MEDIT_PREF_PARM_* */
)
{
	GtkWidget *w = PrefParmGetWidget(pref, parameter);
	if(w == NULL)
	    return(FALSE);

	if(GTK_IS_RADIO_BUTTON((GtkObject *)w))
	{
	    return((GTK_TOGGLE_BUTTON(w)->active) ? TRUE : FALSE);
	}
	else if(GTK_IS_CHECK_BUTTON((GtkObject *)w))
	{
	    return((GTK_TOGGLE_BUTTON(w)->active) ? TRUE : FALSE);
	}
	else if(GTK_IS_TOGGLE_BUTTON((GtkObject *)w))
	{
	    return((GTK_TOGGLE_BUTTON(w)->active) ? TRUE : FALSE);
	}
	else if(GTK_IS_ENTRY((GtkObject *)w))
	{
	    gchar *s = gtk_entry_get_text(GTK_ENTRY(w));
	    if(s == NULL)
	    {
		return(FALSE);
	    }
	    else
	    {
		while(ISBLANK(*s))
		    s++;
		return(toupper(*s) == 'Y');
	    }
	}
	else if(GTK_IS_COMBO((GtkObject *)w))
	{
	    gchar *s;
	    GtkCombo *combo = GTK_COMBO(w);
	    s = gtk_entry_get_text(GTK_ENTRY(combo->entry));
	    if(s == NULL)
	    {
		return(FALSE);
	    }
	    else
	    {
		while(ISBLANK(*s))
		    s++;
		return(toupper(*s) == 'Y');
	    }
	}

	return(FALSE);
}


/*
 *      Sets the data and destroy function for the given GtkCTreeNode
 *      branch.
 */
void PrefBranchSetData(
	GtkCTree *ctree, GtkCTreeNode *branch,
	pref_item_struct *item, GtkDestroyNotify destroy
)
{
	if((ctree == NULL) || (branch == NULL))
	    return;

	gtk_ctree_node_set_row_data_full(
	    ctree, branch,
	    item, destroy
	);
}

/*
 *      Returns the user set data for the given GtkCTreeNode branch.
 */
pref_item_struct *PrefBranchGetData(
	GtkCTree *ctree, GtkCTreeNode *branch
)
{
	if((ctree == NULL) || (branch == NULL))
	    return(NULL);

	return(
	    (pref_item_struct *)gtk_ctree_node_get_row_data(
		ctree, branch
	    )
	);
}

/*
 *      Marks preferences window as busy.
 */
void PrefSetBusy(pref_struct *pref)
{
	GtkWidget *w;
	GdkCursor *cur;
	medit_core_struct *core_ptr;

	if(pref == NULL)
	    return;

	core_ptr = MEDIT_CORE(pref->core_ptr);
	if(core_ptr == NULL)
	    return;
   
	w = pref->toplevel;
	if(w == NULL)
	    return;

	cur = core_ptr->cursors_list.busy;
	if(cur == NULL)
	    return;

	if(GTK_WIDGET_NO_WINDOW(w))
	    return;

	gdk_window_set_cursor(w->window, cur);
	gdk_flush(); 
}

/*
 *      Marks preferences window as ready (opposite affect of
 *	PrefSetBusy()).
 */
void PrefSetReady(pref_struct *pref)
{
	GtkWidget *w;

	if(pref == NULL)
	    return;
  
	w = pref->toplevel;
	if(w == NULL)
	    return;

	if(GTK_WIDGET_NO_WINDOW(w))
	    return;
	
	gdk_window_set_cursor(w->window, NULL);
	gdk_flush();
}


/*
 *	Adds a new branch and creates and sets a new item data.
 *
 *	The given vbox will be parented to the preference window's
 *	panel_toplevel.
 *
 *	Returns the pointer to the newly created branch.
 */
GtkCTreeNode *PrefAddCatagoryBranch(
	pref_struct *pref,
	const gchar *catagory_name,
	GtkCTreeNode *parent,
	GtkCTreeNode *sibling,
	gboolean is_leaf,
	GtkWidget *panel_vbox,
	gint catagory
)
{
	gchar *text[1];
	GtkWidget *panel_toplevel;
	GtkCTreeNode *new_branch;
	GtkCTree *ctree;
	pref_item_struct *item;

	if(pref == NULL)
	    return(NULL);

	if(catagory < 0)
	    return(NULL);

	ctree = (GtkCTree *)pref->catagory_ctree;
	if(ctree == NULL)
	    return(NULL);

	/* Add panel_vbox to the preference window's panel_toplevel */
	panel_toplevel = pref->panel_toplevel;
	if((panel_toplevel != NULL) && (panel_vbox != NULL))
	{
	    gtk_box_pack_start(
		GTK_BOX(panel_toplevel), panel_vbox, TRUE, TRUE, 0
	    );

	    /* Add this panel vbox to the panel_parent list on pref */
	    PrefPanelRecord(
		pref, catagory, panel_vbox
	    );
	}

	/* Copy catagory name */
	text[0] = STRDUP((catagory_name != NULL) ?
	    catagory_name : "Untitled"
	);
	/* Create new branch */
	new_branch = gtk_ctree_insert_node(
	    ctree, parent, sibling,
	    text,
	    MEDIT_LIST_ICON_TEXT_SPACING,
	    NULL, NULL, NULL, NULL,
	    is_leaf,			/* Is leaf */
	    FALSE			/* Expanded */
	);
	/* Free coppied catagory name */
	g_free(text[0]);

	/* Allocate item data for branch */
	item = (pref_item_struct *)g_malloc0(
	    sizeof(pref_item_struct)
	);
	if(item != NULL)
	{
	    item->catagory = catagory;
	    item->pref = pref;
	    PrefBranchSetData(
		ctree, new_branch,
		item, PrefDestroyItem
	    );
	}

	return(new_branch);
}


/*
 *	Creates a banner like heading for the headings of pref panels.
 */
static void PrefCreateHeading(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label
)
{
	GtkWidget *w;
	GtkStyle *style_ptr;
	medit_core_struct *core_ptr;
	medit_styles_list_struct *styles_list;

	core_ptr = MEDIT_CORE(pref->core_ptr);
	if(core_ptr == NULL)
	    return;

	styles_list = &core_ptr->styles_list;
	style_ptr = styles_list->heading2_rev_text;

	if(style_ptr != NULL)
	{
	    w = (GtkWidget *)GUIBannerCreate(
		label, MEDIT_FONT_NAME_HEADING2_REV,
		style_ptr->fg[GTK_STATE_NORMAL], style_ptr->bg[GTK_STATE_NORMAL],
		GTK_JUSTIFY_LEFT,
		TRUE
	    );
	    gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, parent_border);
	    gtk_widget_show(w);
	}
}

/*
 *	Creates a new select color button.
 *
 *	Returns parent hbox.
 */
static void PrefCreateColorButton(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label,
	gint label_width,
	gint parameter,
	GdkColor gdk_color
)
{
	GdkColormap *colormap;
	GtkWidget *w, *btn, *da;
	csd_color_struct *color_ptr;


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, parent_border);
	gtk_widget_show(w);
	parent = w;

	w = gtk_label_new(label);
	gtk_widget_set_usize(w, label_width, -1);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	btn = w = gtk_button_new();
/*	gtk_widget_set_usize(w, 25, 25); */
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent = w;

	w = gtk_frame_new(NULL);
	gtk_container_add(GTK_CONTAINER(parent), w);
	gtk_container_border_width(GTK_CONTAINER(w), 1);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_OUT);
	gtk_widget_show(w);
	parent = w;

	/* Create drawing area */
	da = w = gtk_drawing_area_new();
	gtk_drawing_area_size(GTK_DRAWING_AREA(w), 15, 15);
	gtk_container_add(GTK_CONTAINER(parent), w);
	gtk_widget_realize(w);
	gtk_widget_show(w);

	/* Allocate a new csd_color_struct for the drawing area */
	color_ptr = (csd_color_struct *)g_malloc0(
	    sizeof(csd_color_struct)
	);
	if(color_ptr != NULL)
	{
	    color_ptr->a = 1.0;
	    color_ptr->r = ((gdouble)gdk_color.red / 65535.0);
	    color_ptr->g = ((gdouble)gdk_color.green / 65535.0);
	    color_ptr->b = ((gdouble)gdk_color.blue / 65535.0);

	    gtk_object_set_user_data(GTK_OBJECT(da), (gpointer)color_ptr);
	    gtk_signal_connect(
		GTK_OBJECT(da), "destroy",
		GTK_SIGNAL_FUNC(PrefDrawingAreaDestroyCB),
		(gpointer)color_ptr
	    );
	}

	/* Set background color of GtkDrawingArea widget */
	colormap = gdk_window_get_colormap(da->window);
	gdk_color_alloc(colormap, &gdk_color);
	gdk_window_set_background(da->window, &gdk_color);


	/* Record drawing area widget */
	PrefParmRecord(pref, parameter, da);

	/* Attach the "clicked" signal to the GtkButton widget and pass
	 * the GtkDrawingArea widget as the data pointer (not the
	 * pref_struct)
	 */
	gtk_signal_connect(
	    GTK_OBJECT(btn), "clicked",
	    GTK_SIGNAL_FUNC(PrefSelectColorCB), da
	);
}

/*
 *      Creates a new select font label and button.
 *
 *      Returns parent hbox.
 */
static void PrefCreateFontButton(
	pref_struct *pref,
	GtkWidget *parent,	/* An hbox */
	gint parent_border,	/* Border when pack into given parent */
	const gchar *label,
	const gchar *font_name,
	gint label_width,
	gint entry_width,
	gint parameter
)
{
	GtkWidget *w, *btn, *entry;


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, parent_border);
	gtk_widget_show(w);
	parent = w;

	if(label != NULL)
	{
	    w = gtk_label_new(label);
	    gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	    gtk_widget_set_usize(w, label_width, -1);
	    gtk_widget_show(w);
	}

	entry = w = gtk_entry_new();
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_set_usize(w, entry_width, -1);
	gtk_entry_set_editable(GTK_ENTRY(w), FALSE);
	gtk_entry_set_text(GTK_ENTRY(w), font_name);
	gtk_widget_show(w);


	btn = w = gtk_button_new_with_label("Select...");
	gtk_widget_set_usize(w, 60, -1);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
	gtk_widget_show(w);

	/* Record entry widget */
	PrefParmRecord(pref, parameter, entry);

	/* Attach the "clicked" signal to the GtkButton widget and pass
	 * the GtkEntry widget as the data pointer (not the pref_struct).
	 */
	gtk_signal_connect(
	    GTK_OBJECT(btn), "clicked",
	    GTK_SIGNAL_FUNC(PrefSelectFontCB), entry
	);
}

/*
 *      Create apperance panel.
 */
static void PrefCreatePanelApperance(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	GtkWidget *w, *parent2, *parent3;
	GSList *gslist;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "Apperance"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("On Startup, Launch");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for editor check button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Editor check button */
	w = gtk_check_button_new_with_label("Editor");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = TRUE;
	PrefParmRecord(pref, MEDIT_PREF_PARM_STARTUP_EDITOR, w);

	/* Hbox for viewer check button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Viewer check button */
	w = gtk_check_button_new_with_label("Viewer");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = FALSE;
	PrefParmRecord(pref, MEDIT_PREF_PARM_STARTUP_VIEWER, w);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Window Placement");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for record window positions and sizes check button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Record window positions and sizes check button */
	w = gtk_check_button_new_with_label("Record Last Position & Size");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = TRUE;
	PrefParmRecord(pref, MEDIT_PREF_PARM_RECORD_WIN_POS, w);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Show Toolbar As");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for `pictures and text' and tool tips check button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* `Pictures and text' radio button */
	gslist = NULL;
	w = gtk_radio_button_new_with_label(gslist, "Pictures & Text");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = TRUE;
	PrefParmRecord(pref, MEDIT_PREF_PARM_TOOLBAR_PT, w);
	gslist = gtk_radio_button_group(GTK_RADIO_BUTTON(w));

	/* Tool tips check button */
	w = gtk_check_button_new_with_label("Tooltips");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = TRUE;
	PrefParmRecord(pref, MEDIT_PREF_PARM_TOOL_TIPS, w);


	/* Hbox for `pictures only' radio button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* `Pictures only' radio button */
	w = gtk_radio_button_new_with_label(gslist, "Pictures Only");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	PrefParmRecord(pref, MEDIT_PREF_PARM_TOOLBAR_P, w);
	gslist = gtk_radio_button_group(GTK_RADIO_BUTTON(w));


	/* Hbox for `text only' radio button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* `Text only' radio button */
	w = gtk_radio_button_new_with_label(gslist, "Text Only");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	PrefParmRecord(pref, MEDIT_PREF_PARM_TOOLBAR_T, w);


}

/*
 *	Create fonts panel.
 */
static void PrefCreatePanelFonts(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	GtkWidget *w, *parent2, *parent3;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "Fonts"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("XML Editing");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;


	/* Edit text standard */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Create font select entry and button */
	PrefCreateFontButton(
	    pref, parent3, border_major,
	    "Editable:",
	    MEDIT_FONT_NAME_EDIT_STD,
	    120,
	    200,
	    MEDIT_PREF_PARM_FONT_EDIT_STD
	);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("ManPage Display");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;
	
	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;


	/* ManPage output standard */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Create font select entry and button */
	PrefCreateFontButton(
	    pref, parent3, border_major,
	    "Normal:",
	    MEDIT_FONT_NAME_MANPAGE_STD,
	    120,
	    200,
	    MEDIT_PREF_PARM_FONT_MANPAGE_STD
	);


	/* ManPage output bold */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Create font select entry and button */
	PrefCreateFontButton(
	    pref, parent3, border_major,
	    "Bold:",
	    MEDIT_FONT_NAME_MANPAGE_BOLD,
	    120,
	    200,
	    MEDIT_PREF_PARM_FONT_MANPAGE_BOLD
	);


	/* ManPage output underline */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Create font select entry and button */
	PrefCreateFontButton(
	    pref, parent3, border_major,
	    "Underline:",
	    MEDIT_FONT_NAME_MANPAGE_UNDERLINE,
	    120,
	    200,
	    MEDIT_PREF_PARM_FONT_MANPAGE_UNDERLINE
	);


}

/*
 *	Create colors panel.
 */
static void PrefCreatePanelColors(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	GdkColor gdk_color;
	GdkColormap *colormap;
	GtkWidget *w, *parent2, *parent3;


	/* Get colormap */
	w = pref->toplevel;
	colormap = ((w != NULL) ?
	    gdk_window_get_colormap(w->window) : NULL
	);


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "Colors"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Text");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;


	/* Edit text standard */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_EDIT_TEXT_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Editable Fg:", 200,
	    MEDIT_PREF_PARM_COLOR_EDIT_TEXT_FG,
	    gdk_color
	);

	/* Edit text background */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_EDIT_TEXT_BG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Editable Bg:", 200,
	    MEDIT_PREF_PARM_COLOR_EDIT_TEXT_BG,
	    gdk_color
	);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("XML Tags");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;


	/* Deliminators */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_EDIT_TEXT_DELIM_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Deliminators:", 200,
	    MEDIT_PREF_PARM_COLOR_EDIT_TEXT_DELIM,
	    gdk_color
	);


	/* Tag text */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_EDIT_TEXT_TAG_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Tags:", 200,
	    MEDIT_PREF_PARM_COLOR_EDIT_TEXT_TAG,
	    gdk_color
	);


	/* Symbol representations */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_EDIT_TEXT_SYMREP_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Symbol Representations:", 200,
	    MEDIT_PREF_PARM_COLOR_EDIT_TEXT_SYMREP,
	    gdk_color
	);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("ManPage Output");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;


	/* Manpage output standard fg */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_MANPAGE_TEXT_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Standard Fg:", 200,
	    MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_FG,
	    gdk_color
	);

	/* Manpage output standard bg */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_MANPAGE_TEXT_BG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Standard Bg:", 200,
	    MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BG,
	    gdk_color
	);

	/* Manpage output bold fg */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_MANPAGE_TEXT_BOLD_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Bold Fg:", 200,
	    MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BOLD,
	    gdk_color
	);

	/* Manpage output underline fg */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Allocate color (this does not need to be deleted) */
	if(colormap != NULL)
	    gdk_color_parse(MEDIT_CSTR_MANPAGE_TEXT_UNDERLINE_FG, &gdk_color);
	/* Create color select button */
	PrefCreateColorButton(
	    pref, parent3, border_major, "Underline Fg:", 200,
	    MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_UNDERLINE,
	    gdk_color
	);


}

/*
 *      Create editor panel.
 */
static void PrefCreatePanelEditor(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	GtkWidget *w, *parent2, *parent3;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "ManEdit Editor Window"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Display");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;
  
	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for enable syntax highlighting check button */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	/* Enable syntax highlighting check button */
	w = gtk_check_button_new_with_label("Syntax Highlighting");
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	GTK_TOGGLE_BUTTON(w)->active = MEDIT_DEF_SYNTAX_HIGHLIGHTING;
	PrefParmRecord(pref, MEDIT_PREF_PARM_EDITOR_ENABLE_SYNHL, w);

}

/*
 *	Viewer panel.
 */
static void PrefCreatePanelViewer(pref_struct *pref, GtkWidget *parent)
{
	const gint border_major = 5;
	GtkWidget *w, *parent2;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "ManEdit Viewer Window"
	);



}

/*
 *      Locations panel.
 */
static void PrefCreatePanelLocations(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	gchar *s;
	gchar *heading[2];
	gpointer entry_rtn, browse_rtn;
	GtkWidget *w, *parent2, *parent3, *parent4, *scroll_parent;
	GtkCList *clist;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "Locations"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Files");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* Configuration */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	w = GUIPromptBarWithBrowse(
	    NULL, "ManEdit Configuration:",
	    NULL, &entry_rtn, &browse_rtn,
	    NULL, NULL
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);

	w = (GtkWidget *)browse_rtn;
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefBrowsePathCB),
	    (gpointer)entry_rtn         /* Pass data as entry widget */
	);

	w = (GtkWidget *)entry_rtn;
	s = g_getenv("HOME");
	s = PrefixPaths(
	    (s != NULL) ? s : "/",
	    MEDIT_RCFILE_LOCAL
	);
	gtk_entry_set_text(GTK_ENTRY(w), s);
	PrefParmRecord(pref, MEDIT_PREF_PARM_LOCATIONS_RCFILE, w);



	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Directories");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* ManEdit global directory */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	w = GUIPromptBarWithBrowse(
	    NULL, "ManEdit Global:",
	    NULL, &entry_rtn, &browse_rtn,
	    NULL, NULL
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);

	w = (GtkWidget *)browse_rtn;
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefBrowsePathCB),
	    (gpointer)entry_rtn         /* Pass data as entry widget */
	);

	w = (GtkWidget *)entry_rtn;
	gtk_entry_set_text(GTK_ENTRY(w), MEDIT_GLOBAL_DIR);
	PrefParmRecord(pref, MEDIT_PREF_PARM_LOCATIONS_GLOBAL_DIR, w);

	/* Tmp directory */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	w = GUIPromptBarWithBrowse(
	    NULL, "Tempory:",
	    NULL, &entry_rtn, &browse_rtn,
	    NULL, NULL
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);

	w = (GtkWidget *)browse_rtn;
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefBrowsePathCB),
	    (gpointer)entry_rtn         /* Pass data as entry widget */
	);

	w = (GtkWidget *)entry_rtn;
	s = g_getenv("TMPDIR");
	if(s == NULL)
#ifdef P_tmpdir
	    s = P_tmpdir;
#else
	    s = NULL;
#endif
	if(s == NULL)
	    s = "/tmp";

	gtk_entry_set_text(GTK_ENTRY(w), s);
	PrefParmRecord(pref, MEDIT_PREF_PARM_LOCATIONS_TMP_DIR, w);




	/* Global manual page directories clist */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	parent3 = w;

	/* Scrolled window, parent for manual page directories clist */
	w = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(
	    GTK_SCROLLED_WINDOW(w),
	    GTK_POLICY_AUTOMATIC,
	    GTK_POLICY_AUTOMATIC
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);
	scroll_parent = w;

	/* Global manual page directories clist */
	heading[0] = "Directory";
	heading[1] = "Label";
	w = gtk_clist_new_with_titles(2, heading);
	clist = GTK_CLIST(w);
#if 0
	if(!GTK_WIDGET_NO_WINDOW(w))
	{
	    gtk_widget_set_events(
		w,
		GDK_BUTTON_PRESS_MASK
	    );
	    gtk_signal_connect_after(
		GTK_OBJECT(w), "button_press_event",
		GTK_SIGNAL_FUNC(EditorFIPMenuMapCB), fip
	    );
	}
#endif
	gtk_clist_set_selection_mode(clist, GTK_SELECTION_SINGLE);
	gtk_clist_set_row_height(clist, MEDIT_LIST_ROW_SPACING);
/*      gtk_clist_set_auto_sort(clist, TRUE); */
	gtk_container_add(GTK_CONTAINER(scroll_parent), w);
	gtk_widget_set_usize(w, -1, 200);
	gtk_clist_set_column_width(clist, 0, 150);
	gtk_clist_set_column_width(clist, 1, 200);
	gtk_clist_column_titles_passive(clist);
	gtk_clist_set_shadow_type(clist, GTK_SHADOW_IN);
	gtk_signal_connect(
	    GTK_OBJECT(w), "select_row",
	    GTK_SIGNAL_FUNC(PrefManPageDirsCListSelectCB),
	    (gpointer)pref
	);
	gtk_signal_connect( 
	    GTK_OBJECT(w), "unselect_row",
	    GTK_SIGNAL_FUNC(PrefManPageDirsCListUnselectCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);
	pref->selected_manpage_dirs_clist_item = -1;
	/* Add some default values to the manpage dirs clist */
	if(w != NULL)
	{
	    gchar *text[2];

	    /* Note to porters:
	     *
	     * Here we set up the default manual page directories on
	     * the preferences window's manpage dirs clist.
	     *
	     * On some systems, the global manual page directories are
	     * prefixed with /usr/share instead of /usr (or even other
	     * names). So you may need to add a new case for your system
	     * to set up the default paths here.
	     *
	     * Only set the path (a const char is just fine) for the
	     * first index of the text array (that's text[0]).
	     */

#if defined(__FreeBSD__)
	    text[0] = "/usr/share/man";
#else
	    text[0] = "/usr/man";
#endif
	    text[1] = "Global";
	    gtk_clist_append(GTK_CLIST(w), text);

#if defined(__FreeBSD__)
	    text[0] = LOCALBASE "/man";
#else
	    text[0] = "/usr/local/man";
#endif
	    text[1] = "Local";
	    gtk_clist_append(GTK_CLIST(w), text);

#if defined(__FreeBSD__)
	    text[0] = X11BASE"/man";
#else
	    text[0] = "/usr/X11R6/man";
#endif
	    text[1] = "X Window Systems";
	    gtk_clist_append(GTK_CLIST(w), text);
	}
	PrefParmRecord(pref, MEDIT_PREF_PARM_LOCATIONS_MAN_DIRS, w);

	w = gtk_hbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent4 = w;

	/* Add button */
	w = GUIButtonPixmapLabelH( 
	    (u_int8_t **)icon_add_20x20_xpm, "Add", NULL
	);
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefManPageDirsAddCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);

	/* Properties button */
	w = GUIButtonPixmapLabelH(
	    (u_int8_t **)icon_properties2_20x20_xpm, "Properties", NULL
	);
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefManPageDirsEditCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);

	/* Remove button */
	w = GUIButtonPixmapLabelH(
	    (u_int8_t **)icon_remove_20x20_xpm, "Remove", NULL
	);
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefManPageDirsRemoveCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);



}

/*
 *	Converters panel.
 */
static void PrefCreatePanelConverters(pref_struct *pref, GtkWidget *parent)
{
	const gint	border_major = 5,
			border_minor = 2;
	gpointer entry_rtn, browse_rtn;
	GtkWidget *w, *parent2, *parent3;


	/* Heading */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	PrefCreateHeading(
	    pref, parent2, border_major,
	    "Converters"
	);


	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_frame_new("Output");
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, border_major);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_ETCHED_IN);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent2 = w;

	/* ...to Manual Page command */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_minor);
	gtk_widget_show(w);
	parent3 = w;

	w = GUIPromptBarWithBrowse(
	    NULL, "to Manual Page Command",
	    NULL, &entry_rtn, &browse_rtn,
	    NULL, NULL
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, border_major);
	gtk_widget_show(w);

	w = (GtkWidget *)browse_rtn;
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefBrowsePathCB),
	    (gpointer)entry_rtn		/* Pass data as entry widget */
	);

	w = (GtkWidget *)entry_rtn;
	gtk_entry_set_text(GTK_ENTRY(w), MEDIT_CMD_MANPAGE_TO_OUTPUT);
	PrefParmRecord(pref, MEDIT_PREF_PARM_CONVERTERS_MANPAGE_TO_OUTPUT, w);




}

/*
 *	Creates each catagory into the preferences window.
 */
static void PrefCreateCatagories(pref_struct *pref)
{
	GtkWidget *parent;
	GtkCTreeNode *branch, *parent_branch;
	GtkCTree *ctree;


	ctree = (GtkCTree *)pref->catagory_ctree;
	if(ctree == NULL)
	    return;


	/* Apperance */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Appearance",
	    NULL, NULL,
	    FALSE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_APPERANCE
	);
	parent_branch = branch;
	PrefCreatePanelApperance(pref, parent);

	/* Fonts */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Fonts",
	    parent_branch, NULL,
	    TRUE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_FONTS
	);
	PrefCreatePanelFonts(pref, parent);

	/* Colors */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Colors", 
	    parent_branch, NULL,
	    TRUE, 		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_COLORS
	);
	PrefCreatePanelColors(pref, parent);


	/* Editor */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Editor",
	    NULL, NULL,
	    TRUE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_EDITOR
	);
	PrefCreatePanelEditor(pref, parent);

	/* Viewer */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Viewer",
	    NULL, NULL,
	    TRUE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_VIEWER
	);
	PrefCreatePanelViewer(pref, parent);

	/* Locations */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch( 
	    pref, "Locations",
	    NULL, NULL,
	    TRUE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_LOCATIONS
	);
	PrefCreatePanelLocations(pref, parent);

	/* Converters */
	parent = gtk_vbox_new(FALSE, 0);
	branch = PrefAddCatagoryBranch(
	    pref, "Converters",
	    NULL, NULL,
	    TRUE,		/* Is leaf */
	    parent,
	    MEDIT_PREF_CAT_CONVERTERS
	);
	PrefCreatePanelConverters(pref, parent);


	/* Update column width */
	gtk_clist_set_column_width(
	    (GtkCList *)ctree,
	    0,			/* Column */
	    gtk_clist_optimal_column_width((GtkCList *)ctree, 0)
	);
}


/*
 *	Creates a new preferences window.
 */
pref_struct *PrefNew(gpointer core_ptr)
{
	GtkWidget *w, *parent, *parent2, *parent3;
	GtkWidget *scroll_parent;
	GtkCList *clist;
	gchar *title[1];
	pref_struct *pref = PREF(g_malloc0(
	    sizeof(pref_struct)
	));
	if(pref == NULL)
	    return(NULL);

	/* Reset values */
	pref->initialized = TRUE;
	pref->map_state = FALSE;
	pref->has_changes = FALSE;
	pref->processing = FALSE;

	pref->core_ptr = core_ptr;

	pref->panel_parent = NULL;
	pref->total_panel_parents = 0;

	pref->parm_widget = NULL;
	pref->total_parm_widgets = 0;


	/* Toplevel */
	w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	pref->toplevel = w;
	gtk_widget_realize(w);
	GUISetWMIcon(w->window, (u_int8_t **)manedit_48x48_xpm);
	gtk_widget_set_usize(
	    w,
	    MEDIT_PREF_DEF_WIDTH,
	    MEDIT_PREF_DEF_HEIGHT
	);
	gtk_window_set_policy(
	    GTK_WINDOW(w),
	    TRUE, TRUE, FALSE
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "destroy",
	    GTK_SIGNAL_FUNC(PrefDestroyCB),
	    (gpointer)pref
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "delete_event",
	    GTK_SIGNAL_FUNC(PrefCloseCB),
	    (gpointer)pref
	);
	gtk_window_set_title(GTK_WINDOW(w), MEDIT_PREF_TITLE);
	parent = w;


	/* Main vbox */
	w = gtk_vbox_new(FALSE, 0);
	pref->main_vbox = w;
	gtk_container_add(GTK_CONTAINER(parent), w);
	gtk_widget_show(w);
	parent = w;


	/* Paned */
	w = gtk_hpaned_new();
	gtk_paned_set_handle_size(GTK_PANED(w), MEDIT_DEF_PANED_HANDLE_SIZE);
	gtk_paned_set_gutter_size(GTK_PANED(w), MEDIT_DEF_PANED_GUTTER_SIZE);
	gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
	gtk_paned_set_position(GTK_PANED(w), 200);
	gtk_widget_show(w);
	parent2 = w;


	/* Vbox for layout ctree */
	w = gtk_vbox_new(FALSE, 0);
	gtk_paned_add1(GTK_PANED(parent2), w);
	gtk_widget_show(w);
	parent3 = w;

	/* Scrolled window for catagory ctree */
	w = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(
	    GTK_SCROLLED_WINDOW(w),
	    GTK_POLICY_AUTOMATIC,
	    GTK_POLICY_AUTOMATIC
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	scroll_parent = w;

	title[0] = "Category";
	pref->catagory_ctree = w = gtk_ctree_new_with_titles(
	    1, 0, title
	);
	clist = GTK_CLIST(w);
/*
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "button_press_event",
	    GTK_SIGNAL_FUNC(PrefMenuMapCB),
	    (gpointer)pref
	);
 */
	gtk_clist_column_titles_passive(clist);
/*	gtk_clist_column_titles_hide(clist); */
	gtk_clist_set_row_height(clist, MEDIT_LIST_ROW_SPACING);
	gtk_clist_set_shadow_type(clist, GTK_SHADOW_IN);
	gtk_container_add(GTK_CONTAINER(scroll_parent), w);
	gtk_signal_connect(
	    GTK_OBJECT(w), "tree_select_row",
	    GTK_SIGNAL_FUNC(PrefCatagoryCTreeSelectCB),
	    (gpointer)pref
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "tree_unselect_row",
	    GTK_SIGNAL_FUNC(PrefCatagoryCTreeUnselectCB),
	    (gpointer)pref
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "tree_expand",
	    GTK_SIGNAL_FUNC(PrefCatagoryCTreeExpandCB),
	    (gpointer)pref
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "tree_collapse",
	    GTK_SIGNAL_FUNC(PrefCatagoryCTreeExpandCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);

#if 0
	/* Layout ctree right click menu */
	menu = (GtkWidget *)GUIMenuCreate();
	pref->catagory_menu = menu;
	accel_group = NULL;
	mclient_data = (gpointer)pref;

	if(menu != NULL)
	{
	    icon = (u_int8_t **)mp_viewer_20x20_xpm;
	    label = "Expand";
	    accel_key = 0;
	    accel_mods = 0;
	    func_cb = NULL;
	    DO_ADD_MENU_ITEM_LABEL 
	    pref->menu_mi = w;

	}
#endif


	/* ********************************************************** */
	/* Right panel side vbox */
	w = gtk_vbox_new(FALSE, 0);
	pref->panel_toplevel = w;
	gtk_paned_add2(GTK_PANED(parent2), w);
	gtk_widget_show(w);
	parent2 = w;






	/* ********************************************************** */

	/* Get main vbox parent */
	parent = pref->main_vbox;

	/* Horizontal rule above buttons hbox */
	w = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	/* Hbox to hold buttons */
	w = gtk_hbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 5);
	gtk_widget_show(w);
	parent2 = w;

	/* OK button */
	w = GUIButtonPixmapLabelH(
	    (u_int8_t **)icon_ok_20x20_xpm, "OK", NULL
	);
	pref->ok_btn = w;
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefOKCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);

	/* Apply button */
	w = GUIButtonPixmapLabelH(
	    (u_int8_t **)icon_select_20x20_xpm, "Apply", NULL
	);
	pref->apply_btn = w;
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefApplyCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);

	/* Close button */
	w = GUIButtonPixmapLabelH(
	    (u_int8_t **)icon_close_20x20_xpm, "Close", NULL
	);
	pref->apply_btn = w;
	gtk_widget_set_usize(w, PREF_BTN_WIDTH, PREF_BTN_HEIGHT);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, FALSE, 5);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(PrefCloseMCB),
	    (gpointer)pref
	);
	gtk_widget_show(w);


	/* Reset values (before creating catagories) */
	PrefReset(pref, FALSE);

	/* Create all catagories on the preferences window */
	PrefCreateCatagories(pref);

	/* Update menus */
	PrefUpdateMenus(pref);
 
	return(pref);
}

/*
 *	Updates all menus on the preferences window.
 */
void PrefUpdateMenus(pref_struct *pref)
{
	static gboolean reenterant = FALSE;

	if(pref == NULL)
	    return;

	if(!pref->initialized)
	    return;

	if(reenterant)
	    return;
	else
	    reenterant = TRUE;




	reenterant = FALSE;
}

/*
 *	Resets the preferences window, deallocating any loaded data on
 *	it and unmapping it if requested.
 */
void PrefReset(pref_struct *pref, gboolean need_unmap)
{
	static gboolean reenterant = FALSE;
	GtkWidget *w;
	GtkCTree *ctree;
	GtkCTreeNode *branch, *prev_branch;
	GtkCTreeRow *branch_row;


	if(pref == NULL)
	    return;

	if(!pref->initialized)
	    return;

	/* Still processing? */
	if(pref->processing)
	    return;

	if(reenterant)
	    return;
	else
	    reenterant = TRUE;


	/* Reset values */
	pref->processing = FALSE;
	pref->has_changes = FALSE;

	pref->selected_branch = NULL;


	/* Delete all branches in catagory ctree */
	w = pref->catagory_ctree;
	if(w != NULL)
	{
	    ctree = (GtkCTree *)w;
	    branch = gtk_ctree_node_nth(ctree, 0);

	    while(branch != NULL)
	    {
		prev_branch = branch;

		branch_row = GTK_CTREE_ROW(branch);
		branch = ((branch_row == NULL) ?
		    NULL : branch_row->sibling
		);

		gtk_ctree_remove_node(ctree, prev_branch);
	    }
	}


	/* Delete all items from global manual pages directories clist */
	w = PrefParmGetWidget(pref, MEDIT_PREF_PARM_LOCATIONS_MAN_DIRS);
	if(w != NULL)
	{
	    gtk_clist_freeze((GtkCList *)w);
	    gtk_clist_clear((GtkCList *)w);
	    gtk_clist_thaw((GtkCList *)w);
	}


	/* Delete or reset other values data */
	pref->last_editor_width = MEDIT_DEF_WIDTH;
	pref->last_editor_height = MEDIT_DEF_HEIGHT;

	pref->last_viewer_width = MEDIT_VIEWER_DEF_WIDTH;
	pref->last_viewer_height = MEDIT_VIEWER_DEF_HEIGHT;

	g_free(pref->last_opened_manpage_path);
	pref->last_opened_manpage_path = NULL;
	g_free(pref->last_saved_manpage_path);
	pref->last_saved_manpage_path = NULL;
	g_free(pref->last_opened_manage_view_path);
	pref->last_opened_manage_view_path = NULL;

	pref->selected_manpage_dirs_clist_item = -1;


	/* Unmap as needed */
	if(need_unmap)
	{
	    w = pref->toplevel;
	    if(w != NULL)
		gtk_widget_hide(w);
	    pref->map_state = FALSE;
	}

	reenterant = FALSE;
}

/*
 *	Maps the preferences window as needed.
 */
void PrefMap(pref_struct *pref)
{
	GtkWidget *w;

	if(pref == NULL)
	    return;

	if(!pref->initialized)
	    return;

	w = pref->toplevel;
	if(w == NULL)
	    return;

	if(!pref->map_state)
	{
	    pref->map_state = TRUE;
	    gtk_widget_show(w);
	}
}

/*
 *	Unmaps the preferences window as needed.
 */
void PrefUnmap(pref_struct *pref)
{
	GtkWidget *w;

	if(pref == NULL)
	    return;

	if(!pref->initialized)
	    return;

	w = pref->toplevel;
	if(w == NULL)
	    return;

	if(pref->map_state)
	{
	    pref->map_state = FALSE;
	    gtk_widget_hide(w);
	}
}

/*
 *	Destroys all resources on the preferences window and deletes
 *	the structure itself.
 */
void PrefDelete(pref_struct *pref)
{
	GtkWidget *w;

	if(pref == NULL)
	    return;

	if(pref->initialized)
	{
	    /* Still processing? */
	    if(pref->processing)
		return;

	    /* Reset values to defaults, this will cause any loaded data
	     * to be deleted.
	     */
	    PrefReset(pref, TRUE);

#define DO_DESTROY_WIDGET	\
{ \
 if(w != NULL) \
  gtk_widget_destroy(w); \
}


	    w = pref->panel_toplevel;
	    pref->panel_toplevel = NULL;
	    DO_DESTROY_WIDGET


	    w = pref->catagory_ctree;
	    pref->catagory_ctree = NULL;
	    DO_DESTROY_WIDGET


	    w = pref->main_vbox;
	    pref->main_vbox = NULL;
	    DO_DESTROY_WIDGET

	    w = pref->toplevel;
	    pref->toplevel = NULL;
	    DO_DESTROY_WIDGET

#undef DO_DESTROY_WIDGET
	}

	g_free(pref->panel_parent);
	pref->panel_parent = NULL;
	pref->total_panel_parents = 0;

	g_free(pref->parm_widget);
	pref->parm_widget = NULL;
	pref->total_parm_widgets = 0;

	g_free(pref);
}
