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

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

#include "guiutils.h"
#include "toolbar.h"

#include "edvtypes.h"
#include "edvlistcb.h"
#include "cfg.h"
#include "edvstatusbar.h"
#include "archiver.h"
#include "archivercb.h"
#include "archiveropcb.h"
#include "archivercontents.h"
#include "archiverdnd.h"
#include "endeavour.h"
#include "edvcb.h"
#include "edvutils.h"
#include "edvutilsgtk.h"
#include "edvcfglist.h"
#include "config.h"

#include "images/icon_hsep_20x20.xpm"
#include "images/icon_new_20x20.xpm"
#include "images/icon_open_20x20.xpm"
#include "images/icon_save_20x20.xpm"
#include "images/icon_trace_20x20.xpm"
#include "images/icon_run_20x20.xpm"
#include "images/icon_terminal_20x20.xpm"
#include "images/icon_close_20x20.xpm"
#include "images/icon_exit_20x20.xpm"
#include "images/icon_archive_add_20x20.xpm"
#include "images/icon_archive_extract_20x20.xpm"
#include "images/icon_security_20x20.xpm"
#include "images/icon_cancel_20x20.xpm"
#include "images/icon_select_all_20x20.xpm"
#include "images/icon_unselect_all_20x20.xpm"
#include "images/icon_invert_selection_20x20.xpm"
#include "images/icon_reload_20x20.xpm"
#include "images/icon_info_20x20.xpm"
#include "images/icon_mimetypes_20x20.xpm"
#include "images/icon_search_20x20.xpm"
#include "images/icon_properties2_20x20.xpm"
#include "images/icon_tool_bar_20x20.xpm"
#include "images/icon_status_bar_20x20.xpm"
#include "images/icon_options2_20x20.xpm"
#include "images/icon_customize_20x20.xpm"
#include "images/icon_insecure_20x20.xpm"
#include "images/icon_secure_20x20.xpm"
#include "images/icon_help_20x20.xpm"
#include "images/icon_about_20x20.xpm"

#include "images/endeavour_20x20.xpm"
#include "images/image_browser_20x20.xpm"
#include "images/archiver_20x20.xpm"
#include "images/icon_trash_20x20.xpm"
#include "images/icon_trash_empty_20x20.xpm"
#include "images/archiver_48x48.xpm"


/* Utilities */
static edv_archiver_opid_struct *EDVArchiverMatchOPID(
	edv_archiver_struct *archiver, edv_archiver_op op
);

/* Title */
void EDVArchiverSetTitle(
	edv_archiver_struct *archiver, const gchar *path
);

/* Location */
gchar *EDVArchiverCurrentLocation(edv_archiver_struct *archiver);
void EDVArchiverSetLocation(
	edv_archiver_struct *archiver,
	const gchar *path, gboolean record_history
);
void EDVArchiverUpdateLocationIcon(
	edv_archiver_struct *archiver, const gchar *path
);

/* Password */
gchar *EDVArchiverCurrentPassword(edv_archiver_struct *archiver);
void EDVArchiverSetPassword(
	edv_archiver_struct *archiver, const gchar *password
);

/* Regenerate Style, Menus, and Tool Bar */
void EDVArchiverToolbarRegenerate(edv_archiver_struct *archiver);
void EDVArchiverContentsMenuRegenerate(edv_archiver_struct *archiver);

/* Sync Configuration */
void EDVArchiverSyncConfiguration(edv_archiver_struct *archiver);

/* Select Archive */
void EDVArchiverSelectArchive(
	edv_archiver_struct *archiver, const gchar *arch_obj,
	const gchar *password
);

/* Operation IDs */
edv_archiver_opid_struct **EDVArchiverOPIDListNew(
	edv_archiver_struct *archiver,      /* Can be NULL */
	gint *total
);
void EDVArchiverOPIDListDelete(
	edv_archiver_opid_struct **list, gint total
);

/* Basics */
static void EDVArchiverCreateMenuBar(
	edv_archiver_struct *archiver, GtkWidget *parent
);
edv_archiver_struct *EDVArchiverNew(gpointer core_ptr);
void EDVArchiverSyncData(edv_archiver_struct *archiver);
void EDVArchiverUpdateMenus(edv_archiver_struct *archiver);
void EDVArchiverUpdateContentsHeadings(
	edv_archiver_struct *archiver,
	const gint *contents_heading, gint total_contents_headings
);
void EDVArchiverSetBusy(edv_archiver_struct *archiver, gboolean is_busy);
gboolean EDVArchiverIsMapped(edv_archiver_struct *archiver);
void EDVArchiverMap(edv_archiver_struct *archiver);
void EDVArchiverUnmap(edv_archiver_struct *archiver);
void EDVArchiverDelete(edv_archiver_struct *archiver);


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


/*
 *	Returns the Archiver Operation ID that matches the given
 *	operation.
 */
static edv_archiver_opid_struct *EDVArchiverMatchOPID(
	edv_archiver_struct *archiver, edv_archiver_op op
)
{
	gint i;
	edv_archiver_opid_struct *opid;

	if(archiver == NULL)
	    return(NULL);

	for(i = 0; i < archiver->total_opids; i++)
	{
	    opid = archiver->opid[i];
	    if((opid != NULL) ? (opid->op == op) : FALSE)
		return(opid);
	}

	return(NULL);
}


/*
 *	Sets the Archiver's title.
 */
void EDVArchiverSetTitle(
	edv_archiver_struct *archiver, const gchar *path
)
{
	gboolean include_user_name, include_location;
	const gchar *prog_name = "Archiver";
	gchar *title;
	GtkWidget *w;
	const cfg_item_struct *cfg_list;
	edv_core_struct *core_ptr;

	if(archiver == NULL)
	    return;

	w = archiver->toplevel;
	core_ptr = EDV_CORE(archiver->core_ptr);
	if((w == NULL) || (core_ptr == NULL))
	    return;

	cfg_list = core_ptr->cfg_list;

	/* Use user defined title? */
	if(!STRISEMPTY(core_ptr->title))
	    prog_name = core_ptr->title;

	/* Get title bar customization */
	include_user_name = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_TITLE_WITH_USER);
	include_location = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_TITLE_WITH_LOCATION);

	/* Format new title */
	if(include_user_name && include_location &&
	   (path != NULL)
	)
	    title = g_strdup_printf(
		"%s: %s %s",
		prog_name, core_ptr->effective_user_id_host_str,
		path
	    );
	else if(include_location && (path != NULL))
	    title = g_strdup_printf(
		"%s: %s",
		prog_name, path
	    );
	else if(include_user_name)
	    title = g_strdup_printf(
		"%s: %s",
		prog_name, core_ptr->effective_user_id_host_str
	    );
	else
	    title = STRDUP(prog_name);

	/* Set new title */
	gtk_window_set_title(GTK_WINDOW(w), title);

	g_free(title);
}

/*
 *	Returns the Archiver's current location.
 */
gchar *EDVArchiverCurrentLocation(edv_archiver_struct *archiver)
{
	GtkCombo *combo = (GtkCombo *)((archiver != NULL) ?
	    archiver->location_combo : NULL
	);
	return((combo != NULL) ?
	    gtk_entry_get_text(GTK_ENTRY(combo->entry)) : NULL
	);
}

/*
 *	Sets the Archiver's location.
 *
 *	If record_history is TRUE then the given path will also be
 *	recorded on the locations history.
 */
void EDVArchiverSetLocation(
	edv_archiver_struct *archiver,
	const gchar *path, gboolean record_history
)
{
	const gchar *s;
	gchar *new_path;
	GtkEntry *entry;
	GtkCombo *combo = (GtkCombo *)((archiver != NULL) ?
	    archiver->location_combo : NULL
	);
	if((combo == NULL) || STRISEMPTY(path))
	    return;

	entry = GTK_ENTRY(combo->entry);

	/* Get new path */
	new_path = STRDUP(path);

	/* Simplify new path */
	SimplifyPath(new_path);

	/* No change? */
	s = gtk_entry_get_text(entry);
	if((s != NULL) ? !strcmp(s, new_path) : FALSE)
	{
	    g_free(new_path);
	    return;
	}

	/* Record new location on the combo list? */
	if(record_history)
	    GUIComboAddItem(GTK_WIDGET(combo), new_path);

	/* Set new location */
	gtk_entry_set_text(entry, new_path);
	gtk_entry_set_position(entry, -1);

	g_free(new_path);
}

/*
 *	Updates the Archiver Location Bar's icon.
 *
 *      If the given path is NULL then the icon will be set as unknown.
 */
void EDVArchiverUpdateLocationIcon(
	edv_archiver_struct *archiver, const gchar *path
)
{
	edv_object_type type;
	edv_permission_flags permissions;
	GdkPixmap *pixmap_closed, *pixmap_opened;
	GdkBitmap *mask_closed, *mask_opened;
	GtkWidget *parent, *w;
	edv_core_struct *core_ptr;


	if(archiver == NULL)
	    return;

	core_ptr = EDV_CORE(archiver->core_ptr);
	parent = archiver->location_icon_fixed;
	if((core_ptr == NULL) || (parent == NULL))
	    return;

	/* Get type and permissions of the object specified by path */
	type = EDV_OBJECT_TYPE_FILE;
	permissions = 0x00000000;
	if(path != NULL)
	{
	    struct stat lstat_buf;
	    if(!lstat(path, &lstat_buf))
	    {
		mode_t m = lstat_buf.st_mode;
		type = EDVObjectGetTypeFromStatMode(m);
		permissions = EDVObjectGetPermissionsFromStatMode(m);
	    }
	}

	/* Get appropriate icon for the given path */
	EDVMatchObjectIcon(
	    core_ptr->device, core_ptr->total_devices,
	    core_ptr->mimetype, core_ptr->total_mimetypes,
	    type,
	    path,
	    TRUE,
	    permissions,
	    0,                  /* Small icons */
	    &pixmap_closed, &mask_closed,
	    &pixmap_opened, &mask_opened,
	    NULL, NULL,
	    NULL, NULL
	);
	/* If the opened pixmap is not available then revert to the
	 * closed pixmap
	 */
	if(pixmap_opened == NULL)
	{
	    pixmap_opened = pixmap_closed;
	    mask_opened = mask_closed;
	}
	if(pixmap_opened == NULL)
	    return;

	/* Create new icon pixmap widget as needed and set the new
	 * pixmap and mask on it
	 */
	w = archiver->location_icon_pm;
	if(w == NULL)
	{
	    archiver->location_icon_pm = w = gtk_pixmap_new(
		pixmap_opened, mask_opened
	    );
	    gtk_fixed_put(GTK_FIXED(parent), w, 0, 0);
	    gtk_widget_show(w);
	}
	else
	{
	    gtk_pixmap_set(GTK_PIXMAP(w), pixmap_opened, mask_opened);
	}
}

/*
 *	Returns the Archiver's current password.
 */
