#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <unistd.h>

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

#include "guiutils.h"
#include "pulist.h"
#include "cdialog.h"
#include "fb.h"
#include "fprompt.h"
#include "editclist.h"

#include "edv_types.h"
#include "edv_mime_type.h"
#include "edv_mime_types_list.h"
#include "mime_types_list_win.h"
#include "endeavour2.h"
#include "edv_cb.h"
#include "edv_utils.h"
#include "edv_utils_gtk.h"
#include "config.h"
#include "edv_cfg_list.h"

#include "images/icon_ok_20x20.xpm"
#include "images/icon_select_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"
#include "images/icon_close_20x20.xpm"
#include "images/icon_mimetypes_48x48.xpm"


static void EDVMimeTypeEditDlgIconUpdateDisplay(
	edv_mime_type_icon_picker_struct *ei,
	const edv_mime_type_icon_state state
);
static void EDVMimeTypeEditDlgIconChangeCB(
	GtkWidget *widget, gpointer data
);
static void EDVMimeTypeEditDlgIconPrevCB(
	GtkWidget *widget, gpointer data
);
static void EDVMimeTypeEditDlgIconNextCB(
	GtkWidget *widget, gpointer data
);

static gint EDVMimeTypeEditDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
);
static void EDVMimeTypeEditDlgAnyChangedCB(
	GtkWidget *widget, gpointer data
);
static void EDVMimeTypeEditDlgECListRowAddedCB(
	editclist_struct *eclist, gint row,
	gpointer data
);
static void EDVMimeTypeEditDlgECListCellChangedCB(
	editclist_struct *eclist, gint row, gint column,
	gpointer data
);
static void EDVMimeTypeEditDlgECListRowRemovedCB(
	editclist_struct *eclist, gint row,
	gpointer data
);
static void EDVMimeTypeEditDlgClassChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
);
static void EDVMimeTypeEditDlgHandlerChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
);
static void EDVMimeTypeEditDlgOKCB(
	GtkWidget *widget, gpointer data
);
static void EDVMimeTypeEditDlgApplyCB(
	GtkWidget *widget, gpointer data
);
static void EDVMimeTypeEditDlgCancelCB(
	GtkWidget *widget, gpointer data
);

static edv_mime_type_class EDVMimeTypeEditDlgGetClass(
	edv_mime_type_edit_dlg_struct *d
);
static edv_mime_type_handler EDVMimeTypeEditDlgGetHandler(
	edv_mime_type_edit_dlg_struct *d
);

static gint EDVMimeTypeEditDlgCheckMIMEType(
	edv_core_struct *core,
	edv_mime_type_struct **list, const gint total,
	const gint mt_num,
	const gboolean verbose, GtkWidget *toplevel
);

void EDVMimeTypeEditDlgGetValues(
	edv_mime_type_edit_dlg_struct *d, const gint mt_num
);

void EDVMimeTypeEditDlgMimeTypeRemovedCB(
	edv_mime_type_edit_dlg_struct *d, gint mt_num
);

static edv_mime_type_icon_picker_struct *EDVMimeTypeEditDlgIconNew(
	gpointer editwin, GtkWidget *parent, const gchar *title,
	gint icon_width, gint icon_height,
	gint btn_width, gint btn_height
);
static void EDVMimeTypeEditDlgIconDelete(edv_mime_type_icon_picker_struct *ei);

edv_mime_type_edit_dlg_struct *EDVMimeTypeEditDlgNew(
	edv_core_struct *core, edv_mime_types_list_win_struct *lw
);
void EDVMimeTypeEditDlgResetHasChanges(
	edv_mime_type_edit_dlg_struct *d, gboolean has_changes
);
void EDVMimeTypeEditDlgUpdateMenus(edv_mime_type_edit_dlg_struct *d);
gboolean EDVMimeTypeEditDlgIsMapped(edv_mime_type_edit_dlg_struct *d);
void EDVMimeTypeEditDlgMap(edv_mime_type_edit_dlg_struct *d);
void EDVMimeTypeEditDlgUnmap(edv_mime_type_edit_dlg_struct *d);
void EDVMimeTypeEditDlgDelete(edv_mime_type_edit_dlg_struct *d);


#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 EDITWIN_WIDTH		500
#define EDITWIN_HEIGHT		-1

#define EDITWIN_TITLE		"MIME Type"


/*
 *	Updates the icon displayed on the button of the given edit window
 *	icon structure with the corresponding pixmap and mask pair of
 *	the given state.
 */
static void EDVMimeTypeEditDlgIconUpdateDisplay(
	edv_mime_type_icon_picker_struct *ei,
	const edv_mime_type_icon_state state
)
{
	const gchar *label_str = "";
	GdkPixmap *pixmap;
	GdkBitmap *mask;
	GtkWidget *w, *parent;

	if(ei == NULL)
	    return;

	if((state < 0) || (state >= EDV_MIME_TYPE_TOTAL_ICON_STATES))
	    return;

	/* Get references to pixmap and mask pair specified by the
	 * given state
	 */
	pixmap = ei->pixmap[state];
	mask = ei->mask[state];

	/* Get button widget as the parent to create GtkPixmap in */
	parent = ei->button;
	if(parent == NULL)
	    return;

	/* Referenced pixmap valid? */
	if(pixmap != NULL)
	{
	    /* Referenced pixmap is valid, now check if the GtkPixmap
	     * that is to be used to display the pixmap has been
	     * created yet (if not then create a new one)
	     */
	    w = ei->gtk_pixmap;
	    if(w == NULL)
	    {
		ei->gtk_pixmap = w = gtk_pixmap_new(pixmap, mask);
		gtk_container_add(GTK_CONTAINER(parent), w);
		gtk_widget_show(w);
	    }
	    else
	    {
		/* GtkPixmap exists, so just update it */
		gtk_pixmap_set(GTK_PIXMAP(w), pixmap, mask);
		gtk_widget_show(w);
	    }
	}
	else
	{
	    /* No referenced pixmap, so unmap the the GtkPixmap */
	    w = ei->gtk_pixmap;
	    if(w != NULL)
	    {
		gtk_widget_hide(w);
	    }
	}


	/* Update state label, get the currect label string to display
	 * for the state label based on the given state
	 */
	switch(state)
	{
	  case EDV_MIME_TYPE_ICON_STATE_HIDDEN:
	    label_str = "Hidden";
	    break;
	  case EDV_MIME_TYPE_ICON_STATE_EXTENDED:
	    label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"Prolongado"
#elif defined(PROG_LANGUAGE_FRENCH)
"Etendu"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ausgedehnt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Esteso"
#elif defined(PROG_LANGUAGE_DUTCH)
"Verlengde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Estendido"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Forlenget"
#else
"Extended"
#endif
	    ;
	    break;
	  case EDV_MIME_TYPE_ICON_STATE_SELECTED:
	    label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"Escogido"
#elif defined(PROG_LANGUAGE_FRENCH)
"Choisi"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ausgewählt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Scelto"
#elif defined(PROG_LANGUAGE_DUTCH)
"Geselecteerde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Selecionado"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Valgt Ut"
#else
"Selected"
#endif
	    ;
	    break;
	  case EDV_MIME_TYPE_ICON_STATE_STANDARD:
	    label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"El Estándar"
#elif defined(PROG_LANGUAGE_FRENCH)
"Normal"
#elif defined(PROG_LANGUAGE_GERMAN)
"Standard"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Norma"
#elif defined(PROG_LANGUAGE_DUTCH)
"Standaard"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Padrão"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Standard"
#else
"Standard"
#endif
	    ;
	    break;
	}
	w = ei->state_label;
	if(w != NULL)
	    gtk_label_set_text(GTK_LABEL(w), label_str);


#if 0
	/* Update button sensitivities */
	w = ei->left_btn;
	if(w != NULL)
	    GTK_WIDGET_SET_SENSITIVE(
		w,
		(state > 0) ? TRUE : FALSE
	    )
	w = ei->right_btn;
	if(w != NULL)
	    GTK_WIDGET_SET_SENSITIVE(
		w,
		(state < (EDV_MIME_TYPE_TOTAL_ICON_STATES - 1)) ? TRUE : FALSE
	    )
#endif
}

/*
 *	Edit window icon change callback.
 */
