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

#ifdef __SOLARIS__
# include "../include/os.h"
#endif

#include "guiutils.h"
#include "pulist.h"
#include "cfg.h"
#include "edv_types.h"
#include "archive_options_dlg.h"
#include "endeavour2.h"
#include "edv_utils.h"
#include "edv_utils_gtk.h"
#include "edv_cfg_list.h"
#include "config.h"

#include "images/icon_archive_add_20x20.xpm"
#include "images/icon_archive_extract_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"

#include "images/icon_archive_add_32x32.xpm"
#include "images/icon_archive_extract_32x32.xpm"


/*
 *	Dialog Common:
 */
typedef struct {
	GtkWidget	*toplevel;
	GtkAccelGroup	*accelgrp;
	gint		freeze_count;
	edv_core_struct	*core;
	GtkWidget	*main_vbox,
			*client_vbox,
			*ok_btn,
			*cancel_btn;
	gchar           *path;		/* Path to archive */
	gboolean	got_response;
} Dlg;
#define DLG(p)			((Dlg *)(p))

/*
 *	Add Options Dialog:
 */
typedef struct {
	Dlg		d;
	GtkWidget	*recursive_check,
			*compression_scale,
			*compression_label,
			*dereference_links_check;
	GtkAdjustment	*compression_adj;
	pulistbox_struct	*compression_pulistbox;
} AddDlg;
#define ADD_DLG(p)		((AddDlg *)(p))

/*
 *	Extract Options Dialog:
 */
typedef struct {
	Dlg		d;
	GtkWidget	*preserve_directories_check,
			*preserve_timestamps_check;
} ExtractDlg;
#define EXTRACT_DLG(p)		((ExtractDlg *)(p))


/* Dialog Common Callbacks */
static gint EDVDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
);
static void EDVDlgOKCB(GtkWidget *widget, gpointer data);
static void EDVDlgCancelCB(GtkWidget *widget, gpointer data);

/* Add Dialog Callbacks */
static void EDVArchOptsDlgAddCompressionValueChangedCB(
	GtkAdjustment *adj, gpointer data
);
static void EDVArchOptsDlgAddCompressionPUListChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
);

/* Dialog Common */
static Dlg *EDVDlgNew(
	gint size, gint width, gint height,
	const gchar *title, guint8 **icon_data,
	const gchar *ok_label, guint8 **ok_icon_data,
	const gchar *cancel_label, guint8 **cancel_icon_data,
	GtkWidget *ref_toplevel,
	edv_core_struct *core, const gchar *path
);
static void EDVDlgDelete(Dlg *d);


/* Add Options Querying */
gboolean EDVArchAddOptsGetResponse(
	edv_core_struct *core,
	GtkWidget *ref_toplevel,
	const gchar *arch_obj,
	gboolean *recursive,
	gint *compression,		/* 0 to 100 */
	gboolean *dereference_links
);

/* Extract Options Querying */
gboolean EDVArchExtractOptsGetResponse(
	edv_core_struct *core,
	GtkWidget *ref_toplevel,
	const gchar *arch_obj,
	gboolean *preserve_directories,
	gboolean *preserve_timestamps
);


#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)


/*
 *	Dialog toplevel GtkWindow "delete_event" signal callback.
 */
static gint EDVDlgDeleteEventCB(
	GtkWidget *widget, GdkEvent *event, gpointer data
)
{
	EDVDlgCancelCB(widget, data);
	return(TRUE);
}

/*
 *	Dialog OK callback.
 */
static void EDVDlgOKCB(GtkWidget *widget, gpointer data)
{
	Dlg *d = DLG(data);
	if(d == NULL)
	    return;

	d->got_response = TRUE;
	gtk_main_quit();
}

/*
 *	Dialog Cancel callback.
 */
static void EDVDlgCancelCB(GtkWidget *widget, gpointer data)
{
	Dlg *d = DLG(data);
	if(d == NULL)
	    return;

	d->got_response = FALSE;
	gtk_main_quit();
}


/*
 *	Add Options Dialog compression GtkAdjustment "value_changed"
 *	signal callback.
 */
static void EDVArchOptsDlgAddCompressionValueChangedCB(
	GtkAdjustment *adj, gpointer data
)
{
	gint nitems;
	gfloat v;
	gchar *s;
	GtkLabel *label;
	pulist_struct *pulist;
	pulistbox_struct *pulistbox;
	AddDlg *d = ADD_DLG(data);
	if((adj == NULL) || (d == NULL))
	    return;

	if(DLG(d)->freeze_count > 0)
	    return;

	DLG(d)->freeze_count++;

	v = adj->value;
	label = GTK_LABEL(d->compression_label);
	pulistbox = d->compression_pulistbox;
	pulist = PUListBoxGetPUList(pulistbox);
	nitems = PUListGetTotalItems(pulist);

	/* Update the label */
	s = g_strdup_printf("%i%%", (gint)v);
	gtk_label_set_text(label, s);
	g_free(s);

	/* Update the popup list box */
	if(nitems > 1)
	    PUListBoxSelect(
		pulistbox,
		(gint)rint(
		    (v / 100.0f) * (gfloat)(nitems - 1)
		)
	    );

	DLG(d)->freeze_count--;
}