gchar *EDVArchiverCurrentPassword(edv_archiver_struct *archiver)
{
	GtkEntry *entry = (GtkEntry *)((archiver != NULL) ?
	    archiver->location_password_entry : NULL
	);
	return((entry != NULL) ? gtk_entry_get_text(entry) : NULL);
}

/*
 *	Sets the Archiver's password.
 */
void EDVArchiverSetPassword(
	edv_archiver_struct *archiver, const gchar *password
)
{
	GtkEntry *entry;
	gchar *new_password;

	if((archiver == NULL) || (password == NULL))
	    return;

	entry = (GtkEntry *)archiver->location_password_entry;
	if(entry == NULL)
	    return;

	/* Copy password */
	new_password = STRDUP(password);

	/* Set new password */
	gtk_entry_set_text(entry, new_password);
	gtk_entry_set_position(entry, -1);

	g_free(new_password);
}


/*
 *	Recreates the Archiver's Tool Bar.
 */
void EDVArchiverToolbarRegenerate(edv_archiver_struct *archiver)
{
	gint i, total_items;
	toolbar_display tb_display;
	toolbar_relief tb_relief;
	GtkWidget *w, *parent;
	const cfg_intlist_struct *intlist;
	const cfg_item_struct *cfg_list;
	edv_archiver_opid_struct *opid;
	toolbar_struct *toolbar;
	toolbar_item_struct **item, *item_ptr;
	edv_core_struct *core_ptr;

	if(archiver == NULL)
	    return;

	parent = archiver->tool_bar_handle;
	core_ptr = EDV_CORE(archiver->core_ptr);
	if((parent == NULL) || (core_ptr == NULL))
	    return;

	cfg_list = core_ptr->cfg_list;

	/* Get Tool Bar configuration */
	tb_display = (toolbar_display)EDV_GET_I(
	    EDV_CFG_PARM_ARCHIVER_TOOL_BAR_DISPLAY
	);
	tb_relief = (toolbar_relief)EDV_GET_I(
	    EDV_CFG_PARM_ARCHIVER_TOOL_BAR_RELIEF
	);
	intlist = EDV_GET_INTLIST(EDV_CFG_PARM_ARCHIVER_TOOL_BAR);
	if(intlist == NULL)
	    return;

	/* Delete existing Tool Bar if any */
	ToolBarDelete(archiver->toolbar);
	archiver->toolbar = NULL;

	/* Create Tool Bar items list */
	total_items = intlist->total;
	if(total_items > 0)
	{
	    item = (toolbar_item_struct **)g_malloc0(
		total_items * sizeof(toolbar_item_struct *)
	    );
	    if(item == NULL)
		total_items = 0;
	}
	else
	{
	    item = NULL;
	}
	for(i = 0; i < total_items; i++)
	{
	    /* Get Operation ID */
	    opid = EDVArchiverMatchOPID(archiver, intlist->i[i]);
	    if(opid == NULL)
		continue;

	    switch(opid->op)
	    {
	      case EDV_ARCHIVER_OP_NONE:
		item[i] = item_ptr = NULL;
		break;

	      default:
		item[i] = item_ptr = ToolBarItemNew(
		    opid->tb_item_type,
		    opid->button_name,
		    opid->button_icon_data,
		    opid->tooltip,
		    opid->op,
		    EDVArchiverOPCB, opid,
		    EDVArchiverOPEnterCB, opid,
		    EDVArchiverOPLeaveCB, opid
		);
		break;
	    }
	}

	/* Create new Tool Bar */
	archiver->toolbar = toolbar = ToolBarNew(
	    item, total_items, parent,
	    tb_display, tb_relief, FALSE
	);
	ToolBarMap(toolbar);

	/* Delete Tool Bar items list */
	ToolBarItemListDeleteAll(&item, &total_items);

	/* Need to queue resize of toplevel since the Tool Bar size
	 * may have changed
	 */
	w = archiver->toplevel;
	if(w != NULL)
	    gtk_widget_queue_resize(w);
}

/*
 *	Recreates the Archiver Contents List right click menu.
 */
void EDVArchiverContentsMenuRegenerate(edv_archiver_struct *archiver)
{
	edv_archiver_op op;
	guint8 **icon_data = NULL;
	GtkAccelGroup *accelgrp = NULL;
	GtkWidget *w, *menu;

	if(archiver == NULL)
	    return;

	/* Recreate menu */
	GTK_WIDGET_DESTROY(archiver->contents_clist_menu);
	archiver->contents_clist_menu = menu = GUIMenuCreate();

#define DO_ADD_MENU_ITEM_LABEL		{	\
 edv_archiver_opid_struct *opid =		\
  EDVArchiverMatchOPID(archiver, op);		\
 if(opid != NULL) {				\
  w = GUIMenuItemCreate(			\
   menu, GUI_MENU_ITEM_TYPE_LABEL, accelgrp,	\
   (guint8 **)((icon_data != NULL) ?		\
    icon_data : opid->menu_icon_data),		\
   opid->menu_name,				\
   opid->accel_key, opid->accel_mods, NULL,	\
   opid, EDVArchiverMenuItemCB			\
  );						\
  GUISetMenuItemCrossingCB(			\
   w,						\
   (gpointer)EDVArchiverMenuItemEnterCB, opid,	\
   (gpointer)EDVArchiverMenuItemLeaveCB, opid	\
  );						\
 } else {					\
  w = NULL;					\
 }						\
}

#define DO_ADD_MENU_SEP		{		\
 w = GUIMenuItemCreate(				\
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL,	\
  NULL, NULL, 0, 0, NULL,			\
  NULL, NULL					\
 );						\
}

	op = EDV_ARCHIVER_OP_ADD;
	DO_ADD_MENU_ITEM_LABEL
	GUISetMenuItemDefault(w);
	archiver->contents_clist_add_mi = w;

	op = EDV_ARCHIVER_OP_EXTRACT;
	DO_ADD_MENU_ITEM_LABEL
	archiver->contents_clist_extract_mi = w;

	op = EDV_ARCHIVER_OP_EXTRACT_ALL;
	DO_ADD_MENU_ITEM_LABEL
	archiver->contents_clist_extract_all_mi = w;

	op = EDV_ARCHIVER_OP_DELETE;
	DO_ADD_MENU_ITEM_LABEL
	archiver->contents_clist_delete_mi = w;

	DO_ADD_MENU_SEP

	op = EDV_ARCHIVER_OP_COMMENT_AND_STATISTICS;
	DO_ADD_MENU_ITEM_LABEL
	archiver->contents_clist_comment_and_statistics_mi = w;

	DO_ADD_MENU_SEP

	op = EDV_ARCHIVER_OP_PROPERTIES;
	DO_ADD_MENU_ITEM_LABEL
	archiver->contents_clist_properties_mi = w;

#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_SEP
}


/*
 *	Sets the Archiver's current values to the configuration.
 */
void EDVArchiverSyncConfiguration(edv_archiver_struct *archiver)
{
	GtkWidget *w;
	edv_core_struct *core_ptr;
	cfg_item_struct *cfg_list;

	if(archiver == NULL)
	    return;

	core_ptr = EDV_CORE(archiver->core_ptr);
	if(core_ptr == NULL)
	    return;

	cfg_list = core_ptr->cfg_list;

	/* Location history */
	w = archiver->location_combo;
	if(w != NULL)
	{
	    EDVSaveFileGList(
		EDV_GET_S(EDV_CFG_PARM_FILE_ARCHIVER_LOCATION_HISTORY),
		GUIComboGetList(w)
	    );
	}

	/* Toplevel geometry */
	w = archiver->toplevel;
	if(w != NULL)
	{
	    GdkWindow *window = w->window;
	    gint x = 0, y = 0;

	    if(window != NULL)
		gdk_window_get_root_origin(window, &x, &y);

	    EDV_SET_I(EDV_CFG_PARM_ARCHIVER_X, x);
	    EDV_SET_I(EDV_CFG_PARM_ARCHIVER_Y, y);
	    EDV_SET_I(EDV_CFG_PARM_ARCHIVER_WIDTH, w->allocation.width);
	    EDV_SET_I(EDV_CFG_PARM_ARCHIVER_HEIGHT, w->allocation.height);
	}

	/* EDV_CFG_PARM_ARCHIVER_CONTENTS_COLUMN_WIDTH parameter is updated
	 * as they change in EDVArchiverResizeColumnCB() or when the
	 * configuration list is changed directly
	 */

	/* EDV_CFG_PARM_ARCHIVER_CONTENTS_COLUMN parameter is updated
	 * when the configuration list is changed directly
	 */
}

/*
 *	Sets the Archiver's Location Bar to refer to the archive
 *	specified by arch_obj and updates the Contents List to reflect
 *	the contents of the archive.
 */
void EDVArchiverSelectArchive(
	edv_archiver_struct *archiver, const gchar *arch_obj,
	const gchar *password
)
{
	gboolean show_info_on_open;
	gulong size;
	gchar *darch_obj, *dpassword;
	GtkCList *clist;
	const cfg_item_struct *cfg_list;
	edv_core_struct *core_ptr;
	struct stat stat_buf;

	if((archiver == NULL) || STRISEMPTY(arch_obj))
	    return;

	clist = (GtkCList *)archiver->contents_clist;
	core_ptr = EDV_CORE(archiver->core_ptr);
	if((clist == NULL) || (core_ptr == NULL))
	    return;

	cfg_list = core_ptr->cfg_list;

	/* Get configuration */
	show_info_on_open = EDV_GET_B(
	    EDV_CFG_PARM_ARCHIVER_SHOW_ARCHIVE_INFO_ON_OPEN
	);

	darch_obj = STRDUP(arch_obj);
	dpassword = STRDUP(password);

	/* Check if archive exists and get its size */
	if(stat(darch_obj, &stat_buf))
	    size = 0l;
	else if(!S_ISREG(stat_buf.st_mode))
	    size = 0l;
	else
	    size = stat_buf.st_size;

	/* Update title and Location Bar */
	EDVArchiverSetTitle(archiver, darch_obj);
	EDVArchiverSetLocation(archiver, darch_obj, TRUE);
	EDVArchiverSetPassword(archiver, dpassword);
	EDVArchiverUpdateLocationIcon(archiver, darch_obj);

	/* Clear contents list and update it with the list of objects
	 * found in the archive
	 */
	gtk_clist_freeze(clist);
	EDVArchiverContentsDoUpdate(
	    archiver,
	    EDV_GET_B(EDV_CFG_PARM_LISTS_ANIMATE_UPDATES)
	);
	gtk_clist_thaw(clist);

	/* Does the archive have a non-zero size (implying it is not
	 * an empty new archive) and we should show the archive info
	 * on open?
	 */
	if((size > 0l) && show_info_on_open)
	    EDVArchiverOPCommentAndStatistics(archiver);

	g_free(darch_obj);
	g_free(dpassword);
}