static void EDVMimeTypeEditDlgIconChangeCB(
	GtkWidget *widget, gpointer data
)
{
	gint status;
	const gchar *old_path;
	gchar *old_parent_path;
	GtkWidget *toplevel;
	fb_type_struct **ftype = NULL, *ftype_rtn = NULL;
	gint total_ftypes = 0;
	gchar **path_rtn = NULL;
	gint total_path_rtns = 0;
	edv_mime_type_icon_state state;
	edv_core_struct *core;
	edv_mime_type_edit_dlg_struct *d;
	edv_mime_type_icon_picker_struct *ei =
	    EDV_MIME_TYPE_ICON_PICKER(data);
	if((ei == NULL) || FileBrowserIsQuery())
	    return;

	/* Get icon state */
	state = (edv_mime_type_icon_state)GTK_ADJUSTMENT_GET_VALUE(ei->adj);
	if((state < 0) || (state >= EDV_MIME_TYPE_TOTAL_ICON_STATES))
	    return;

	d = EDV_MIME_TYPE_EDIT_DLG(ei->d);
	core = d->core;
	if((d == NULL) || (core == NULL))
	    return;

	toplevel = d->toplevel;

	/* Get current path to the icon file */
	old_path = ei->path[state];
	if(old_path != NULL)
	    old_parent_path = g_dirname(old_path);
	else
	    old_parent_path = NULL;

	/* Create file types list */
	FileBrowserTypeListNew(
	    &ftype, &total_ftypes,
	    ".xpm", "XPM Image"
	);
	FileBrowserTypeListNew(
	    &ftype, &total_ftypes,
	    "*.*", "All files"
	);

	/* Current old_path must be considered invalid at this point */
	old_path = NULL;


	/* Query user for new icon file */
	FileBrowserSetTransientFor(toplevel);
	status = FileBrowserGetResponse(
#if defined(PROG_LANGUAGE_SPANISH)
"Icono Selecto",
"Selecto",
"Cancele",
#elif defined(PROG_LANGUAGE_FRENCH)
"Icône Privilégiée",
"Privilégié",
"Annuler",
#elif defined(PROG_LANGUAGE_GERMAN)
"Erlesenes Abbild",
"Erlesen",
"Heben",
#elif defined(PROG_LANGUAGE_ITALIAN)
"Scegliere L'Icona",
"Scegliere",
"Annullare",
#elif defined(PROG_LANGUAGE_DUTCH)
"Uitgezochte Beeld",
"Uitgezocht",
"Annuleer",
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Selecione Icone",
"Selecione",
"Cancelamento",
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Utvalgt Ikon",
"Utvalgt",
"Kanseller",
#else
"Select Icon",
"Select",
"Cancel",
#endif
	    old_parent_path,
	    ftype, total_ftypes,
	    &path_rtn, &total_path_rtns,
	    &ftype_rtn
	);
	FileBrowserSetTransientFor(NULL);

	/* Got user response? */
	if(status)
	{
	    const gchar *new_path = (total_path_rtns > 0) ?
		path_rtn[0] : NULL;
	    if(!STRISEMPTY(new_path))
	    {
		/* Load new pixmap and mask */
		GdkBitmap *mask;
		GdkPixmap *pixmap = GDK_PIXMAP_NEW_FROM_XPM_FILE(
		    &mask, new_path
		);
		if(pixmap != NULL)
		{
		    /* New pixmap and mask loaded successfully */

		    /* Unref old and set new pixmap and mask */
		    GDK_PIXMAP_UNREF(ei->pixmap[state])
		    GDK_BITMAP_UNREF(ei->mask[state])
		    EDVResizePixmap(
			pixmap, mask,
			ei->icon_width, ei->icon_height,
			&ei->pixmap[state], &ei->mask[state]
		    );
		    GDK_PIXMAP_UNREF(pixmap)
		    GDK_BITMAP_UNREF(mask)

		    /* Set new icon file path */
		    g_free(ei->path[state]);
		    ei->path[state] = STRDUP(new_path);

		    /* Update the displayed icon */
		    EDVMimeTypeEditDlgIconUpdateDisplay(ei, state);

		    /* Mark has changes */
		    EDVMimeTypeEditDlgResetHasChanges(d, TRUE);
		}
		else
		{
		    /* Failed to load icon */
 		    gchar *s;

		    /* Update the displayed icon */
		    EDVMimeTypeEditDlgIconUpdateDisplay(ei, state);

		    /* Notify user about failed load */
		    s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Incapaz de cargar el archivo de icono:\n\
\n\
    %s\n\
\n\
Verifique por favor que el sendero especificado es correcto y que el\n\
archivo es un archivo válido de la imagen de XPM."
#elif defined(PROG_LANGUAGE_FRENCH)
"Impossible de charger le fichier d'icône:\n\
\n\
    %s\n\
\n\
S'il vous plaît vérifier que le répertoire spécifié est exact et que le\n\
fichier est un fichier d'image de XPM valide."
#elif defined(PROG_LANGUAGE_GERMAN)
"Unfähig, abbild akte zu beladen:\n\
\n\
    %s\n\
\n\
Beglaubigen sie bitte, daß der angegebene pfad richtig ist, und, daß\n\
die akte eine gültige XPM bildnis akte ist."
#elif defined(PROG_LANGUAGE_ITALIAN)
"Incapace per caricare il file di icona:\n\
\n\
    %s\n\
\n\
Per favore di verificare che il sentiero specificato è corretto e\n\
che il file è un file di immagine di XPM valido."
#elif defined(PROG_LANGUAGE_DUTCH)
"Onbekwaam beeld dossier te laden:\n\
\n\
    %s\n\
\n\
Bevestiig alstublieft dat het gespecificeerd pad correcte is en dat\n\
het dossier een geldig XPM beeld dossier is."
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Incapaz de carregar arquivo de ícone:\n\
\n\
    %s\n\
\n\
Por favor verifique-se que o caminho especificado é correto e que o\n\
arquivo é um arquivo válido de imagem de XPM."
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Maktesløs laste ikonarkiv:\n\
\n\
    %s\n\
\n\
Vær så snill og bekreft at den spesifiserte stien er riktig og at\n\
arkivet er et gyldig XPM avbildearkiv"
#else
"Unable to load icon file:\n\
\n\
    %s\n\
\n\
Please verify that the specified path is correct and that the file\n\
is a valid XPM image file."
#endif
			, new_path
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(
#if defined(PROG_LANGUAGE_SPANISH)
"Cargue Icono Fallado"
#elif defined(PROG_LANGUAGE_FRENCH)
"Charger Icône Echoué"
#elif defined(PROG_LANGUAGE_GERMAN)
"Beladen Sie Abbild, Versagt Wird, Das"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Caricare L'Icona Fallita"
#elif defined(PROG_LANGUAGE_DUTCH)
"Laad Beeld Verzuimde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Carregue ícone Fracassado"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Last Sviktet Ikon"
#else
"Load Icon Failed"
#endif
			, s, NULL,
			toplevel
		    );
		    g_free(s);
		}
	    }
	}


	/* Delete file types list */
	FileBrowserDeleteTypeList(ftype, total_ftypes);

	g_free(old_parent_path);
}

/*
 *      Prev icon edit window icon callback.
 */
static void EDVMimeTypeEditDlgIconPrevCB(
	GtkWidget *widget, gpointer data
)
{
	GtkAdjustment *adj;
	edv_mime_type_edit_dlg_struct *d;
	edv_mime_type_icon_picker_struct *ei =
	    EDV_MIME_TYPE_ICON_PICKER(data);
	if(ei == NULL)
	    return;

	d = EDV_MIME_TYPE_EDIT_DLG(ei->d);
	if(d == NULL)
	    return;

	adj = ei->adj;
	if(adj == NULL)
	    return;

	/* Increment adjustment position */
	if(adj->value > adj->lower)
	    adj->value -= adj->step_increment;
	if(adj->value < adj->lower)
	    adj->value = adj->lower;

	EDVMimeTypeEditDlgIconUpdateDisplay(
	    ei, (edv_mime_type_icon_state)adj->value
	);
}

/*
 *	Next icon edit window icon callback.
 */
static void EDVMimeTypeEditDlgIconNextCB(
	GtkWidget *widget, gpointer data
)
{
	GtkAdjustment *adj;
	edv_mime_type_edit_dlg_struct *d;
	edv_mime_type_icon_picker_struct *ei =
	    EDV_MIME_TYPE_ICON_PICKER(data);
	if(ei == NULL)
	    return;

	d = EDV_MIME_TYPE_EDIT_DLG(ei->d);
	if(d == NULL)
	    return;

	adj = ei->adj;
	if(adj == NULL)
	    return;

	/* Increment adjustment position */
	if(adj->value < adj->upper)
	    adj->value += adj->step_increment;
	if(adj->value > adj->upper)
	    adj->value = adj->upper;

	EDVMimeTypeEditDlgIconUpdateDisplay(
	    ei, (edv_mime_type_icon_state)adj->value
	);
}


/*
 *	GtkWindow "delete_event" signal callback.
 */
static gint EDVMimeTypeEditDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
)
{
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return(TRUE);

	EDVMimeTypeEditDlgCancelCB(NULL, d);

	return(TRUE);
}

/*
 *	Any GtkWidget changed signal callback.
 */
static void EDVMimeTypeEditDlgAnyChangedCB(
	GtkWidget *widget, gpointer data
)
{
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	if(d->freeze_count > 0)
	    return;

	d->freeze_count++;

	if(!d->has_changes)
	    EDVMimeTypeEditDlgResetHasChanges(d, TRUE);

	d->freeze_count--;
}

/*
 *	Edit CList row added signal callback.
 */
static void EDVMimeTypeEditDlgECListRowAddedCB(
	editclist_struct *eclist, gint row,
	gpointer data
)
{
	const gchar *name, *cmd;
	const cfg_item_struct *cfg_list;
	edv_core_struct *core;
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)                                               
	    return;

	if(d->freeze_count > 0)
	    return;

	core = d->core;
	if(core == NULL)
	    return;

	cfg_list = core->cfg_list;

	d->freeze_count++;

	/* Set default values for the new row */
	switch(row)
	{
	  case 0:
	    name = "default";
	    break;
	  case 1:
	    name = "edit";
	    break;
	  default:
	    name = "other";
	    break;
	}
	cmd = EDV_GET_S(EDV_CFG_PARM_PROG_DEF_VIEWER);

	EditCListSetCellText(eclist, row, 0, name);
	EditCListSetCellText(eclist, row, 1, cmd);

	d->freeze_count--;

	EDVMimeTypeEditDlgAnyChangedCB(NULL, data);
}

/*
 *	Edit CList cell changed signal callback.
 */
static void EDVMimeTypeEditDlgECListCellChangedCB(
	editclist_struct *eclist, gint row, gint column,
	gpointer data
)
{
	EDVMimeTypeEditDlgAnyChangedCB(NULL, data);
}

/*
 *	Edit CList row removed signal callback.
 */
static void EDVMimeTypeEditDlgECListRowRemovedCB(
	editclist_struct *eclist, gint row,
	gpointer data
)
{
	EDVMimeTypeEditDlgAnyChangedCB(NULL, data);
}

/*
 *	Class popup list box "changed" signal callback.
 *
 *	This will update the value_label and value_entry widgets.
 */
static void EDVMimeTypeEditDlgClassChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
)
{
	gboolean sensitive = TRUE;
	edv_mime_type_class mt_class;
	const gchar *value_label_str = "";
	GtkWidget *w;
	pulist_struct *pulist;
	pulistbox_struct *pulistbox2;
	editclist_struct *eclist;
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	pulist = PUListBoxGetPUList(d->class_pulistbox);
	if(pulist == NULL)
	    return;

	/* Get the new class */
	mt_class = (edv_mime_type_class)PUListGetItemData(pulist, i);

	/* Update the widgets depending on class */
	switch(mt_class)
	{
	  case EDV_MIME_TYPE_CLASS_SYSTEM:
	    sensitive = FALSE;
	    value_label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"El Valor"
#elif defined(PROG_LANGUAGE_FRENCH)
"Valeur"
#elif defined(PROG_LANGUAGE_GERMAN)
"Wert"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Valore"
#elif defined(PROG_LANGUAGE_DUTCH)
"Waarde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Valor"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Verdi"
#else
"Value"
#endif
		":";
	    break;

	  case EDV_MIME_TYPE_CLASS_FORMAT:
	    sensitive = TRUE;
	    value_label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"Las Extensiones"
#elif defined(PROG_LANGUAGE_FRENCH)
"Extensions"
#elif defined(PROG_LANGUAGE_GERMAN)
"Verlängerungen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Le Estensioni"
#elif defined(PROG_LANGUAGE_DUTCH)
"Uitbreidingen"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"As Extensões"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Utvidelser"
#else
"Extensions"
#endif
		":";
	    break;

	  case EDV_MIME_TYPE_CLASS_PROGRAM:
	    sensitive = TRUE;
	    value_label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"La Ubicación"
#elif defined(PROG_LANGUAGE_FRENCH)
"Emplacement"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ort"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Posizione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Plaats"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Localidade"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Plassering"
#else
"Location"
#endif
		":";
	    break;

	  case EDV_MIME_TYPE_CLASS_UNIQUE:
	    sensitive = TRUE;
	    value_label_str =
#if defined(PROG_LANGUAGE_SPANISH)
"La Ubicación"
#elif defined(PROG_LANGUAGE_FRENCH)
"Emplacement"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ort"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Posizione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Plaats"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Localidade"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Plassering"
#else
"Location"
#endif
		":";
	    break;
	}

	w = d->value_label;
	if(w != NULL)
	    gtk_label_set_text(GTK_LABEL(w), value_label_str);

	GTK_WIDGET_SET_SENSITIVE(d->value_entry, sensitive);

	pulistbox2 = d->handler_pulistbox;
	if(pulistbox2 != NULL)
	{
	    w = pulistbox2->toplevel;
	    GTK_WIDGET_SET_SENSITIVE(w, sensitive);
	}

	eclist = d->editclist;
	if(eclist != NULL)
	{
	    w = EDITCLIST_TOPLEVEL(eclist);
	    GTK_WIDGET_SET_SENSITIVE(w, sensitive);
	}

	EDVMimeTypeEditDlgAnyChangedCB(NULL, data);
}

/*
 *	Handler popup list box "changed" signal callback.
 *
 *	This will update the sensitivity or mapping of some widgets
 *	such as the command editable clist.
 */
static void EDVMimeTypeEditDlgHandlerChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
)
{
	gboolean sensitive = FALSE;
	edv_mime_type_class mt_class;
	edv_mime_type_handler handler;
	GtkWidget *w;
	pulist_struct *pulist;
	editclist_struct *eclist;
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	pulist = PUListBoxGetPUList(d->handler_pulistbox);
	if(pulist == NULL)
	    return;

	if(d->freeze_count > 0)
	    return;

	d->freeze_count++;

	/* Get the current class and handler values */
	mt_class = EDVMimeTypeEditDlgGetClass(d);
	handler = (edv_mime_type_handler)PUListGetItemData(pulist, i);

	/* Update widgets depending on class */
	switch(handler)
	{
	  case EDV_MIME_TYPE_HANDLER_COMMAND:
	    switch(mt_class)
	    {
	      case EDV_MIME_TYPE_CLASS_SYSTEM:
		sensitive = FALSE;
		break;
	      case EDV_MIME_TYPE_CLASS_FORMAT:
	      case EDV_MIME_TYPE_CLASS_PROGRAM:
	      case EDV_MIME_TYPE_CLASS_UNIQUE:
		sensitive = TRUE;
		break;
	    }
	    break;
	  case EDV_MIME_TYPE_HANDLER_EDV_ARCHIVER:
	  case EDV_MIME_TYPE_HANDLER_EDV_IMAGE_BROWSER:
	  case EDV_MIME_TYPE_HANDLER_EDV_RECYCLE_BIN:
	    sensitive = FALSE;
	    break;
	}

	eclist = d->editclist;
	if(eclist != NULL)
	{
	    w = EDITCLIST_TOPLEVEL(eclist);
	    GTK_WIDGET_SET_SENSITIVE(w, sensitive);
	}

	d->freeze_count--;

	EDVMimeTypeEditDlgAnyChangedCB(NULL, data);
}

/*
 *      MIME Types edit window OK button callback.
 */
static void EDVMimeTypeEditDlgOKCB(
	GtkWidget *widget, gpointer data
)
{
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	EDVMimeTypeEditDlgApplyCB(NULL, d);
	EDVMimeTypeEditDlgUnmap(d);
}

/*
 *      MIME Types edit window Apply button callback.
 */
static void EDVMimeTypeEditDlgApplyCB(
	GtkWidget *widget, gpointer data
)
{
	GtkWidget *toplevel;
	GtkEntry *entry;
	GtkCList *clist;
	editclist_struct *eclist;
	gint mt_num;
	edv_mime_type_struct *mt;
	edv_mime_types_list_win_struct *lw;
	edv_mime_type_icon_picker_struct *ei;
	edv_core_struct *core;
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	toplevel = d->toplevel;
	lw = d->list_win;
	core = d->core;
	if((lw == NULL) || (core == NULL))
	    return;

	/* Get MIME Type being edited */
	mt_num = d->mt_num;
	mt = ((mt_num >= 0) && (mt_num < core->total_mimetypes)) ?
	    core->mimetype[mt_num] : NULL;

	/* Does the MIME Type no longer exist? */
	if(mt == NULL)
	{
	    EDVPlaySoundError(core);
	    EDVMessageError(
#if defined(PROG_LANGUAGE_SPANISH)
"Aplique Fallado",
"Este MIME Type no más largo existe, estos valores se tirarán.",
#elif defined(PROG_LANGUAGE_FRENCH)
"Appliquer Echoué",
"Ce MIME Type n'existe plu, les valeurs seront rejetées.",
#elif defined(PROG_LANGUAGE_GERMAN)
"Verwenden Sie Versagt".
"Dieser MIME Type werden nicht mehr, diese werte\n\
ausgeschieden werden existiert.",
#elif defined(PROG_LANGUAGE_ITALIAN)
"Applicare Fallito".
"Questo MIME Type non più esistere, questi valori saranno scartati.",
#elif defined(PROG_LANGUAGE_DUTCH)
"Pas Geverzuimenene Toe".
"Deze MIME Type zullen, deze waarde niet langer weggegooid\n\
worden bestaat.",
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Aplique Fracassado".
"Este MIME Type não existe mais, estes valores serão descartados.",
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Gjeld Sviktet".
"Denne MIME Type finnes ikke mer, disse verdiene kastet.",
#else
"Apply Failed",
"This MIME Type no longer exists, these values will be discarded.",
#endif
		NULL,
		toplevel
	    );
	    return;
	}

	/* MIME Type marked as read only? */
	if(mt->read_only)
	{
	    gchar *s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"MIME Type \"%s\" no se puede redactar, porque era ni\n\
creado internamente ni cargado de una configuración global."
#elif defined(PROG_LANGUAGE_FRENCH)
"Le Type MIME \"%s\" ne peut pas être édité, parce qu'il\n\
ou a été soit créé intérieurement soit chargé par la configuration\n\
globale."
#elif defined(PROG_LANGUAGE_GERMAN)
"MIME Type \"%s\" kann nicht redigiert werden, weil es\n\
war, entweder geschaffen inner oder kann von einer globalen\n\
konfiguration beladen werden."
#elif defined(PROG_LANGUAGE_ITALIAN)
"MIME Type \"%s\" non può essere redatto, perché era sia\n\
creato internamente o caricato da una configurazione globale."
#elif defined(PROG_LANGUAGE_DUTCH)
"MIME Type \"%s\" kun niet is geredigeerd, omdat het ofwel\n\
gecreëerde inwendig ofwel gelaade van een globale\n\
configuratie was."
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"\"%s\" de MIME Type não pode ser editado, porque ele\n\
qualquer um foi criado internamente nem foi carregado de uma\n\
configuração global."
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"MIME Type \"%s\" redigert ikke, fordi det var hver\n\
skape innvendig eller lastet fra en global konfigurasjon."
#else
"MIME Type \"%s\" cannot be edited, because it\n\
was either created internally or loaded from a global\n\
configuration."
#endif
		, mt->type
	    );
	    EDVPlaySoundWarning(core);
	    EDVMessageWarning(
#if defined(PROG_LANGUAGE_SPANISH)
"Aplique Fallado"
#elif defined(PROG_LANGUAGE_FRENCH)
"appliquer Echoué"
#elif defined(PROG_LANGUAGE_GERMAN)
"Verwenden Sie Versagt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Applicare Fallito"
#elif defined(PROG_LANGUAGE_DUTCH)
"Pas Geverzuimenene Toe"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Aplique Fracassado"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Gjeld Sviktet"
#else
"Apply Failed"
#endif
		, s, NULL,
		toplevel
	    );
	    g_free(s);
	    return;
	}


	/* Begin applying values */

	/* Class */
	mt->mt_class = EDVMimeTypeEditDlgGetClass(d);

	/* Type */
	entry = (GtkEntry *)d->type_entry;
	if(entry != NULL)
	{
	    const gchar *s = gtk_entry_get_text(entry);
	    if(s != NULL)
	    {
		g_free(mt->type);
		mt->type = STRDUP(s);
	    }
	}

	/* Value */
	entry = (GtkEntry *)d->value_entry;
	if(entry != NULL)
	{
	    const gchar *s = gtk_entry_get_text(entry);
	    if(s != NULL)
	    {
		g_free(mt->value);
		mt->value = STRDUP(s);
	    }
	}

	/* Description */
	entry = (GtkEntry *)d->description_entry;
	if(entry != NULL)
	{
	    const gchar *s = gtk_entry_get_text(entry);
	    if(s != NULL)
	    {
		g_free(mt->description);
		mt->description = STRDUP(s);
	    }
	}

	/* Handler */
	mt->handler = EDVMimeTypeEditDlgGetHandler(d);

	/* Commands */
	eclist = d->editclist;
	clist = (GtkCList *)EDITCLIST_CLIST(eclist);
	if(clist != NULL)
	{
	    gint i, n;
	    gchar *s;
	    edv_mime_type_command_struct *cmd;

	    /* Delete the old commands */
	    if(mt->commands_list != NULL)
	    {
		g_list_foreach(
		    mt->commands_list, (GFunc)EDVMimeTypeCommandDelete, NULL
		);
		g_list_free(mt->commands_list);
		mt->commands_list = NULL;
	    }

	    /* Adjust total commands on MIME Type structure and
	     * reallocate the command and command_name pointer arrays
	     * to the new size
	     */
	    n = clist->rows;
	    for(i = 0; i < n; i++)
	    {
		cmd = EDVMimeTypeCommandNew();
		if(cmd == NULL)
		    break;

		EditCListGetCellText(eclist, i, 0, &s);
		cmd->name = STRDUP(s);

		EditCListGetCellText(eclist, i, 1, &s);
		cmd->command = STRDUP(s);

		mt->commands_list = g_list_append(
		    mt->commands_list, cmd
		);
	    }
	}

	/* Begin applying icons file paths */

	/* Small icon */
	ei = d->icon_small;
	if(ei != NULL)
	{
	    gint i;
	    const gchar *s;

	    for(i = 0; i < EDV_MIME_TYPE_TOTAL_ICON_STATES; i++)
	    {
		s = ei->path[i];

		g_free(mt->small_icon_file[i]);
		mt->small_icon_file[i] = STRDUP(s);
	    }
	}

	/* Medium icon */
	ei = d->icon_medium;
	if(ei != NULL)
	{
	    gint i;
	    const gchar *s;

	    for(i = 0; i < EDV_MIME_TYPE_TOTAL_ICON_STATES; i++)
	    {
		s = ei->path[i];

		g_free(mt->medium_icon_file[i]);
		mt->medium_icon_file[i] = STRDUP(s);
	    }
	}

	/* Large icon */
	ei = d->icon_large;
	if(ei != NULL)
	{
	    gint i;
	    const gchar *s;

	    for(i = 0; i < EDV_MIME_TYPE_TOTAL_ICON_STATES; i++)
	    {
		s = ei->path[i];

		g_free(mt->large_icon_file[i]);
		mt->large_icon_file[i] = STRDUP(s);
	    }
	}

	/* Update time stamps */
	mt->access_time =
	mt->modify_time =
	mt->change_time = time(NULL);

	/* Check all of the MIME Type's values to see if they are any
	 * problems
	 */
	EDVMimeTypeEditDlgCheckMIMEType(
	    core,
	    core->mimetype, core->total_mimetypes,
	    mt_num,
	    TRUE, d->toplevel
	);


	/* Reset has changes marker */
	EDVMimeTypeEditDlgResetHasChanges(d, FALSE);


	/* Re-realize the MIME Type */
	EDVMimeTypeRealize(mt, TRUE);

	/* Send MIME Type modified signal to all of endeavour's resources */
	EDVMimeTypeModifiedEmit(core, mt_num, mt);
}