/*
 *	Add Options Dialog compression popup list box changed signal
 *	callback.
 */
static void EDVArchOptsDlgAddCompressionPUListChangedCB(
	pulistbox_struct *pulistbox, gint i, gpointer data
)
{
	float v = 0.0f;
	gint nitems;
	gchar *s;
	GtkAdjustment *adj;
	GtkLabel *label;
	pulist_struct *pulist;
	AddDlg *d = ADD_DLG(data);
	if((pulistbox == NULL) || (d == NULL))
	    return;

	if(DLG(d)->freeze_count > 0)
	    return;

	DLG(d)->freeze_count++;

	adj = d->compression_adj;
	label = GTK_LABEL(d->compression_label);
	pulist = PUListBoxGetPUList(pulistbox);
	nitems = PUListGetTotalItems(pulist);

	/* Calculate the compression value from 0.0 to 100.0 */
	if(nitems > 1)
	    v = MIN(
		((gfloat)i / (gfloat)(nitems - 1)),
		1.0f
	    ) * 100.0f;
	else
	    v = 0.0f;

	/* Update the label */
	s = g_strdup_printf("%i%%", (gint)v);
	gtk_label_set_text(label, s);
	g_free(s);

	/* Update the scale */
	gtk_adjustment_set_value(adj, v);

	DLG(d)->freeze_count--;
}


/*
 *	Creates a new Dialog.
 */
static Dlg *EDVDlgNew(
	gint size, gint width, gint height,
	const gchar *title, guint8 **icon_data,
	const gchar *ok_label, guint8 **ok_icon_data,
	const gchar *cancel_label, guint8 **cancel_icon_data,
	GtkWidget *ref_toplevel,
	edv_core_struct *core, const gchar *path
)
{
	const gint	border_major = 5;
	GdkWindow *window;
	GtkAccelGroup *accelgrp;
	GtkWidget *w, *parent, *parent2;
	Dlg *d = (size > 0) ? DLG(g_malloc0(size)) : NULL;
	if(d == NULL)
	    return(NULL);

	d->accelgrp = accelgrp = gtk_accel_group_new();
	d->freeze_count = 0;
	d->core = core;
	d->path = STRDUP(path);
	d->got_response = FALSE;

	/* Toplevel */
	d->toplevel = w = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_widget_set_usize(w, width, height);
	gtk_window_set_title(GTK_WINDOW(w), title);
	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, icon_data);
	}
	gtk_widget_add_events(
	    w,
	    GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "delete_event",
	    GTK_SIGNAL_FUNC(EDVDlgDeleteEventCB), d
	);
	gtk_window_add_accel_group(GTK_WINDOW(w), accelgrp);
	if((ref_toplevel != NULL) ?
	    GTK_IS_WINDOW(ref_toplevel) : FALSE
	)
	{
	    gtk_window_set_modal(GTK_WINDOW(w), TRUE);
	    gtk_window_set_transient_for(
		GTK_WINDOW(w), GTK_WINDOW(ref_toplevel)
	    );
	}
	parent = w;

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

	/* Client vbox */
	d->client_vbox = w = gtk_vbox_new(FALSE, border_major);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
	gtk_widget_show(w);

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

	/* Buttons hbox */
	w = gtk_hbox_new(TRUE, 0);
	gtk_container_border_width(GTK_CONTAINER(w), border_major);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* OK button */
	d->ok_btn = w = GUIButtonPixmapLabelH(
	    ok_icon_data, ok_label, 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(EDVDlgOKCB), d
	);
	gtk_widget_show(w);
	  
	/* Cancel button */
	d->cancel_btn = w = GUIButtonPixmapLabelH(
	    cancel_icon_data, cancel_label, 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(EDVDlgCancelCB), d
	);
	gtk_accel_group_add(
	    accelgrp, GDK_Escape, 0, GTK_ACCEL_VISIBLE,
	    GTK_OBJECT(w), "clicked"
	);
	gtk_widget_show(w); 

	/* Grab focus and default for the OK button */
	w = d->ok_btn;
	gtk_widget_grab_default(w);
	gtk_widget_grab_focus(w);

	return(d);
}

/*
 *	Deletes the Dialog.
 */
static void EDVDlgDelete(Dlg *d)
{
	if(d == NULL)
	    return;

	gtk_widget_hide(d->toplevel);
	gtk_window_set_modal(GTK_WINDOW(d->toplevel), FALSE);
	gtk_window_set_transient_for(GTK_WINDOW(d->toplevel), NULL);
	GTK_WIDGET_DESTROY(d->ok_btn);
	GTK_WIDGET_DESTROY(d->cancel_btn);
	GTK_WIDGET_DESTROY(d->client_vbox);
	GTK_WIDGET_DESTROY(d->main_vbox);
	GTK_WIDGET_DESTROY(d->toplevel);
	GTK_ACCEL_GROUP_UNREF(d->accelgrp);
	g_free(d->path);
	g_free(d);
}