/*
 *	Creates a new Archiver Operation IDs list.
 */
edv_archiver_opid_struct **EDVArchiverOPIDListNew(
	edv_archiver_struct *archiver,      /* Can be NULL */
	gint *total
)
{
	edv_archiver_op op;
	gboolean allow_multiple;
	toolbar_item_type tb_item_type;
	const gchar *button_name, *menu_name, *tooltip;
	guint accel_key, accel_mods;
	guint8 **button_icon_data, **menu_icon_data;
	edv_archiver_opid_struct **list, *opid;
	void (*func_cb)(toolbar_item_struct *, gint, gpointer);
	void (*enter_func_cb)(toolbar_item_struct *, gint, gpointer);

	if(total == NULL)
	    return(NULL);

	*total = 0;
	list = NULL;

#define DO_APPEND_OPID	{				\
 const gint i = MAX(*total, 0);				\
 *total = i + 1;					\
 list = (edv_archiver_opid_struct **)g_realloc(		\
  list,							\
  (*total) * sizeof(edv_archiver_opid_struct *)		\
 );							\
 if(list == NULL) {					\
  *total = 0;						\
  return(list);						\
 } else {						\
  list[i] = opid = EDV_ARCHIVER_OPID(g_malloc0(		\
   sizeof(edv_archiver_opid_struct)			\
  ));							\
  if(opid != NULL) {					\
   opid->archiver = archiver;				\
   opid->op = op;					\
   opid->allow_multiple = allow_multiple;		\
   opid->tb_item_type = tb_item_type;			\
   opid->func_cb = func_cb;				\
   opid->enter_func_cb = enter_func_cb;			\
   opid->button_name = STRDUP(button_name);		\
   opid->menu_name = STRDUP(menu_name);			\
   opid->tooltip = STRDUP(tooltip);			\
   opid->accel_key = accel_key;				\
   opid->accel_mods = accel_mods;			\
   opid->button_icon_data = button_icon_data;		\
   opid->menu_icon_data = menu_icon_data;		\
  }							\
 }							\
}

	func_cb = EDVArchiverOPCB;
	enter_func_cb = EDVArchiverOPEnterCB;


	op = EDV_ARCHIVER_OP_SEPARATOR;
	tb_item_type = TOOLBAR_ITEM_SEPARATOR;
	allow_multiple = TRUE;
	button_icon_data = (guint8 **)icon_hsep_20x20_xpm;
	menu_icon_data = button_icon_data;
#if defined(PROG_LANGUAGE_SPANISH)
	button_name = "Separador";
	menu_name = "Separador";
	tooltip = "Separador";
#elif defined(PROG_LANGUAGE_FRENCH)
	button_name = "Séparateur";
	menu_name = "Séparateur";
	tooltip = "Séparateur";
#elif defined(PROG_LANGUAGE_GERMAN)
	button_name = "Separator";
	menu_name = "Separator";
	tooltip = "Separator";
#elif defined(PROG_LANGUAGE_ITALIAN)
	button_name = "Separatore";
	menu_name = "Separatore";
	tooltip = "Separatore";
#elif defined(PROG_LANGUAGE_DUTCH)
	button_name = "Separator";
	menu_name = "Separator";
	tooltip = "Separator";
#elif defined(PROG_LANGUAGE_PORTUGUESE)
	button_name = "Separador";
	menu_name = "Separador";
	tooltip = "Separador";
#elif defined(PROG_LANGUAGE_NORWEGIAN)
	button_name = "Separator";
	menu_name = "Separator";
	tooltip = "Separator";
#else
	button_name = "Separator";
	menu_name = "Separator";
	tooltip = "Separator";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_CLOSE;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_close_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Close";
	menu_name = "Close";
	tooltip = "Close this window";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Cierre";
	menu_name = "Cierre";
	tooltip = "Cierre esta ventana";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Proche";
	menu_name = "Proche";
	tooltip = "Fermer cette fenêtre";
#endif
	accel_key = GDK_w;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_EXIT;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_exit_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Exit";
	menu_name = "Exit";
	tooltip = "Close all windows in the application and exit";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "La Salida";
	menu_name = "La Salida";
	tooltip = "Cierra todas ventanas en la aplicación y la";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Sortie";
	menu_name = "Sortie";
	tooltip = "Ferme toutes fenêtres dans l'application et sortie";
#endif
	accel_key = GDK_q;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_SYNC_DISKS;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_save_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Sync Disks";
	menu_name = "Sync Disks";
	tooltip = "Flush any pending data transfers to disk";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Discos Sincro";
	menu_name = "Discos Sincro";
	tooltip = "Limpían cualquiera transferencias pendientes de datos al disco";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Disq Syn";
	menu_name = "Les Disques De Syn";
	tooltip = "Rincer des transferts de données en attente au disque";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_RUN;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_run_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Run";
	menu_name = "Run...";
	tooltip = "Run a program";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Corra";
	menu_name = "Corra...";
	tooltip = "Corra un programa";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Courir";
	menu_name = "Courir...";
	tooltip = "Exécute un programme";
#endif
	accel_key = GDK_r;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_RUN_TERMINAL;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_terminal_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Terminal";
	menu_name = "Terminal";
	tooltip = "Run a terminal";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "La Terminal";
	menu_name = "La Terminal";
	tooltip = "Corre una terminal";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Le Terminal";
	menu_name = "Le Terminal";
	tooltip = "Courir un terminal";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_WRITE_PROTECT;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_secure_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Protect";
	menu_name = "Write Protect";
	tooltip = "Enable/disable write protect";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Proteja";
	menu_name = "Escriba Proteja";
	tooltip = "Habilite/incapacita escribe protege";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Protége";
	menu_name = "Protége En écriture";
	tooltip = "Rend capable/rend infirme protége en écriture";
#endif
	accel_key = GDK_y;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_NEW;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_new_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "New";
	menu_name = "New...";
	tooltip = "Create a new archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Nuevo";
	menu_name = "Nuevo...";
	tooltip = "Crea un archivo nuevo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Nouveau";
	menu_name = "Nouveau...";
	tooltip = "Créer une nouvelle archive";
#endif
	accel_key = GDK_n;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_OPEN;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_open_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Open";
	menu_name = "Open...";
	tooltip = "Open an archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Abierto";
	menu_name = "Abierto...";
	tooltip = "Abre un archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Ouvert";
	menu_name = "Ouvert...";
	tooltip = "Ouvrir une archive";
#endif
	accel_key = GDK_F3;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_ADD;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_archive_add_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Add";
	menu_name = "Add...";
	tooltip = "Add objects to archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Agregue";
	menu_name = "Agregue...";
	tooltip = "Agregue objetos al archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Ajouter";
	menu_name = "Ajouter...";
	tooltip = "Ajoute des objets à l'archive";
#endif
	accel_key = GDK_Insert;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_EXTRACT;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_archive_extract_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Extract";
	menu_name = "Extract...";
	tooltip = "Extract selected object(s) from archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Extracto";
	menu_name = "El Extracto...";
	tooltip = "El Extracto escogió se opone(s) del archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "L'Extrait";
	menu_name = "L'Extrait...";
	tooltip = "L'Extrait a choisi l'objet (s) de l'archive";
#endif
	accel_key = GDK_Return;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_EXTRACT_ALL;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_archive_extract_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "ExtractAll";
	menu_name = "Extract All...";
	tooltip = "Extract all objects from archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "ExtrTodo";
	menu_name = "Extraiga Todo...";
	tooltip = "Extrae todo se opone del archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "ExtrTout";
	menu_name = "Extraire Tout...";
	tooltip = "Extraire tous objets de l'archive";
#endif
	accel_key = GDK_Return;
	accel_mods = GDK_SHIFT_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_DELETE;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_cancel_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Delete";
	menu_name = "Delete";
	tooltip = "Delete selected object(s) from archive";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Borre";
	menu_name = "Borre";
	tooltip = "Borre escogido se opone(s) del archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Effacer";
	menu_name = "Effacer";
	tooltip = "Efface l'objet choisi (s) de l'archive";
#endif
	accel_key = GDK_Delete;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_SELECT_ALL;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_select_all_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "SelAll";
	menu_name = "Select All";
	tooltip = "Select all objects";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "SelAll";
	menu_name = "Escoja Todo";
	tooltip = "Escoge todo se opone";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "SelAll";
	menu_name = "Choisir Tout";
	tooltip = "Choisir tous objets";
#endif
	accel_key = GDK_a;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_UNSELECT_ALL;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_unselect_all_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "UnSelAll";
	menu_name = "Unselect All";
	tooltip = "Unselect all objects";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "UnSelAll";
	menu_name = "Unescoja Todo";
	tooltip = "Unescoge todo se opone";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "UnSelAll";
	menu_name = "Unchoisir Tout";
	tooltip = "Unchoisir tous objets";
#endif
	accel_key = GDK_u;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_INVERT_SELECTION;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_invert_selection_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "InvSel";
	menu_name = "Invert Selection";
	tooltip =
 "Select all unselected objects and unselect all selected objects";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "InvSel";
	menu_name = "Invierta Selección";
	tooltip =
 "Selectos todos objetos y unselect no seleccionados todos objetos escogidos";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "InvSel";
	menu_name = "Inverser Sélection";
	tooltip =
 "Choisir tous objets désélectionés et desélectionner tous objets choisis";
#endif
	accel_key = GDK_i;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_FIND;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_search_20x20_xpm;;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Find";
	menu_name = "Find...";
	tooltip = "Find object(s) by specific attributes";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Hallazgo";
	menu_name = "El Hallazgo";
	tooltip = "El Hallazgo se opone (s) por atributos especificados";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Découverte";
	menu_name = "La Découverte";
	tooltip = "L'objet de Découverte (s) par les attributs spécifiés ";
#endif
	accel_key = GDK_f;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_PROPERTIES;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_properties2_20x20_xpm;;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Properties";
	menu_name = "Properties...";
	tooltip = "Modify selected object's properties";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Props";
	menu_name = "Las Propiedades";
	tooltip = "Modifican escogió las propiedades de objeto";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Props";
	menu_name = "Les Propriétés";
	tooltip = "Modifier a choisi les propriétés de l'objet";
#endif
	accel_key = GDK_Return;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_HISTORY;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_trace_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "History";
	menu_name = "History...";
	tooltip = "History of commands processed by this application";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Historia";
	menu_name = "La Historia...";
	tooltip = "La Historia de órdenes procesadas por esta aplicación";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "L'Histoire";
	menu_name = "L'Histoire...";
	tooltip = "L'Histoire d'ordres traités par cette application";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_REFRESH;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_reload_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Refresh";
	menu_name = "Refresh";
	tooltip = "Refresh the archive objects listing";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Refresque";
	menu_name = "Refresque";
	tooltip = "Refresque objetos de archivo que listan";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Rafraîchir";
	menu_name = "Rafraîchir";
	tooltip = "Rafraîchit les objets d'archive énumérants";