/*
 *      MIME Types edit window Cancel button callback.
 */
static void EDVMimeTypeEditDlgCancelCB(
	GtkWidget *widget, gpointer data
)
{
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(data);
	if(d == NULL)
	    return;

	EDVMimeTypeEditDlgUnmap(d);
}

/*
 *	Returns the current MIME Type class value set on the dialog.
 */
static edv_mime_type_class EDVMimeTypeEditDlgGetClass(
	edv_mime_type_edit_dlg_struct *d
)
{
	pulist_struct *pulist;
	pulistbox_struct *pulistbox;

	if(d == NULL)
	    return(EDV_MIME_TYPE_CLASS_SYSTEM);

	pulistbox = d->class_pulistbox;
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist == NULL)
	    return(EDV_MIME_TYPE_CLASS_SYSTEM);

	return((edv_mime_type_class)PUListGetItemData(
	    pulist, PUListBoxGetSelected(pulistbox)
	));
}

/*
 *	Returns the current MIME Type handler value set on the dialog.
 */
static edv_mime_type_handler EDVMimeTypeEditDlgGetHandler(
	edv_mime_type_edit_dlg_struct *d
)
{
	pulist_struct *pulist;
	pulistbox_struct *pulistbox;

	if(d == NULL)
	    return(EDV_MIME_TYPE_HANDLER_COMMAND);

	pulistbox = d->handler_pulistbox;
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist == NULL)
	    return(EDV_MIME_TYPE_HANDLER_COMMAND);

	return((edv_mime_type_handler)PUListGetItemData(
	    pulist, PUListBoxGetSelected(pulistbox)
	));
}


/*
 *	Checks all of the specified MIME Type's values to see if they
 *	are any problems
 *
 *	Returns non-zero if there was a problem.
 */