/*
 *	Queries user for add to archive options.
 *
 *	Returns TRUE if the user response with OK or FALSE if the
 *	user response with Cancel.
 */
gboolean EDVArchAddOptsGetResponse(
	edv_core_struct *core,
	GtkWidget *ref_toplevel,
	const gchar *arch_obj,
	gboolean *recursive,
	gint *compression,		/* 0 to 100 */
	gboolean *dereference_links
)
{
	const gint	border_major = 5,
			border_minor = 2,
			width = 350,
			height = -1;
	gboolean	got_response = FALSE;
	GtkAccelGroup *accelgrp;
	GtkStyle *style;
	GtkWidget *toplevel, *client_vbox;
	cfg_item_struct *cfg_list;
	AddDlg *d;

	if(core == NULL)
	    return(FALSE);

	cfg_list = core->cfg_list;

	/* Get configuration values */
	if(recursive != NULL)
	    *recursive = EDV_GET_B(EDV_CFG_PARM_ARCHIVE_ADD_RECURSIVE);
	if(compression != NULL)
	    *compression = EDV_GET_I(EDV_CFG_PARM_ARCHIVE_ADD_COMPRESSION);
	if(dereference_links != NULL)
	    *dereference_links = EDV_GET_B(EDV_CFG_PARM_ARCHIVE_ADD_DEREFERENCE_LINKS);

	/* Create new Dialog */
	d = (AddDlg *)EDVDlgNew(
	    sizeof(AddDlg), width, height,
#if defined(PROG_LANGUAGE_SPANISH)
"Añada A Opciones De Archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Ajouter Pour Archiver Des Options"
#elif defined(PROG_LANGUAGE_GERMAN)
"Fügen Sie Zu Archiv Optionen Hinzu"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Aggiungere Alle Opzioni Di Archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Voeg Aan archief Opties toe"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Adicione A Opções de Arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Tilføy To Archive Options"
#elif defined(PROG_LANGUAGE_POLISH)
"Opcje dodawania do archiwum"
#else
"Add To Archive Options"
#endif
	    , (guint8 **)icon_archive_add_32x32_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Agregue"
#elif defined(PROG_LANGUAGE_FRENCH)
"Ajouter"
#elif defined(PROG_LANGUAGE_GERMAN)
"Fügen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Aggiungere"
#elif defined(PROG_LANGUAGE_DUTCH)
"Toevoeg"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Adicione"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Tilføy"
#elif defined(PROG_LANGUAGE_POLISH)
"Dodaj"
#else
"Add"
#endif
	    , (guint8 **)icon_archive_add_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"
#elif defined(PROG_LANGUAGE_POLISH)
"Anuluj"
#else   
"Cancel"
#endif
	    , (guint8 **)icon_cancel_20x20_xpm,
	    ref_toplevel,
	    core, arch_obj
	);
	if(d == NULL)
	    return(got_response);

	toplevel = DLG(d)->toplevel;
	accelgrp = DLG(d)->accelgrp;
	client_vbox = DLG(d)->client_vbox;
	style = gtk_widget_get_style(toplevel);

	/* Create the option widgets */
	if(client_vbox != NULL)
	{
	    gint i;
	    GtkStateType state;
	    GtkRcStyle *rcstyle;
	    GtkAdjustment *adj;
	    GtkWidget *w, *parent = client_vbox, *parent2, *parent3;
	    pulist_struct *pulist;
	    pulistbox_struct *pulistbox;

	    w = DLG(d)->ok_btn;
	    gtk_accel_group_add(
		accelgrp, GDK_a, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
		GTK_OBJECT(w), "clicked"
	    );
	    GUIButtonLabelUnderline(w, GDK_a);
	    w = DLG(d)->cancel_btn;
	    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);

	    /* Archive object */
	    if(!STRISEMPTY(arch_obj))
	    {
		w = gtk_frame_new(NULL);
		gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
		gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
		gtk_widget_show(w); 
		parent2 = w;

		rcstyle = gtk_rc_style_new();
		state = GTK_STATE_NORMAL;
		rcstyle->color_flags[state] = GTK_RC_BG | GTK_RC_BASE;
		memcpy(
		    &rcstyle->bg[state],
		    &style->base[state],
		    sizeof(GdkColor)
		);
		memcpy(
		    &rcstyle->base[state], 
		    &style->base[state],
		    sizeof(GdkColor)
		);
		w = gtk_event_box_new();
		gtk_container_add(GTK_CONTAINER(parent2), w);
		gtk_widget_modify_style(w, rcstyle);
		gtk_widget_show(w);
		GTK_RC_STYLE_UNREF(rcstyle);
		parent2 = w;

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

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

		w = EDVNewPixmapWidget(
		    core,
		    (guint8 **)icon_archive_add_32x32_xpm,
		    "icon_archive_add_32x32_xpm"
		);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);

		rcstyle = gtk_rc_style_new();
		rcstyle->font_name = g_strdup(
#if defined(PROG_LANGUAGE_POLISH)
"-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-2"
#else
"-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1"
#endif
		);
		w = gtk_label_new(g_basename(arch_obj));
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_modify_style(w, rcstyle);
		gtk_widget_show(w);
		GTK_RC_STYLE_UNREF(rcstyle)

		w = gtk_hbox_new(FALSE, border_major);
		gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
		parent3 = w;
		w = gtk_label_new(
"Specify the options for adding objects to this archive."
		);
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);

		w = gtk_hbox_new(FALSE, border_major);
		gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
		parent3 = w;
		w = gtk_label_new(
"Note that some options are not available on certain\n\
archive formats and therefore do not apply."
		);
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
	    }

	    /* Vbox for option widgets */
	    w = gtk_vbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent2 = w;

	    /* Recursive check */
	    w = gtk_hbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent3 = w;
	    /* Check button */
	    d->recursive_check = w =
		gtk_check_button_new_with_label(
#if defined(PROG_LANGUAGE_SPANISH)
"Recurse En Guías"
#elif defined(PROG_LANGUAGE_FRENCH)
"Recurse Dans Les Annuaires"
#elif defined(PROG_LANGUAGE_GERMAN)
"Recurse In Verzeichnisse"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Recurse Negli Elenchi"
#elif defined(PROG_LANGUAGE_DUTCH)
"Recurse In Gidzen"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Recurse Em Guias"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Dra In Directories"
#elif defined(PROG_LANGUAGE_POLISH)
"Uwzglêdnij podkatalogi"
#else
"Recurse Into Directories"
#endif
		);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    if((recursive != NULL) ? *recursive : FALSE)
		GTK_TOGGLE_BUTTON(w)->active = TRUE;
	    GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Verifique esto incluir el agregar de objetos encontró en todas guías\
 de niño del sendero(s) escogido"