#endif
	accel_key = GDK_F5;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_REFRESH_ALL;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_reload_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Refresh All";
	menu_name = "Refresh All";
	tooltip = "Refresh all listings";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Refresque Todo";
	menu_name = "Refresque Todo";
	tooltip = "Refresca todas listas";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Rafraîchir Tout";
	menu_name = "Rafraîchir Tout";
	tooltip = "Rafraîchir toutes listes";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_COMMENT_AND_STATISTICS;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_info_20x20_xpm;
	menu_icon_data = button_icon_data;
#if defined(PROG_LANGUAGE_SPANISH)
	button_name = "Info";
	menu_name = "El Comentario & La Estadística";
	tooltip = "Vea el comentario & la estadística";
#elif defined(PROG_LANGUAGE_FRENCH)
	button_name = "Info";
	menu_name = "Commenter & La Statistique";
	tooltip = "Regarder le commentaire & la statistique";
#elif defined(PROG_LANGUAGE_GERMAN)
	button_name = "Info";
	menu_name = "Bemerkung & Statistik";
	tooltip = "Siehe bemerkung & statistik an";
#elif defined(PROG_LANGUAGE_ITALIAN)
	button_name = "Info";
	menu_name = "Il Commento & La Statistica";
	tooltip = "Osservare il commento & la statistica";
#elif defined(PROG_LANGUAGE_DUTCH)
	button_name = "Info";
	menu_name = "Opmerking & Statistieken";
	tooltip = "Bekijk opmerking & statistieken";
#elif defined(PROG_LANGUAGE_PORTUGUESE)
	button_name = "Info";
	menu_name = "O Comentário & Estatística";
	tooltip = "Veja comentário & estatística";
#elif defined(PROG_LANGUAGE_NORWEGIAN)
	button_name = "Info";
	menu_name = "Kommentar & Statistics";
	tooltip = "Sikt kommentar & statistikk";
#else
	button_name = "Info";
	menu_name = "Comment & Statistics";
	tooltip = "View comment & statistics";
#endif
	accel_key = GDK_F9;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_SHOW_TOOL_BAR;
	tb_item_type = TOOLBAR_ITEM_TOGGLE_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_tool_bar_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "ToolBar";
	menu_name = "Tool Bar";
	tooltip = "Show/hide tool bar";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "ToolBar";
	menu_name = "Tool Bar";
	tooltip = "La Exposición/la barra de herramienta de cuero";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "ToolBar";
	menu_name = "Tool Bar";
	tooltip = "La barre d'outil de montre/peau";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_SHOW_LOCATION_BAR;
	tb_item_type = TOOLBAR_ITEM_TOGGLE_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_tool_bar_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "LocBar";
	menu_name = "Location Bar";
	tooltip = "Show/hide location bar";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "LocBar";
	menu_name = "Location Bar";
	tooltip = "La exposición/la barra de la ubicación del cuero";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "LocBar";
	menu_name = "Location Bar";
	tooltip = "La barre d'emplacement de montre/peau";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_SHOW_FIND_BAR;
	tb_item_type = TOOLBAR_ITEM_TOGGLE_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_tool_bar_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "FindBar";
	menu_name = "Find Bar";
	tooltip = "Show/hide find bar";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "FindBar";
	menu_name = "Find Bar";
	tooltip = "La exposición/la barra del hallazgo del cuero";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "FindBar";
	menu_name = "Find Bar";
	tooltip = "La barre de découverte de montre/peau";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_SHOW_STATUS_BAR;
	tb_item_type = TOOLBAR_ITEM_TOGGLE_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_status_bar_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "StatusBar";
	menu_name = "Status Bar";
	tooltip = "Show/hide status bar";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "StatusBar";
	menu_name = "Status Bar";
	tooltip = "La exposición/la barra de la posición del cuero";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "StatusBar";
	menu_name = "Status Bar";
	tooltip = "La barre de statut de montre/peau";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_MIME_TYPES;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_mimetypes_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "MIMETypes";
	menu_name = "MIME Types...";
	tooltip = "View/modify MIME Types";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "MIMETypes";
	menu_name = "MIME Types...";
	tooltip = "El panorama/modifica MIME Types";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "MIMETypes";
	menu_name = "MIME Types...";
	tooltip = "Vue/modifie MIME Types";
#endif
	accel_key = GDK_m;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_NEW_BROWSER;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)endeavour_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "FBrowser";
	menu_name = "New File Browser";
	tooltip = "Create a new file browser";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "FBrowser";
	menu_name = "El Examinador Nuevo Del Archivo";
	tooltip = "Crea a un examinador nuevo del archivo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "FBrowser";
	menu_name = "Nouveau Browser de Fichier";
	tooltip = "Créer un nouveau browser de fichier";
#endif
	accel_key = GDK_1;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_NEW_IMBR;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)image_browser_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "IBrowser";
	menu_name = "New Image Browser";
	tooltip = "Create a new image browser";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "IBrowser";
	menu_name = "El Examinador Nuevo De La Imagen";
	tooltip = "Crea a un examinador nuevo de la imagen";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "IBrowser";
	menu_name = "Nouveau Browser D'Image";
	tooltip = "Créer un nouveau browser d'image";
#endif
	accel_key = GDK_2;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_NEW_ARCHIVER;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)archiver_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Archiver";
	menu_name = "New Archiver";
	tooltip = "Create a new archiver";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Archiver";
	menu_name = "Archiver Nuevo";
	tooltip = "Crea un archiver nuevo";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Archiver";
	menu_name = "Nouveau Archiver";
	tooltip = "Créer un nouveau archiver";
#endif
	accel_key = GDK_3;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_RECYCLE_BIN;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_trash_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "RecBin";
	menu_name = "Recycle Bin";
	tooltip = "Open Recycle Bin";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "RecBin";
	menu_name = "El Cajón De La Recirculación";
	tooltip = "Cajón de Recirculación (basura puede)";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "RecBin";
	menu_name = "Recycler L'Huche";
	tooltip = "Recycler l'huche (la poubelle)";
#endif
	accel_key = GDK_4;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_OPTIONS;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_options2_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Options";
	menu_name = "Options...";
	tooltip = "Modify this application's options";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Las Opciones";
	menu_name = "Las Opciones...";
	tooltip = "Modifican estas opciones de la aplicación";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Les Options";
	menu_name = "Les Options";
	tooltip = "Modifier ces options de l'application";
#endif
	accel_key = GDK_o;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_CUSTOMIZE;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_customize_20x20_xpm;
	menu_icon_data = button_icon_data;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Custom";
	menu_name = "Customize...";
	tooltip = "Customize the look and feel of this application";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Personal";
	menu_name = "Personaliza...";
	tooltip = "Personaliza la mirada y se siente de esta aplicación";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "Personnal";
	menu_name = "Personnalise...";
	tooltip = "Personnalise le regard et sens de cette application";
#endif
	accel_key = GDK_t;
	accel_mods = GDK_CONTROL_MASK;
	DO_APPEND_OPID


	op = EDV_ARCHIVER_OP_HELP_CONTENTS;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "Help";
	menu_name = "Contents";
	tooltip = "Index of all help pages";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "La Ayuda";
	menu_name = "El Contenido";
	tooltip = "El Indice de toda ayuda pagina";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "L'Aide";
	menu_name = "Les Contenus";
	tooltip = "L'Index de toutes pages d'aide";
#endif
	accel_key = GDK_F1;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_FILE_BROWSER;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
	button_name = "Help";
	menu_name = "File Browser";
	tooltip = "Help on using the file browser";
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_IMAGE_BROWSER;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
	button_name = "Help";
	menu_name = "Image Browser";
	tooltip = "Help on using the image browser";
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_ARCHIVER;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
	button_name = "Help";
	menu_name = "Archiver";
	tooltip = "Help on using the archiver";
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_RECYCLE_BIN;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
	button_name = "Help";
	menu_name = "Recycle Bin";
	tooltip = "Help on using the recycle bin";
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_KEYS_LIST;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "HelpKeys";
	menu_name = "Keys List";
	tooltip = "List of all keyboard key operations";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "HelpKeys";
	menu_name = "La Lista De Llaves";
	tooltip = "La Lista de todo teclado las operaciones claves";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "HelpKeys";
	menu_name = "La Liste De Clefs";
	tooltip = "La Liste de tout clavier toutes opérations principales";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_COMMON_OPERATIONS;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_help_20x20_xpm;
	menu_icon_data = NULL;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "HelpMIME";
	menu_name = "Mime Types";
	tooltip = "Help on setting up MIME Types";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "HelpMIME";
	menu_name = "Mime Types";
	tooltip = "Ayude a establecer MIME Types";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "HelpMIME";
	menu_name = "Mime Types";
	tooltip = "Aider sur montant MIME Types";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID

	op = EDV_ARCHIVER_OP_HELP_ABOUT;
	tb_item_type = TOOLBAR_ITEM_BUTTON;
	allow_multiple = FALSE;
	button_icon_data = (guint8 **)icon_about_20x20_xpm;
	menu_icon_data = (guint8 **)icon_about_20x20_xpm;
#ifdef PROG_LANGUAGE_ENGLISH
	button_name = "About";
	menu_name = "About";
	tooltip = "About this application";
#endif
#ifdef PROG_LANGUAGE_SPANISH
	button_name = "Acerca";
	menu_name = "Acerca De";
	tooltip = "Acerca de esta aplicación";
#endif
#ifdef PROG_LANGUAGE_FRENCH
	button_name = "De";
	menu_name = "De";
	tooltip = "De cette application";
#endif
	accel_key = 0;
	accel_mods = 0;
	DO_APPEND_OPID


#undef DO_APPEND_OPID

	return(list);
}

/*
 *	Deletes the Archiver Operation IDs list.
 */
void EDVArchiverOPIDListDelete(
	edv_archiver_opid_struct **list, gint total
)
{
	gint i;
	edv_archiver_opid_struct *opid;

	if(list == NULL)
	    return;

	for(i = 0; i < total; i++)
	{
	    opid = list[i];
	    if(opid == NULL)
		continue;

	    g_free(opid->button_name);
	    g_free(opid->menu_name);
	    g_free(opid->tooltip);

	    g_free(opid);
	}
	g_free(list);
}


/*
 *	Creates the Archiver's Menu Bar.
 *
 *	This function should be called by EDVArchiverNew().
 */