static gint EDVMimeTypeEditDlgCheckMIMEType(
	edv_core_struct *core,
	edv_mime_type_struct **list, const gint total,
	const gint mt_num,
	const gboolean verbose, GtkWidget *toplevel
)
{
	gint status = 0;
	edv_mime_type_class mt_class;
	const gchar *type, *val, *desc;
	edv_mime_type_handler handler;
	const gchar *title =
#if defined(PROG_LANGUAGE_SPANISH)
"MIME Type Advertencia"
#elif defined(PROG_LANGUAGE_FRENCH)
"MIME Type Avertissement"
#elif defined(PROG_LANGUAGE_GERMAN)
"MIME Type Warnen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"MIME Type L'avvertimento"
#elif defined(PROG_LANGUAGE_DUTCH)
"MIME Type Waarschuwen"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"MIME Type Aviso"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"MIME Type Varsling"
#else
"MIME Type Warning"
#endif
	;
	edv_mime_type_struct *mt;


	if((core == NULL) || (list == NULL))
	    return(status);

	/* Get pointer to the MIME Type from the MIME Types list */
	mt = ((mt_num >= 0) && (mt_num < total)) ?
	    list[mt_num] : NULL;
	/* Not in the list? */
	if(mt == NULL)
	{
	    status = -1;
	    if(verbose)
	    {
		gchar *s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"MIME Type con el índice #%i no está en la lista"
#elif defined(PROG_LANGUAGE_FRENCH)
"MIME Type avec l'index %i n'est pas dans la liste"
#elif defined(PROG_LANGUAGE_GERMAN)
"MIME Type mit index #%i ist nicht in der liste"
#elif defined(PROG_LANGUAGE_ITALIAN)
"MIME Type con #%i di indice non è nell'elenco"
#elif defined(PROG_LANGUAGE_DUTCH)
"MIME Type met index #%i is niet in de lijst"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"MIME Type com #%i de índice não está na lista"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"MIME Type med indeks #%i er ikke i listen"
#else
"MIME Type with index #%i is not in the list"
#endif
		    , mt_num
		);
		EDVPlaySoundError(core);
		EDVMessageError(title, s, NULL, toplevel);
		g_free(s);
	    }
	    return(status);
	}

	/* Get MIME Type's values */
	mt_class = mt->mt_class;
	type = mt->type;
	val = mt->value;
	desc = mt->description;
	handler = mt->handler;

	/* Check the MIME Type's type and value
	 *
	 * Handle by the MIME Type class
	 */
	switch(mt_class)
	{
	  case EDV_MIME_TYPE_CLASS_SYSTEM:
	    /* Is the Type defined? */
	    if(STRISEMPTY(type))
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s = STRDUP(
"The MIME Type's Type is not set, there will be no way to\n\
identify this MIME Type"
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    /* Value is ignored */
	    break;

	  case EDV_MIME_TYPE_CLASS_FORMAT:
	    /* Is the Type defined? */
	    if(STRISEMPTY(type))
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s = STRDUP(
"The MIME Type's Type is not set, there will be no way to\n\
identify this MIME Type"
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    /* Is the Value defined? */
	    if(STRISEMPTY(val))
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s = STRDUP(
"The MIME Type's Value is not set, this MIME Type will not\n\
identify any file formats"
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    /* Check handler
	     *
	     * Command?
	     */
	    if(handler == EDV_MIME_TYPE_HANDLER_COMMAND)
	    {
		const gchar *name, *command;
		GList *glist;
		edv_mime_type_command_struct *cmd;

		/* Check all the commands */
		for(glist = mt->commands_list;
		    glist != NULL;
		    glist = g_list_next(glist)
		)
		{
		    cmd = EDV_MIME_TYPE_COMMAND(glist->data);
		    if(cmd == NULL)
			continue;

		    name = cmd->name;
		    command = cmd->command;
		    if(command == NULL)
			continue;

		    /* Does the command not start with a path
		     * deliminator, suggesting that it refers to another
		     * MIME Type?
		     */
		    if(*command != G_DIR_SEPARATOR)
		    {
			/* This MIME Type refers to another MIME Type,
			 * so check if that MIME Type exists in the list
			 */
			edv_mime_type_struct *m_ref = EDVMimeTypesListMatchType(
			    list, total, NULL, command, TRUE
			);
			if(m_ref == NULL)
			{
			    /* Referenced MIME Type was not found */
			    status = -2;
			    if(verbose)
			    {
			        gchar *s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Ordene reffers de \"%s\" a un MIME Type\n\
inexistente llamó \"%s\"."
#elif defined(PROG_LANGUAGE_FRENCH)
"la commande \"%s\" fait référence à un MIME Type\n\
inexistant nommé \"%s\"."
#elif defined(PROG_LANGUAGE_GERMAN)
"Befehlen Sie \"%s\" reffers zu einem nicht\n\
vorhandenen MIME Type hat gerufen \"%s\"."
#elif defined(PROG_LANGUAGE_ITALIAN)
"Comandare il reffers di \"%s\" a un MIME Type\n\
non-esistente ha chiamato \"%s\"."
#elif defined(PROG_LANGUAGE_DUTCH)
"Beveel aan een onbestaande MIME Type\n\
\"%s\" reffers riep \"%s\"."
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Comande reffers de \"%s\" a um MIME Type\n\
inexistente chamou \"%s\"."
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Kommander \"%s\" reffers til en\n\
ikke-eksisterende MIME Type kalt \"%s\"."
#else
"Command \"%s\" refers to a non-existent MIME Type\n\
called \"%s\"."
#endif
				    , name, command
				);
				EDVPlaySoundWarning(core);
				EDVMessageWarning(
				    title, s, NULL,
				    toplevel
			        );
			        g_free(s);
			    }
		        }
		    }
		}	/* Check all defined commands */ 
	    }
	    break;

	  case EDV_MIME_TYPE_CLASS_PROGRAM:
	    /* Is the Type defined? */
	    if(STRISEMPTY(type))
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s = STRDUP(
"The MIME Type's Type is not set, there will be no way to\n\
identify this MIME Type"
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    /* Is the Value defined and refers to an object that is
	     * executable?
	     */
	    if(!STRISEMPTY(val) ? access(val, X_OK) : TRUE)
	    {
		/* Value not defined, object does not exist, or object
		 * is not executable
		 */
		status = -2;
		if(verbose)
		{
		    gchar *s;
		    if(STRISEMPTY(val))
#if defined(PROG_LANGUAGE_SPANISH)
			s = STRDUP(
"La ubicación de objeto de aplicación no conjunto"
			);
#elif defined(PROG_LANGUAGE_FRENCH)
			s = STRDUP(
"L'emplacement d'objet d'application pas série"
			);
#else
			s = STRDUP(
"Location of application object not set"
			);
#endif
		    else
			s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"El objeto inválido de la aplicación:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_FRENCH)
"Objet d'application invalide:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ungültiges anwendung objekt:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'oggetto di domanda di invalido:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_DUTCH)
"Ongeldig toepassing voorwerp:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O objeto de aplicação de inválido:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Ugyldig anvendelses objekt:\n\
\n\
    %s"
#else
"Invalid application object:\n\
\n\
    %s"
#endif
			    , val
			);
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(
			title, s,
#if defined(PROG_LANGUAGE_SPANISH)
"El objeto de la aplicación no se define, no existe, ni no es puesto\n\
executable. También, se cerciora que usted especifica un sendero\n\
repleto al objeto de la aplicación."
#elif defined(PROG_LANGUAGE_FRENCH)
"L'application n'est pas défini, ou n'existe pas, ou n'est pas\n\
executable. Aussi, assurez-vous que vous spécifiez le répertoire complet\n\
d'accès à l'application."
#elif defined(PROG_LANGUAGE_GERMAN)
"Das anwendung objekt ist nicht definiert, existiert nicht, oder ist\n\
nicht ausführbar gesetzt. Vergewissern sie auch sich, daß Sie einen\n\
vollen pfad zum anwendung objekt angeben."
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'oggetto di domanda non è definito, non esiste, o non è regolato\n\
eseguibile. , Assicura anche che lei specifica un sentiero pieno\n\
all'oggetto di domanda."
#elif defined(PROG_LANGUAGE_DUTCH)
"Het toepassing voorwerp is niet gedefinieerd, niet bestaat of niet\n\
is uitvoerbaar gezet. Vergewis ook zich ervan dat u een vol pad aan\n\
het toepassing voorwerp specificeert."
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O objeto de aplicação não é definido, não existe, nem não é posto\n\
executable. Também, assegure-se que especifica um pleno caminho ao\n\
objeto de aplicação."
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Anvendelsesobjektet ikke-definert, finnes ikke, eller ikke setter\n\
gjennomførbar. Sjekk også at De spesifiserer en full sti til\n\
anvendelses objektet."
#else
"The application object is not defined, does not exist, or is not\n\
set executable. Also, make sure that you specify a full path to\n\
the application object."
#endif
			, toplevel
		    );
		    g_free(s);
		}
	    }
	    /* Is the handler set to EDV_MIME_TYPE_HANDLER_COMMAND and
	     * does it have at least one defined command?
	     */
	    if((handler == EDV_MIME_TYPE_HANDLER_COMMAND) ?
		(mt->commands_list == NULL) : FALSE
	    )
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s;
#if defined(PROG_LANGUAGE_SPANISH)
			s = STRDUP(
"Ninguna orden se ha definido en esta clase de la\n\
aplicación MIME Type, este MIME Type no será capaz de\n\
ejecutar la aplicación reffers a."
			);
#elif defined(PROG_LANGUAGE_FRENCH)
			s = STRDUP(
"Aucune commande n'a été définie pour cette classe d'application MIME Type\n\
, le MIME Type ne pourra pas donc\n\
exécuter l'application auquel il se réfère."
			);
#else
			s = STRDUP(
"No command has been defined on this application\n\
class MIME Type, this MIME Type will not be able to\n\
execute the application that it refers to."
			);
#endif
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    break;

	  case EDV_MIME_TYPE_CLASS_UNIQUE:
	    /* Is the Type defined? */
	    if(STRISEMPTY(type))
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s = STRDUP(
"The MIME Type's Type is not set, there will be no way to\n\
identify this MIME Type"
		    );
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(title, s, NULL, toplevel);
		    g_free(s);
		}
	    }
	    /* Is the Value defined and reffers to a valid object? */
	    if(!STRISEMPTY(val) ? access(val, F_OK) : TRUE)
	    {
		status = -2;
		if(verbose)
		{
		    gchar *s;
		    if(STRISEMPTY(val))
#if defined(PROG_LANGUAGE_SPANISH)
			s = STRDUP(
"La ubicación de objeto extraordinario no conjunto"
			);
#elif defined(PROG_LANGUAGE_FRENCH)
			s = STRDUP(
"L'emplacement de l'objet spécifique n'est pas défini"
			);
#else
			s = STRDUP(
"Location of specific object not set"
			);
#endif
		    else
			s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Incapaz de encontrar objeto:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_FRENCH)
"Impossible de trouver l'objet:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_GERMAN)
"Unfähig, objec zu finden:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Incapace per trovare l'objec:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_DUTCH)
"Onbekwaam objec te vinden:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Incapaz de achar objec:\n\
\n\
    %s"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Maktesløs finne objec:\n\
\n\
    %s"
#else
"Unable to find object:\n\
\n\
    %s"
#endif
			    , val
			);
		    EDVPlaySoundWarning(core);
		    EDVMessageWarning(
			title, s,
#if defined(PROG_LANGUAGE_SPANISH)
"El objeto extraordinario no se define ni no aparece existir. Si\n\
se define y existe, entonces cheque si sus permisos no permiten\n\
ser conseguido acceso a."
#elif defined(PROG_LANGUAGE_FRENCH)
"L'objet spécifique n'est pas défini ou ne semble pas exister. S'il\n\
est défini et existe, alors ses permissions ne\n\
permettent pas d'y accéder."
#elif defined(PROG_LANGUAGE_GERMAN)
"Das spezifische objekt ist nicht definiert oder nicht erscheint zu\n\
existieren. Wenn es dann kontrolle definiert und ist existiert ist,\n\
wenn seine erlaubnis nicht erlaubt, daß es auf zugegriffen wird."
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'oggetto specifico non è definito o non appare esistere. Se è\n\
definito ed esiste poi l'assegno se i suoi permessi non lasciano che\n\
esso essere accesso a."
#elif defined(PROG_LANGUAGE_DUTCH)
"Het specifiek voorwerp is niet gedefinieerd of niet verschijnt te\n\
bestaan. Indien het dan controle gedefinieerd en is bestaan is indien\n\
zijne toestemmingen niet toestaan dat het toegang tot te worden\n\
gehad."
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O objeto específico não é definido nem não aparece existir. Se é\n\
definido e existe então cheque se seuas permissões não permitem ser\n\
acedido."
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Det spesifikke ikke-definerte objektet eller kommer ikke fram\n\
dinnes. Om det definerer og finnes da kontroll om dets tillatelse\n\
ikke tillater det kommet til."
#else
"The specific object is not defined or does not appear to exist. If\n\
it is defined and exists then check if its permissions do not\n\
allow it to be accessed."
#endif
			, toplevel
		    );
		    g_free(s);
		}
	    }
	    break;

	  default:
	    status = -2;
	    if(verbose)
	    {
		gchar *s = g_strdup_printf(
#if defined(PROG_LANGUAGE_SPANISH)
"Código `%i' no apoyado de clase de MIME Type."
#elif defined(PROG_LANGUAGE_FRENCH)
"Le code de la classe MIME Type `%i' n'est pas supporté."
#else
"Unsupported MIME Type class code `%i'."
#endif
		    , mt_class
		);
		EDVPlaySoundError(core);
		EDVMessageError(title, s, NULL, toplevel);
		g_free(s);
	    }
	    break;
	}

	return(status);
}

/*
 *	Gets the values from the MIME Type and sets them to the
 *	dialog.
 *
 *	The mt_num specifies the MIME Type.
 */