#elif defined(PROG_LANGUAGE_FRENCH)
"Vérifier ceci pour inclure l'ajoute d'objets a trouvé dans tous\
 annuaires d'enfant de l'a choisi le sentier (le s)"
#elif defined(PROG_LANGUAGE_GERMAN)
"Prüfen Sie dies, das hinzufügen der objekte miteinzuschließen, in\
 allem kind verzeichnissen des ausgewählten pfads(s) hat gefunden"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Controllare questo per includere l'aggiunta di oggetti trovati in\
 tutto gli elenchi di bambino del sentiero scelto(s)"
#elif defined(PROG_LANGUAGE_DUTCH)
"Controleer dit om het toevoegen van voorwerpen te omvatten in alle\
 kind gidzen van het geselecteerd pad(s) vond"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Verifique isto incluir o adicionar de objetos achado em todos guias\
 de criança do caminho selecionado(s)"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sjekk dette inkludere tilføyingen av objekt som funnet i all\
 barnkataloger av den valgte ut stien(s)"
#elif defined(PROG_LANGUAGE_POLISH)
"Zaznacz to pole by dodaæ do archiwum wszystkie obiekty znajduj±ce\
 siê w podanej ¶cie¿ce (¶cie¿kach) i jej (ich) podkatalogach"
#else
"Check this to include the adding of objects found in all child\
 directories of the selected path(s)"
#endif
	    );
	    gtk_widget_show(w);

	    /* Compression scale */
	    w = gtk_hbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent3 = w;
	    /* Label */
	    w = gtk_label_new(
#if defined(PROG_LANGUAGE_SPANISH)
"Compresión"
#elif defined(PROG_LANGUAGE_FRENCH)
"Compression"
#elif defined(PROG_LANGUAGE_GERMAN)
"Kompression"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Compressione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Samendrukking"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Compressão"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Kompresjon"
#elif defined(PROG_LANGUAGE_POLISH)
"Kompresja"
#else
"Compression"
#endif
		":"
	    );
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    /* Adjustment and scale */
	    d->compression_adj = adj = (GtkAdjustment *)gtk_adjustment_new(
		(compression != NULL) ? (gfloat)*compression : 0.0f,
		0.0f, 100.0f,
		10.0f, 25.0f, 0.0f
	    );
	    d->compression_scale = w = gtk_hscale_new(adj);
	    gtk_scale_set_draw_value(GTK_SCALE(w), FALSE);
/*	    gtk_widget_set_usize(w, scale_width, -1); */
	    gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
	    gtk_signal_connect(
		GTK_OBJECT(adj), "value_changed",
		GTK_SIGNAL_FUNC(EDVArchOptsDlgAddCompressionValueChangedCB), d
	    );
	    GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Ponga la cantidad de la compresión; 0% para ninguna compresión,\
 50% para la compresión uniforme, y 100% para la compresión máxima"