static void EDVArchiverCreateMenuBar(
	edv_archiver_struct *archiver, GtkWidget *parent
)
{
	edv_archiver_op op;
	guint8 **icon_data = NULL;
	GtkAccelGroup *accelgrp = archiver->accelgrp;
	GtkWidget *w, *menu, *menu_bar;

	/* Create menu bar */
	archiver->menu_bar = menu_bar = GUIMenuBarCreate(NULL);
	gtk_container_add(GTK_CONTAINER(parent), menu_bar);
	gtk_widget_show(menu_bar);

#define DO_ADD_MENU_ITEM_LABEL		{	\
 edv_archiver_opid_struct *opid =		\
  EDVArchiverMatchOPID(archiver, op);		\
 if(opid != NULL) {				\
  w = GUIMenuItemCreate(			\
   menu, GUI_MENU_ITEM_TYPE_LABEL, accelgrp,	\
   (guint8 **)((icon_data != NULL) ?		\
    icon_data : opid->menu_icon_data),		\
   opid->menu_name,				\
   opid->accel_key, opid->accel_mods, NULL,	\
   opid, EDVArchiverMenuItemCB			\
  );						\
  GUISetMenuItemCrossingCB(			\
   w,						\
   (gpointer)EDVArchiverMenuItemEnterCB, opid,	\
   (gpointer)EDVArchiverMenuItemLeaveCB, opid	\
  );						\
 } else {					\
  w = NULL;					\
 }						\
}

#define DO_ADD_MENU_ITEM_SUBMENU	{	\
 edv_archiver_opid_struct *opid =		\
  EDVArchiverMatchOPID(archiver, op);		\
 if(opid != NULL) {				\
  w = GUIMenuItemCreate(			\
   menu, GUI_MENU_ITEM_TYPE_SUBMENU, accelgrp,	\
   (guint8 **)((icon_data != NULL) ?		\
    icon_data : opid->menu_icon_data),		\
   opid->menu_name,				\
   opid->accel_key, opid->accel_mods, NULL,	\
   opid, NULL					\
  );						\
  GUISetMenuItemCrossingCB(			\
   w,						\
   (gpointer)EDVArchiverMenuItemEnterCB, opid,	\
   (gpointer)EDVArchiverMenuItemLeaveCB, opid	\
  );						\
  if(w != NULL)					\
   GUIMenuItemSetSubMenu(w, submenu);		\
  if(w_record != NULL)				\
   *w_record = w;				\
 }						\
}

#define DO_ADD_MENU_ITEM_CHECK		{	\
 edv_archiver_opid_struct *opid =		\
  EDVArchiverMatchOPID(archiver, op);		\
 if(opid != NULL) {				\
  w = GUIMenuItemCreate(			\
   menu, GUI_MENU_ITEM_TYPE_CHECK, accelgrp,	\
   (guint8 **)((icon_data != NULL) ?		\
    icon_data : opid->menu_icon_data),		\
   opid->menu_name,				\
   opid->accel_key, opid->accel_mods, NULL,	\
   opid, EDVArchiverMenuItemCB			\
  );						\
  GUISetMenuItemCrossingCB(			\
   w,						\
   (gpointer)EDVArchiverMenuItemEnterCB, opid,	\
   (gpointer)EDVArchiverMenuItemLeaveCB, opid	\
  );						\
 } else {					\
  w = NULL;					\
 }						\
}

#define DO_ADD_MENU_SEP		{		\
 w = GUIMenuItemCreate(				\
  menu, GUI_MENU_ITEM_TYPE_SEPARATOR, NULL,	\
  NULL, NULL, 0, 0, NULL,			\
  NULL, NULL					\
 );						\
}

	/* Create Menus */
	/* File */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_NEW;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->new_mi = w;

	    op = EDV_ARCHIVER_OP_OPEN;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->open_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_SYNC_DISKS;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->sync_disks_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_HISTORY;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->history_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_RUN;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->run_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_CLOSE;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->close_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Fichier"
#elif defined(PROG_LANGUAGE_GERMAN)
"Akte"
#elif defined(PROG_LANGUAGE_ITALIAN)
"File"
#elif defined(PROG_LANGUAGE_DUTCH)
"Dossier"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Arkiv"
#else
"File"
#endif
	    , GUI_MENU_BAR_ALIGN_LEFT
	);

	/* Edit */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_ADD;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->edit_add_mi = w;

	    op = EDV_ARCHIVER_OP_EXTRACT;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->edit_extract_mi = w;

	    op = EDV_ARCHIVER_OP_EXTRACT_ALL;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->edit_extract_all_mi = w;

	    op = EDV_ARCHIVER_OP_DELETE;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->edit_delete_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_SELECT_ALL;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->select_all_mi = w;

	    op = EDV_ARCHIVER_OP_UNSELECT_ALL;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->unselect_all_mi = w;

	    op = EDV_ARCHIVER_OP_INVERT_SELECTION;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->invert_selection_mi = w;

	    op = EDV_ARCHIVER_OP_FIND;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->find_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_PROPERTIES;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->properties_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Redacte"
#elif defined(PROG_LANGUAGE_FRENCH)
"Editer"
#elif defined(PROG_LANGUAGE_GERMAN)
"Redigieren"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Redigere"
#elif defined(PROG_LANGUAGE_DUTCH)
"Bewerking"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Edite"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Rediger"
#else
"Edit"
#endif
	    , GUI_MENU_BAR_ALIGN_LEFT
	);

	/* View */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_REFRESH;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->refresh_mi = w;

	    op = EDV_ARCHIVER_OP_REFRESH_ALL;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->refresh_all_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_COMMENT_AND_STATISTICS;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->comment_and_statistics_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_SHOW_TOOL_BAR;
	    DO_ADD_MENU_ITEM_CHECK
	    archiver->show_tool_bar_micheck = w;

	    op = EDV_ARCHIVER_OP_SHOW_LOCATION_BAR;
	    DO_ADD_MENU_ITEM_CHECK
	    archiver->show_location_bar_micheck = w;

	    op = EDV_ARCHIVER_OP_SHOW_FIND_BAR;
	    DO_ADD_MENU_ITEM_CHECK
	    archiver->show_find_bar_micheck = w;

	    op = EDV_ARCHIVER_OP_SHOW_STATUS_BAR;
	    DO_ADD_MENU_ITEM_CHECK
	    archiver->show_status_bar_micheck = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_MIME_TYPES;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->mime_types_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Vista"
#elif defined(PROG_LANGUAGE_FRENCH)
"Vue"
#elif defined(PROG_LANGUAGE_GERMAN)
"Blick"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Veduta"
#elif defined(PROG_LANGUAGE_DUTCH)
"Overzicht"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Vista"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Sikt"
#else
"View"
#endif
	    , GUI_MENU_BAR_ALIGN_LEFT
	);

	/* Settings */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_WRITE_PROTECT;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->write_protect_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_OPTIONS;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->options_mi = w;

	    op = EDV_ARCHIVER_OP_CUSTOMIZE;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->customize_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Escenarios"
#elif defined(PROG_LANGUAGE_FRENCH)
"Montages"
#elif defined(PROG_LANGUAGE_GERMAN)
"Setzen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Montaggi"
#elif defined(PROG_LANGUAGE_DUTCH)
"Zetten"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Por"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Innstillinger"
#else
"Settings"
#endif
	    , GUI_MENU_BAR_ALIGN_LEFT
	);

	/* Windows */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_NEW_BROWSER;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->window_new_browser_mi = w;

	    op = EDV_ARCHIVER_OP_NEW_IMBR;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->window_new_imbr_mi = w;

	    op = EDV_ARCHIVER_OP_NEW_ARCHIVER;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->window_new_archiver_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_RECYCLE_BIN;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->window_recycle_bin_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Ventanas"
#elif defined(PROG_LANGUAGE_FRENCH)
"Windows"
#elif defined(PROG_LANGUAGE_GERMAN)
"Fenster"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Finestre"
#elif defined(PROG_LANGUAGE_DUTCH)
"Ramen"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Janelas"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Vinduer"
#else
"Windows"
#endif
	    , GUI_MENU_BAR_ALIGN_LEFT
	);

	/* Help */
	menu = GUIMenuCreateTearOff();
	if(menu != NULL)
	{
	    op = EDV_ARCHIVER_OP_HELP_CONTENTS;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->help_contents_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_HELP_ARCHIVER;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->help_archiver_mi = w;

	    op = EDV_ARCHIVER_OP_HELP_KEYS_LIST;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->help_keys_list_mi = w;

	    op = EDV_ARCHIVER_OP_HELP_COMMON_OPERATIONS;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->help_common_operations_mi = w;

	    DO_ADD_MENU_SEP

	    op = EDV_ARCHIVER_OP_HELP_ABOUT;
	    DO_ADD_MENU_ITEM_LABEL
	    archiver->help_about_mi = w;
	}
	GUIMenuAddToMenuBar(
	    menu_bar, menu,
#if defined(PROG_LANGUAGE_SPANISH)
"Ayuda"
#elif defined(PROG_LANGUAGE_FRENCH)
"Aide"
#elif defined(PROG_LANGUAGE_GERMAN)
"Hilfe"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Aiuto"
#elif defined(PROG_LANGUAGE_DUTCH)
"Hulp"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Ajuda"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Hjelp"
#else
"Help"
#endif
	    , GUI_MENU_BAR_ALIGN_RIGHT
	);

#undef DO_ADD_MENU_ITEM_LABEL
#undef DO_ADD_MENU_ITEM_SUBMENU
#undef DO_ADD_MENU_ITEM_CHECK
#undef DO_ADD_MENU_SEP
}

/*
 *	Creates a new Archiver.
 */