void EDVMimeTypeEditDlgGetValues(
	edv_mime_type_edit_dlg_struct *d, const gint mt_num
)
{
	GtkEntry *entry;
	GtkCList *clist;
	pulist_struct *pulist;
	pulistbox_struct *pulistbox;
	editclist_struct *eclist;
	edv_mime_type_struct *mt;
	edv_core_struct *core;
	edv_mime_type_icon_picker_struct *ei;

	if(d == NULL)
	    return;

	core = d->core;
	if(core == NULL)
	    return;

	/* Get pointer to MIME Type structure on core's MIME Types list */
	if((mt_num < 0) || (mt_num >= core->total_mimetypes))
	    return;
	else
	    mt = core->mimetype[mt_num];
	if(mt == NULL)
	    return;


	/* Begin fetching values */

	/* Set MIME Type index on core structure from the given mt_num */
	d->mt_num = mt_num;

	/* Class */
	pulistbox = d->class_pulistbox;
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist != NULL)
	{
	    gint i;
	    const gint m = PUListGetTotalItems(pulist);
	    edv_mime_type_class mt_class;

	    for(i = 0; i < m; i++)
	    {
		mt_class = (edv_mime_type_class)PUListGetItemData(pulist, i);
		if(mt_class == mt->mt_class)
		{
		    PUListBoxSelect(pulistbox, i);
		    EDVMimeTypeEditDlgClassChangedCB(pulistbox, i, d);
		    break;
		}
	    }
	}

	/* Type */
	entry = (GtkEntry *)d->type_entry;
	if(entry != NULL)
	{
	    gtk_entry_set_text(
		entry,
		(mt->type != NULL) ? mt->type : ""
	    );
	}

	/* Value */
	entry = (GtkEntry *)d->value_entry;
	if(entry != NULL)
	{
	    gtk_entry_set_text(
		entry,
		(mt->value != NULL) ? mt->value : ""
	    );
	}

	/* Description */
	entry = (GtkEntry *)d->description_entry;
	if(entry != NULL)
	{
	    gtk_entry_set_text(
		entry,
		(mt->description != NULL) ? mt->description : ""
	    );
	}

	/* Handler */
	pulistbox = d->handler_pulistbox;
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist != NULL)
	{
	    gint i;
	    const gint m = PUListGetTotalItems(pulist);
	    edv_mime_type_handler handler;

	    for(i = 0; i < m; i++)
	    {
		handler = (edv_mime_type_handler)PUListGetItemData(pulist, i);
		if(handler == mt->handler)
		{
		    PUListBoxSelect(pulistbox, i);
		    EDVMimeTypeEditDlgHandlerChangedCB(pulistbox, i, d);
		    break;
		}
	    }
	}

	/* Commands */
	eclist = d->editclist;
	clist = (GtkCList *)EditCListGetCList(eclist);
	if(clist != NULL)
	{
	    gint row;
	    GList *glist;
	    edv_mime_type_command_struct *cmd;

	    gtk_clist_freeze(clist);

	    /* Clear list */
	    EditCListClear(eclist);

	    /* Append the commands */
	    for(glist = mt->commands_list;
		glist != NULL;
		glist = g_list_next(glist)
	    )
	    {
		cmd = EDV_MIME_TYPE_COMMAND(glist->data);
		if(cmd == NULL)
		    continue;

		row = EditCListAppendRow(eclist);
		EditCListSetCellText(
		    eclist, row, 0, cmd->name
		);
		EditCListSetCellText(
		    eclist, row, 1, cmd->command
		);
	    }

	    gtk_clist_thaw(clist);
	}


	/* Begin loading icons */

#define DO_LOAD_ICON	{				\
 gint i;						\
 for(i = 0; i < EDV_MIME_TYPE_TOTAL_ICON_STATES; i++) {	\
  /* Unref existing pixmap and mask on the Edit		\
   * Window's Icon Picker				\
   */							\
  if(ei->pixmap[i] != NULL)				\
   gdk_pixmap_unref(ei->pixmap[i]);			\
  if(ei->mask[i] != NULL)				\
   gdk_bitmap_unref(ei->mask[i]);			\
							\
  /* Increase ref count on new pixmap and mask and set	\
   * if to the Edit Window's Icon Picker		\
   */							\
  if(pixmap[i] != NULL)					\
   gdk_pixmap_ref(pixmap[i]);				\
  if(mask[i] != NULL)					\
   gdk_bitmap_ref(mask[i]);				\
							\
  ei->pixmap[i] = pixmap[i];				\
  ei->mask[i] = mask[i];				\
							\
  /* Set icon path */					\
  g_free(ei->path[i]);					\
  ei->path[i] = STRDUP(path[i]);			\
 }							\
}

	/* Small icons */
	ei = d->icon_small;
	if(ei != NULL)
	{
	    GdkPixmap **pixmap = mt->small_pixmap;
	    GdkBitmap **mask = mt->small_mask;
	    gchar **path = mt->small_icon_file;

	    if(ei->adj != NULL)
		ei->adj->value = 0.0f;

	    DO_LOAD_ICON

	    if(ei->adj != NULL)
		EDVMimeTypeEditDlgIconUpdateDisplay(
		    ei, (edv_mime_type_icon_state)ei->adj->value
		);
	}

	/* Medium icons */
	ei = d->icon_medium;
	if(ei != NULL)
	{
	    GdkPixmap **pixmap = mt->medium_pixmap;
	    GdkBitmap **mask = mt->medium_mask;
	    gchar **path = mt->medium_icon_file;

	    if(ei->adj != NULL)
		ei->adj->value = 0.0f;

	    DO_LOAD_ICON

	    if(ei->adj != NULL)
		EDVMimeTypeEditDlgIconUpdateDisplay(
		    ei, (edv_mime_type_icon_state)ei->adj->value
		);
	}

	/* Large icons */
	ei = d->icon_large;
	if(ei != NULL)
	{
	    GdkPixmap **pixmap = mt->large_pixmap;
	    GdkBitmap **mask = mt->large_mask;
	    gchar **path = mt->large_icon_file;

	    if(ei->adj != NULL)
		ei->adj->value = 0.0f;

	    DO_LOAD_ICON

	    if(ei->adj != NULL)
		EDVMimeTypeEditDlgIconUpdateDisplay(
		    ei, (edv_mime_type_icon_state)ei->adj->value
		);
	}

#undef DO_LOAD_ICON


	EDVMimeTypeEditDlgUpdateMenus(d);
}


/*
 *      Notifies the given MIME Types list window that the given MIME Type
 *      has been removed.
 */
void EDVMimeTypeEditDlgMimeTypeRemovedCB(
	edv_mime_type_edit_dlg_struct *d, gint mt_num
)
{
	if(d == NULL)
	    return;

	/* If the removed MIME Type is the MIME Type that this edit window
	 * is displaying values for then this edit window needs to be
	 * unmapped
	 */
	if(d->mt_num == mt_num)
	{
	    d->mt_num = -1;
	    EDVMimeTypeEditDlgUnmap(d);
	}
}


/*
 *	Creates a new Icon Picker.
 */
static edv_mime_type_icon_picker_struct *EDVMimeTypeEditDlgIconNew(
	gpointer editwin, GtkWidget *parent, const gchar *title,
	gint icon_width, gint icon_height,
	gint btn_width, gint btn_height
)
{
	gint bw = 20, bh = 20;
	GtkAdjustment *adj;
	GtkWidget *w, *parent2, *parent3, *parent4;
	edv_mime_type_icon_picker_struct *ei = EDV_MIME_TYPE_ICON_PICKER(
	    g_malloc0(sizeof(edv_mime_type_icon_picker_struct))
	);
	if(ei == NULL)
	    return(ei);

	/* Reset values */
	ei->d = editwin;
	ei->icon_width = icon_width;
	ei->icon_height = icon_height;

	/* Create adjustment for keeping track of displayed icon */
	ei->adj = adj = (GtkAdjustment *)gtk_adjustment_new(
	    0.0f,		/* Value */
	    0.0f,		/* Lower */
	    (gfloat)EDV_MIME_TYPE_TOTAL_ICON_STATES - 1.0f,	/* Upper */
	    1.0f, 1.0f,		/* Step and page increments */
	    1.0f		/* Page size */
	);

	/* Create toplevel */
	ei->toplevel = w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for title label */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent3 = w;
	/* Label */
	w = gtk_label_new(title);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


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

	/* Create button */
	ei->button = w = gtk_button_new();
	gtk_widget_set_usize(w, btn_width, btn_height);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgIconChangeCB), ei
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, FALSE, 0);
	gtk_widget_show(w);
	parent3 = w;
#if 0
	ei->gtk_pixmap = w = gtk_pixmap_new(NULL, NULL);
	gtk_container_add(GTK_CONTAINER(parent3), w);
	gtk_widget_show(w);
#endif


	/* Hbox for buttons and labels */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent3 = w;


	/* Left button */
	ei->left_btn = w = gtk_button_new();
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgIconPrevCB), ei
	);
	gtk_widget_set_usize(w, bw, bh);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;
	/* Arrow */
	w = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_OUT);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);

	/* Frame for state label */
	w = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_OUT);
	gtk_widget_set_usize(w, 80, -1);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;
	/* State label */
	ei->state_label = w = gtk_label_new("");
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);

	/* Right button */
	ei->right_btn = w = gtk_button_new();
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgIconNextCB), ei
	);
	gtk_widget_set_usize(w, bw, bh);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;
	/* Arrow */
	w = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);


	return(ei);
}

/*
 *	Deletes the Icon Picker.
 */
static void EDVMimeTypeEditDlgIconDelete(edv_mime_type_icon_picker_struct *ei)
{
	gint i;

	if(ei == NULL)
	    return;

	/* Unref all loaded pixmap and mask pairs */
	for(i = 0; i < EDV_MIME_TYPE_TOTAL_ICON_STATES; i++)
	{
	    GDK_PIXMAP_UNREF(ei->pixmap[i])
	    GDK_BITMAP_UNREF(ei->mask[i])
	    g_free(ei->path[i]);
	}

	/* Begin destroying widgets */
	GTK_WIDGET_DESTROY(ei->gtk_pixmap)
	GTK_WIDGET_DESTROY(ei->button)
	GTK_WIDGET_DESTROY(ei->left_btn)
	GTK_WIDGET_DESTROY(ei->right_btn)
	GTK_WIDGET_DESTROY(ei->state_label)
	GTK_WIDGET_DESTROY(ei->toplevel)

	GTK_OBJECT_UNREF(ei->adj)

	g_free(ei);
}


/*
 *	Creates a new MIME Types edit window.
 */