#elif defined(PROG_LANGUAGE_FRENCH)
"Régler la quantité de compression; 0% pour aucune compression, 50%\
 pour la compression standard, et 100% pour la compression maximum"
#elif defined(PROG_LANGUAGE_GERMAN)
"Setzen Sie den Betrag der Kompression; 0% für keine Kompression,\
 50% für normale Kompression, und 100% für maximale Kompression"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Ha regolato la quantità di compressione; 0% per nessuna compressione,\
 50% per la compressione standard, e 100% per la compressione massima"
#elif defined(PROG_LANGUAGE_DUTCH)
"Zet de hoeveelheid van samendrukking; 0% voor geen samendrukking,\
 50% voor normale samendrukking en 100% voor maximale samendrukking"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Ponha a quantia de compressão; 0% para nenhuma compressão, 50% para\
 compressão normal, e 100% para compressão máxima"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sett mengden av kompresjon; 0% for ingen kompresjon, 50% for normal\
 kompresjon, og 100% for maksimum kompresjon"
#elif defined(PROG_LANGUAGE_POLISH)
"Ustaw stopieñ kompresji. 0% - brak kompresji, 50%\
 - normalna kompresja, 100% - maksymalna kompresja"
#else
"Set the amount of compression; 0% for no compression,\
 50% for standard compression, and 100% for maximum\
 compression"
#endif
	    );
	    gtk_widget_show(w);

	    /* Compression label */
	    d->compression_label = w = gtk_label_new("");
	    gtk_widget_set_usize(w, 30, -1);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);

	    /* Compression popup list box */
	    d->compression_pulistbox = pulistbox = PUListBoxNew(
		parent3,
		90, -1
	    );
	    pulist = PUListBoxGetPUList(pulistbox);
	    PUListBoxSetChangedCB(
		pulistbox,
		EDVArchOptsDlgAddCompressionPUListChangedCB, d
	    );
	    PUListBoxMap(pulistbox);
#if defined(PROG_LANGUAGE_SPANISH)
	    i = PUListAddItem(pulist, "Ninguno");
	    i = PUListAddItem(pulist, "Bajo");
	    i = PUListAddItem(pulist, "Estándar");
	    i = PUListAddItem(pulist, "Alto");
	    i = PUListAddItem(pulist, "Máximo");
#elif defined(PROG_LANGUAGE_FRENCH)
	    i = PUListAddItem(pulist, "Aucun");
	    i = PUListAddItem(pulist, "Niveau Bas");
	    i = PUListAddItem(pulist, "Norme");
	    i = PUListAddItem(pulist, "Haut");
	    i = PUListAddItem(pulist, "Maximum");
#elif defined(PROG_LANGUAGE_GERMAN)
	    i = PUListAddItem(pulist, "Keiner");
	    i = PUListAddItem(pulist, "Niedrig");
	    i = PUListAddItem(pulist, "Standard");
	    i = PUListAddItem(pulist, "Hoch");
	    i = PUListAddItem(pulist, "Maximum");
#elif defined(PROG_LANGUAGE_ITALIAN)
	    i = PUListAddItem(pulist, "Nessuno");
	    i = PUListAddItem(pulist, "Basso");
	    i = PUListAddItem(pulist, "Norma");
	    i = PUListAddItem(pulist, "Alto");
	    i = PUListAddItem(pulist, "Massimo");
#elif defined(PROG_LANGUAGE_DUTCH)
	    i = PUListAddItem(pulist, "Geen");
	    i = PUListAddItem(pulist, "Laag");
	    i = PUListAddItem(pulist, "Standaard");
	    i = PUListAddItem(pulist, "Hoog");
	    i = PUListAddItem(pulist, "Maximum");
#elif defined(PROG_LANGUAGE_PORTUGUESE)
	    i = PUListAddItem(pulist, "Nenhum");
	    i = PUListAddItem(pulist, "Baixo");
	    i = PUListAddItem(pulist, "Padrão");
	    i = PUListAddItem(pulist, "Alto");
	    i = PUListAddItem(pulist, "Máximo");
#elif defined(PROG_LANGUAGE_NORWEGIAN)
	    i = PUListAddItem(pulist, "Ingen");
	    i = PUListAddItem(pulist, "Lav");
	    i = PUListAddItem(pulist, "Standard");
	    i = PUListAddItem(pulist, "Høy");
	    i = PUListAddItem(pulist, "Maksimum");
#elif defined(PROG_LANGUAGE_POLISH)
	    i = PUListAddItem(pulist, "Brak");
	    i = PUListAddItem(pulist, "Niska");
	    i = PUListAddItem(pulist, "Normalna");
	    i = PUListAddItem(pulist, "Wysoka");
	    i = PUListAddItem(pulist, "Maksymalna");
#else
	    i = PUListAddItem(pulist, "None");
	    i = PUListAddItem(pulist, "Low");
	    i = PUListAddItem(pulist, "Standard");
	    i = PUListAddItem(pulist, "High");
	    i = PUListAddItem(pulist, "Maximum");