edv_archiver_struct *EDVArchiverNew(gpointer core_ptr)
{
	gint i;
	const gchar	*location_history_file = NULL;
	gint		border_major = 5;
	gint		toplevel_x = 0,
			toplevel_y = 0,
			toplevel_width = EDV_DEF_ARCHIVER_WIDTH,
			toplevel_height = EDV_DEF_ARCHIVER_HEIGHT;
	gboolean	tool_bar_map_state = TRUE,
			location_bar_map_state = TRUE,
			find_bar_map_state = TRUE,
			status_bar_map_state = TRUE;
	const gchar	*wm_name = NULL,
			*wm_class = NULL;
	gpointer entry_rtn, combo_rtn;
	GList *glist;
	const cfg_item_struct *cfg_list = (core_ptr != NULL) ?
	    EDV_CORE(core_ptr)->cfg_list : NULL;
	GdkCursor *cursor;
	GdkWindow *window;
	GtkAccelGroup *accelgrp;
	GtkRcStyle	*standard_rcstyle = NULL,
			*lists_rcstyle = NULL;
	GtkStyle *style;
	GtkWidget *w, *parent, *parent2, *parent3, *parent4;
	GtkEntry *entry;
	GtkCombo *combo;
	GtkCList *clist;
	edv_status_bar_struct *status_bar;
	const GtkTargetEntry dnd_tar_types[] = {
{"text/plain",				0,	EDV_DND_TYPE_INFO_TEXT_PLAIN},
{"text/uri-list",			0,	EDV_DND_TYPE_INFO_TEXT_URI_LIST},
{"STRING",				0,	EDV_DND_TYPE_INFO_STRING}
	};
	const GtkTargetEntry dnd_src_types[] = {
{EDV_DND_TYPE_STRING_ARCHIVE_OBJECT,	0,	EDV_DND_TYPE_INFO_ARCHIVE_OBJECT}
	};
	edv_archiver_struct *archiver = EDV_ARCHIVER(
	    g_malloc0(sizeof(edv_archiver_struct))
	);
	if(archiver == NULL)
	    return(archiver);


	/* Get configuration */
	if(cfg_list != NULL)
	{
	    edv_core_struct *c_ptr = EDV_CORE(core_ptr);

	    standard_rcstyle = c_ptr->standard_rcstyle;
	    lists_rcstyle = c_ptr->lists_rcstyle;

	    wm_name = c_ptr->wm_name;
	    wm_class = c_ptr->wm_class;

	    location_history_file = EDV_GET_S(
		EDV_CFG_PARM_FILE_ARCHIVER_LOCATION_HISTORY
	    );

	    if(c_ptr->geometry_set)
	    {
		GdkRectangle *rect = &c_ptr->geometry;
		toplevel_x = rect->x;
		toplevel_y = rect->y;
		toplevel_width = rect->width;
		toplevel_height = rect->height;
	    }
	    else
	    {
		toplevel_x = EDV_GET_I(EDV_CFG_PARM_ARCHIVER_X);
		toplevel_y = EDV_GET_I(EDV_CFG_PARM_ARCHIVER_Y);
		toplevel_width = EDV_GET_I(EDV_CFG_PARM_ARCHIVER_WIDTH);
		toplevel_height = EDV_GET_I(EDV_CFG_PARM_ARCHIVER_HEIGHT);
	    }

	    tool_bar_map_state = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVER_SHOW_TOOL_BAR
	    );
	    location_bar_map_state = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVER_SHOW_LOCATION_BAR
	    );
	    find_bar_map_state = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVER_SHOW_FIND_BAR
	    );
	    status_bar_map_state = EDV_GET_B(
		EDV_CFG_PARM_ARCHIVER_SHOW_STATUS_BAR
	    );
	}

	archiver->accelgrp = accelgrp = gtk_accel_group_new();
	archiver->processing = FALSE;
	archiver->busy_count = 0;
	archiver->freeze_count = 0;  
	archiver->core_ptr = core_ptr;

	archiver->opid = EDVArchiverOPIDListNew(
	    archiver, &archiver->total_opids
	);

	archiver->tool_bar_map_state = tool_bar_map_state;
	archiver->location_bar_map_state = location_bar_map_state;
	archiver->find_bar_map_state = find_bar_map_state;
	archiver->status_bar_map_state = status_bar_map_state;
	archiver->contents_clist_selected_row = -1;
	archiver->last_recbin_items = -1;
	archiver->last_write_protect_state = -1;
	archiver->findbar = NULL;
	archiver->status_bar = NULL;


	/* Begin creating widgets */

	/* Toplevel */
	archiver->toplevel = w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_widget_set_uposition(
	    w, toplevel_x, toplevel_y
	);
	gtk_widget_set_usize(
	    w, toplevel_width, toplevel_height
	);
	if(!STRISEMPTY(wm_name) && !STRISEMPTY(wm_class))
	    gtk_window_set_wmclass(GTK_WINDOW(w), wm_name, wm_class);
	else
	    gtk_window_set_wmclass(
		GTK_WINDOW(w), "archiver", PROG_NAME
	    );
	gtk_window_set_policy(
	    GTK_WINDOW(w),
	    TRUE, TRUE, TRUE
	);
	gtk_widget_realize(w);
	window = w->window;
	if(window != NULL)
	{
	    GdkGeometry geo;

	    geo.min_width = 100;
	    geo.min_height = 70;
	    geo.base_width = 0;
	    geo.base_height = 0;
	    geo.width_inc = 1;
	    geo.height_inc = 1;
	    gdk_window_set_geometry_hints(
		window, &geo,
		GDK_HINT_MIN_SIZE |
		GDK_HINT_BASE_SIZE |
		GDK_HINT_RESIZE_INC
	    );

	    GUISetWMIcon(window, (guint8 **)archiver_48x48_xpm);
	}
	gtk_signal_connect(
	    GTK_OBJECT(w), "delete_event",
	    GTK_SIGNAL_FUNC(EDVArchiverDeleteEventCB), archiver
	);
	gtk_window_add_accel_group(GTK_WINDOW(w), accelgrp);
	style = gtk_widget_get_style(w);
	parent = w;


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


	/* Vbox for tool bars */
	archiver->bars_vbox = w = gtk_vbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent2 = w;


	/* Handle for menu bar */
	archiver->menu_bar_handle = w = gtk_handle_box_new();
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_attached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildAttachedCB), archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_detached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildDetachedCB), archiver
	);
	gtk_widget_show(w);
	/* Create menu bar */
	EDVArchiverCreateMenuBar(archiver, w);


	/* Handle for tool bar */
	archiver->tool_bar_handle = w = gtk_handle_box_new();
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, 0);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_attached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildAttachedCB), archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_detached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildDetachedCB), archiver
	);
	if(archiver->tool_bar_map_state)
	    gtk_widget_show(w);
	/* Build tool bar later */
	archiver->toolbar = NULL;


	/* Location bar handle box */
	archiver->location_bar_handle = w = gtk_handle_box_new();
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_attached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildAttachedCB), archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_detached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildDetachedCB), archiver
	);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	if(archiver->location_bar_map_state)
	    gtk_widget_show(w);
	parent2 = w;

	/* Hbox for location bar */
	archiver->location_bar_hbox = w = gtk_hbox_new(FALSE, 0);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_show(w);
	parent2 = w;

	/* Hbox for location icon and combo (no spacing between icon
	 * and combo needed since combo already has spacing)
	 */
	w = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent3 = w;

	/* Vbox to orient location icon fixed parent */
	w = gtk_vbox_new(TRUE, 0);
	gtk_widget_set_usize(w, 20, 20);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	parent4 = w;
	/* Location icon fixed parent */
	archiver->location_icon_fixed = w = gtk_fixed_new();
	gtk_widget_add_events(
	    w,
	    GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
	    GDK_POINTER_MOTION_MASK |
	    GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK
	);
	gtk_box_pack_start(GTK_BOX(parent4), w, TRUE, FALSE, 0);
	gtk_signal_connect(
	    GTK_OBJECT(w), "enter_notify_event",
	    GTK_SIGNAL_FUNC(EDVArchiverLocBarIconCrossingCB), archiver
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "leave_notify_event",
	    GTK_SIGNAL_FUNC(EDVArchiverLocBarIconCrossingCB), archiver
	);
	gtk_widget_realize(w);
	cursor = EDVGetCursor(
	    EDV_CORE(core_ptr), EDV_CURSOR_CODE_HAND
	);
	gdk_window_set_cursor(w->window, cursor);
	GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Arrastre esto crear una conexión a este archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Traîner ceci pour créer un lien à cette archive"