edv_mime_type_edit_dlg_struct *EDVMimeTypeEditDlgNew(
	edv_core_struct *core, edv_mime_types_list_win_struct *lw
)
{
	const gint	border_major = 5,
			border_minor = 2;
	gchar *heading[2];
	gpointer entry_rtn, label_rtn;
	GdkWindow *window;
	GtkAccelGroup *accelgrp;
	GtkWidget *w, *parent, *parent2, *parent3, *parent4, *parent5;
	GtkCList *clist;
	pulist_struct *pulist;
	pulistbox_struct *pulistbox;
	editclist_struct *eclist;
	edv_mime_type_edit_dlg_struct *d = EDV_MIME_TYPE_EDIT_DLG(
	    g_malloc0(sizeof(edv_mime_type_edit_dlg_struct))
	);
	if((d == NULL) || (core == NULL))
	{
	    g_free(d);
	    return(NULL);
	}

	d->accelgrp = accelgrp = gtk_accel_group_new();
	d->processing = FALSE;
	d->freeze_count = 0;
	d->busy_count = 0;
	d->core = core;

	d->list_win = lw;

	d->has_changes = FALSE;
	d->title = NULL;

	d->mt_num = -1;


	/* Set title */
	d->title = STRDUP(EDITWIN_TITLE);


	/* Begin creating widgets */

	/* Toplevel */
	d->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_widget_set_usize(w, EDITWIN_WIDTH, EDITWIN_HEIGHT);
	gtk_window_set_wmclass(
	    GTK_WINDOW(w), "dialog", PROG_NAME
	);
	gtk_widget_realize(w);
	window = w->window;
	if(window != NULL)
	{
	    gdk_window_set_decorations(
		window,
		GDK_DECOR_BORDER | GDK_DECOR_TITLE | GDK_DECOR_MENU |
		GDK_DECOR_MINIMIZE
	    );
	    gdk_window_set_functions(
		window,
		GDK_FUNC_MOVE | GDK_FUNC_MINIMIZE | GDK_FUNC_CLOSE
	    );
	    GUISetWMIcon(window, (guint8 **)icon_mimetypes_48x48_xpm);
	}
	gtk_widget_add_events(
	    w,
	    GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
	    GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "delete_event",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgDeleteEventCB), d
	);
	gtk_container_border_width(GTK_CONTAINER(w), 0);
	gtk_window_add_accel_group(GTK_WINDOW(w), accelgrp);
	parent = w;


	/* Main vbox */
	d->main_vbox = w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_container_add(GTK_CONTAINER(parent), w);
	gtk_widget_show(w);
	parent = w;


	/* Hbox to split things into two columns */
	w = gtk_hbox_new(FALSE, border_major);
	gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent2 = w;


	/* Left side vbox */
	w = gtk_vbox_new(FALSE, border_major);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent3 = w;


	/* Class Frame */
	w = gtk_frame_new(
#if defined(PROG_LANGUAGE_SPANISH)
"La Clase"
#elif defined(PROG_LANGUAGE_FRENCH)
"Classe"
#elif defined(PROG_LANGUAGE_GERMAN)
"Klasse"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Classe"
#elif defined(PROG_LANGUAGE_DUTCH)
"Klas"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Classe"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Klasse"
#else
"Class"
#endif
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;

	w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);
	parent4 = w;

	/* Class popup list box */
	d->class_pulistbox = pulistbox = PUListBoxNew(
	    parent4, -1, -1
	);
	PUListBoxSetChangedCB(
	    pulistbox,
	    EDVMimeTypeEditDlgClassChangedCB, d
	);
	PUListBoxMap(pulistbox);
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist != NULL)
	{
	    gint i;

	    i = PUListAddItem(
		pulist,
		"System Object Type"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_CLASS_SYSTEM);
	    i = PUListAddItem(
		pulist,
		"File Format"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_CLASS_FORMAT);
	    i = PUListAddItem(
		pulist,
		"Application"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_CLASS_PROGRAM);
	    i = PUListAddItem(
		pulist,
		"Specific Object"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_CLASS_UNIQUE);

	    PUListBoxSetLinesVisible(pulistbox, i + 1);
	}


	/* Identification frame */
	w = gtk_frame_new(
#if defined(PROG_LANGUAGE_SPANISH)
"Identificación"
#elif defined(PROG_LANGUAGE_FRENCH)
"Identification"
#elif defined(PROG_LANGUAGE_GERMAN)
"Identifikation"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Identificazione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Identificatie"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Identificação"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Identification"
#else
"Identification"
#endif
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;

	w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);
	parent4 = w;

	/* Type entry */
	w = GUIPromptBar(
	    NULL,
#if defined(PROG_LANGUAGE_SPANISH)
"El Tipo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Type"
#elif defined(PROG_LANGUAGE_GERMAN)
"Typ"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Tipo"
#elif defined(PROG_LANGUAGE_DUTCH)
"Type"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Tipo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Type"
#else
"Type"
#endif
	    ":", NULL, &entry_rtn
	);
	d->type_entry = (GtkWidget *)entry_rtn;
	gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	w = (GtkWidget *)entry_rtn;
	EDVEntrySetDND(core, w);
	gtk_signal_connect(
	    GTK_OBJECT(w), "changed",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgAnyChangedCB), d
	);


	/* Value entry */
	w = GUIPromptBar(
	    NULL,
#if defined(PROG_LANGUAGE_SPANISH)
"El Valor"
#elif defined(PROG_LANGUAGE_FRENCH)
"Valeur"
#elif defined(PROG_LANGUAGE_GERMAN)
"Wert"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Valore"
#elif defined(PROG_LANGUAGE_DUTCH)
"Waarde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Valor"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Verdi"
#else
"Value"
#endif
	    ":", &label_rtn, &entry_rtn
	);
	d->value_label = (GtkWidget *)label_rtn;
	d->value_entry = (GtkWidget *)entry_rtn;
	gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	w = (GtkWidget *)entry_rtn;
	EDVEntrySetDND(core, w);
	gtk_signal_connect(
	    GTK_OBJECT(w), "changed",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgAnyChangedCB), d
	);


	/* Description entry */
	w = GUIPromptBar(
	    NULL,
#if defined(PROG_LANGUAGE_SPANISH)
"La Descripción"
#elif defined(PROG_LANGUAGE_FRENCH)
"Description"
#elif defined(PROG_LANGUAGE_GERMAN)
"Beschreibung"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Descrizione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Beschrijving"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Descrição"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Beskrivelse"
#else
"Description"
#endif
	    ":", NULL, &entry_rtn
	);
	d->description_entry = (GtkWidget *)entry_rtn;
	gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	w = (GtkWidget *)entry_rtn;
	EDVEntrySetDND(core, w);
	gtk_signal_connect(
	    GTK_OBJECT(w), "changed",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgAnyChangedCB), d
	);


	/* Handler frame */
	w = gtk_frame_new(
#if defined(PROG_LANGUAGE_SPANISH)
"El Tratante"
#elif defined(PROG_LANGUAGE_FRENCH)
"Agent"
#elif defined(PROG_LANGUAGE_GERMAN)
"Behandler"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Addestratore"
#elif defined(PROG_LANGUAGE_DUTCH)
"Handler"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Manipulador"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Behandler"
#else
"Handler"
#endif
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;

	w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);
	parent4 = w;


	/* Handle By GtkHBox */
	w = gtk_hbox_new(FALSE, border_minor);
	gtk_box_pack_start(GTK_BOX(parent4), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent5 = w;

	/* Label */
	w = gtk_label_new("Handle By:");
	gtk_box_pack_start(GTK_BOX(parent5), w, FALSE, FALSE, 0);
	gtk_widget_show(w);

	/* Popup list box */
	d->handler_pulistbox = pulistbox = PUListBoxNew(
	    parent5, -1, -1
	);
	PUListBoxSetChangedCB(
	    pulistbox,
	    EDVMimeTypeEditDlgHandlerChangedCB, d
	);
	PUListBoxMap(pulistbox);
	pulist = PUListBoxGetPUList(pulistbox);
	if(pulist != NULL)
	{
	    gint i;

	    i = PUListAddItem(
		pulist,
		"Command"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_HANDLER_COMMAND);
	    i = PUListAddItem(
		pulist,
		"Endeavour Archiver"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_HANDLER_EDV_ARCHIVER);
	    i = PUListAddItem(
		pulist,
		"Endeavour Image Browser"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_HANDLER_EDV_IMAGE_BROWSER);
	    i = PUListAddItem(
		pulist,
		"Endeavour Recycle Bin"
	    );
	    PUListSetItemData(pulist, i, (gpointer)EDV_MIME_TYPE_HANDLER_EDV_RECYCLE_BIN);

	    PUListBoxSetLinesVisible(pulistbox, i + 1);
	}

	/* Commands editable clist */
#if defined(PROG_LANGUAGE_SPANISH)
heading[0] = "El Nombre";
heading[1] = "La Orden";
#elif defined(PROG_LANGUAGE_FRENCH)
heading[0] = "Nom";
heading[1] = "Commande";
#elif defined(PROG_LANGUAGE_GERMAN)
heading[0] = "Name";
heading[1] = "Befehl";
#elif defined(PROG_LANGUAGE_ITALIAN)
heading[0] = "Il Nome";
heading[1] = "Il Comando";
#elif defined(PROG_LANGUAGE_DUTCH)
heading[0] = "Naam";
heading[1] = "Bevel";
#elif defined(PROG_LANGUAGE_PORTUGUESE)
heading[0] = "O Nome";
heading[1] = "O Comando";
#elif defined(PROG_LANGUAGE_NORWEGIAN)
heading[0] = "Navn";
heading[1] = "Kommando";
#else
heading[0] = "Name";
heading[1] = "Command";
#endif
	d->editclist = eclist = EditCListNew(
	    parent4, -1, 120,
	    FALSE, FALSE, 0,
	    heading, 2
	);
	clist = (GtkCList *)EDITCLIST_CLIST(eclist);
	gtk_clist_set_column_width(clist, 0, 80);
	gtk_clist_set_column_width(clist, 1, 230);
	gtk_clist_column_titles_passive(clist);
	gtk_clist_set_row_height(clist, EDV_LIST_ROW_SPACING);
	gtk_clist_set_shadow_type(clist, GTK_SHADOW_IN);
	EditCListSetRowAddedCB(
	    eclist,
	    EDVMimeTypeEditDlgECListRowAddedCB, d
	);
	EditCListSetCellChangedCB(
	    eclist,
	    EDVMimeTypeEditDlgECListCellChangedCB, d
	);
	EditCListSetRowRemovedCB(
	    eclist,
	    EDVMimeTypeEditDlgECListRowRemovedCB, d
	);
	EditCListMap(eclist);



	/* Right side vbox */
	w = gtk_vbox_new(FALSE, border_major);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent3 = w;

	/* Icons frame */
	w = gtk_frame_new(
#if defined(PROG_LANGUAGE_SPANISH)
"Iconos"
#elif defined(PROG_LANGUAGE_FRENCH)
"Icône"
#elif defined(PROG_LANGUAGE_GERMAN)
"Abbilder"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Le Icone"
#elif defined(PROG_LANGUAGE_DUTCH)
"Beelden"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Os ícones"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Ikoner"
#else
"Icons"
#endif
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent4 = w;

	w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_container_add(GTK_CONTAINER(parent4), w);
	gtk_widget_show(w);
	parent4 = w;


	/* Create icon structures */
	d->icon_large = EDVMimeTypeEditDlgIconNew(
	    d, parent4,
#if defined(PROG_LANGUAGE_SPANISH)
"Grande"
#elif defined(PROG_LANGUAGE_FRENCH)
"Grand"
#elif defined(PROG_LANGUAGE_GERMAN)
"Groß"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Grande"
#elif defined(PROG_LANGUAGE_DUTCH)
"Groot"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Grande"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Stor"
#else
"Large"
#endif
	    " 48x48:",
	    48, 48,
	    54, 54
	);
	d->icon_medium = EDVMimeTypeEditDlgIconNew(
	    d, parent4,
#if defined(PROG_LANGUAGE_SPANISH)
"El Medio"
#elif defined(PROG_LANGUAGE_FRENCH)
"Moyen"
#elif defined(PROG_LANGUAGE_GERMAN)
"Medium"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Mezzo"
#elif defined(PROG_LANGUAGE_DUTCH)
"Middel"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Médio"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Middel"
#else
"Medium"
#endif
	    " 32x32:",
	    32, 32,
	    38, 38
	);
	d->icon_small = EDVMimeTypeEditDlgIconNew(
	    d, parent4,
#if defined(PROG_LANGUAGE_SPANISH)
"Pequeño"
#elif defined(PROG_LANGUAGE_FRENCH)
"Petit"
#elif defined(PROG_LANGUAGE_GERMAN)
"Klein"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Piccolo"
#elif defined(PROG_LANGUAGE_DUTCH)
"Klein"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Pequeno"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Liten"
#else
"Small"
#endif
	    " 20x20:",
	    20, 20,
	    26, 26
	);


	/* Horizontal separator */
	w = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);


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

	/* OK button */
	d->ok_btn = w = GUIButtonPixmapLabelH(
	    (guint8 **)icon_ok_20x20_xpm, "OK", NULL
	);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_widget_set_usize(
	    w,
	    GUI_BUTTON_HLABEL_WIDTH_DEF, GUI_BUTTON_HLABEL_HEIGHT_DEF
	);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgOKCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_o, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	GUIButtonLabelUnderline(w, GDK_o);
	gtk_widget_show(w);

	/* Apply button */
	d->apply_btn = w = GUIButtonPixmapLabelH(
	    (guint8 **)icon_select_20x20_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Aplique"
#elif defined(PROG_LANGUAGE_FRENCH)
"Appliquer"
#elif defined(PROG_LANGUAGE_GERMAN)
"Verwenden"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Applicare"
#elif defined(PROG_LANGUAGE_DUTCH)
"Toepas"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Aplique"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Gjeld"
#else
"Apply"
#endif
	    , NULL
	);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_widget_set_usize(
	    w,
	    GUI_BUTTON_HLABEL_WIDTH_DEF, GUI_BUTTON_HLABEL_HEIGHT_DEF
	);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgApplyCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_a, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	GUIButtonLabelUnderline(w, GDK_a);
	gtk_widget_show(w);

	/* Cancel button */
	d->cancel_btn = w = GUIButtonPixmapLabelH(
	    (guint8 **)icon_cancel_20x20_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Cancele"
#elif defined(PROG_LANGUAGE_FRENCH)
"Annuler"
#elif defined(PROG_LANGUAGE_GERMAN)
"Heben"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Annullare"
#elif defined(PROG_LANGUAGE_DUTCH)
"Annuleer"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Cancelamento"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Kanseller"
#else
"Cancel"
#endif
	    , NULL
	);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_widget_set_usize(
	    w,
	    GUI_BUTTON_HLABEL_WIDTH_DEF, GUI_BUTTON_HLABEL_HEIGHT_DEF
	);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgCancelCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	gtk_accel_group_add(
	    accelgrp, GDK_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	GUIButtonLabelUnderline(w, GDK_c);
	gtk_widget_show(w);

	/* Close button */
	d->close_btn = w = GUIButtonPixmapLabelH(
	    (guint8 **)icon_close_20x20_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Cierre"
#elif defined(PROG_LANGUAGE_FRENCH)
"Quitter"
#elif defined(PROG_LANGUAGE_GERMAN)
"Nah"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Vicino"
#elif defined(PROG_LANGUAGE_DUTCH)
"Einde"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Próximo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Nær"
#else
"Close"
#endif
	    , NULL
	);
	GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
	gtk_widget_set_usize(
	    w,
	    GUI_BUTTON_HLABEL_WIDTH_DEF, GUI_BUTTON_HLABEL_HEIGHT_DEF
	);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "clicked",
	    GTK_SIGNAL_FUNC(EDVMimeTypeEditDlgCancelCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	gtk_accel_group_add(
	    accelgrp, GDK_c, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	GUIButtonLabelUnderline(w, GDK_c);
	gtk_widget_show(w);


	EDVMimeTypeEditDlgUpdateMenus(d);


	return(d);
}

/*
 *	Resets the MIME Types Edit Window's has changes marker.
 */
void EDVMimeTypeEditDlgResetHasChanges(
	edv_mime_type_edit_dlg_struct *d, gboolean has_changes
)
{
	if(d == NULL)
	    return;

	if(d->has_changes == has_changes)
	    return;

	d->has_changes = has_changes;
	EDVMimeTypeEditDlgUpdateMenus(d);
}

/*
 *	Updates the MIE Types Edit Window's widgets to reflect current
 *	values.
 */
void EDVMimeTypeEditDlgUpdateMenus(edv_mime_type_edit_dlg_struct *d)
{
	gboolean	sensitive,
			has_changes;
	gint mt_num;
	const edv_mime_type_struct *mt;
	GtkWidget *w;
	editclist_struct *eclist;
	edv_core_struct *core;

	if(d == NULL)
	    return;

	eclist = d->editclist;
	core = d->core;
	if((eclist == NULL) || (core == NULL))
	    return;

	has_changes = d->has_changes;
	mt_num = d->mt_num;
	if((mt_num >= 0) && (mt_num < core->total_mimetypes))
	    mt = core->mimetype[mt_num];
	else
	    mt = NULL;

#define MAP(w)                  \
{ if((w) != NULL) { gtk_widget_show(w); } }
#define UNMAP(w)                \
{ if((w) != NULL) { gtk_widget_hide(w); } }

	/* Update title */
	w = d->toplevel;
	if(w != NULL)
	{
	    gchar *title = g_strdup_printf(
		"%s%s",
		STRISEMPTY(d->title) ? "Untitled" : d->title,
		(has_changes) ? " (*)" : ""
	    );
	    gtk_window_set_title(GTK_WINDOW(w), title);
	    g_free(title);
	}

	/* Edit CList */
	EditCListUpdateMenus(eclist);

	/* Update OK, Apply, Save, Cancel Buttons */
	sensitive = has_changes;
	if(sensitive && (mt != NULL))
	    sensitive = !mt->read_only;
	GTK_WIDGET_SET_SENSITIVE(d->ok_btn, sensitive)
	GTK_WIDGET_SET_SENSITIVE(d->apply_btn, sensitive)

	if(has_changes)
	{
	    MAP(d->cancel_btn);
	    UNMAP(d->close_btn);
	}
	else
	{
	    UNMAP(d->cancel_btn);
	    MAP(d->close_btn);
	}
	sensitive = TRUE;
	GTK_WIDGET_SET_SENSITIVE(d->cancel_btn, sensitive)
	GTK_WIDGET_SET_SENSITIVE(d->close_btn, sensitive)

#undef UNMAP
#undef MAP
}

/*
 *	Checks if the MIME Types Edit Window is mapped.
 */
gboolean EDVMimeTypeEditDlgIsMapped(
	edv_mime_type_edit_dlg_struct *d
)
{
	GtkWidget *w = (d != NULL) ? d->toplevel : NULL;
	return((w != NULL) ? GTK_WIDGET_MAPPED(w) : FALSE);
}

/*
 *	Maps the MIME Types Edit Window.
 */
void EDVMimeTypeEditDlgMap(
	edv_mime_type_edit_dlg_struct *d
)
{
	pulistbox_struct *pulistbox;

	if(d == NULL)
	    return;

	gtk_widget_show_raise(d->toplevel);

	pulistbox = d->class_pulistbox;
	if(pulistbox != NULL)
	    gtk_widget_grab_focus(pulistbox->da);
}

/*
 *	Unmaps the MIME Types Edit Window.
 */
void EDVMimeTypeEditDlgUnmap(
	edv_mime_type_edit_dlg_struct *d
)
{
	if(d == NULL)
	    return;

	gtk_widget_hide(d->toplevel);
}

/*
 *	Deletes the MIME Types Edit Window.
 */
void EDVMimeTypeEditDlgDelete(
	edv_mime_type_edit_dlg_struct *d
)
{
	if(d == NULL)
	    return;

	EDVMimeTypeEditDlgIconDelete(d->icon_small);
	EDVMimeTypeEditDlgIconDelete(d->icon_medium);
	EDVMimeTypeEditDlgIconDelete(d->icon_large);

	EditCListDelete(d->editclist);

	GTK_WIDGET_DESTROY(d->ok_btn);
	GTK_WIDGET_DESTROY(d->apply_btn);
	GTK_WIDGET_DESTROY(d->cancel_btn);
	GTK_WIDGET_DESTROY(d->close_btn);

	PUListBoxDelete(d->class_pulistbox);
	GTK_WIDGET_DESTROY(d->description_entry);
	GTK_WIDGET_DESTROY(d->value_label);
	GTK_WIDGET_DESTROY(d->value_entry);

	GTK_WIDGET_DESTROY(d->type_entry);
	PUListBoxDelete(d->handler_pulistbox);

	GTK_WIDGET_DESTROY(d->toplevel);

	GTK_ACCEL_GROUP_UNREF(d->accelgrp)

	g_free(d->title);

	g_free(d);
}