#endif
	    PUListBoxSetLinesVisible(pulistbox, i + 1);

	    /* Update the compression value */
	    EDVArchOptsDlgAddCompressionValueChangedCB(adj, d);

	    /* Dereference links check */
	    w = gtk_hbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent3 = w;
	    /* Check button */
	    d->dereference_links_check = w =
		gtk_check_button_new_with_label(
#if defined(PROG_LANGUAGE_SPANISH)
"Dereference Traba"
#elif defined(PROG_LANGUAGE_FRENCH)
"Dereference Relie"
#elif defined(PROG_LANGUAGE_GERMAN)
"Dereference Verknüpft"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Il Dereference Concatena"
#elif defined(PROG_LANGUAGE_DUTCH)
"Dereference Verbindt"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"O Dereference Liga"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Dereference Ledds"
#elif defined(PROG_LANGUAGE_POLISH)
"Obiekty docelowe odno¶ników"
#else
"Dereference Links"
#endif
		);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    if((dereference_links != NULL) ? *dereference_links : FALSE)
		GTK_TOGGLE_BUTTON(w)->active = TRUE;
	    GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Verifique esto agregar el destino de objetos de conexión en vez de\
 la conexión se opone a sí mismo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Vérifier ceci pour ajouter la destination d'objets de lien au lieu\
 des objets de lien se"
#elif defined(PROG_LANGUAGE_GERMAN)
"Prüfen Sie dies, das reiseziel von kettenglied objekten statt des\
 kettenglieds hinzuzufügen, wendet gegen sich ein"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Controllare questo per aggiungere la destinazione di oggetti di\
 maglia invece della maglia sei obbietta"
#elif defined(PROG_LANGUAGE_DUTCH)
"Controleer dit om de bestemming van schakel voorwerpen in plaats\
 van de schakel toe te voegen bezwaar heeft zich"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Verifique isto adicionar o destino de objetos de elo em vez do elo\
 opõe-se sees"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sjekk dette tilføye destinasjonen av leddobjekt i stedet for\
 leddet protesterer seg"
#elif defined(PROG_LANGUAGE_POLISH)
"Zaznacz to pole by do archwium zosta³y dodane obiekty wskazywane\
 przez odno¶niki zamiast ich samych"
#else
"Check this to add the destination of link objects instead of the\
 link objects themselves"
#endif
	    );
	    gtk_widget_show(w);


	}

	/* Map toplevel */
	gtk_widget_show(toplevel);

	/* Wait for user response */
	gtk_main();

	/* Get user response */
	got_response = DLG(d)->got_response;


	/* Update returns if the user responded with ok */
	if(got_response)
	{
	    /* Recursive */
	    if(recursive != NULL)
	    {
		*recursive = GTK_TOGGLE_BUTTON_GET_ACTIVE(
		    d->recursive_check
		);
		EDV_SET_B(
		    EDV_CFG_PARM_ARCHIVE_ADD_RECURSIVE,
		    *recursive
		);
	    }
	    /* Compression */
	    if(compression != NULL)
	    {
		*compression = (gint)GTK_ADJUSTMENT_GET_VALUE(
		    d->compression_adj
		);
		EDV_SET_I(
		    EDV_CFG_PARM_ARCHIVE_ADD_COMPRESSION,
		    *compression
		);
	    }
	    /* Dereference Links */
	    if(dereference_links != NULL)
	    {
		*dereference_links = GTK_TOGGLE_BUTTON_GET_ACTIVE(
		    d->dereference_links_check
		);
		EDV_SET_B(
		    EDV_CFG_PARM_ARCHIVE_ADD_DEREFERENCE_LINKS,
		    *dereference_links
		);
	    }
	}

	/* Delete the Dialog */
	PUListBoxDelete(d->compression_pulistbox);
	EDVDlgDelete(DLG(d));

	return(got_response);
}


/*
 *	Queries user for extract from archive options.
 *
 *	Returns TRUE if the user response with OK or FALSE if the
 *	user response with Cancel.            
 */