#elif defined(PROG_LANGUAGE_GERMAN)
"Schleppen sie dies, ein kettenglied zu diesem archiv zu schaffen"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Trascinare questo per creare una maglia a quest'archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Sleep dit om een schakel aan deze archief te creëren"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Arraste isto criar um elo a este arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Slep dette skape et ledd til dette arkivet"
#else
"Drag this to create a link to this archive"
#endif
	);
	gtk_widget_show(w);

	/* Reset location icon pixmap */
	archiver->location_icon_pm = NULL;

	/* Location combo */
	glist = EDVOpenFileGList(location_history_file, 0);
	w = GUIComboCreate(
#if defined(PROG_LANGUAGE_SPANISH)
"Archivo:"
#elif defined(PROG_LANGUAGE_FRENCH)
"Archive:"
#elif defined(PROG_LANGUAGE_GERMAN)
"Archiv:"
#elif defined(PROG_LANGUAGE_ITALIAN)
"L'Archivio:"
#elif defined(PROG_LANGUAGE_DUTCH)
"Archief:"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Arquivo:"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Arkiv:"
#else
"Archive:"
#endif
	    , "/",
	    glist,
	    20,		/* Maximum items */
	    &combo_rtn,
	    archiver,
	    EDVArchiverComboActivateCB,
	    NULL
	);
	if(glist != NULL)
	{
	    g_list_foreach(glist, (GFunc)g_free, NULL);
	    g_list_free(glist);
	    glist = NULL;
	}
	gtk_box_pack_start(GTK_BOX(parent3), w, TRUE, TRUE, 0);
	gtk_widget_show(w);

	archiver->location_combo = w = (GtkWidget *)combo_rtn;
	combo = GTK_COMBO(w);
	gtk_combo_set_case_sensitive(combo, TRUE);
	if(TRUE)
	{
	    /* Need to set different dnd_src_types for the drag source */
	    const GtkTargetEntry dnd_src_types[] = {
{"text/plain",                          0,      EDV_DND_TYPE_INFO_TEXT_PLAIN},
{"text/uri-list",                       0,      EDV_DND_TYPE_INFO_TEXT_URI_LIST},
{"STRING",                              0,      EDV_DND_TYPE_INFO_STRING}
	    };
	    GUIDNDSetSrc(
		archiver->location_icon_fixed,
		dnd_src_types,
		sizeof(dnd_src_types) / sizeof(GtkTargetEntry),
		GDK_ACTION_COPY | GDK_ACTION_MOVE |
		GDK_ACTION_LINK,			/* Actions */
		GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,	/* Buttons */
		NULL,
		EDVLocBarIconDragDataGet,
		NULL,
		NULL,
		combo
	    );
	}
	EDVEntrySetDND(EDV_CORE(core_ptr), combo->entry);
	EDVEntrySetCompletePath(EDV_CORE(core_ptr), combo->entry);

	/* VBox for password prompt */
	w = gtk_vbox_new(TRUE, 0);
	gtk_box_pack_start(GTK_BOX(parent2), w, FALSE, FALSE, border_major);
	gtk_widget_show(w);
	parent3 = w;
	/* Password prompt */
	w = GUIPromptBar(
	    (guint8 **)icon_security_20x20_xpm,
#if defined(PROG_LANGUAGE_SPANISH)
"Contraseña:"
#elif defined(PROG_LANGUAGE_FRENCH)
"Mot De Passe:"
#elif defined(PROG_LANGUAGE_GERMAN)
"Kennwort:"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Parola D'Ordine:"
#elif defined(PROG_LANGUAGE_DUTCH)
"Wachtwoord:"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Senha:"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Passord:"
#else
"Password:"
#endif
	    , NULL, &entry_rtn
	);
	gtk_box_pack_start(GTK_BOX(parent3), w, FALSE, FALSE, 0);
	gtk_widget_show(w);
	archiver->location_password_entry = w = (GtkWidget *)entry_rtn;
	entry = GTK_ENTRY(w);
	gtk_widget_set_usize(w, 100, -1);
	gtk_entry_set_visibility(entry, FALSE);
	gtk_entry_set_editable(entry, TRUE);
	gtk_signal_connect(
	    GTK_OBJECT(w), "activate",
	    GTK_SIGNAL_FUNC(EDVArchiverComboActivateCB), archiver
	);
	GUISetWidgetTip(w,
#if defined(PROG_LANGUAGE_SPANISH)
"Entre la contraseña (si necesitó) para el decrypting/codificado\
 el archivo"
#elif defined(PROG_LANGUAGE_FRENCH)
"Entrer le mot de passe (si nécessaire) pour le decrypting\
 encrypting l'archive"
#elif defined(PROG_LANGUAGE_GERMAN)
"Tragen das kennwort (wenn hat gebraucht) für decrypting\
 verschlüsseln des archivs zu ein dem sie"
#elif defined(PROG_LANGUAGE_ITALIAN)
"Entrare la parola d'ordine (se bisogno avuto di) per decrypting\
 codificare l'archivio"
#elif defined(PROG_LANGUAGE_DUTCH)
"Ga het wachtwoord binnen (indien nodig) voor decrypting coderen\
 het archief had"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"Entre a senha (se necessário) para decrypting encrypting o arquivo"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Gå inn i passordet (om trengt) for decrypting encrypting arkivet"
#else
"Enter the password (if needed) for decrypting/encrypting the archive"
#endif
	);

	/* Find bar handle box */
	archiver->find_bar_handle = w = gtk_handle_box_new();
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_attached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildAttachedCB), archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "child_detached",
	    GTK_SIGNAL_FUNC(EDVArchiverHandleChildDetachedCB), archiver
	);
	gtk_box_pack_start(GTK_BOX(parent), w, FALSE, FALSE, 0);
	if(archiver->find_bar_map_state)
	    gtk_widget_show(w);
	parent2 = w;

	/* Create find bar */
	archiver->findbar = EDVFindBarNew(
	    core_ptr, parent2,
	    EDV_FINDBAR_ROLE_ARCHIVE_OBJECT,
	    EDVArchiverBarStatusMessageCB,
	    EDVArchiverBarStatusProgressCB,
	    EDVArchiverFindBarLocationCB,
	    EDVArchiverFindBarStartCB,
	    EDVArchiverFindBarEndCB,
	    EDVArchiverFindBarMatchCB,
	    archiver
	);
	EDVFindBarMap(archiver->findbar);


	/* Scrolled window for contents clist */
	w = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(
	    GTK_SCROLLED_WINDOW(w),
	    GTK_POLICY_AUTOMATIC,
	    GTK_POLICY_AUTOMATIC
	);
	gtk_box_pack_start(GTK_BOX(parent), w, TRUE, TRUE, 0);
	gtk_widget_show(w);
	parent2 = w;

	/* Contents clist */
	archiver->contents_clist = w = gtk_clist_new(
	    EDV_ARCHIVER_CONTENTS_CLIST_COLUMNS_MAX
	);
	clist = GTK_CLIST(w);
	gtk_widget_add_events(
	    w,
	    GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK |
	    GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
	    GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
	    GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "key_press_event",
	    GTK_SIGNAL_FUNC(EDVCListKeyEventCB), core_ptr
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "key_release_event",
	    GTK_SIGNAL_FUNC(EDVCListKeyEventCB), core_ptr
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "button_press_event",
	    GTK_SIGNAL_FUNC(EDVCListButtonEventCB), core_ptr
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "button_release_event",
	    GTK_SIGNAL_FUNC(EDVCListButtonEventCB), core_ptr
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "motion_notify_event",
	    GTK_SIGNAL_FUNC(EDVCListMotionEventCB), core_ptr
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "key_press_event",
	    GTK_SIGNAL_FUNC(EDVArchiverKeyEventCB), archiver
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "key_release_event",
	    GTK_SIGNAL_FUNC(EDVArchiverKeyEventCB), archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "button_press_event",
	    GTK_SIGNAL_FUNC(EDVArchiverButtonPressEventCB), archiver
	);
	gtk_container_add(GTK_CONTAINER(parent2), w);
	gtk_widget_realize(w);
	gtk_clist_set_selection_mode(clist, GTK_SELECTION_EXTENDED);
	for(i = 0; i < clist->columns; i++)
	    gtk_clist_set_column_width(clist, i, 10);
	gtk_clist_set_row_height(clist, EDV_LIST_ROW_SPACING);
	gtk_clist_set_shadow_type(clist, GTK_SHADOW_IN);
	gtk_signal_connect(
	    GTK_OBJECT(w), "resize_column",
	    GTK_SIGNAL_FUNC(EDVArchiverResizeColumnCB), archiver
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "click_column",
	    GTK_SIGNAL_FUNC(EDVArchiverClickColumnCB), archiver
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "select_row",
	    GTK_SIGNAL_FUNC(EDVArchiverSelectRowCB), archiver
	);
	gtk_signal_connect(
	    GTK_OBJECT(w), "unselect_row",
	    GTK_SIGNAL_FUNC(EDVArchiverUnselectRowCB), archiver
	);
	/* Set up DND for the contents list */
	GUIDNDSetSrc(
	    w,
	    dnd_src_types,
	    sizeof(dnd_src_types) / sizeof(GtkTargetEntry),
	    GDK_ACTION_COPY,			/* Actions */
	    GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,/* Buttons */
	    NULL,
	    EDVArchiverContentsDragDataGetCB,
	    EDVArchiverContentsDragDataDeleteCB,
	    NULL,
	    archiver
	);
	GUIDNDSetTar(
	    w,
	    dnd_tar_types,
	    sizeof(dnd_tar_types) / sizeof(GtkTargetEntry),
	    GDK_ACTION_COPY,			/* Actions */
	    GDK_ACTION_COPY,			/* Default action if same */
	    GDK_ACTION_COPY,			/* Default action */
	    EDVArchiverContentsDragDataReceivedCB,
	    archiver
	);
	gtk_signal_connect_after(
	    GTK_OBJECT(w), "drag_motion",
	    GTK_SIGNAL_FUNC(EDVArchiverContentsDragMotionCB), archiver
	);
	gtk_widget_show(w);



	/* Create tool bar */
	EDVArchiverToolbarRegenerate(archiver);

	/* Create contents clist menu */
	EDVArchiverContentsMenuRegenerate(archiver);


	/* Create status bar */
	archiver->status_bar = status_bar = EDVStatusBarNew(
	    core_ptr, archiver->main_vbox
	);
	if(status_bar != NULL)
	{
	    if(archiver->status_bar_map_state)
		EDVStatusBarMap(status_bar);
	    else
		EDVStatusBarUnmap(status_bar);
	}


	/* Archive info dialog (created later when needed) */
	archiver->arch_info = NULL;


	/* Set initial RC styles */
	if(standard_rcstyle != NULL)
	    gtk_widget_modify_style_recursive(
		archiver->toplevel, standard_rcstyle
	    );
	if(lists_rcstyle != NULL)
	    gtk_widget_modify_style_recursive(
		archiver->contents_clist, lists_rcstyle
	    );
	if(standard_rcstyle != NULL)
	    gtk_widget_modify_style_recursive(
		archiver->contents_clist_menu, standard_rcstyle
	    );


	/* Reset values */
	EDVArchiverSetTitle(archiver, NULL);
	EDVArchiverUpdateMenus(archiver);

	return(archiver);
}

/*
 *      Syncronizes all data in the archiver's widgets to internal data
 *      on the archiver.
 */
void EDVArchiverSyncData(edv_archiver_struct *archiver)
{
	if(archiver == NULL)
	    return;

/* This function may be removed in the future, since there really is
 * no floating data from widgets to be synced to disk on the archiver
 */
}

/*
 *      Updates all widgets on the given archiver to reflect the current
 *      data.
 */