gboolean EDVArchExtractOptsGetResponse(
	edv_core_struct *core,
	GtkWidget *ref_toplevel,
	const gchar *arch_obj,
	gboolean *preserve_directories,
	gboolean *preserve_timestamps
)
{
	const gint	border_major = 5,
			border_minor = 2,
			width = 350,
			height = -1;
	gboolean        got_response = FALSE;
	GtkAccelGroup *accelgrp;
	GtkStyle *style;
	GtkWidget *toplevel, *client_vbox;
	cfg_item_struct *cfg_list;
	ExtractDlg *d;

	if(core == NULL)
	    return(FALSE);

	cfg_list = core->cfg_list;

	/* Get configuration values */
	if(preserve_directories != NULL)
	    *preserve_directories = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVE_EXTRACT_PRESERVE_DIR
	    );
	if(preserve_timestamps != NULL)
	    *preserve_timestamps = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVE_EXTRACT_PRESERVE_TIMESTAMPS
	    );

	/* Create new Dialog */
	d = (ExtractDlg *)EDVDlgNew(
	    sizeof(ExtractDlg), width, height,
#if defined(PROG_LANGUAGE_SPANISH)
"Extraiga De Opciones De Archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Extraire Des Options D'Archive"
#elif defined(PROG_LANGUAGE_GERMAN)
"Extrahieren Sie Von Archiv Optionen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Estrarre Dalle Opzioni Di Archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Onttrek Van Archief Opties"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Extraia De Opções De Arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Trekk Ut From Archive Options"
#elif defined(PROG_LANGUAGE_POLISH)
"Opcje rozpakowywania archiuwum"
#else
"Extract From Archive Options"
#endif
	    , (guint8 **)icon_archive_extract_32x32_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Extracto"
#elif defined(PROG_LANGUAGE_FRENCH)
"Extrait"
#elif defined(PROG_LANGUAGE_GERMAN)
"Extrakt"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Estratto"
#elif defined(PROG_LANGUAGE_DUTCH)
"Extract"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Extraia"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Extrakt"
#elif defined(PROG_LANGUAGE_POLISH)
"Rozpakuj"
#else
"Extract"
#endif
	    , (guint8 **)icon_archive_extract_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"
#elif defined(PROG_LANGUAGE_POLISH)
"Anuluj"
#else
"Cancel"
#endif
	    , (guint8 **)icon_cancel_20x20_xpm,
	    ref_toplevel,
	    core, arch_obj
	);
	if(d == NULL)
	    return(got_response);

	toplevel = DLG(d)->toplevel;
	accelgrp = DLG(d)->accelgrp;
	client_vbox = DLG(d)->client_vbox;
	style = gtk_widget_get_style(toplevel);

	/* Create options widgets */
	if(client_vbox != NULL)
	{
	    GtkStateType state;
	    GtkRcStyle *rcstyle;
	    GtkWidget *w, *parent = client_vbox, *parent2, *parent3;

	    w = DLG(d)->ok_btn;
	    gtk_accel_group_add(
		accelgrp, GDK_e, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
		GTK_OBJECT(w), "clicked"
	    );
	    GUIButtonLabelUnderline(w, GDK_e);
	    w = DLG(d)->cancel_btn;
	    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);

	    /* Archive object */
	    if(!STRISEMPTY(arch_obj))
	    {
		w = gtk_frame_new(NULL);
		gtk_frame_set_shadow_type(GTK_FRAME(w), GTK_SHADOW_IN);
		gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
		parent2 = w;

		rcstyle = gtk_rc_style_new();
		state = GTK_STATE_NORMAL;
		rcstyle->color_flags[state] = GTK_RC_BG | GTK_RC_BASE;
		memcpy(
		    &rcstyle->bg[state],
		    &style->base[state],
		    sizeof(GdkColor)
		);
		memcpy(
		    &rcstyle->base[state],
		    &style->base[state],
		    sizeof(GdkColor)
		);
		w = gtk_event_box_new();
		gtk_container_add(GTK_CONTAINER(parent2), w);
		gtk_widget_modify_style(w, rcstyle);
		gtk_widget_show(w);
		GTK_RC_STYLE_UNREF(rcstyle);
		parent2 = w;

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

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

		w = EDVNewPixmapWidget(
		    core, 
		    (guint8 **)icon_archive_extract_32x32_xpm,
		    "icon_archive_extract_32x32_xpm"
		);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);

		rcstyle = gtk_rc_style_new();
		rcstyle->font_name = g_strdup(
#if defined(PROG_LANGUAGE_POLISH)
"-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-2"
#else
"-adobe-helvetica-bold-r-normal-*-14-*-*-*-*-*-iso8859-1"
#endif
		);
		w = gtk_label_new(g_basename(arch_obj));
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_modify_style(w, rcstyle);
		gtk_widget_show(w);
		GTK_RC_STYLE_UNREF(rcstyle)

		w = gtk_hbox_new(FALSE, border_major);
		gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
		parent3 = w;
		w = gtk_label_new(
"Specify the options for extracting objects from this\n\
archive."
		);
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);

		w = gtk_hbox_new(FALSE, border_major);
		gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
		parent3 = w;
		w = gtk_label_new(
"Note that some options are not available on certain\n\
archive formats and therefore do not apply."
		);
		gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_LEFT);
		gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
		gtk_widget_show(w);
	    }

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

	    /* Preserve Directories Check */
	    w = gtk_hbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent3 = w;
	    /* Check button */
	    d->preserve_directories_check = w =
		gtk_check_button_new_with_label(
#if defined(PROG_LANGUAGE_SPANISH)
"Preserve Guías"
#elif defined(PROG_LANGUAGE_FRENCH)
"Conserver Des Annuaires"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bewahren Sie Verzeichnisse"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Conservare Gli Elenchi"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bewaar Gidzen"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Conserve Guias"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bevar Directories"
#elif defined(PROG_LANGUAGE_POLISH)
"Zachowaj strukturê katalogów"
#else
"Preserve Directories"
#endif
		);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    if((preserve_directories != NULL) ? *preserve_directories : FALSE)
		GTK_TOGGLE_BUTTON(w)->active = TRUE;
	    GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Verifique esto mantener los prefijos originales de sendero de\
 cada objeto extraído del archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Vérifier ceci pour maintenir les préfixes originaux de sentier\
 de chaque extrait d'objet de l'archive"
#elif defined(PROG_LANGUAGE_GERMAN)
"Prüfen sie dies beizubehalten, daß die ursprüngliche pfad vorsilben\
 jedes objekts vom archiv extrahiert haben"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Controllare questo per mantenere i prefissi di sentiero originali\
 di ogni oggetto estratto dall'archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Controleer dit om het oorspronkelijk pad prefixen van elk voorwerp\
 te handhaven van het archief onttrokk"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Verifique isto manter o prefixes original de caminho de cada objeto\
 extraído do arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sjekk dette vedlikeholde det originale stiprefikser av hver objekt\
 som trukket ut fra arkivet"
#elif defined(PROG_LANGUAGE_POLISH)
"Zaznacz to pole by zachowaæ oryginalne ¶cie¿ki obiektów\
 wypakowywanych archiwum"
#else
"Check this to maintain the original path prefixes of each object\
 extracted from the archive"
#endif
	    );
	    gtk_widget_show(w);

	    /* Preserve Time Stamps Check */
	    w = gtk_hbox_new(FALSE, border_minor);
	    gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	    gtk_widget_show(w);
	    parent3 = w;
	    /* Check Button */
	    d->preserve_timestamps_check = w =
		gtk_check_button_new_with_label(
#if defined(PROG_LANGUAGE_SPANISH)
"Preserve Sellos De Tiempo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Conserver Les Timbres De Temps"
#elif defined(PROG_LANGUAGE_GERMAN)
"Bewahren Sie Zeit Briefmarken"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Conservare I Francobolli Di Tempo"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bewaar Tijd Stempels"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Conserve Selos De Tempo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Bevar Time Stamps"
#elif defined(PROG_LANGUAGE_POLISH)
"Zachowaj daty dostêpu"
#else
"Preserve Time Stamps"
#endif
		);
	    gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	    if((preserve_timestamps != NULL) ? *preserve_timestamps : FALSE)
		GTK_TOGGLE_BUTTON(w)->active = TRUE;
	    GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Verifique esto mantener los sellos originales de tiempo de cada\
 objeto extraído del archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Vérifier ceci pour maintenir les timbres originaux de temps de\
 chaque extrait d'objet de l'archive"
#elif defined(PROG_LANGUAGE_GERMAN)
"Prüfen sie dies, das ursprüngliches mal briefmarken jedes objekts\
 haben extrahiert vom archiv beizubehalten"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Controllare questo per mantenere i francobolli di tempo originali\
 di ogni oggetto estratto dall'archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Controleer dit om de oorspronkelijke tijd stempels van elk\
 voorwerp onttrokken van het archief te handhaven"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Verifique isto manter os selos originais de tempo de cada objeto\
 extraído do arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sjekk dette vedlikeholde det originale tidsfrimerker av hver\
 objekt som trukket ut fra arkivet"
#elif defined(PROG_LANGUAGE_POLISH)
"Zaznacz to pole by zachowaæ oryginalne daty utworzenia\
 i modyfikacji obiektów rozpakowywanych z archiwum"
#else
"Check this to maintain the original time stamps of each object\
 extracted from the archive"
#endif
	    );
	    gtk_widget_show(w);
	}

	/* Map toplevel */
	gtk_widget_show(toplevel);

	/* Wait for user response */
	gtk_main();

	/* Get user response */
	got_response = DLG(d)->got_response;

	/* Update returns if the user responded with ok */
	if(got_response)
	{
	    /* Preserve Directories */
	    if(preserve_directories != NULL)
	    {
		*preserve_directories = GTK_TOGGLE_BUTTON_GET_ACTIVE(
		    d->preserve_directories_check
		);
		EDV_SET_B(
		    EDV_CFG_PARM_ARCHIVE_EXTRACT_PRESERVE_DIR,
		    *preserve_directories
		);
	    }
	    /* Preserve Time Stamps */
	    if(preserve_timestamps != NULL)
	    {
		*preserve_timestamps = GTK_TOGGLE_BUTTON_GET_ACTIVE(
		    d->preserve_timestamps_check
		);
		EDV_SET_B(
		    EDV_CFG_PARM_ARCHIVE_EXTRACT_PRESERVE_TIMESTAMPS,
		    *preserve_timestamps
		);
	    }
	}

	/* Delete the Dialog */
	EDVDlgDelete(DLG(d));

	return(got_response);
}