void EDVArchiverUpdateMenus(edv_archiver_struct *archiver)
{
	gboolean write_protect, write_protect_changed = FALSE;
	gboolean sensitive, state;
	guint8 **icon_data, **recbin_icon_data;
	const gchar *location;
	gint selected_obj_row = -1;
	GtkWidget *w;
	GtkCList *clist;
	const cfg_item_struct *cfg_list;
	toolbar_struct *tb;
	edv_core_struct *core_ptr;


	if(archiver == NULL)
	    return;

	core_ptr = EDV_CORE(archiver->core_ptr);
	if(core_ptr == NULL)
	    return;

	cfg_list = core_ptr->cfg_list;
	tb = archiver->toolbar;

#define DO_SHOW			\
{ if(w != NULL) gtk_widget_show(w); }
#define DO_HIDE			\
{ if(w != NULL) gtk_widget_hide(w); }
#define DO_SET_CHECK_STATE				\
{							\
 if((w != NULL) ? GTK_IS_CHECK_MENU_ITEM(w) : FALSE)	\
  GTK_CHECK_MENU_ITEM(w)->active = state;		\
}

	/* Get global write protect state */
	write_protect = EDV_GET_B(EDV_CFG_PARM_WRITE_PROTECT);
	if(archiver->last_write_protect_state < 0)
	{
	    write_protect_changed = TRUE;
	}
	else
	{
	    if((write_protect && !archiver->last_write_protect_state) ||
	       (!write_protect && archiver->last_write_protect_state)
	    )
		write_protect_changed = TRUE;
	}
	archiver->last_write_protect_state = write_protect ? 1 : 0;

	/* Get last selected row on the contents clist */
	clist = (GtkCList *)archiver->contents_clist;
	selected_obj_row = EDVCListGetSelectedLast(clist, NULL);

	/* Update recycle bin icon data, setting it to not NULL if it
	 * needs to be changed and update the recycle bin's last_recbin_items
	 * to match the value on the core structure
	 */
	icon_data = NULL;
	if(archiver->last_recbin_items < 0)
	{
	    if(core_ptr->last_recbin_items > 0)
		icon_data = (guint8 **)icon_trash_20x20_xpm;
	    else
		icon_data = (guint8 **)icon_trash_empty_20x20_xpm;
	}
	else
	{
	    if(!archiver->last_recbin_items &&
	       core_ptr->last_recbin_items
	    )
		icon_data = (guint8 **)icon_trash_20x20_xpm;
	    else if(archiver->last_recbin_items &&
		    !core_ptr->last_recbin_items
	    )
		icon_data = (guint8 **)icon_trash_empty_20x20_xpm;
	}
	archiver->last_recbin_items = core_ptr->last_recbin_items;
	recbin_icon_data = icon_data;

	/* Get current location */
	location = EDVArchiverCurrentLocation(archiver);



	/* Begin updating menu items and tool bar items */

	/* Edit */
	/* Add */
	sensitive = !STRISEMPTY(location);
	GTK_WIDGET_SET_SENSITIVE(archiver->edit_add_mi, sensitive)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_ADD, sensitive
	);
	/* Extract all */
	GTK_WIDGET_SET_SENSITIVE(archiver->edit_extract_all_mi, sensitive)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_EXTRACT_ALL, sensitive
	);

	/* Extract */
	sensitive = (selected_obj_row < 0) ? FALSE : TRUE;
	GTK_WIDGET_SET_SENSITIVE(archiver->edit_extract_mi, sensitive)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_EXTRACT, sensitive
	);
	/* Delete */
	GTK_WIDGET_SET_SENSITIVE(archiver->edit_delete_mi, sensitive)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_DELETE, sensitive
	);

	/* Properties */
	sensitive = !STRISEMPTY(location);
	GTK_WIDGET_SET_SENSITIVE(archiver->properties_mi, sensitive)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_PROPERTIES, sensitive
	);


	/* View */
	/* Archive Info */
	sensitive = !STRISEMPTY(location);
	GTK_WIDGET_SET_SENSITIVE(
	    archiver->comment_and_statistics_mi, sensitive
	)
	ToolBarItemSetSensitiveID(
	    tb, EDV_ARCHIVER_OP_COMMENT_AND_STATISTICS, sensitive
	);
	/* Show Tool Bar */
	w = archiver->show_tool_bar_micheck;
	state = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_SHOW_TOOL_BAR);
	DO_SET_CHECK_STATE
	ToolBarItemSetToggleID(
	    tb, EDV_ARCHIVER_OP_SHOW_TOOL_BAR, state
	);
	/* Show Location Bar */
	w = archiver->show_location_bar_micheck;
	state = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_SHOW_LOCATION_BAR);
	DO_SET_CHECK_STATE
	ToolBarItemSetToggleID(
	    tb, EDV_ARCHIVER_OP_SHOW_LOCATION_BAR, state
	);
	/* Show Find Bar */
	w = archiver->show_find_bar_micheck;
	state = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_SHOW_FIND_BAR);
	DO_SET_CHECK_STATE
	ToolBarItemSetToggleID(
	    tb, EDV_ARCHIVER_OP_SHOW_FIND_BAR, state
	);
	/* Show Status Bar */
	w = archiver->show_status_bar_micheck;
	state = EDV_GET_B(EDV_CFG_PARM_ARCHIVER_SHOW_STATUS_BAR);
	DO_SET_CHECK_STATE
	ToolBarItemSetToggleID(
	    tb, EDV_ARCHIVER_OP_SHOW_STATUS_BAR, state
	);


	/* Settings */
	if(write_protect_changed)
	{
	    w = archiver->write_protect_mi;
	    if(w != NULL)
		GUIMenuItemSetPixmap(
		    w,
		    (guint8 **)(write_protect ?
			icon_secure_20x20_xpm : icon_insecure_20x20_xpm)
		);
	    ToolBarItemUpdateByID(
		tb, EDV_ARCHIVER_OP_WRITE_PROTECT,
		NULL,
		(guint8 **)(write_protect ?
		    icon_secure_20x20_xpm : icon_insecure_20x20_xpm),
		NULL
	    );
	}


	/* Windows */
	if(recbin_icon_data != NULL)
	{
	    GUIMenuItemSetPixmap(
		archiver->window_recycle_bin_mi, recbin_icon_data
	    );
	    ToolBarItemUpdateByID(
		tb, EDV_ARCHIVER_OP_RECYCLE_BIN,
		NULL, recbin_icon_data, NULL
	    );
	}


	/* Update contents clist menu */
	sensitive = (selected_obj_row < 0) ?
	    FALSE : TRUE;
	GTK_WIDGET_SET_SENSITIVE(
	    archiver->contents_clist_extract_mi, sensitive
	)
	GTK_WIDGET_SET_SENSITIVE(
	    archiver->contents_clist_delete_mi, sensitive
	)

	sensitive = !STRISEMPTY(location);
	GTK_WIDGET_SET_SENSITIVE(
	    archiver->contents_clist_comment_and_statistics_mi, sensitive
	)
	GTK_WIDGET_SET_SENSITIVE(
	    archiver->contents_clist_properties_mi, sensitive
	)




	/* Update status bar */
	EDVStatusBarUpdate(archiver->status_bar);



#undef DO_SHOW
#undef DO_HIDE
#undef DO_SET_CHECK_STATE
}

/*
 *      Marks the archiver as busy or ready.
 */
void EDVArchiverSetBusy(edv_archiver_struct *archiver, gboolean is_busy)
{
	GdkCursor *cursor;
	GtkWidget *w;
	edv_core_struct *core_ptr;


	if(archiver == NULL)
	    return;

	core_ptr = EDV_CORE(archiver->core_ptr);
	if(core_ptr == NULL)
	    return;

	w = archiver->toplevel;
	if(w != NULL)
	{
	    if(is_busy)
	    {
		/* Increase busy count */
		archiver->busy_count++;

		/* If already busy then don't change anything */
		if(archiver->busy_count > 1)
		    return;

		cursor = EDVGetCursor(core_ptr, EDV_CURSOR_CODE_BUSY);
	    }
	    else
	    {
		/* Reduce busy count */
		archiver->busy_count--;
		if(archiver->busy_count < 0)
		    archiver->busy_count = 0;

		/* If still busy do not change anything */
		if(archiver->busy_count > 0)
		    return;

		cursor = NULL;  /* Use default cursor */
	    }

	    /* Update toplevel window's cursor */
	    if(w->window != NULL)
	    {
		gdk_window_set_cursor(w->window, cursor);
		gdk_flush();
	    }
	}
}


/*
 *	Checks if the Archiver is mapped.
 */
gboolean EDVArchiverIsMapped(edv_archiver_struct *archiver)
{
	GtkWidget *w = (archiver != NULL) ? archiver->toplevel : NULL;
	return((w != NULL) ? GTK_WIDGET_MAPPED(w) : FALSE);
}

/*
 *	Maps the Archiver.
 */
void EDVArchiverMap(edv_archiver_struct *archiver)
{
	GtkWidget *w = (archiver != NULL) ? archiver->toplevel : NULL;
	if(w == NULL)
	    return;

	gtk_widget_show_raise(w);
}

/*
 *	Unmaps the Archiver.
 */
void EDVArchiverUnmap(edv_archiver_struct *archiver)
{
	GtkWidget *w = (archiver != NULL) ? archiver->toplevel : NULL;
	if(w == NULL)
	    return;

	gtk_widget_hide(w);
}

/*
 *	Deletes the Archiver.
 */
void EDVArchiverDelete(edv_archiver_struct *archiver)
{
	if(archiver == NULL)
	    return;

	/* Archive Info Dialog */
	EDVArchiveInfoDelete(archiver->arch_info);
	archiver->arch_info = NULL;

	/* Reset last selected item references */
	archiver->contents_clist_selected_row = -1;

	/* Destroy right-click menus */
	archiver->contents_clist_add_mi = NULL;
	archiver->contents_clist_extract_mi = NULL;
	archiver->contents_clist_extract_all_mi = NULL;
	archiver->contents_clist_delete_mi = NULL;
	archiver->contents_clist_comment_and_statistics_mi = NULL;
	archiver->contents_clist_properties_mi = NULL;
	GTK_WIDGET_DESTROY(archiver->contents_clist_menu)
	archiver->contents_clist_menu = NULL;

	/* Delete the Status Bar */
	EDVStatusBarDelete(archiver->status_bar);
	archiver->status_bar = NULL;

	/* Delete the Find Bar */
	EDVFindBarDelete(archiver->findbar);
	archiver->findbar = NULL;

	/* Delete the Location Bar */
	GTK_WIDGET_DESTROY(archiver->location_password_entry)
	archiver->location_password_entry = NULL;
	GTK_WIDGET_DESTROY(archiver->location_combo)
	archiver->location_combo = NULL;
	GTK_WIDGET_DESTROY(archiver->location_icon_pm)
	archiver->location_icon_pm = NULL;
	GTK_WIDGET_DESTROY(archiver->location_icon_fixed)
	archiver->location_icon_fixed = NULL;

	/* Delete the Tool Bar */
	ToolBarDelete(archiver->toolbar);
	archiver->toolbar = NULL;


	/* Destroy the Menus and the Menu Bar */
	archiver->new_mi = NULL;
	archiver->open_mi = NULL;
	archiver->sync_disks_mi = NULL;
	archiver->history_mi = NULL;
	archiver->run_mi = NULL;
	archiver->close_mi = NULL;

	archiver->edit_add_mi = NULL;
	archiver->edit_extract_mi = NULL;
	archiver->edit_extract_all_mi = NULL;
	archiver->edit_delete_mi = NULL;
	archiver->select_all_mi = NULL;
	archiver->unselect_all_mi = NULL;
	archiver->invert_selection_mi = NULL;
	archiver->find_mi = NULL;
	archiver->properties_mi = NULL;

	archiver->refresh_mi = NULL;
	archiver->refresh_all_mi = NULL;
	archiver->comment_and_statistics_mi = NULL;
	archiver->show_tool_bar_micheck = NULL;
	archiver->show_location_bar_micheck = NULL;
	archiver->show_find_bar_micheck = NULL;
	archiver->show_status_bar_micheck = NULL;
	archiver->mime_types_mi = NULL;

	archiver->write_protect_mi = NULL;
	archiver->options_mi = NULL;
	archiver->customize_mi = NULL;

	archiver->window_new_browser_mi = NULL;
	archiver->window_new_imbr_mi = NULL;
	archiver->window_new_archiver_mi = NULL;
	archiver->window_recycle_bin_mi = NULL;

	archiver->help_contents_mi = NULL;
	archiver->help_archiver_mi = NULL;
	archiver->help_keys_list_mi = NULL;
	archiver->help_common_operations_mi = NULL;
	archiver->help_about_mi = NULL;

	GTK_WIDGET_DESTROY(archiver->menu_bar)
	archiver->menu_bar = NULL;


	/* Destroy toplevel and the rest of the widgets */
	GTK_WIDGET_DESTROY(archiver->menu_bar_handle)
	archiver->menu_bar_handle = NULL;
	GTK_WIDGET_DESTROY(archiver->tool_bar_handle)
	archiver->tool_bar_handle = NULL;
	GTK_WIDGET_DESTROY(archiver->bars_vbox)
	archiver->bars_vbox = NULL;
	GTK_WIDGET_DESTROY(archiver->contents_clist)
	archiver->contents_clist = NULL;
	GTK_WIDGET_DESTROY(archiver->main_vbox)
	archiver->main_vbox = NULL;
	GTK_WIDGET_DESTROY(archiver->toplevel)
	archiver->toplevel = NULL;

	GTK_ACCEL_GROUP_UNREF(archiver->accelgrp)
	archiver->accelgrp = NULL;


	/* Delete all Operation IDs */
	EDVArchiverOPIDListDelete(
	    archiver->opid, archiver->total_opids
	);

	g_free(archiver);
}
