Jump to content

Aros/Developer/Scalos

From Wikibooks, open books for an open world
Navbar for the Aros wikibook
Aros User
Aros User Docs
Aros User FAQs
Aros User Applications
Aros User DOS Shell
Aros/User/AmigaLegacy
Aros Dev Docs
Aros Developer Docs
Porting Software from AmigaOS/SDL
For Zune Beginners
Zune .MUI Classes
For SDL Beginners
Aros Developer BuildSystem
Specific platforms
Aros x86 Complete System HCL
Aros x86 Audio/Video Support
Aros x86 Network Support
Aros Intel AMD x86 Installing
Aros Storage Support IDE SATA etc
Aros Poseidon USB Support
x86-64 Support
Motorola 68k Amiga Support
Linux and FreeBSD Support
Windows Mingw and MacOSX Support
Android Support
Arm Raspberry Pi Support
PPC Power Architecture
misc
Aros Public License


Introduction

[edit | edit source]

This is an incomplete guide, please support

#Plugins #Modules #Tools #Scalos Reference #See also #See also #Scalos #History


  • scalos.library - This library is used as application interface for the Scalos Workbench replacement
  • scalosgfx.library - This documentation gives you information about scalosgfx.library
  • scalos API - This documentation gives you information on how to communicate with Scalos and its windowtasks
  • Scalos devicelist - This class is used to generate a list of all currently available devices
  • Scalos devicewindow - This class implements the main Workbench (= root) window, which shows the icons for the mounted devices and volumes
  • Scalos filetrans - This class is used to display a progress window showing the user what is currently going on while copying or moving files/directories
  • Scalos root - This class is used for some fundamental message and event handling
  • Scalos window - This class implements all common window functionality used for icon windows, text windows and device windows
  • Scalos iconwindow - This class implements the functionality for the common Workbench icon windows
  • Scalos textwindow - This class implements the text-only Scalos windows
  • Scalos title - This class implements the screen title and window title functionality
  • preferences.library - This library provides a convenient way to store the preferences for your program
  • iconobject.library - This library is an interface to the iconobject.datatype
  • iconobject.datatype - The iconobject.datatype has a special API to work with icons. makes both images, tooltypes and many more

AROS icon.library won't work on Scalos. Scalos uses its own iconobject.library and an iconobject datatype system enable the support for icon.library or other icons somewhere in the Scalos menu


Developer Docs

[edit | edit source]

src from here


Plugins

[edit | edit source]

src from here


Source examples

[edit | edit source]






Prefs for any plugins

// FileTypesPrefs.c
// $Date$
// $Revision$

#ifdef __AROS__
#define MUIMASTER_YES_INLINE_STDARG
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include <time.h>
#include <limits.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/resident.h>
#include <utility/utility.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <libraries/mui.h>
#include <libraries/iffparse.h>
#include <libraries/ttengine.h>
#include <devices/clipboard.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <intuition/intuition.h>
#include <intuition/classusr.h>
#include <graphics/gfxmacros.h>
#include <prefs/prefhdr.h>

#include <clib/alib_protos.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/utility.h>
#include <proto/asl.h>
#include <proto/locale.h>
#include <proto/preferences.h>
#include <proto/iconobject.h>
#define USE_INLINE_STDARG
#include <proto/ttengine.h>
#undef	USE_INLINE_STDARG

#if !defined(__AROS__)
#define	NO_INLINE_STDARG
#endif
#include <proto/muimaster.h>

#include <mui/NListview_mcc.h>
#include <mui/NListtree_mcc.h>
#include <mui/Lamp_mcc.h>

#include <scalos/scalosprefsplugin.h>
#include <scalos/preferences.h>
#include <DefIcons.h>

#include "defs.h"
#include <Year.h> // +jmc+

#include <FontSampleMCC.h>
#include "IconobjectMCC.h"
#include "DataTypesMCC.h"
#include "debug.h"

#include "FileTypesPrefs.h"
#include "FileTypesPrefs_proto.h"

#define	ScalosFileTypes_NUMBERS
#define	ScalosFileTypes_ARRAY
#define	ScalosFileTypes_CODE
#include STR(SCALOSLOCALE)

#include "plugin.h"

//----------------------------------------------------------------------------

#define	ID_MAIN		MAKE_ID('M','A','I','N')
#define	PS_DATA(prefsstruct)	((STRPTR) (prefsstruct)) + sizeof((prefsstruct)->ps_Size)

#define	ENV_FILETYPES_DIR     	"ENV:Scalos/FileTypes"
#define	ENVARC_FILETYPES_DIR    "ENVARC:Scalos/FileTypes"
#define	ENV_DEFICONS_PREFS	"ENV:deficons.prefs"
#define	ENVARC_DEFICONS_PREFS	"ENVARC:deficons.prefs"

//----------------------------------------------------------------------------

#define IMG(prefix1,PREFIX2) \
  BodychunkObject,\
    MUIA_FixWidth             , PREFIX2##_WIDTH ,\
    MUIA_FixHeight            , PREFIX2##_HEIGHT,\
    MUIA_Bitmap_Width         , PREFIX2##_WIDTH ,\
    MUIA_Bitmap_Height        , PREFIX2##_HEIGHT,\
    MUIA_Bodychunk_Depth      , PREFIX2##_DEPTH ,\
    MUIA_Bodychunk_Body       , (IPTR) prefix1##_body,\
    MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\
    MUIA_Bodychunk_Masking    , PREFIX2##_MASKING,\
    MUIA_Bitmap_SourceColors  , (IPTR) prefix1##_colors,\
    MUIA_Bitmap_Transparent   , 0,\
  End

//----------------------------------------------------------------------------

// local data structures

#define KeyButtonHelp(name,key,HelpText)\
	TextObject,\
		ButtonFrame,\
		MUIA_CycleChain, TRUE, \
		MUIA_Font, MUIV_Font_Button,\
		MUIA_Text_Contents, (IPTR) GetLocString(name),\
		MUIA_Text_PreParse, (IPTR)"\33c",\
		MUIA_Text_HiChar  , (IPTR)key,\
		MUIA_ControlChar  , (IPTR)key,\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
		MUIA_ShortHelp	  , (IPTR) GetLocString(HelpText),\
		End

#define KeyButtonHelp2(name,key,HelpText,Weight)\
	TextObject,\
		ButtonFrame,\
		MUIA_CycleChain, TRUE, \
		MUIA_Font, MUIV_Font_Button,\
		MUIA_Text_Contents, (IPTR) GetLocString(name),\
		MUIA_Text_PreParse, (IPTR)"\33c",\
		MUIA_Text_HiChar  , (IPTR) *GetLocString(key),\
		MUIA_ControlChar  , (IPTR) *GetLocString(key),\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
		MUIA_ShortHelp	  , (IPTR) GetLocString(HelpText),\
		MUIA_Weight	  , (Weight), \
		End

#define CheckMarkHelp(selected, HelpTextID)\
	ImageObject,\
		ImageButtonFrame,\
		MUIA_CycleChain       , TRUE, \
		MUIA_InputMode        , MUIV_InputMode_Toggle,\
		MUIA_Image_Spec       , MUII_CheckMark,\
		MUIA_Image_FreeVert   , TRUE,\
		MUIA_Selected         , selected,\
		MUIA_Background       , MUII_ButtonBack,\
		MUIA_ShowSelState     , FALSE,\
		MUIA_ShortHelp	      , (IPTR)GetLocString(HelpTextID),\
		End

struct AddEntryListEntry
	{
	enum FtEntryType ael_EntryType;
	};

struct AddAttrListEntry
	{
	enum ftAttributeType aal_EntryType;
	};

struct EditAttrListEntry
	{
	char eal_ValueString[MAX_ATTRVALUE];
	struct FtAttribute eal_fta;
	};

enum AttrDefaultType
	{
	ATTRDEFTYPE_None,
	ATTRDEFTYPE_ULong,
	ATTRDEFTYPE_LocString,
	ATTRDEFTYPE_String,
	ATTRDEFTYPE_String2,
	ATTRDEFTYPE_PathName,
	ATTRDEFTYPE_FileName,
	ATTRDEFTYPE_FontString,
	ATTRDEFTYPE_TTFontString,
	};

struct AttrDefaultValue
	{
	enum AttrDefaultType avd_Type;
	ULONG avd_ULongValue;

	char *avd_StringValue;

	ULONG (*avd_ConvertValueFromString)(CONST_STRPTR DisplayString);
	};

struct AttributeDef
	{
	enum ftAttributeType atd_Type;

	BOOL atd_Required;

	ULONG atd_ExcludeCount;
	enum ftAttributeType atd_Exclude[10];

	ULONG atd_MinValue;		// Minimum ULONG value or minimal string length
	ULONG atd_MaxValue;		// Maximum ULONG value or maximal string length

	struct AttrDefaultValue atd_DefaultContents;

	struct AttrDefaultValue *atd_PossibleContents;
	ULONG atd_NumberOfValues;
	};

struct EntryAttributes
	{
	enum FtEntryType eat_EntryType;
	const struct AttributeDef *eat_AttrArray;
	ULONG eat_AttrCount;		// number of entries in eat_AttrArray
	};

enum FindDir
	{
	FINDDIR_First = 0,
	FINDDIR_Next,
	FINDDIR_Prev
	};

struct FoundNode
	{
	struct Node fdn_Node;
	Object *fdn_ListTree;
	struct MUI_NListtree_TreeNode *fdn_TreeNode;
	ULONG fdn_Index;
	};

//----------------------------------------------------------------------------

// aus mempools.lib
#if !defined(__amigaos4__) && !defined(__AROS__)
extern int _STI_240_InitMemFunctions(void);
extern void _STD_240_TerminateMemFunctions(void);
#endif

//----------------------------------------------------------------------------

// local functions

DISPATCHERPROTO(FileTypesPrefs);
static Object *CreatePrefsGroup(struct FileTypesPrefsInst *inst);
static Object **CreateSubWindows(Class *cl, Object *o);
static Object *CreatePrefsImage(void);
static void InitHooks(struct FileTypesPrefsInst *inst);

static BOOL OpenLibraries(void);
static void CloseLibraries(void);
static void TranslateNewMenu(struct NewMenu *nm);
static void TranslateStringArray(STRPTR *stringArray);

static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm);

static SAVEDS(APTR) INTERRUPT AttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT AttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT AttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm);

static SAVEDS(APTR) INTERRUPT AddEntryConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT AddEntryDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT AddEntryDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm);

static SAVEDS(APTR) INTERRUPT AddAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT AddAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT AddAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm);

static SAVEDS(APTR) INTERRUPT EditAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT EditAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT EditAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm);

static SAVEDS(ULONG) INTERRUPT EditAttrTTFontOpenHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(ULONG) INTERRUPT EditAttrTTFontCloseHookFunc(struct Hook *hook, Object *obj, Msg msg);

static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT HideEmptyEntriesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CopyHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CutHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT PasteHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CopyAttrHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CutAttrHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT PasteAttrHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SelectAttributeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT EditAttributeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT AboutFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT AddEntryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT AddAttributeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT RemoveAttributeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ChangeAttributeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SelectAttributeValueHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(ULONG) INTERRUPT EditAttributePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(ULONG) INTERRUPT EditAttributePopAslPathStartHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg);
static BOOL IncrementalSearchFileType(struct FileTypesPrefsInst *inst,
	CONST_STRPTR SearchString, enum FindDir dir);
static void BuildFindTree(struct FileTypesPrefsInst *inst,
	Object *ListTree,
	struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern,
	struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch, BOOL CaseSensitive);
static SAVEDS(void) INTERRUPT ShowFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT HideFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT IncrementalFindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT IncrementalFindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT IncrementalFindPrevFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg);

static LONG ReadPrefs(struct FileTypesPrefsInst *inst,
	CONST_STRPTR LoadName, CONST_STRPTR DefIconPrefsName);
static LONG WritePrefs(struct FileTypesPrefsInst *inst,
	CONST_STRPTR SaveName, CONST_STRPTR DefIconPrefsName, ULONG Flags);

DISPATCHERPROTO(myNListTree);
DISPATCHERPROTO(myFileTypesNListTree);
DISPATCHERPROTO(myNList);
DISPATCHERPROTO(myFileTypesActionsNList);


static void DisposeAttribute(struct FtAttribute *fta);
static void CleanupAttributes(struct List *AttributesList);
static const struct FtAttribute *FindAttribute(const struct FileTypesListEntry *fte, enum FtEntryType AttrType);
static void RemoveAttribute(struct FileTypesListEntry *fte, enum ftAttributeType AttrType);
static struct FileTypesListEntry *FindChildByType(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tn, enum FtEntryType RequestedType);
static BOOL HasChildren(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn);
static void AddDefaultAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte);
static void SetAddableAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte);
static void UpdateAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte);
static void AddNewAttribute(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte, enum ftAttributeType AttrType);
static void BeginSetMenuDefaultAction(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn);
static void SetMenuDefaultAction(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnMenu, struct MUI_NListtree_TreeNode *tnNewDefault);
static const struct AttributeDef *GetAttributeDef(enum ftAttributeType AttrType, enum FtEntryType fteEntryType);
static void FillListOfAttributeValues(struct FileTypesPrefsInst *inst, 
	const struct FileTypesListEntry *fte, const struct AttributeDef *atd, 
	const struct AttrListEntry *Attr);
static ULONG ConvertGroupOrientationFromString(CONST_STRPTR DisplayString);
static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, 
	struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList);
static BOOL MayPasteOnto(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom);
static struct MUI_NListtree_TreeNode *MayPasteBelow(struct FileTypesPrefsInst *inst,
	struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom);
static void EnablePasteMenuEntry(struct FileTypesPrefsInst *inst);
static BOOL MayPasteAttr(struct FileTypesPrefsInst *inst, const struct FileTypesListEntry *fte, const struct AttrListEntry *Attr);
static void EnablePasteAttrMenuEntry(struct FileTypesPrefsInst *inst);
static BOOL IsAttrRequired(struct FileTypesListEntry *fte, const struct AttributeDef *atd);
static void EntryHasChanged(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn);
static void SetChangedFlag(struct FileTypesPrefsInst *inst, BOOL changed);
static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList);
static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, 
	IPTR *FontStyle, IPTR *FontWeight, IPTR *FontSize,
	STRPTR FontName, size_t FontNameSize);
static void ShowHiddenNodes(struct FileTypesPrefsInst *inst);
static void ParseToolTypes(struct FileTypesPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt);
static LONG ReadScalosPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR PrefsFileName);
static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString);
static ULONG DoDragDrop(Class *cl, Object *obj, Msg msg);
static struct FoundNode *AddFoundNode(struct FileTypesPrefsInst *inst, Object *ListTree, struct MUI_NListtree_TreeNode *tn);
static CONST_STRPTR FindString(CONST_STRPTR string, CONST_STRPTR pattern, BOOL CaseSensitive);

#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__)
static size_t stccpy(char *dest, const char *src, size_t MaxLen);
#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */

//----------------------------------------------------------------------------

// local data items

#ifndef __AROS__
struct Library *MUIMasterBase;
T_LOCALEBASE LocaleBase;
struct GfxBase *GfxBase;
struct Library *IconBase;
T_UTILITYBASE UtilityBase;
struct IntuitionBase *IntuitionBase;
#endif
struct Library *TTEngineBase;
struct Library *IconobjectBase;
struct Library *WorkbenchBase;
struct Library *IFFParseBase;
struct Library *DiskfontBase;
struct Library *PreferencesBase;
struct Library *DataTypesBase;

#ifdef __amigaos4__
struct Library *DOSBase;
struct DOSIFace *IDOS;
struct MUIMasterIFace *IMUIMaster;
struct LocaleIFace *ILocale;
struct GraphicsIFace *IGraphics;
struct WorkbenchIFace *IWorkbench;
struct IconIFace *IIcon;
struct IFFParseIFace *IIFFParse;
struct IconobjectIFace *IIconobject;
struct UtilityIFace *IUtility;
struct IntuitionIFace *IIntuition;
struct TTEngineIFace *ITTEngine;
struct DiskfontIFace *IDiskfont;
struct PreferencesIFace *IPreferences;
struct DataTypesIFace *IDataTypes;
struct Library *NewlibBase;
struct Interface *INewlib;
#endif

#ifdef __AROS__
struct DosLibrary *DOSBase;
#endif

struct MUI_CustomClass *FileTypesPrefsClass;
struct MUI_CustomClass *myNListClass;
struct MUI_CustomClass *myFileTypesActionsNListClass;
struct MUI_CustomClass *myNListTreeClass;
struct MUI_CustomClass *myFileTypesNListTreeClass;
struct MUI_CustomClass *FontSampleClass;
struct MUI_CustomClass *IconobjectClass;
struct MUI_CustomClass *DataTypesImageClass;

#ifdef __AROS__
#define myNListTreeObject BOOPSIOBJMACRO_START(myNListTreeClass->mcc_Class)
#define myNListObject BOOPSIOBJMACRO_START(myNListClass->mcc_Class)
#define myFileTypesNListTreeObject BOOPSIOBJMACRO_START(myFileTypesNListTreeClass->mcc_Class)
#define myFileTypesActionsNListObject BOOPSIOBJMACRO_START(myFileTypesActionsNListClass->mcc_Class)
#else
#define myNListTreeObject NewObject(myNListTreeClass->mcc_Class, 0
#define myNListObject NewObject(myNListClass->mcc_Class, 0
#define myFileTypesNListTreeObject NewObject(myFileTypesNListTreeClass->mcc_Class, 0
#define myFileTypesActionsNListObject NewObject(myFileTypesActionsNListClass->mcc_Class, 0
#endif

static struct Catalog *FileTypesPrefsCatalog;
static struct Locale *FileTypesPrefsLocale;

static BOOL StaticsTranslated;

static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] =
	{
	{ MUIC_NListtree, 18, 18 },
	{ MUIC_NList, 18, 0 },
	{ NULL, 0, 0 }
	};

static ULONG MajorVersion, MinorVersion;

static const struct Hook FileTypesPrefsHooks[] =
{
	{ { NULL, NULL }, NULL, NULL, NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(TreeDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(TreeConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(TreeDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AttrDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AttrConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AttrDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AddEntryDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AddEntryConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AddEntryDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AddAttrDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AddAttrConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AddAttrDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttrDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttrConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttrDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDisplayFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionConstructFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDestructFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(SelectEntryHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SelectAttributeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttributeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AboutFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ContextMenuTriggerHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(CollapseHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ExpandHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(CollapseAllHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ExpandAllHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(CollapseFileTypesHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ExpandFileTypesHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(CollapseAllFileTypesHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ExpandAllFileTypesHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(CopyHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(CutHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(PasteHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(CopyAttrHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(CutAttrHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(PasteAttrHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AddEntryHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AddAttributeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RemoveEntryHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RemoveAttributeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ChangeAttributeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SelectAttributeValueHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttributePopAslFileStartHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttributePopAslPathStartHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttrTTFontOpenHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditAttrTTFontCloseHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(HideEmptyEntriesHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesEntryHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesActionEntryHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(RenameFileTypeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AddFileTypeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RemoveFileTypeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AddFileTypesMethodHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RemoveFileTypesActionHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchMatchHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchCaseHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMatchOffsetHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchSearchHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchCaseHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionSearchSkipSpacesHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionFilesizeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionPatternHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionProtectionHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDosDeviceHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDeviceNameHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionContentsHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionDosTypeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(ChangedFileTypesActionMinSizeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(FileTypesActionDragDropSortHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ShowFindGroupHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(HideFindGroupHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindFileTypeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindNextFileTypeHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(IncrementalFindPrevFileTypeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(LearnFileTypeHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(CreateNewFileTypesIconHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(EditFileTypesIconHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL },
};


// Context menu in "filetypes" list
static struct NewMenu ContextMenuFileTypes[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_TITLENAME,			NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE,	 	NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_CollapseFileTypes },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_ExpandFileTypes },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, 	NULL, 	0,			0, (APTR) HOOKNDX_CollapseAllFileTypes },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, 	NULL, 	0,			0, (APTR) HOOKNDX_ExpandAllFileTypes },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_FIND, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_ShowFindGroup },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) HOOKNDX_About },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

// Context menu on "methods" list
static struct NewMenu ContextMenuFileTypesActions[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_TITLENAME,			NULL, 						0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_OPEN, 		(STRPTR) MSGID_MENU_PROJECT_OPEN_SHORT, 	0,	0, (APTR) HOOKNDX_Open },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_SAVEAS, 	(STRPTR) MSGID_MENU_PROJECT_SAVEAS_SHORT,	0,	0, (APTR) HOOKNDX_SaveAs },
	{  NM_ITEM, NM_BARLABEL,				NULL, 						0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) HOOKNDX_About },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

static struct NewMenu ContextMenus[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_TITLENAME,			NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE,	 	NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_Collapse },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_Expand },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_HIDE_EMPTY_ENTRIES,	NULL, 				CHECKIT|MENUTOGGLE,	0, (APTR) HOOKNDX_HideEmptyEntries },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COPY,	 	NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_Copy },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_CUT, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_Cut },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_PASTE, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_Paste },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, 	NULL, 	0,			0, (APTR) HOOKNDX_CollapseAll },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, 	NULL, 	0,			0, (APTR) HOOKNDX_ExpandAll },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) HOOKNDX_About },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

static struct NewMenu ContextMenusAttrList[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_TITLENAME,			NULL, 	0,			0, NULL },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COPY,	 	NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_CopyAttr },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_CUT, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_CutAttr },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_PASTE, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) HOOKNDX_PasteAttr },
	{  NM_ITEM, NM_BARLABEL,				NULL, 						0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) HOOKNDX_About },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

static const BOOL MayPasteAfterMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] =
	{
	//    0      1      2      3      4      5      6      7      8      9     10     11     12     13     14     15     16     17
	/* 0 ENTRYTYPE_FileType */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 1 ENTRYTYPE_PopupMenu */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 2 ENTRYTYPE_PopupMenu_SubMenu */
	{ FALSE, FALSE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 3 ENTRYTYPE_PopupMenu_MenuItem */
	{ FALSE, FALSE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 4 ENTRYTYPE_PopupMenu_InternalCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 5 ENTRYTYPE_PopupMenu_WbCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 6 ENTRYTYPE_PopupMenu_ARexxCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 7 ENTRYTYPE_PopupMenu_CliCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 8 ENTRYTYPE_PopupMenu_PluginCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 9 ENTRYTYPE_PopupMenu_IconWindowCmd */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 10 ENTRYTYPE_PopupMenu_MenuSeparator */
	{ FALSE, FALSE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 11 ENTRYTYPE_ToolTip */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 12 ENTRYTYPE_ToolTip_Group */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 13 ENTRYTYPE_ToolTip_Member */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE},
	/* 14 ENTRYTYPE_ToolTip_HBar */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 15 ENTRYTYPE_ToolTip_String */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 16 ENTRYTYPE_ToolTip_Space */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 17 ENTRYTYPE_ToolTip_DtImage */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	//    0      1      2      3      4      5      6      7      8      9     10     11     12     13     14     15     16     17
	};
static const BOOL MayPasteIntoMatrix[ENTRYTYPE_MAX][ENTRYTYPE_MAX] =
	{
	//    0      1      2      3      4      5      6      7      8      9     10     11     12     13     14     15     16     17
	/* 0 ENTRYTYPE_FileType */
	{ FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE,  FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 1 ENTRYTYPE_PopupMenu */
	{ FALSE, FALSE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 2 ENTRYTYPE_PopupMenu_SubMenu */
	{ FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 3 ENTRYTYPE_PopupMenu_MenuItem */
	{ FALSE, FALSE, FALSE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 4 ENTRYTYPE_PopupMenu_InternalCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 5 ENTRYTYPE_PopupMenu_WbCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 6 ENTRYTYPE_PopupMenu_ARexxCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 7 ENTRYTYPE_PopupMenu_CliCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 8 ENTRYTYPE_PopupMenu_PluginCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 9 ENTRYTYPE_PopupMenu_IconWindowCmd */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 10 ENTRYTYPE_PopupMenu_MenuSeparator */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},

	/* 11 ENTRYTYPE_ToolTip */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 12 ENTRYTYPE_ToolTip_Group */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE, FALSE, FALSE, FALSE},
	/* 13 ENTRYTYPE_ToolTip_Member */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,  TRUE, FALSE,  TRUE,  TRUE,  TRUE,  TRUE},
	/* 14 ENTRYTYPE_ToolTip_HBar */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 15 ENTRYTYPE_ToolTip_String */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 16 ENTRYTYPE_ToolTip_Space */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	/* 17 ENTRYTYPE_ToolTip_DtImage */
	{ FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE},
	//    0      1      2      3      4      5      6      7      8      9     10     11     12     13     14     15     16     17
	};

static const ULONG EntryTypeNames[] =
	{
	MSGID_ENTRYTYPE_FILETYPE,

	MSGID_ENTRYTYPE_POPUPMENU,
	MSGID_ENTRYTYPE_SUBMENU,
	MSGID_ENTRYTYPE_MENUITEM,
	MSGID_ENTRYTYPE_INTERNALCMD,
	MSGID_ENTRYTYPE_WBCMD,
	MSGID_ENTRYTYPE_AREXXCMD,
	MSGID_ENTRYTYPE_CLICMD,
	MSGID_ENTRYTYPE_PLUGINCMD,
	MSGID_ENTRYTYPE_ICONWINDOWCMD,
	MSGID_ENTRYTYPE_MENUSEPARATOR,

	MSGID_ENTRYTYPE_TOOLTIP,
	MSGID_ENTRYTYPE_GROUP,
	MSGID_ENTRYTYPE_MEMBER,
	MSGID_ENTRYTYPE_HBAR,
	MSGID_ENTRYTYPE_STRING,
	MSGID_ENTRYTYPE_SPACE,
	MSGID_ENTRYTYPE_DTIMAGE,
	};

static const ULONG AddFiletypeStringsPM[] =
	{
	ENTRYTYPE_PopupMenu,
	0
	};
static const ULONG AddFiletypeStringsTT[] =
	{
	ENTRYTYPE_ToolTip,
	0
	};
static const ULONG AddFiletypeStringsPMTT[] =
	{
	ENTRYTYPE_PopupMenu,
	ENTRYTYPE_ToolTip,
	0
	};
static const ULONG AddPopupMenuStrings[] =
	{
	ENTRYTYPE_PopupMenu_SubMenu,
	ENTRYTYPE_PopupMenu_MenuItem,
	ENTRYTYPE_PopupMenu_MenuSeparator,
	0
	};
static const ULONG AddSubMenuStrings[] =
	{
	ENTRYTYPE_PopupMenu_MenuItem,
	ENTRYTYPE_PopupMenu_MenuSeparator,
	0
	};
static const ULONG AddMenuItemStrings[] =
	{
	ENTRYTYPE_PopupMenu_InternalCmd,
	ENTRYTYPE_PopupMenu_WbCmd,
	ENTRYTYPE_PopupMenu_ARexxCmd,
	ENTRYTYPE_PopupMenu_CliCmd,
	ENTRYTYPE_PopupMenu_PluginCmd,
	ENTRYTYPE_PopupMenu_IconWindowCmd,
	0
	};
static const ULONG AddToolTipStrings[] =
	{
	ENTRYTYPE_ToolTip_Group,
	0
	};
static const ULONG AddGroupStrings[] =
	{
	ENTRYTYPE_ToolTip_Member,
	0
	};
static const ULONG AddMemberStrings[] =
	{
	ENTRYTYPE_ToolTip_Group,
	ENTRYTYPE_ToolTip_HBar,
	ENTRYTYPE_ToolTip_String,
	ENTRYTYPE_ToolTip_Space,
	ENTRYTYPE_ToolTip_DtImage,
	0
	};

static STRPTR RegisterTitles[] =
	{
	(STRPTR) MSGID_REGISTERTITLE_RECOGNITION,
	(STRPTR) MSGID_REGISTERTITLE_ACTIONS,
	NULL
	};

STRPTR AddFileTypeActionStrings[] =
	{
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MATCH,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_SEARCH,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_FILESIZE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_PATTERN,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_PROTECTION,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_OR,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSDEVICE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DEVICENAME,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_CONTENTS,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSTYPE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MINSIZEMB,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS,
	NULL
	};

STRPTR AddFileTypeActionStringsProject[] =
	{
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MATCH,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_SEARCH,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_FILESIZE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_PATTERN,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_PROTECTION,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_OR,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS,
	NULL
	};

STRPTR AddFileTypeActionStringsDisk[] =
	{
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_OR,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_ISASCII,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSDEVICE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DEVICENAME,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_CONTENTS,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_DOSTYPE,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MINSIZEMB,
	(STRPTR) MSGID_FILETYPE_ADD_ACTION_MACROCLASS,
	NULL
	};

static STRPTR FileTypeActionProtectionStrings[] =
	{
	(STRPTR) MSGID_FILETYPE_PROTECTION_SET,
	(STRPTR) MSGID_FILETYPE_PROTECTION_UNSET,
	(STRPTR) MSGID_FILETYPE_PROTECTION_IGNORE,
	NULL,
	};

static struct AttrDefaultValue AttrDefStringStyleContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "normal" },
	{ ATTRDEFTYPE_String, 0, "bold" },
	{ ATTRDEFTYPE_String, 0, "italic" },
	{ ATTRDEFTYPE_String, MSGID_CHANGEME, "bolditalic" },
	};
static struct AttrDefaultValue AttrDefStringHAlignContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "left" },
	{ ATTRDEFTYPE_String, 0, "center" },
	{ ATTRDEFTYPE_String, 0, "right" },
	};
static struct AttrDefaultValue AttrDefStringVAlignContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "top" },
	{ ATTRDEFTYPE_String, 0, "center" },
	{ ATTRDEFTYPE_String, 0, "bottom" },
	};
static struct AttrDefaultValue AttrDefStringPenContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "PENIDX_HSHINEPEN"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_HSHADOWPEN"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTOUTLINEPEN",	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_DRAWERTEXT"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_DRAWERTEXTSEL"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_DRAWERBG",		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_FILETEXT"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_FILETEXTSEL"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_FILEBG"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_BACKDROPDETAIL"	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_BACKDROPBLOCK"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_TEXT"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_BG"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_DRAGINFOTEXT_TEXT"	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_DRAGINFOTEXT_BG"	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_STATUSBAR_BG"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_STATUSBAR_TEXT"	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTPEN"		},
	{ ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTPENSEL"	},
	{ ATTRDEFTYPE_String, 0, "PENIDX_ICONTEXTSHADOWPEN"	},
	};
static struct AttrDefaultValue AttrDefStringIDContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "MSGID_BYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_KBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_GBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_HBYTENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_REQTITLE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_OPENERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_OPENERRORGADGETS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_QUITERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_GADGETSNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_WBLOADNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_WBLOAD_ASLTITLE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_REPLACENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_REPLACEGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_DOWAITERRNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_SCAERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_CLOSEWBNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUTNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_OKNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_UPDATENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_SYSINFONAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FLUSHNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_REBOOTNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_EXISTSNAME_COPY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_EXISTSGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_SUREREBOOTNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_OKCANCELNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_LIBERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_SCALIBERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLNAMENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLSIZENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLACCESSNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLDATENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLTIMENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLCOMNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_USEDLIBSNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_SCARUNNINGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PREVIEWNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_EMULATIONNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSTITLE_COPY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COPYINGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FROMNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TONAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE1NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE2NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE3NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE4NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE5NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMTITLE6NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COPYERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COPYERRORGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MOVEERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_DELETEERRORNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUT_TESTTEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUT_UNREGTEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUT_REGTOTEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUT_REGTEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ABOUT_COMREGINFO"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SETUPSCREEN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SETUPSCRPATTERN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITMENU"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITTIMER"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_STARTWINDOWPROC"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITNOTIFY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUP"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUP_RUNPRG"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_READDEVICEICONS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_INITDEVICEWINDOW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_WBSTARTUPFINISHED"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_SCALOSVERSION"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_ROOTDIR"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USERDIR"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_SOFTLINK"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_HARDLINKDIR"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_HARDLINKFILE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_PIPEFILE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_UNKNOWNTYPE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_LASTCHANGE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_SIZE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_PROTECTION"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_WRITEPROTECT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_VALIDATING"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_READWRITE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE_UNKNOWN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_DISK"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_CREATED"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_STATE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USED"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILESIZEFMT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_APPICON"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ICON_WITHOUT_FILE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ICONIFIED_WINDOW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_OPEN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_COPY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_RENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_INFO"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_SNAPSHOT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_UNSNAPSHOT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_LEAVEOUT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_PUTAWAY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_DELETE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_FORMATDISK"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PMMENU_APPICON_EMPTYTRASHCAN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_EXISTSNAME_MOVE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DRAWER_1"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DRAWER_2"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_FILE_1"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_FILE_2"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_DRAWER"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_TRASHCAN"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_ENDREADDEVICEICONS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_STATUSBARTEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DEVICE_1"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MULTIDRAG_DEVICE_2"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_CANCELBUTTON"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PREPARING_COPY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PREPARING_MOVE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_REMAININGTIME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_MINUTES"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_SECONDS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSFER_SECOND"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_FILETRANSTITLE_MOVE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_MOVINGNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_READINGPREFS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_DISK_UNREADABLE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_PROGRESS_MAINWINDOW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_NEW_DRAWER_NAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_CANNOT_OPEN_DRAWER"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ALLOCPENSREQ_CONTENTS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ALLOCPENSREQ_GADGETSNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBGARBAGE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBPROJECT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBDEVICE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBKICK"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBTOOL"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILETYPE_WBDISK"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_ERROR_NO_DEFAULTTOOL"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_RIGHTSCROLLER"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_BOTTOMSCROLLER"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_UPARROW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_DOWNARROW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_RIGHTARROW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_LEFTARROW"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_ICONIFY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_TEXT"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_READONLY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_READING"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_TYPING"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_GADGET_STATUSBAR_SHOWALL"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_EXISTSICON_COPY"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_FULL"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_FREE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_USEDCOUNTFMT_INUSE"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_DRAWERS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_FILES"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_LINKTO"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TOOLTIP_KICKSTART"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_NODEFAULTTOOL_REQ"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_NODEFAULTTOOL_REQ_GADGETS"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_REQ_SELECTDEFTOOL"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_TEXTICON_SOLOICON"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLOWNERNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLGROUPNAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLFILETYPENAME"	},
	{ ATTRDEFTYPE_String, 0, "MSGID_COLVERSIONNAME"	},
	};
static struct AttrDefaultValue AttrDefGroupOrientationContents[] =
	{
	{ ATTRDEFTYPE_ULong, TTL_Horizontal, "", ConvertGroupOrientationFromString	},
	{ ATTRDEFTYPE_ULong, TTL_Vertical, "", ConvertGroupOrientationFromString	},
	};
static struct AttrDefaultValue AttrDefGroupStringSrcContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "diskstate",		},
	{ ATTRDEFTYPE_String, 0, "diskusage",		},
	{ ATTRDEFTYPE_String, 0, "diskusagefree",	},
	{ ATTRDEFTYPE_String, 0, "diskusageinuse",	},
	{ ATTRDEFTYPE_String, 0, "diskusagepercent",	},
	{ ATTRDEFTYPE_String, 0, "fibfilename",		},
	{ ATTRDEFTYPE_String, 0, "filecomment",		},
	{ ATTRDEFTYPE_String, 0, "filedate",		},
	{ ATTRDEFTYPE_String, 0, "fileprotection",	},
	{ ATTRDEFTYPE_String, 0, "filesize",		},
	{ ATTRDEFTYPE_String, 0, "filetime",		},
	{ ATTRDEFTYPE_String, 0, "filetypestring",	},
	{ ATTRDEFTYPE_String, 0, "iconname",		},
	{ ATTRDEFTYPE_String, 0, "linktarget",		},
	{ ATTRDEFTYPE_String, 0, "plugin",		},
	{ ATTRDEFTYPE_String, 0, "versionstring",	},
	{ ATTRDEFTYPE_String, 0, "volumecreateddate",	},
	{ ATTRDEFTYPE_String, 0, "volumecreatedtime",	},
	{ ATTRDEFTYPE_String, 0, "volumeordevicename",	},
	};
static struct AttrDefaultValue AttrDefPopupMenuInternalCmds[] =
	{
	{ ATTRDEFTYPE_String2, MSGID_COM5NAME, 			"about",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM1NAME, 			"backdrop",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM12NAME, 		"cleanup",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM43NAME, 		"cleanupbyname",       },
	{ ATTRDEFTYPE_String2, MSGID_COM44NAME, 		"cleanupbydate",       },
	{ ATTRDEFTYPE_String2, MSGID_COM45NAME, 		"cleanupbysize",       },
	{ ATTRDEFTYPE_String2, MSGID_COM46NAME, 		"cleanupbytype",       },
	{ ATTRDEFTYPE_String2, MSGID_COM36NAME, 		"clearselection",      },
	{ ATTRDEFTYPE_String2, MSGID_COM28NAME, 		"clone",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM9NAME, 			"close",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM39NAME, 		"copy",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM51NAME, 		"createthumbnail",     },
	{ ATTRDEFTYPE_String2, MSGID_COM40NAME, 		"cut",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM49NAME, 		"copyto",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM27NAME, 		"delete",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM29NAME, 		"emptytrashcan",       },
	{ ATTRDEFTYPE_String2, MSGID_COM2NAME, 			"executecommand",      },
	{ ATTRDEFTYPE_String2, MSGID_COM_FIND, 			"find",	         	},
	{ ATTRDEFTYPE_String2, MSGID_COM33NAME, 		"formatdisk",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM32NAME, 		"iconify",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM22NAME, 		"iconinfo",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM_ICONPROPERTIES,	"iconproperties",      },
	{ ATTRDEFTYPE_String2, MSGID_COM30NAME, 		"lastmsg",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM25NAME, 		"leaveout",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM7NAME, 			"makedir",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM50NAME, 		"moveto",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM19NAME, 		"open",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM_OPENBROWSERWINDOW, 	"openinbrowserwindow", },
	{ ATTRDEFTYPE_String2, MSGID_COM_OPENNEWWINDOW, 	"openinnewwindow",     },
	{ ATTRDEFTYPE_String2, MSGID_COM8NAME, 			"parent",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM41NAME, 		"paste",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM26NAME, 		"putaway",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM6NAME, 			"quit",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM_REDO,			"redo",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM31NAME, 		"redraw",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM3NAME, 			"redrawall",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM21NAME, 		"rename",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM20NAME, 		"reset",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM11NAME, 		"selectall",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM16NAME, 		"showallfiles",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM15NAME, 		"showonlyicons",       },
	{ ATTRDEFTYPE_String2, MSGID_COM48NAME, 		"showdefault",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM34NAME, 		"shutdown",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM35NAME, 		"sizetofit",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM23NAME, 		"snapshot",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM14NAME, 		"snapshotall",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM13NAME, 		"snapshotwindow",      },
	{ ATTRDEFTYPE_String2, MSGID_COM_THUMBNAILCACHECLEANUP,	"thumbnailcachecleanup", },
	{ ATTRDEFTYPE_String2, MSGID_COM24NAME, 		"unsnapshot",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM_UNDO,			"undo",		       },
	{ ATTRDEFTYPE_String2, MSGID_COM10NAME, 		"update",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM4NAME, 			"updateall",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM47NAME, 		"viewbydefault",       },
	{ ATTRDEFTYPE_String2, MSGID_COM38NAME, 		"viewbydate",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM17NAME, 		"viewbyicon",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM37NAME, 		"viewbysize",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM42NAME, 		"viewbytype",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM18NAME, 		"viewbytext",	       },
	{ ATTRDEFTYPE_String2, MSGID_COM_WINDOWPROPERTIES, 	"windowproperties",    },
	};
static struct AttrDefaultValue AttrDefGroupMemberHideContents[] =
	{
	{ ATTRDEFTYPE_String, 0, "novolumenode",	},
	{ ATTRDEFTYPE_String, 0, "isempty",		},
	};

static struct AttributeDef AttrDefFileType[] =
	{
		{ 
		ATTRTYPE_FtDescription, 
		FALSE,
		0, { ATTRTYPE_FtDescription },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "" },
		NULL, 0,
		},
		{
		ATTRTYPE_PvPluginName,
		FALSE,
		0, { ATTRTYPE_PvPluginName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "Scalos:Plugins/Preview/" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefDtImage[] =
	{
		{ 
		ATTRTYPE_DtImageName, 
		TRUE,
		0, { ATTRTYPE_DtImageName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "SYS:" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefSubMenu[] =
	{
		{ 
		ATTRTYPE_MenuItemName, 
		TRUE,
		0, { ATTRTYPE_MenuItemName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		NULL, 0,
		},
		{
		ATTRTYPE_UnselIconName,
		FALSE,
		0, { ATTRTYPE_UnselIconName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" },
		NULL, 0,
		},
		{
		ATTRTYPE_SelIconName,
		FALSE,
		0, { ATTRTYPE_SelIconName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefMenuItem[] =
	{
		{ 
		ATTRTYPE_MenuItemName, 
		TRUE,
		0, { ATTRTYPE_MenuItemName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		NULL, 0,
		},
		{ 
		ATTRTYPE_MenuCommKey, 
		FALSE,
		0, { ATTRTYPE_MenuCommKey },
		1, 1,
		{ ATTRDEFTYPE_String, 0, "" },
		NULL, 0,
		},
		{ 
		ATTRTYPE_MenuDefaultAction, 
		FALSE,
		0, { ATTRTYPE_MenuDefaultAction },
		0, 0,
		{ ATTRDEFTYPE_None, 0, "" },
		NULL, 0,
		},
		{
		ATTRTYPE_UnselIconName,
		FALSE,
		0, { ATTRTYPE_UnselIconName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" },
		NULL, 0,
		},
		{
		ATTRTYPE_SelIconName,
		FALSE,
		0, { ATTRTYPE_SelIconName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "THEME:Filetypes/" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefWBCmd[] =
	{
		{ 
		ATTRTYPE_CommandName, 
		TRUE,
		0, { ATTRDEFTYPE_FileName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "SYS:" },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandStacksize, 
		FALSE,
		0, { ATTRTYPE_CommandStacksize },
		4096, 4194304,
		{ ATTRDEFTYPE_ULong, 16384, "", NULL },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandPriority, 
		FALSE,
		0, { ATTRTYPE_CommandPriority },
		SCHAR_MIN, SCHAR_MAX,
		{ ATTRDEFTYPE_ULong, 0, "", NULL },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandWbArgs, 
		FALSE,
		0, { ATTRTYPE_CommandWbArgs },
		0, 0,
		{ ATTRDEFTYPE_None, 0, "" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefCmd[] =
	{
		{ 
		ATTRTYPE_CommandName, 
		TRUE,
		0, { ATTRTYPE_CommandName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FileName, 0, "SYS:" },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandStacksize, 
		FALSE,
		0, { ATTRTYPE_CommandStacksize },
		4096, 4194304,
		{ ATTRDEFTYPE_ULong, 16384, "", NULL },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandPriority, 
		FALSE,
		0, { ATTRTYPE_CommandPriority },
		SCHAR_MIN, SCHAR_MAX,
		{ ATTRDEFTYPE_ULong, 0, "", NULL },
		NULL, 0,
		},
		{ 
		ATTRTYPE_CommandWbArgs, 
		FALSE,
		0, { ATTRTYPE_CommandWbArgs },
		0, 0,
		{ ATTRDEFTYPE_None, 0, "" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefInternalCmd[] =
	{
		{ 
		ATTRTYPE_CommandName, 
		TRUE,
		0, { ATTRTYPE_CommandName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		AttrDefPopupMenuInternalCmds, Sizeof(AttrDefPopupMenuInternalCmds),
		},
	};
static struct AttributeDef AttrDefPluginCmd[] =
	{
		{ 
		ATTRTYPE_CommandName, 
		TRUE,
		0, { ATTRTYPE_CommandName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefIconWindowCmd[] =
	{
		{ 
		ATTRTYPE_CommandName, 
		TRUE,
		0, { ATTRTYPE_CommandName },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_PathName, 0, "SYS:" },
		NULL, 0,
		},
	};
static struct AttributeDef AttrDefGroup[] =
	{
		{ 
		ATTRTYPE_GroupOrientation, 
		TRUE,
		0, { ATTRTYPE_GroupOrientation },
		TTL_Horizontal, TTL_Vertical,
		{ ATTRDEFTYPE_ULong, TTL_Vertical, "", ConvertGroupOrientationFromString },
		AttrDefGroupOrientationContents, Sizeof(AttrDefGroupOrientationContents),
		},
	};
static struct AttributeDef AttrDefMember[] =
	{
		{ 
		ATTRTYPE_MemberHideString, 
		FALSE,
		0, { ATTRTYPE_MemberHideString },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		AttrDefGroupMemberHideContents, Sizeof(AttrDefGroupMemberHideContents),
		},
	};
static struct AttributeDef AttrDefString[] =
	{
		{ 
		ATTRTYPE_StringText, 
		TRUE,
		2, { ATTRTYPE_StringSrc, ATTRTYPE_StringId },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_LocString, MSGID_CHANGEME, "" },
		NULL, 0,
		},
		{ 
		ATTRTYPE_StringSrc, 
		TRUE,
		2, { ATTRTYPE_StringText, ATTRTYPE_StringId },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "diskstate" },
		AttrDefGroupStringSrcContents, Sizeof(AttrDefGroupStringSrcContents),
		},
		{ 
		ATTRTYPE_StringId, 
		TRUE,
		2, { ATTRTYPE_StringText, ATTRTYPE_StringSrc },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "MSGID_BYTENAME" },
		AttrDefStringIDContents, Sizeof(AttrDefStringIDContents),
		},
		{ 
		ATTRTYPE_StringPen, 
		FALSE,
		0, { ATTRTYPE_StringPen },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "PENIDX_TOOLTIP_TEXT" },
		AttrDefStringPenContents, Sizeof(AttrDefStringPenContents),
		},
		{ 
		ATTRTYPE_StringFont, 
		FALSE,
		0, { ATTRTYPE_StringFont },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_FontString, 0, "" },
		NULL,
		},
		{ 
		ATTRTYPE_StringTTFont, 
		FALSE,
		0, { ATTRTYPE_StringTTFont },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_TTFontString, 0, "" },
		NULL,
		},
		{ 
		ATTRTYPE_StringStyle, 
		FALSE,
		0, { ATTRTYPE_StringStyle },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "normal" },
		AttrDefStringStyleContents, Sizeof(AttrDefStringStyleContents),
		},
		{ 
		ATTRTYPE_StringVAlign, 
		FALSE,
		0, { ATTRTYPE_StringVAlign },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "center" },
		AttrDefStringVAlignContents, Sizeof(AttrDefStringVAlignContents),
		},
		{ 
		ATTRTYPE_StringHAlign, 
		FALSE,
		0, { ATTRTYPE_StringHAlign },
		0, MAX_ATTRVALUE,
		{ ATTRDEFTYPE_String, 0, "center" },
		AttrDefStringHAlignContents, Sizeof(AttrDefStringHAlignContents),
		},
	};
static struct AttributeDef AttrDefSpace[] =
	{
		{ 
		ATTRTYPE_SpaceSize, 
		TRUE,
		0, { ATTRTYPE_SpaceSize },
		1, 255,
		{ ATTRDEFTYPE_ULong, 1, "", NULL },
		NULL, 0,
		},
	};

static const struct EntryAttributes AllEntryAttributes[] =
	{
		{
		ENTRYTYPE_FileType,
		AttrDefFileType, Sizeof(AttrDefFileType),
		},
		{
		ENTRYTYPE_PopupMenu,
		NULL, 0,
		},
		{
		ENTRYTYPE_PopupMenu_SubMenu,
		AttrDefSubMenu, Sizeof(AttrDefSubMenu),
		},
		{
		ENTRYTYPE_PopupMenu_MenuItem,
		AttrDefMenuItem, Sizeof(AttrDefMenuItem),
		},
		{
		ENTRYTYPE_PopupMenu_InternalCmd,
		AttrDefInternalCmd, Sizeof(AttrDefInternalCmd),
		},
		{
		ENTRYTYPE_PopupMenu_WbCmd,
		AttrDefWBCmd, Sizeof(AttrDefWBCmd),
		},
		{
		ENTRYTYPE_PopupMenu_ARexxCmd,
		AttrDefCmd, Sizeof(AttrDefCmd),
		},
		{
		ENTRYTYPE_PopupMenu_CliCmd,
		AttrDefCmd, Sizeof(AttrDefCmd),
		},
		{
		ENTRYTYPE_PopupMenu_PluginCmd,
		AttrDefPluginCmd, Sizeof(AttrDefPluginCmd),
		},
		{
		ENTRYTYPE_PopupMenu_IconWindowCmd,
		AttrDefIconWindowCmd, Sizeof(AttrDefIconWindowCmd),
		},
		{
		ENTRYTYPE_PopupMenu_MenuSeparator,
		NULL, 0,
		},
		{
		ENTRYTYPE_ToolTip,
		NULL, 0,
		},
		{
		ENTRYTYPE_ToolTip_Group,
		AttrDefGroup, Sizeof(AttrDefGroup),
		},
		{
		ENTRYTYPE_ToolTip_Member,
		AttrDefMember, Sizeof(AttrDefMember),
		},
		{
		ENTRYTYPE_ToolTip_HBar,
		NULL, 0,
		},
		{
		ENTRYTYPE_ToolTip_String,
		AttrDefString, Sizeof(AttrDefString),
		},
		{
		ENTRYTYPE_ToolTip_Space,
		AttrDefSpace, Sizeof(AttrDefSpace),
		},
		{
		ENTRYTYPE_ToolTip_DtImage,
		AttrDefDtImage, Sizeof(AttrDefDtImage),
		}
	};

//---------------------------------------------------------------

BOOL closePlugin(struct PluginBase *PluginBase)
{
	d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__));

	if (DataTypesImageClass)
		{
		CleanupDtpicClass(DataTypesImageClass);
		DataTypesImageClass = NULL;
		}
	if (FontSampleClass)
		{
		CleanupFontSampleClass(FontSampleClass);
		FontSampleClass = NULL;
		}
	if (IconobjectClass)
		{
		CleanupIconobjectClass(IconobjectClass);
		IconobjectClass = NULL;
		}
	if (myNListClass)
		{
		MUI_DeleteCustomClass(myNListClass);
		myNListClass = NULL;
		}
	if (myFileTypesActionsNListClass)
		{
		MUI_DeleteCustomClass(myFileTypesActionsNListClass);
		myFileTypesActionsNListClass = NULL;
		}
	if (myNListTreeClass)
		{
		MUI_DeleteCustomClass(myNListTreeClass);
		myNListTreeClass = NULL;
		}
	if (myFileTypesNListTreeClass)
		{
		MUI_DeleteCustomClass(myFileTypesNListTreeClass);
		myFileTypesNListTreeClass = NULL;
		}

	if (FileTypesPrefsCatalog)
		{
		CloseCatalog(FileTypesPrefsCatalog);
		FileTypesPrefsCatalog = NULL;
		}
	if (FileTypesPrefsLocale)
		{
		CloseLocale(FileTypesPrefsLocale);
		FileTypesPrefsLocale = NULL;
		}

	if (FileTypesPrefsClass)
		{
		MUI_DeleteCustomClass(FileTypesPrefsClass);
		FileTypesPrefsClass = NULL;
		}

	CloseLibraries();

#if !defined(__amigaos4__) && !defined(__AROS__)
	_STD_240_TerminateMemFunctions();
#endif

	return TRUE;
}


LIBFUNC_P2(IPTR, LIBSCAGetPrefsInfo,
	D0, ULONG, which,
	A6, struct PluginBase *, PluginBase, 5)
{
	IPTR result;

	(void) PluginBase;

	d1(kprintf(__FILE__ "/%s/%ld: which=%ld\n", __FUNC__, __LINE__, which));

	switch(which)
		{
	case SCAPREFSINFO_GetClass:
		result = (IPTR) FileTypesPrefsClass;
		break;

	case SCAPREFSINFO_GetTitle:
		result = (IPTR) GetLocString(MSGID_PLUGIN_LIST_TITLE);
		break;

	case SCAPREFSINFO_GetTitleImage:
		result = (IPTR) CreatePrefsImage();
		break;

	default:
		result = (IPTR) NULL;
		break;
		}

	d1(kprintf(__FILE__ "/%s/%ld: Result=%08lx\n", __FUNC__, __LINE__, result));

	return result;
}
LIBFUNC_END

//----------------------------------------------------------------------------

DISPATCHER(FileTypesPrefs)
{
	struct FileTypesPrefsInst *inst;
	ULONG n;
	IPTR result = 0;

	d1(kprintf("%s/%ld:  START obj=%08lx\n", __FUNC__, __LINE__, obj));

	switch(msg->MethodID)
		{
	case OM_NEW:
		obj = (Object *) DoSuperMethodA(cl, obj, msg);
		d1(kprintf(__FILE__ "/%s/%ld: OM_NEW obj=%08lx\n", __FUNC__, __LINE__, obj));
		if (obj)
			{
			Object *prefsobject;
			struct opSet *ops = (struct opSet *) msg;

			inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);

			memset(inst, 0, sizeof(struct FileTypesPrefsInst));

			inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG;
			inst->fpb_Changed = FALSE;
			inst->fpb_HideEmptyNodes = FALSE;
			inst->fpb_FileTypesDirLock = (BPTR) NULL;
			inst->fpb_IncludeNesting = 0;
			inst->fpb_WBScreen = LockPubScreen("Workbench");
			inst->fpb_MenuImageIndex = 0;

			inst->fpb_TTfAntialias = TT_Antialias_Auto;
			inst->fpb_TTfGamma = 2500;

			NewList(&inst->fpb_FoundList);
			inst->fpb_CurrentFound = (struct FoundNode *) &inst->fpb_FoundList.lh_Tail;

			InitHooks(inst);

			ReadScalosPrefs(inst, "ENV:scalos/scalos.prefs");

			inst->fpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList);
			inst->fpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (IPTR) "", ops->ops_AttrList);
			inst->fpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (IPTR) NULL, ops->ops_AttrList);
			inst->fpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (IPTR) NULL, ops->ops_AttrList);

			prefsobject = CreatePrefsGroup(inst);
			d1(kprintf(__FILE__ "/%s/%ld: prefsobject=%08lx\n", __FUNC__, __LINE__, prefsobject));
			if (prefsobject)
				{
				DoMethod(obj, OM_ADDMEMBER, prefsobject);

				result = (IPTR) obj;
				}
			else
				{
				CoerceMethod(cl, obj, OM_DISPOSE);
				}
			}
		break;

	case OM_DISPOSE:
		d1(kprintf(__FILE__ "/%s/%ld: OM_DISPOSE obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);

		CleanupFoundNodes(inst);

		if (inst->fpb_WBScreen)
			{
			UnlockPubScreen(NULL, inst->fpb_WBScreen);
			inst->fpb_WBScreen = NULL;
			}
		for (n=0; n<Sizeof(inst->fpb_FileHandles); n++)
			{
			if (inst->fpb_FileHandles[n].ftfd_FileHandle)
				{
				Close(inst->fpb_FileHandles[n].ftfd_FileHandle);
				inst->fpb_FileHandles[n].ftfd_FileHandle = (BPTR) NULL;
				}
			}
		if (inst->fpb_LearnReq)
			{
			MUI_FreeAslRequest(inst->fpb_LearnReq);
			inst->fpb_LearnReq = NULL;
			}
		if (inst->fpb_LoadReq)
			{
			MUI_FreeAslRequest(inst->fpb_LoadReq);
			inst->fpb_LoadReq = NULL;
			}
		if (inst->fpb_SaveReq)
			{
			MUI_FreeAslRequest(inst->fpb_SaveReq);
			inst->fpb_SaveReq = NULL;
			}
		if (inst->fpb_FileTypesDirLock)
			{
			UnLock(inst->fpb_FileTypesDirLock);
			inst->fpb_FileTypesDirLock = (BPTR) NULL;
			}
		if (inst->fpb_Objects[OBJNDX_ContextMenuFileTypes])
			{
			MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes]);
			inst->fpb_Objects[OBJNDX_ContextMenuFileTypes] = NULL;
			}
		if (inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions])
			{
			MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions]);
			inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions] = NULL;
			}
		if (inst->fpb_Objects[OBJNDX_ContextMenu])
			{
			MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenu]);
			inst->fpb_Objects[OBJNDX_ContextMenu] = NULL;
			}
		if (inst->fpb_Objects[OBJNDX_ContextMenuAttrList])
			{
			MUI_DisposeObject(inst->fpb_Objects[OBJNDX_ContextMenuAttrList]);
			inst->fpb_Objects[OBJNDX_ContextMenuAttrList] = NULL;
			}
		if (inst->fpb_IconObject)
			{
			DisposeIconObject(inst->fpb_IconObject);
			inst->fpb_IconObject = NULL;
			}

		CleanupDefIcons(inst);

		d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog));
		return DoSuperMethodA(cl, obj, msg);
		break;

	case OM_SET:
		{
		struct opSet *ops = (struct opSet *) msg;

		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		d1(kprintf("%s/%ld:   OM_SET  createIcons=%ld\n", __FUNC__, __LINE__, inst->fpb_fCreateIcons));

		inst->fpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->fpb_fCreateIcons, ops->ops_AttrList);
		inst->fpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (IPTR) inst->fpb_ProgramName, ops->ops_AttrList);
		inst->fpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, 
			(IPTR) inst->fpb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList);
		inst->fpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, 
			(IPTR) inst->fpb_Objects[OBJNDX_APP_Main], ops->ops_AttrList);

		d1(kprintf("%s/%ld:   OM_SET  createIcons=%ld\n", __FUNC__, __LINE__, inst->fpb_fCreateIcons));

		return DoSuperMethodA(cl, obj, msg);
		}
		break;

	case OM_GET:
		{
		struct opGet *opg = (struct opGet *) msg;

		d1(kprintf(__FILE__ "/%s/%ld: OM_GET obj=%08lx\n", __FUNC__, __LINE__, obj));

		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		switch (opg->opg_AttrID)
			{
		case MUIA_ScalosPrefs_CreateIcons:
			*opg->opg_Storage = inst->fpb_fCreateIcons;
			result = 0;
			break;
		default:
			result = DoSuperMethodA(cl, obj, msg);
			}
		}
		break;

	case MUIM_ScalosPrefs_ParseToolTypes:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_ParseToolTypes obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		d1(kprintf(__FILE__ "/%s/%ld: before ParseToolTypes\n", __FUNC__, __LINE__));
		ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg);
		d1(kprintf(__FILE__ "/%s/%ld: after ParseToolTypes\n", __FUNC__, __LINE__));
		 break;

	case MUIM_ScalosPrefs_LoadConfig:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LoadConfig obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		ReadPrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS);
		inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG;
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_UseConfig:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_UseConfig obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags);
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_UseConfigIfChanged:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_UseConfigIfChanged obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		if (inst->fpb_Changed)
			{
			WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags);
			SetChangedFlag(inst, FALSE);
			}
		break;

	case MUIM_ScalosPrefs_SaveConfig:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfig obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags & ~FTWRITEFLAG_CLEAR_CHANGE_FLAG);
		WritePrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS, inst->fpb_SaveFlags);
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_SaveConfigIfChanged:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfigIfChanged obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		if (inst->fpb_Changed)
			{
			WritePrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS, inst->fpb_SaveFlags & ~FTWRITEFLAG_CLEAR_CHANGE_FLAG);
			WritePrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS, inst->fpb_SaveFlags);
			SetChangedFlag(inst, FALSE);
			}
		break;

	case MUIM_ScalosPrefs_RestoreConfig:
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_RestoreConfig\n", __FUNC__, __LINE__));
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_Restore], 0);
		break;

	case MUIM_ScalosPrefs_ResetToDefaults:
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_ResetToDefaults", __FUNC__, __LINE__));
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ResetToDefaults], 0);
		break;

	case MUIM_ScalosPrefs_LastSavedConfig:
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		d1(KPrintF(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LastSavedConfig", __FUNC__, __LINE__));
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_LastSaved], 0);
		break;

	case MUIM_ScalosPrefs_OpenConfig:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_OpenConfig obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_Open], 0);
		break;

	case MUIM_ScalosPrefs_SaveConfigAs:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_SaveConfigAs obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SaveAs], 0);
		break;

	case MUIM_ScalosPrefs_About:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_About obj=%08lx\n", __FUNC__, __LINE__, obj));
		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_About], 0);
		break;

	case MUIM_ScalosPrefs_LoadNamedConfig:
		{
		struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg;

		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_LoadNamedConfig obj=%08lx\n", __FUNC__, __LINE__, obj));

		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		ReadPrefs(inst, lnc->ConfigFileName, ENV_DEFICONS_PREFS);
		inst->fpb_SaveFlags = FTWRITEFLAG_ONLY_SAVE_CHANGED | FTWRITEFLAG_CLEAR_CHANGE_FLAG;
		}
		break;

	case MUIM_ScalosPrefs_CreateSubWindows:
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_CreateSubWindows obj=%08lx\n", __FUNC__, __LINE__, obj));
		result = (IPTR) CreateSubWindows(cl, obj);
		break;

	case MUIM_ScalosPrefs_PageActive:
		{
		struct MUIP_ScalosPrefs_PageActive *spa = (struct MUIP_ScalosPrefs_PageActive *) msg;

		inst = (struct FileTypesPrefsInst *) INST_DATA(cl, obj);
		inst->fpb_PageIsActive = spa->isActive;
		d1(kprintf(__FILE__ "/%s/%ld: MUIM_ScalosPrefs_PageActive  isActive=%08lx  inst=%08lx\n", __FUNC__, __LINE__, spa->isActive, inst));
		}
		break;

	case MUIM_ScalosPrefs_GetListOfMCCs:
		result = (IPTR) RequiredMccList;
		break;

	default:
		d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));
		result = DoSuperMethodA(cl, obj, msg);
		break;
		}

	d1(kprintf("%s/%ld:  END inst=%08lx\n", __FUNC__, __LINE__, inst));
	return result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

static Object *CreatePrefsGroup(struct FileTypesPrefsInst *inst)
{
	d1(kprintf("%s/%ld:  inst=%08lx\n", __FUNC__, __LINE__, inst));

	inst->fpb_Objects[OBJNDX_ContextMenuFileTypes] = MUI_MakeObject(MUIO_MenustripNM, ContextMenuFileTypes, 0);
	if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuFileTypes])
		return NULL;

	inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions] = MUI_MakeObject(MUIO_MenustripNM, ContextMenuFileTypesActions, 0);
	if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions])
		return NULL;

	inst->fpb_Objects[OBJNDX_Menu_ExpandFileTypes] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes],
			MUIM_FindUData, HOOKNDX_ExpandFileTypes);
	inst->fpb_Objects[OBJNDX_Menu_CollapseFileTypes] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes],
			MUIM_FindUData, HOOKNDX_CollapseFileTypes);

	inst->fpb_Objects[OBJNDX_Menu_Find] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuFileTypes],
			MUIM_FindUData, HOOKNDX_ShowFindGroup);

	inst->fpb_Objects[OBJNDX_ContextMenu] = MUI_MakeObject(MUIO_MenustripNM, ContextMenus, 0);
	if (NULL == inst->fpb_Objects[OBJNDX_ContextMenu])
		return NULL;

	inst->fpb_Objects[OBJNDX_Menu_Expand] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_Expand);
	inst->fpb_Objects[OBJNDX_Menu_Collapse] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_Collapse);

	inst->fpb_Objects[OBJNDX_Menu_Copy] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_Copy);
	inst->fpb_Objects[OBJNDX_Menu_Cut] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_Cut);
	inst->fpb_Objects[OBJNDX_Menu_Paste] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_Paste);

	inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenu],
			MUIM_FindUData, HOOKNDX_HideEmptyEntries);


	inst->fpb_Objects[OBJNDX_ContextMenuAttrList] = MUI_MakeObject(MUIO_MenustripNM, ContextMenusAttrList, 0);
	if (NULL == inst->fpb_Objects[OBJNDX_ContextMenuAttrList])
		return NULL;

	inst->fpb_Objects[OBJNDX_Menu_CopyAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList],
			MUIM_FindUData, HOOKNDX_CopyAttr);
	inst->fpb_Objects[OBJNDX_Menu_CutAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList],
			MUIM_FindUData, HOOKNDX_CutAttr);
	inst->fpb_Objects[OBJNDX_Menu_PasteAttr] = (Object *) DoMethod(inst->fpb_Objects[OBJNDX_ContextMenuAttrList],
			MUIM_FindUData, HOOKNDX_PasteAttr);


	d1(kprintf("%s/%ld:  inst=%08lx\n", __FUNC__, __LINE__, inst));

	inst->fpb_Objects[OBJNDX_Group_Main] = VGroup,
		MUIA_Background, MUII_PageBack,

		// OBJNDX_ShadowListView is used as invisible storage
		// for copy and paste operations
		Child, (IPTR)(inst->fpb_Objects[OBJNDX_ShadowListView] = NListviewObject,
			MUIA_ShowMe, FALSE,
			MUIA_CycleChain, TRUE,
			MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_ShadowListTree] = myNListTreeObject,
				MUIA_NList_PrivateData, (IPTR)inst,
				MUIA_NList_Format, (IPTR)"",
				MUIA_NListtree_DisplayHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDisplay],
				MUIA_NListtree_ConstructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeConstruct],
				MUIA_NListtree_DestructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDestruct],
                        End), // myNListTreeClass
                End), // NListviewObject

		Child, (IPTR)(inst->fpb_Objects[OBJNDX_ShadowAttrListView] = NListviewObject,
			MUIA_ShowMe, FALSE,
			MUIA_CycleChain, TRUE,
			MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_ShadowAttrList] = myNListObject,
				MUIA_NList_PrivateData, (IPTR)inst,
				MUIA_NList_Format, (IPTR)",",
				InputListFrame,
				MUIA_Background, MUII_ListBack,
				MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrDisplay],
				MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrConstruct],
				MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrDestruct],
				MUIA_NList_DragSortable, FALSE,
				MUIA_NList_ShowDropMarks, FALSE,
				MUIA_NList_Title, TRUE,
				MUIA_NList_TitleSeparator, TRUE,
                        End), // myNListTreeClass

			MUIA_Listview_DragType, MUIV_Listview_DragType_None,
			MUIA_Weight, 50,
                End), // NListviewObject

		Child, (IPTR)(RegisterObject,
			MUIA_Register_Titles, (IPTR)RegisterTitles,
			MUIA_CycleChain, TRUE,

			// --- filetypes
			Child, (IPTR)(VGroup,
				Child, (IPTR)(HGroup,
					MUIA_Weight, 200,
					Child, (IPTR)(VGroup,
						Child, (IPTR)(VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPES_FILETYPES),
							GroupFrame,

							Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_FindFiletype] = HGroup,
								GroupFrame,
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_HideFind] = TextObject,
									MUIA_Weight, 10,
									ButtonFrame,
									MUIA_CycleChain, TRUE,
#if defined(MUII_Close)
									MUIA_Text_Contents, (IPTR)MUIX_C "\33I[6:" STR(MUII_Close) "]",
#else
									MUIA_Text_Contents, (IPTR)MUIX_C "\33I[6:" STR(MUII_TapeStop) "]",
#endif
									MUIA_InputMode, MUIV_InputMode_RelVerify,
									MUIA_Background, MUII_ButtonBack,
									MUIA_ShortHelp, (IPTR)GetLocString(MSGID_BUTTON_FIND_HIDE_SHORTHELP),
                                                                End),

								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FindFileType] = StringObject,
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_ShortHelp, (IPTR)GetLocString(MSGID_STRING_FIND_SHORTHELP),
                                                                End), //StringObject
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType] = TextObject,
									MUIA_Weight, 10,
									ButtonFrame,
									MUIA_CycleChain, TRUE,
									MUIA_Text_Contents, (IPTR)MUIX_C "\33I[6:" STR(MUII_TapePlayBack) "]",
									MUIA_InputMode, MUIV_InputMode_RelVerify,
									MUIA_Background, MUII_ButtonBack,
									MUIA_ShortHelp, (IPTR)GetLocString(MSGID_BUTTON_FIND_PREV_SHORTHELP),
                                                                End),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FindNextFileType] = TextObject,
									MUIA_Weight, 10,
									ButtonFrame,
									MUIA_CycleChain, TRUE,
									MUIA_Text_Contents, (IPTR)MUIX_C "\33I[6:" STR(MUII_TapePlay) "]",
									MUIA_InputMode, MUIV_InputMode_RelVerify,
									MUIA_Background, MUII_ButtonBack,
									MUIA_ShortHelp, (IPTR)GetLocString(MSGID_BUTTON_FIND_NEXT_SHORTHELP),
                                                                End),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FindHitCount] = TextObject,
									MUIA_Weight, 10,
									MUIA_Text_Contents, (IPTR)"",
                                                                End), //TextObject

                                                        End), //HGroup

							Child, (IPTR)(inst->fpb_Objects[OBJNDX_NListview_FileTypes] = NListviewObject,
								MUIA_CycleChain, TRUE,
								MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPES),
								MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_NListtree_FileTypes] = myFileTypesNListTreeObject,
									MUIA_Background, MUII_ListBack,
									MUIA_NList_PrivateData, (IPTR)inst,
									MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenuFileTypes],
									MUIA_NListtree_DisplayHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesDisplay],
									MUIA_NListtree_ConstructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesConstruct],
									MUIA_NListtree_DestructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesDestruct],
									MUIA_NListtree_DragDropSort, TRUE,
									MUIA_NList_ShowDropMarks, TRUE,
									MUIA_NListtree_EmptyNodes, TRUE,
									MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand,
								End), //myFileTypesNListTreeClass
							End), //NListtreeObject

							Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Name] = StringObject,
								MUIA_CycleChain, TRUE,
								MUIA_Disabled, TRUE,
								MUIA_String_AdvanceOnCR, TRUE,
								MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPES),
								StringFrame,
                                                        End), //StringObject

							Child, (IPTR)(ColGroup(2),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FileTypes_Add] = KeyButtonHelp(MSGID_BUTTON_ADD_FILETYPE,
									'a',
									MSGID_SHORTHELP_BUTTON_ADD_FILETYPE)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove] = KeyButtonHelp(MSGID_BUTTON_DELETE_FILETYPE,
									'r',
									MSGID_SHORTHELP_BUTTON_DELETE_FILETYPE)),
                                                        End), //ColGroup
                                                End), //VGroup
                                        End), //VGroup

					Child, (IPTR)(VGroup,
						Child, (IPTR)HVSpace,
						MUIA_Weight, 10,
						MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_DEFAULTICON),

						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Text_FileTypes_FileTypesName] = TextObject,
							MUIA_ShowMe, FALSE,
							MUIA_Text_Contents, (IPTR)"",
							MUIA_Text_PreParse, (IPTR)MUIX_B "\33c",
                                                End), //TextObject

						Child, (IPTR)HVSpace,

						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Text_FileTypes_DefIconName] = TextObject,
							MUIA_Text_Contents, (IPTR)"",
							MUIA_Text_PreParse, (IPTR)"\33c",
							MUIA_Text_SetMin, TRUE,
                                                End), //TextObject
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon] = IconobjectMCCObject,
							MUIA_InputMode, MUIV_InputMode_RelVerify,
							NoFrame,
							MUIA_ShowSelState, FALSE,
                                                End), //IconobjectMCCObject

						Child, (IPTR)HVSpace,

						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon] = KeyButtonHelp(MSGID_BUTTON_CREATE_ICON,
							'i',
							MSGID_SHORTHELP_BUTTON_CREATE_ICON)),
						
                                                Child, (IPTR)HVSpace,
                                        End), //VGroup
                                End), //HGroup

				Child, (IPTR)(BalanceObject,
					End), // BalanceObject

				Child, (IPTR)(VGroup,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPES_METHODS),
					GroupFrame,
					MUIA_Weight, 50,

					Child, (IPTR)(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods] = NListviewObject,
						MUIA_CycleChain, TRUE,
						MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPE_ACTION),
						MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions] = myFileTypesActionsNListObject,
							MUIA_NList_PrivateData, (IPTR)inst,
							MUIA_NList_Format, (IPTR)"BAR,",
							InputListFrame,
							MUIA_Background, MUII_ListBack,
							MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenuFileTypesActions],
							MUIA_NList_DragSortable, TRUE,
							MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesActionDisplay],
							MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesActionConstruct],
							MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_FileTypesActionDestruct],
						End), //myFileTypesActionsNListClass
					End), //NListviewObject

					Child, (IPTR)(ColGroup(3),
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add] = PopobjectObject,
							MUIA_Disabled, TRUE,
							MUIA_UserData, (IPTR)inst,
							MUIA_CycleChain, TRUE,
							MUIA_Popstring_Button, (IPTR)(KeyButtonHelp(MSGID_BUTTON_ADD_FILETYPEACTION,
								'a',
								MSGID_SHORTHELP_BUTTON_ADD_FILETYPEACTION)),
							MUIA_Popobject_Object, (IPTR)(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add] = NListviewObject,
								MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_Nlist_FileTypes_Methods_Add] = NListObject,
									InputListFrame,
									MUIA_Background, MUII_ListBack,
									MUIA_NList_AdjustWidth, TRUE,
                                                                End), //NListObject
                                                        End), //NListviewObject
							MUIA_Popstring_CloseHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddFileTypesMethod],
                                                End), //PopobjectObject
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove] = KeyButtonHelp(MSGID_BUTTON_REMOVE_FILETYPEACTION,
							'r',
							MSGID_SHORTHELP_BUTTON_REMOVE_FILETYPEACTION)),
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn] = KeyButtonHelp(MSGID_BUTTON_LEARN_FILETYPEACTION,
							'l',
							MSGID_SHORTHELP_BUTTON_LEARN_FILETYPEACTION)),
                                        End), //ColGroup
                                End), //VGroup

				Child, (IPTR)(BalanceObject,
                                End), // BalanceObject

				Child, (IPTR)(ScrollgroupObject,
					MUIA_Weight, 25,
					MUIA_Scrollgroup_Contents, (IPTR)(VirtgroupObject,
						MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_VIRTGROUP_FILETYPE_ACTION_ATTRIBUTES),

						// empty placeholder
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Empty] = VGroup,
							MUIA_ShowMe, TRUE,
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for MATCH
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Match] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_MATCH),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_MATCH_OFFSET)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset] = StringObject,
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_Integer, 0,
									MUIA_String_AdvanceOnCR, TRUE,
									MUIA_String_Accept , (IPTR)"0123456879",
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH_OFFSET),
                                                                End), //StringObject
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_MATCH_CASE_SENSITIVE)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case] = KeyCheckMark(FALSE, (IPTR)"v")),
                                                        End), //HGroup

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_MATCH_MATCH)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MATCH),
									MUIA_CycleChain, TRUE,
									MUIA_String_AdvanceOnCR, TRUE,
									StringFrame,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for SEARCH
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Search] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_SEARCH),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)HVSpace,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_SEARCH_SKIP_SPACES)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces] = KeyCheckMark(FALSE, (IPTR)"v")),
								Child, (IPTR)HVSpace,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_SEARCH_CASE_SENSITIVE)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case] = KeyCheckMark(FALSE, (IPTR)"v")),
								Child, (IPTR)HVSpace,
                                                        End), //HGroup

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_SEARCH_SEARCH)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_SEARCH),
									MUIA_CycleChain, TRUE,
									MUIA_String_AdvanceOnCR, TRUE,
									StringFrame,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for FILESIZE
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Filesize] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_FILESIZE),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_FILESIZE_FILESIZE)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_FILESIZE),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_Integer, 0,
									MUIA_String_Accept , (IPTR)"0123456879",
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for MINSIZEMB
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_FileTypes_Action_MinSizeMB] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_MINSIZEMB),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_MINSIZEMB_SIZE)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_MINSIZEMB),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_Integer, 0,
									MUIA_String_Accept , (IPTR)"0123456879",
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup
						// for PATTERN
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Pattern] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_PATTERN),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PATTERN_PATTERN)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PATTERN),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for DOSDEVICE
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DosDevice] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_DOSDEVICE),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_DOSDEVICE_PATTERN)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSDEVICE),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for DEVICENAME
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DeviceName] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_DEVICENAME),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_DEVICENAME_PATTERN)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DEVICENAME),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for CONTENTS
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Contents] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_CONTENTS),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_CONTENTS_PATTERN)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_CONTENTS),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for DOSTYPE
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_DosType] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_DOSTYPE),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(HGroup,
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_DOSTYPE_PATTERN)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern] = StringObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_DOSTYPE),
									MUIA_CycleChain, TRUE,
									StringFrame,
									MUIA_String_AdvanceOnCR, TRUE,
                                                                End), //StringObject
                                                        End), //HGroup
							Child, (IPTR)HVSpace,
                                                End), //VGroup

						// for PROTECTION
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_Filetypes_Actions_Protection] = VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_FILETYPESACTION_PROTECTION),
							GroupFrame,
							MUIA_ShowMe, FALSE,

							Child, (IPTR)(ColGroup(4),
								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_R)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_R),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_W)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_W),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_E)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_E),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_D)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_D),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_S)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_S),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_P)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_P),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_A)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_A),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

								Child, (IPTR)Label2(GetLocString(MSGID_FILETYPEACTION_PROTECTION_H)),
								Child, (IPTR)(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H] = CycleObject,
									MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_STRING_FILETYPEACTION_PROTECTION_H),
									MUIA_CycleChain, TRUE,
		                                                        MUIA_Font, MUIV_Font_Button,
									MUIA_Cycle_Entries, (IPTR)FileTypeActionProtectionStrings,
                                                                End), //CycleObject

                                                        End), //ColGroup
                                                        Child, (IPTR)HVSpace,
                                                End), //VGroup
                                        End), //VirtualGroup
                                End), //Scrollgroup

                        End), //VGroup

			// --- filetype actions
			Child, (IPTR)(VGroup,
				Child, (IPTR)(inst->fpb_Objects[OBJNDX_MainListView] = NListviewObject,
					MUIA_CycleChain, TRUE,
					MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_MainListTree] = myNListTreeObject,
						MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenu],
						MUIA_NList_PrivateData, (IPTR)inst,
						MUIA_NList_Format, (IPTR)"",
						InputListFrame,
						MUIA_Background, MUII_ListBack,
						MUIA_NListtree_DisplayHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDisplay],
						MUIA_NListtree_ConstructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeConstruct],
						MUIA_NListtree_DestructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDestruct],
						MUIA_NListtree_DragDropSort, TRUE,
						MUIA_NList_ShowDropMarks, TRUE,
						MUIA_NListtree_EmptyNodes, TRUE,
						MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand,
                                        End), // myNListTreeClass

					MUIA_Listview_DragType, MUIV_Listview_DragType_None,
                                End), // NListviewObject

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_HiddenListView] = NListviewObject,
					MUIA_ShowMe, FALSE,
					MUIA_CycleChain, TRUE,
					MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_HiddenListTree] = myNListTreeObject,
						MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenu],
						MUIA_NList_PrivateData, (IPTR)inst,
						MUIA_NList_Format, (IPTR)"",
						InputListFrame,
						MUIA_Background, MUII_ListBack,
						MUIA_NListtree_DisplayHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDisplay],
						MUIA_NListtree_ConstructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeConstruct],
						MUIA_NListtree_DestructHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_TreeDestruct],
						MUIA_NListtree_DragDropSort, TRUE,
						MUIA_NList_ShowDropMarks, TRUE,
						MUIA_NListtree_EmptyNodes, TRUE,
						MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand,
                                        End), // myNListTreeClass

					MUIA_Listview_DragType, MUIV_Listview_DragType_None,
                                End), // NListviewObject

				Child, (IPTR)(HGroup,
					Child, (IPTR)(inst->fpb_Objects[OBJNDX_Lamp_Changed] = LampObject,
						MUIA_Lamp_Type, MUIV_Lamp_Type_Huge, 
						MUIA_Lamp_Color, MUIV_Lamp_Color_Off,
						MUIA_ShortHelp, (IPTR)GetLocString(MSGID_SHORTHELP_LAMP_CHANGED),
                                        End), //LampObject

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)(inst->fpb_Objects[OBJNDX_AddEntryPopObject] = PopobjectObject,
							MUIA_Disabled, TRUE,
							MUIA_CycleChain, TRUE,
							MUIA_Popstring_Button, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonAddEntry] = KeyButtonHelp(MSGID_BUTTON_ADD_ENTRY,
								'a',
								MSGID_SHORTHELP_BUTTON_ADD_ENTRY)),
							MUIA_Popobject_Object, (IPTR)(inst->fpb_Objects[OBJNDX_AddEntryListView] = NListviewObject,
								MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_AddEntryList] = NListObject,
									InputListFrame,
									MUIA_Background, MUII_ListBack,
									MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddEntryListConstruct],
									MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddEntryListDestruct],
									MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddEntryListDisplay],
									MUIA_NList_AdjustWidth, TRUE,
                                                                End), //NListObject
                                                        End), //NListviewObject
                                                End), //PopobjectObject

						Child, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry] = KeyButtonHelp(MSGID_BUTTON_DELETE_ENTRY,
								'd',
								MSGID_SHORTHELP_BUTTON_DELETE_ENTRY)),
					End), //ColGroup
				End), //HGroup

				Child, (IPTR)(BalanceObject,
                                End), // BalanceObject

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_AttrListView] = NListviewObject,
					MUIA_CycleChain, TRUE,
					MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_AttrList] = myNListObject,
						MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenuAttrList],
						MUIA_NList_PrivateData, (IPTR)inst,
						MUIA_NList_Format, (IPTR)",",
						InputListFrame,
						MUIA_Background, MUII_ListBack,
						MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrDisplay],
						MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrConstruct],
						MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AttrDestruct],
						MUIA_NList_DragSortable, FALSE,
						MUIA_NList_ShowDropMarks, FALSE,
						MUIA_NList_Title, TRUE,
						MUIA_NList_TitleSeparator, TRUE,
                                        End), // myNListTreeClass

					MUIA_Listview_DragType, MUIV_Listview_DragType_None,
					MUIA_Weight, 50,
                                End), // NListviewObject

				Child, (IPTR)(ColGroup(3),
					Child, (IPTR)(inst->fpb_Objects[OBJNDX_AddAttrPopObject] = PopobjectObject,
						MUIA_Disabled, TRUE,
						MUIA_CycleChain, TRUE,
						MUIA_Popstring_Button, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonAddAttribute] = KeyButtonHelp(MSGID_BUTTON_ADD_ATTRIBUTE,
							' ',
							MSGID_SHORTHELP_BUTTON_ADD_ATTRIBUTE)),
						MUIA_Popobject_Object, (IPTR)(inst->fpb_Objects[OBJNDX_AddAttrListView] = NListviewObject,
							MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_AddAttrList] = NListObject,
								InputListFrame,
								MUIA_Background, MUII_ListBack,
								MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddAttrListConstruct],
								MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddAttrListDestruct],
								MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddAttrListDisplay],
								MUIA_NList_AdjustWidth, TRUE,
                                                        End), //NListObject
                                                End), //NListviewObject
                                        End), //PopobjectObject
					Child, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonEditAttribute] = KeyButtonHelp(MSGID_BUTTON_EDIT_ATTRIBUTE,
							'e',
							MSGID_SHORTHELP_BUTTON_EDIT_ATTRIBUTE)),
					Child, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute] = KeyButtonHelp(MSGID_BUTTON_DELETE_ATTRIBUTE,
							'r',
							MSGID_SHORTHELP_BUTTON_DELETE_ATTRIBUTE)),
                                End), //ColGroup

				MUIA_ContextMenu, (IPTR)inst->fpb_Objects[OBJNDX_ContextMenu],

                        End),	//VGroup

                End), //RegisterObject

        End; //VGroup

	if (NULL == inst->fpb_Objects[OBJNDX_Group_Main])
		return NULL;

	d1(kprintf("%s/%ld:  inst=%08lx\n", __FUNC__, __LINE__, inst));

	set(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, inst->fpb_HideEmptyNodes);
	set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE);
	set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE);
	set(inst->fpb_Objects[OBJNDX_HiddenListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE);
        
	set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], MUIA_Disabled, TRUE);

	DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_ContextMenuTrigger, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ContextMenuTrigger], MUIV_TriggerValue );

	DoMethod(inst->fpb_Objects[OBJNDX_AddEntryListView], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		inst->fpb_Objects[OBJNDX_AddEntryPopObject], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddEntry]);
	DoMethod(inst->fpb_Objects[OBJNDX_AddAttrListView], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		inst->fpb_Objects[OBJNDX_AddAttrPopObject], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddAttribute]);

	// Call hook when Find Filetype Hide button is clicked
	DoMethod(inst->fpb_Objects[OBJNDX_Button_HideFind], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_HideFind], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_HideFindGroup]);

	// Call hook everytime the contents of StringFindFileType changes
	DoMethod(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FindFileType], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_IncrementalFindFileType]);

	// Call FindNextFileTypeHook when "Next" button is clicked
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FindNextFileType], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_IncrementalFindNextFileType]);

	// Call FindPrevFileTypeHook when "Prev" button is clicked
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_IncrementalFindPrevFileType]);

	// call hook on double click into "Add Method" popup listview
	DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods_Add], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		inst->fpb_Objects[OBJNDX_Popobject_FileTypes_Methods_Add], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddFileTypesMethod]);

	// call hook when the "Learn" button is pressed
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Learn], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_Learn_FileType] );

	// call hook everytime the filetype actions list is drag-drop sorted
	DoMethod(inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions], MUIM_Notify, MUIA_NList_DragSortInsert, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_NList_FileTypes_Actions], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_DragDropSort_FileTypesAction] );

	// call hook everytime a new filetype is added
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Add], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FileTypes_Add], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_AddFileType] );

	// call hook everytime a new filetype is removed
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FileTypes_Remove], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_RemoveFileType] );

	// call hook everytime a new filetype is selected
	DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_NListtree_FileTypes], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SelectFileTypesEntry] );

	// call hook everytime a new filetype is renamed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Name], MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Name], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_RenameFileType] );

	// call hook everytime a new filetypes action is removed
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FileTypes_Actions_Remove], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_RemoveFileTypeAction] );

	// setup hook if "create new" button is presseed for filetypes icon
	DoMethod(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_CreateNewFileTypesIcon] );

	// setup hook if filetypes icon is clicked
	DoMethod(inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon], MUIM_Notify, MUIA_Pressed, FALSE,
		inst->fpb_Objects[OBJNDX_IconObjectMCC_FileTypes_Icon], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditFileTypesIcon] );

	// call hook if filetypes action MATCH attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Offset], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchOffset] );
	DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Match_Case], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchCase] );
	DoMethod(inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_Filetypes_Actions_Match_Match], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMatchMatch] );

	// call hook if filetypes action SEARCH attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Search_Search], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchSearch] );
	DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_Case], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchCase] );
	DoMethod(inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Checkmark_FileTypes_Action_Search_SkipSpaces], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionSearchSkipSpaces] );

	// call hook if filetypes action FILESIZE attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Filesize_Filesize], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionFilesize] );

	// call hook if filetypes action PATTERN attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Pattern_Pattern], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionPattern] );

	// call hook if filetypes action DOSDEVICE attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosDevice_Pattern], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDosDevice] );

	// call hook if filetypes action DEVICENAME attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DeviceName_Pattern], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDeviceName] );

	// call hook if filetypes action CONTENTS attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_Contents_Pattern], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionContents] );

	// call hook if filetypes action DOSTYPE attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_DosType_Pattern], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionDosType] );

	// call hook if filetypes action MINSIZEMB attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_String_FileTypes_Action_MinSizeMB_MinSize], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionMinSize] );

	// call hook if filetypes action PROTECTION attributes are changed
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_R], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_W], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_E], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_D], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_S], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_P], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_A], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );
	DoMethod(inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Cycle_Filetypes_Protection_H], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangedFileTypesActionProtection] );

	// call hook everytime a filetypes action entry is selected
	DoMethod(inst->fpb_Objects[OBJNDX_NListview_FileTypes_Methods], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SelectFileTypesActionEntry] );

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SelectEntry] );

	DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_Notify, MUIA_NList_Active, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SelectAttribute] );

	DoMethod(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIM_Notify, MUIA_Pressed, FALSE, 
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_RemoveEntry]);

	DoMethod(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIM_Notify, MUIA_Pressed, FALSE, 
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_RemoveAttribute]);

	// Edit Attribute by pressing "Edit" button of double-clicking attribute in list

	DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttribute] );

	DoMethod(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIM_Notify, MUIA_Pressed, FALSE, 
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttribute]);

	// initially display icon for "project" filetype
	// "Create new" icon is disabled if "def_project" icon is present
	set(inst->fpb_Objects[OBJNDX_Button_FileTypes_CreateIcon],
		MUIA_Disabled, DisplayFileTypesIcon(inst, "project"));

	return inst->fpb_Objects[OBJNDX_Group_Main];
}


static Object **CreateSubWindows(Class *cl, Object *o)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) INST_DATA(cl, o);

	d1(KPrintF(__FILE__ "/%s/%ld: START\n", __FUNC__, __LINE__));

	inst->fpb_SubWindows[0] = inst->fpb_Objects[OBJNDX_WIN_EditAttribute] = WindowObject,
		MUIA_Window_Title, (IPTR)GetLocString(MSGID_EDITATTRIBUTE_WINDOWTITLE),
		MUIA_Window_ID,	MAKE_ID('F','T','P','R'),
		WindowContents, (IPTR)(VGroup,

			Child, (IPTR)(TextObject,
				MUIA_Text_PreParse, (IPTR)MUIX_C,
				MUIA_Text_Contents, (IPTR)GetLocString(MSGID_EDITATTRIBUTE_TITLE),
                        End), // TextObject

			Child, (IPTR)(HGroup,
				TextFrame,
				Child, (IPTR)HVSpace,
				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Text_AttributeName] = TextObject,
					MUIA_HorizWeight, 200,
					MUIA_Text_PreParse, (IPTR)MUIX_C,
					MUIA_Text_Contents, (IPTR)"xxxxxxxxxxxxxxxxxxxxxxxxxxx",
					MUIA_Text_SetMin, TRUE,
                                End), // TextObject
				Child, (IPTR)HVSpace,
			End), //HGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeValue] = VGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_String_AttributeValue] = StringObject,
					MUIA_CycleChain, TRUE,
					StringFrame,
					MUIA_String_Contents, (IPTR)"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
					MUIA_String_AdvanceOnCR, TRUE,
					MUIA_Text_SetMin, TRUE,
                                End), // StringObject
			End), //VGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath] = VGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath] = PopaslObject,
					MUIA_CycleChain, TRUE,
					MUIA_Popasl_StartHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributePopAslPathStartHook],
					MUIA_Popasl_Type, ASL_FileRequest,
					MUIA_String_AdvanceOnCR, TRUE,
					MUIA_Popstring_String, (IPTR)KeyString((IPTR)"", MAX_ATTRVALUE, '\0'),
					MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopDrawer),
				End), //PopaslObject
			End), //VGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile] = HGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile] = DataTypesImageObject,
					MUIA_ScaDtpic_Name, (IPTR) "",
					MUIA_ScaDtpic_FailIfUnavailable, FALSE,
                                End), //DataTypesMCCObject

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile] = PopaslObject,
					MUIA_CycleChain, TRUE,
					MUIA_Popasl_StartHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributePopAslFileStartHook],
					MUIA_Popasl_Type, ASL_FileRequest,
					MUIA_Popstring_String, (IPTR)KeyString((IPTR)"", MAX_ATTRVALUE, '\0'),
					MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopFile),
				End), //PopaslObject
			End), //VGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont] = VGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont] = PopaslObject,
					MUIA_CycleChain, TRUE,
					TAG_IGNORE, 993,
					MUIA_Popasl_Type, ASL_FontRequest,
					MUIA_Popstring_String, (IPTR)KeyString((IPTR)"", MAX_ATTRVALUE, '\0'),
					MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopUp),
				End), //PopaslObject

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_AslFont_Sample] = FontSampleObject,
					TextFrame,
					MUIA_Background, MUII_TextBack,
					MUIA_FontSample_DemoString, (IPTR) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT),
					MUIA_FontSample_Antialias, inst->fpb_TTfAntialias,
					MUIA_FontSample_Gamma, inst->fpb_TTfGamma,
					MUIA_ShortHelp, (IPTR) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP),
				End), //FontSampleMCCObject
			End), //VGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont] = VGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont] = PopstringObject,
					MUIA_CycleChain, TRUE,
					TAG_IGNORE, 994,
					MUIA_Popstring_String, (IPTR)KeyString((IPTR)"", MAX_ATTRVALUE, '\0'),
					MUIA_String_AdvanceOnCR, TRUE,
					MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopUp),
					MUIA_Popstring_OpenHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributeTTFontOpen],
					MUIA_Popstring_CloseHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributeTTFontClose],
				End), //PopstringObject

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_TTFont_Sample] = FontSampleObject,
					TextFrame,
					MUIA_Background, MUII_TextBack,
					MUIA_FontSample_Antialias, inst->fpb_TTfAntialias,
					MUIA_FontSample_Gamma, inst->fpb_TTfGamma,
					MUIA_FontSample_DemoString, (IPTR) GetLocString(MSGID_TTFONTSPAGE_SAMPLETEXT),
					MUIA_ShortHelp, (IPTR) GetLocString(MSGID_TTFONTSPAGE_SCREENFONT_SAMPLETEXT_SHORTHELP),
				End), //FontSampleMCCObject
			End), //VGroup

			Child, (IPTR)(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue] = VGroup,
				MUIA_ShowMe, FALSE,

				Child, (IPTR)(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue] = PopobjectObject,
					MUIA_CycleChain, TRUE,
					MUIA_Popstring_Button, (IPTR)PopButton(MUII_PopUp),
					MUIA_Popstring_String, (IPTR)KeyString((IPTR)"", MAX_ATTRVALUE, '\0'),
					MUIA_Popobject_Object, (IPTR)(inst->fpb_Objects[OBJNDX_Listview_AttributeSelectValue] = NListviewObject,
						MUIA_NListview_NList, (IPTR)(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue] = NListObject,
							InputListFrame,
							MUIA_Background, MUII_ListBack,
							MUIA_NList_ConstructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributeListConstruct],
							MUIA_NList_DestructHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributeListDestruct],
							MUIA_NList_DisplayHook2, (IPTR)&inst->fpb_Hooks[HOOKNDX_EditAttributeListDisplay],
							MUIA_NList_AdjustWidth, TRUE,
						End), //NListObject
					End), //NListviewObject
				End), //PopobjectObject
			End), //VGroup

                        Child, (IPTR)(ColGroup(2),
				Child, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonChangeAttribute] = KeyButtonHelp(MSGID_BUTTON_CHANGE_ATTRIBUTE,
					' ',
					MSGID_SHORTHELP_BUTTON_CHANGE_ATTRIBUTE)),
				Child, (IPTR)(inst->fpb_Objects[OBJNDX_ButtonKeepAttribute] = KeyButtonHelp(MSGID_BUTTON_KEEP_ATTRIBUTE,
					' ',
					MSGID_SHORTHELP_BUTTON_KEEP_ATTRIBUTE)),
                        End), //ColGroup
                End), //VGroup
        End;

	d1(KPrintF(__FILE__ "/%s/%ld: fpb_SubWindows[0]=%08lx\n", __FUNC__, __LINE__, inst->fpb_SubWindows[0]));

	inst->fpb_SubWindows[1] = NULL;

	set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont], MUIA_Disabled, NULL == TTEngineBase);

	// Selecting a new ASL font updates Asl font sample
	DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime, 
		inst->fpb_Objects[OBJNDX_AslFont_Sample], 3, MUIM_Set, MUIA_FontSample_StdFontDesc, MUIV_TriggerValue);

	// Pressing "change" button in "edit attribute" window calls hook
	DoMethod(inst->fpb_Objects[OBJNDX_ButtonChangeAttribute], MUIM_Notify, MUIA_Pressed, FALSE, 
		inst->fpb_Objects[OBJNDX_Group_Main], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_ChangeAttribute]);

	// Pressing "cancel" button in "edit attribute" window closes window
	DoMethod(inst->fpb_Objects[OBJNDX_ButtonKeepAttribute], MUIM_Notify, MUIA_Pressed, FALSE, 
		inst->fpb_Objects[OBJNDX_WIN_EditAttribute], 3, MUIM_Set, MUIA_Window_Open, FALSE);

	// Doubleclick in "edit attribute" selection listview calls hook
	DoMethod(inst->fpb_Objects[OBJNDX_Listview_AttributeSelectValue], MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], 2, MUIM_CallHook, (IPTR)&inst->fpb_Hooks[HOOKNDX_SelectAttributeValue]);

	// Update sample image everytime the image file string changes
	DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], 3, MUIM_Set, MUIA_ScaDtpic_Name, MUIV_TriggerValue);

	return inst->fpb_SubWindows;
}


static Object *CreatePrefsImage(void)
{
#include "FileTypesPrefsImage.h"
	Object	*img;

	// First try to load datatypes image from THEME: tree
	img = DataTypesImageObject,
		MUIA_ScaDtpic_Name, (IPTR) "THEME:prefs/plugins/filetypes",
		MUIA_ScaDtpic_FailIfUnavailable, TRUE,
		End; //DataTypesMCCObject

	if (NULL == img)
		img = IMG(FileTypes, FILETYPES);        // use built-in fallback image

	return img;
}


static void InitHooks(struct FileTypesPrefsInst *inst)
{
	ULONG n;

	for (n=0; n<HOOKNDX_MAX; n++)
		{
		inst->fpb_Hooks[n] = FileTypesPrefsHooks[n];
		inst->fpb_Hooks[n].h_Data = inst;
		}
}


static BOOL OpenLibraries(void)
{
	DOSBase = (APTR) OpenLibrary( "dos.library", 39 );
	if (NULL == DOSBase)
		return FALSE;
#ifdef __amigaos4__
	IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL);
	if (NULL == IDOS)
		return FALSE;
#endif

	DiskfontBase = OpenLibrary("diskfont.library", 39);
	if (NULL == DiskfontBase)
		return FALSE;
#ifdef __amigaos4__
	IDiskfont = (struct DiskfontIFace *)GetInterface((struct Library *)DiskfontBase, "main", 1, NULL);
	if (NULL == IDiskfont)
		return FALSE;
#endif

	IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
	if (NULL == IntuitionBase)
		return FALSE;
#ifdef __amigaos4__
	IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
	if (NULL == IIntuition)
		return FALSE;
#endif

	MUIMasterBase = OpenLibrary("zune.library", 0);
	if (NULL == MUIMasterBase)
		MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1);
	if (NULL == MUIMasterBase)
		return FALSE;
#ifdef __amigaos4__
	IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL);
	if (NULL == IMUIMaster)
		return FALSE;
#endif

	IFFParseBase = OpenLibrary("iffparse.library", 36);
	if (NULL == IFFParseBase)
		return FALSE;
#ifdef __amigaos4__
	IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL);
	if (NULL == IIFFParse)
		return FALSE;
#endif

	IconBase = OpenLibrary("icon.library", 0);
	if (NULL == IconBase)
		return FALSE;
#ifdef __amigaos4__
	IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL);
	if (NULL == IIcon)
		return FALSE;
#endif

	IconobjectBase = OpenLibrary("iconobject.library", 0);
	if (NULL == IconobjectBase)
		return FALSE;
#ifdef __amigaos4__
	IIconobject = (struct IconobjectIFace *)GetInterface((struct Library *)IconobjectBase, "main", 1, NULL);
	if (NULL == IIconobject)
		return FALSE;
#endif

	GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 39);
	if (NULL == GfxBase)
		return FALSE;
#ifdef __amigaos4__
	IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL);
	if (NULL == IGraphics)
		return FALSE;
#endif

	WorkbenchBase = OpenLibrary("workbench.library", 39);
	if (NULL == WorkbenchBase)
		return FALSE;
#ifdef __amigaos4__
	IWorkbench = (struct WorkbenchIFace *)GetInterface((struct Library *)WorkbenchBase, "main", 1, NULL);
	if (NULL == IWorkbench)
		return FALSE;
#endif

	UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39);
	if (NULL == UtilityBase)
		return FALSE;
#ifdef __amigaos4__
	IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL);
	if (NULL == IUtility)
		return FALSE;
#endif

	PreferencesBase = OpenLibrary("preferences.library", 39);
	if (NULL == PreferencesBase)
		return FALSE;
#ifdef __amigaos4__
	IPreferences = (struct PreferencesIFace *)GetInterface((struct Library *)PreferencesBase, "main", 1, NULL);
	if (NULL == IPreferences)
		return FALSE;
#endif

	DataTypesBase = OpenLibrary("datatypes.library", 39);
	if (NULL == DataTypesBase)
		return FALSE;
#ifdef __amigaos4__
	IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL);
	if (NULL == IDataTypes)
		return FALSE;
#endif

	// TTEngineBase is optional
	TTEngineBase = OpenLibrary(TTENGINENAME, 6);
#ifdef __amigaos4__
	if (TTEngineBase)
		ITTEngine = (struct TTEngineIFace *)GetInterface(TTEngineBase, "main", 1, NULL);
#endif

#ifdef __amigaos4__
	NewlibBase = OpenLibrary("newlib.library", 0);
	if (NULL == NewlibBase)
		return FALSE;
	INewlib = GetInterface(NewlibBase, "main", 1, NULL);
	if (NULL == INewlib)
		return FALSE;
#endif

	LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39);
#ifdef __amigaos4__
	if (LocaleBase)
		ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL);
#endif

	return TRUE;
}


static void CloseLibraries(void)
{
#ifdef __amigaos4__
	if (INewlib)
		{
		DropInterface(INewlib);
		INewlib = NULL;
		}
	if (NewlibBase)
		{
		CloseLibrary(NewlibBase);
		NewlibBase = NULL;
		}
	if (IDataTypes)
		{
		DropInterface((struct Interface *)IDataTypes);
		IDataTypes = NULL;
		}
#endif
	if (DataTypesBase)
		{
		CloseLibrary(DataTypesBase);
		DataTypesBase = NULL;
		}
#ifdef __amigaos4__
	if (ILocale)
		{
		DropInterface((struct Interface *)ILocale);
		ILocale = NULL;
		}
#endif
	if (LocaleBase)
		{
		CloseLibrary((struct Library *) LocaleBase);
		LocaleBase = NULL;
		}
#ifdef __amigaos4__
	if (ITTEngine)
		{
		DropInterface((struct Interface *)ITTEngine);
		ITTEngine = NULL;
		}
#endif
	if (TTEngineBase)
		{
		CloseLibrary(TTEngineBase);
		TTEngineBase = NULL;
		}
#ifdef __amigaos4__
	if (IPreferences)
		{
		DropInterface((struct Interface *)IPreferences);
		IPreferences = NULL;
		}
#endif
	if (PreferencesBase)
		{
		CloseLibrary(PreferencesBase);
		PreferencesBase = NULL;
		}
#ifdef __amigaos4__
	if (IIconobject)
		{
		DropInterface((struct Interface *)IIconobject);
		IIconobject = NULL;
		}
#endif
	if (IconobjectBase)
		{
		CloseLibrary(IconobjectBase);
		IconobjectBase = NULL;
		}
#ifdef __amigaos4__
	if (IUtility)
		{
		DropInterface((struct Interface *)IUtility);
		IUtility = NULL;
		}
#endif
	if (UtilityBase)
		{
		CloseLibrary((struct Library *) UtilityBase);
		UtilityBase = NULL;
		}
#ifdef __amigaos4__
	if (IWorkbench)
		{
		DropInterface((struct Interface *)IWorkbench);
		IWorkbench = NULL;
		}
#endif
	if (WorkbenchBase)
		{
		CloseLibrary(WorkbenchBase);
		WorkbenchBase = NULL;
		}
#ifdef __amigaos4__
	if (IGraphics)
		{
		DropInterface((struct Interface *)IGraphics);
		IGraphics = NULL;
		}
#endif
	if (GfxBase)
		{
		CloseLibrary((struct Library *) GfxBase);
		GfxBase = NULL;
		}
#ifdef __amigaos4__
	if (IIcon)
		{
		DropInterface((struct Interface *)IIcon);
		IIcon = NULL;
		}
#endif
	if (IconBase)
		{
		CloseLibrary(IconBase);
		IconBase = NULL;
		}
#ifdef __amigaos4__
	if (IIFFParse)
		{
		DropInterface((struct Interface *)IIFFParse);
		IIFFParse = NULL;
		}
#endif
	if (IFFParseBase)
		{
		CloseLibrary(IFFParseBase);
		IFFParseBase = NULL;
		}
#ifdef __amigaos4__
	if (IMUIMaster)
		{
		DropInterface((struct Interface *)IMUIMaster);
		IMUIMaster = NULL;
		}
#endif
	if (MUIMasterBase)
		{
		CloseLibrary(MUIMasterBase);
		MUIMasterBase = NULL;
		}
#ifdef __amigaos4__
	if (IIntuition)
		{
		DropInterface((struct Interface *)IIntuition);
		IIntuition = NULL;
		}
#endif
	if (IntuitionBase)
		{
		CloseLibrary((struct Library *) IntuitionBase);
		IntuitionBase = NULL;
		}
#ifdef __amigaos4__
	if (IDiskfont)
		{
		DropInterface((struct Interface *)IDiskfont);
		IDiskfont = NULL;
		}
#endif
	if (DiskfontBase)
		{
		CloseLibrary(DiskfontBase);
		DiskfontBase = NULL;
		}
#ifdef __amigaos4__
	if (IDOS)
		{
		DropInterface((struct Interface *)IDOS);
		IDOS = NULL;
		}
#endif
	if (DOSBase)
		{
		CloseLibrary((struct Library *) DOSBase);
		DOSBase = NULL;
		}
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT TreeConstructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm)
{
	struct FileTypesListEntry *fte = AllocPooled(ltcm->MemPool, sizeof(struct FileTypesListEntry));

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData));
	d1(kprintf(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte));

	if (fte)
		{
		struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
		char UnSelIconName[MAX_ATTRVALUE];

		NewList(&fte->ftle_AttributesList);
		fte->ftle_FileFound = FALSE;
		fte->ftle_Changed = FALSE;

		GetAttributeValueString(FindAttribute(fte, ATTRTYPE_UnselIconName), UnSelIconName, sizeof(UnSelIconName));
		if (strlen(UnSelIconName) > 0)
			{
			fte->fte_ImageObject = DataTypesImageObject, 0,
				MUIA_ScaDtpic_Name, (IPTR) UnSelIconName,
				MUIA_ScaDtpic_FailIfUnavailable, TRUE,
				End; //DataTypesMCCObject

			if (fte->fte_ImageObject)
				{
				fte->fte_ImageIndex = ++inst->fpb_MenuImageIndex;
				DoMethod(obj, MUIM_NList_UseImage, fte->fte_ImageObject, fte->fte_ImageIndex, 0);
				}
			else
				{
				fte->fte_ImageIndex = 0;
				}
			}
		}

	return fte;
}

static SAVEDS(void) INTERRUPT TreeDestructFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm)
{
	struct FileTypesListEntry *fte = (struct FileTypesListEntry *) ltdm->UserData;

	d1(kprintf(__FILE__ "/%s/%ld: mle=%08lx\n", __FUNC__, __LINE__, ltdm->UserData));

	if (fte)
		{
		CleanupAttributes(&fte->ftle_AttributesList);

		if (fte->fte_ImageObject)
			{
			DoMethod(obj, MUIM_NList_UseImage, NULL, fte->fte_ImageIndex, 0);

			MUI_DisposeObject(fte->fte_ImageObject);
			fte->fte_ImageObject = NULL;
			}
		}

	FreePooled(ltdm->MemPool, ltdm->UserData, sizeof(struct FileTypesListEntry));
	ltdm->UserData = NULL;
}

static SAVEDS(ULONG) INTERRUPT TreeDisplayFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm)
{
	struct FileTypesListEntry *fte = (struct FileTypesListEntry *) ltdm->TreeNode->tn_User;

	d1(kprintf(__FILE__ "/%s/%ld: <%s> fte=%08lx\n", __FUNC__, __LINE__, ltdm->TreeNode->tn_Name, fte));

	if (fte)
		{
		const struct FtAttribute *fta;
		char Line[MAX_ATTRVALUE];

		// indicate changed entries
		if (fte->ftle_Changed)
			ltdm->Preparse[0] = MUIX_PH;
		else
			ltdm->Preparse[0] = MUIX_PT;

		switch (fte->ftle_EntryType)
			{
		case ENTRYTYPE_ToolTip_Member:
			fta = FindAttribute(fte, ATTRTYPE_MemberHideString);
			if (fta)
				{
				GetAttributeValueString(fta, Line, sizeof(Line));
				snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
					"%s" MUIX_I " %s %s" MUIX_N,
					ltdm->TreeNode->tn_Name, GetAttributeName(fta->fta_Type), Line);
				}
			else
				{
				snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
					"%s", ltdm->TreeNode->tn_Name);
				}

			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_ToolTip_String:
			fta = FindAttribute(fte, ATTRTYPE_StringId);
			if (NULL == fta)
				fta = FindAttribute(fte, ATTRTYPE_StringText);
			if (NULL == fta)
				fta = FindAttribute(fte, ATTRTYPE_StringSrc);

			GetAttributeValueString(fta, Line, sizeof(Line));
			snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
				"%s" MUIX_I " %s %.*s" MUIX_N,
				ltdm->TreeNode->tn_Name, GetAttributeName(fta->fta_Type), MAX_FTE_NAME, Line);
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_ToolTip_DtImage:
			GetAttributeValueString(FindAttribute(fte, ATTRTYPE_DtImageName), Line, sizeof(Line));
			snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
				"%s" MUIX_I " FILENAME %.*s" MUIX_N,
				ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_PopupMenu_InternalCmd:
		case ENTRYTYPE_PopupMenu_WbCmd:
		case ENTRYTYPE_PopupMenu_ARexxCmd:
		case ENTRYTYPE_PopupMenu_CliCmd:
		case ENTRYTYPE_PopupMenu_PluginCmd:
		case ENTRYTYPE_PopupMenu_IconWindowCmd:
			GetAttributeValueString(FindAttribute(fte, ATTRTYPE_CommandName), Line, sizeof(Line));
			snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
				"%s" MUIX_I " NAME %.*s" MUIX_N,
				ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_PopupMenu_SubMenu:
			GetAttributeValueString(FindAttribute(fte, ATTRTYPE_MenuItemName), Line, sizeof(Line));
			if (fte->fte_ImageObject)
				{
				snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
					 "\33o[%ld]" "%s" MUIX_I " NAME %.*s" MUIX_N,
					(long) fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
				}
			else
				{
				snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
					"%s" MUIX_I " NAME %.*s" MUIX_N,
					ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
				}
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_ToolTip_Group:
			GetAttributeValueString(FindAttribute(fte, ATTRTYPE_GroupOrientation), Line, sizeof(Line));
			snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
				"%s" MUIX_I " ORIENTATION %.*s" MUIX_N,
				ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		case ENTRYTYPE_PopupMenu_MenuItem:
			GetAttributeValueString(FindAttribute(fte, ATTRTYPE_MenuItemName), Line, sizeof(Line));

			if (FindAttribute(fte, ATTRTYPE_MenuDefaultAction))
				{
				if (fte->fte_ImageObject)
					{
					snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
						"\33o[%ld]" MUIX_B "%s" MUIX_I " NAME %.*s" MUIX_N,
						(IPTR)fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
					}
				else
					{
					snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
						MUIX_B "%s" MUIX_I " NAME %.*s" MUIX_N,
						ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
					}
				}
			else
				{
				if (fte->fte_ImageObject)
					{
					snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
						"\33o[%ld]%s" MUIX_I " NAME %.*s" MUIX_N,
						(IPTR)fte->fte_ImageIndex, ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
					}
				else
					{
					snprintf(fte->ftle_NameBuffer, sizeof(fte->ftle_NameBuffer),
						"%s" MUIX_I " NAME %.*s" MUIX_N,
						ltdm->TreeNode->tn_Name, MAX_FTE_NAME, Line);
					}
				}
			ltdm->Array[0] = fte->ftle_NameBuffer;
			break;

		default:
			ltdm->Array[0] = ltdm->TreeNode->tn_Name;
			break;
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm)
{
	const struct FtAttribute *fta = (const struct FtAttribute *) ltcm->entry;
	struct AttrListEntry *ale = (struct AttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct AttrListEntry) + fta->fta_Length);

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->entry));
	d1(kprintf(__FILE__ "/%s/%ld: fta=%08lx\n", __FUNC__, __LINE__, ale));

	if (ale)
		{
		memcpy(&ale->ale_Attribute, fta, sizeof(struct FtAttribute) + fta->fta_Length);
		}

	return ale;
}

static SAVEDS(void) INTERRUPT AttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm)
{
	struct AttrListEntry *ale = (struct AttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: START fta=%08lx\n", __FUNC__, __LINE__, ale));

	if (ale)
		{
		FreePooled(ltdm->pool, ale, sizeof(struct AttrListEntry) + ale->ale_Attribute.fta_Length);
		ltdm->entry = NULL;
		}

	d1(kprintf(__FILE__ "/%s/%ld: END fta=%08lx\n", __FUNC__, __LINE__, ale));
}

static SAVEDS(ULONG) INTERRUPT AttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm)
{
	struct AttrListEntry *ale = (struct AttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: <%s> fta=%08lx\n", __FUNC__, __LINE__, ltdm->TreeNode->tn_Name, fta));

	if (ale)
		{
		ltdm->preparses[0] = "";
		ltdm->preparses[1] = "";

		ltdm->strings[0] = (STRPTR) GetAttributeName(ale->ale_Attribute.fta_Type);
		ltdm->strings[1] = (STRPTR) GetAttributeValueString(&ale->ale_Attribute, 
			ale->ale_ValueString, sizeof(ale->ale_ValueString));
		}
	else
		{
		// display titles
		ltdm->preparses[0] = "\033c";
		ltdm->preparses[1] = "\033c";

		ltdm->strings[0] = GetLocString(MSGID_ATTRCOLUMNTITLE_NAME);
		ltdm->strings[1] = GetLocString(MSGID_ATTRCOLUMNTITLE_VALUE);
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AddEntryConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm)
{
	struct AddEntryListEntry *ael = (struct AddEntryListEntry *) AllocPooled(ltcm->pool, sizeof(struct AddEntryListEntry));

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry));
	d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael));

	if (ael)
		{		
		ael->ael_EntryType = (enum FtEntryType) ltcm->entry;
		d1(kprintf(__FILE__ "/%s/%ld: ael_EntryType=%lu\n", __FUNC__, __LINE__, ael->ael_EntryType));
		}

	return ael;
}

static SAVEDS(void) INTERRUPT AddEntryDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm)
{
	struct AddEntryListEntry *ael = (struct AddEntryListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael));

	if (ael)
		{
		FreePooled(ltdm->pool, ael, sizeof(struct AddEntryListEntry));
		ltdm->entry = NULL;
		}
}

static SAVEDS(ULONG) INTERRUPT AddEntryDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm)
{
	struct AddEntryListEntry *ael = (struct AddEntryListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: ael=%08lx\n", __FUNC__, __LINE__, ael));

	if (ael)
		{
		ltdm->preparses[0] = "";

		ltdm->strings[0] = (STRPTR) GetNameFromEntryType(ael->ael_EntryType);
		}
	else
		{
		// display titles
		ltdm->preparses[0] = "";

		ltdm->strings[0] = "";
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AddAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm)
{
	struct AddAttrListEntry *aal = (struct AddAttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct AddAttrListEntry));

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry));
	d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal));

	if (aal)
		{		
		aal->aal_EntryType = (enum FtEntryType) ltcm->entry;
		d1(kprintf(__FILE__ "/%s/%ld: aal_EntryType=%lu\n", __FUNC__, __LINE__, aal->aal_EntryType));
		}

	return aal;
}

static SAVEDS(void) INTERRUPT AddAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm)
{
	struct AddAttrListEntry *aal = (struct AddAttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal));

	if (aal)
		{
		FreePooled(ltdm->pool, aal, sizeof(struct AddAttrListEntry));
		ltdm->entry = NULL;
		}
}

static SAVEDS(ULONG) INTERRUPT AddAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm)
{
	struct AddAttrListEntry *aal = (struct AddAttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: aal=%08lx\n", __FUNC__, __LINE__, aal));

	if (aal)
		{
		ltdm->preparses[0] = "";

		ltdm->strings[0] = (STRPTR) GetAttributeName(aal->aal_EntryType);
		}
	else
		{
		// display titles
		ltdm->preparses[0] = "";

		ltdm->strings[0] = "";
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT EditAttrConstructFunc(struct Hook *hook, APTR obj, struct NList_ConstructMessage *ltcm)
{
	const struct EditAttrListEntry *newEntry = ltcm->entry;
	struct EditAttrListEntry *eal = (struct EditAttrListEntry *) AllocPooled(ltcm->pool, sizeof(struct EditAttrListEntry) + newEntry->eal_fta.fta_Length);

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->pool, ltcm->entry));
	d1(kprintf(__FILE__ "/%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal));

	if (eal)
		{
		memcpy(eal, newEntry, sizeof(struct EditAttrListEntry) + newEntry->eal_fta.fta_Length);
		}

	return eal;
}

static SAVEDS(void) INTERRUPT EditAttrDestructFunc(struct Hook *hook, APTR obj, struct NList_DestructMessage *ltdm)
{
	struct EditAttrListEntry *eal = (struct EditAttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: START aal=%08lx\n", __FUNC__, __LINE__, eal));

	if (eal)
		{
		FreePooled(ltdm->pool, eal, sizeof(struct EditAttrListEntry) + eal->eal_fta.fta_Length);
		ltdm->entry = NULL;
		}

	d1(kprintf(__FILE__ "/%s/%ld: END aal=%08lx\n", __FUNC__, __LINE__, eal));
}

static SAVEDS(ULONG) INTERRUPT EditAttrDisplayFunc(struct Hook *hook, APTR obj, struct NList_DisplayMessage *ltdm)
{
	struct EditAttrListEntry *eal = (struct EditAttrListEntry *) ltdm->entry;

	d1(kprintf(__FILE__ "/%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal));

	if (eal)
		{
		ltdm->preparses[0] = "";

		GetAttributeValueString(&eal->eal_fta, eal->eal_ValueString, sizeof(eal->eal_ValueString));

		if (eal->eal_fta.fta_Value2)
			{
			d1(KPrintF(__FILE__ "/%s/%ld: Type=%ld  <%s>\n", __FUNC__, __LINE__, \
				eal->eal_fta.fta_Type, eal->eal_ValueString));

			ltdm->strings[0] = GetLocString(eal->eal_fta.fta_Value2);
			ltdm->strings[1] = eal->eal_ValueString;
			}
		else
			{
			d1(KPrintF(__FILE__ "/%s/%ld: Type=%ld  <%s>\n", __FUNC__, __LINE__, \
				eal->eal_fta.fta_Type, eal->eal_ValueString));

			ltdm->strings[0] = eal->eal_ValueString;
			}
		}
	else
		{
		// display titles
		ltdm->preparses[0] = "";
		ltdm->strings[0] = "";

		if (eal->eal_fta.fta_Value2)
			{
			ltdm->preparses[1] = "";
			ltdm->strings[1] = "";
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

STRPTR GetLocString(ULONG MsgId)
{
	struct ScalosFileTypes_LocaleInfo li;

	li.li_Catalog = FileTypesPrefsCatalog;	
#ifndef __amigaos4__
	li.li_LocaleBase = LocaleBase;
#else
	li.li_ILocale = ILocale;
#endif

	return (STRPTR) GetScalosFileTypesString(&li, MsgId);
}


static void TranslateNewMenu(struct NewMenu *nm)
{
	while (nm && NM_END != nm->nm_Type)
		{
		if (NM_BARLABEL != nm->nm_Label)
			nm->nm_Label = GetLocString((IPTR) nm->nm_Label);

		if (nm->nm_CommKey)
			nm->nm_CommKey = GetLocString((IPTR) nm->nm_CommKey);

		nm++;
		}
}

static void TranslateStringArray(STRPTR *stringArray)
{
	while (*stringArray)
		{
		*stringArray = GetLocString((IPTR) *stringArray);
		stringArray++;
		}
}

//----------------------------------------------------------------------------

void _XCEXIT(long x)
{
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AboutFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	MUI_Request(inst->fpb_Objects[OBJNDX_APP_Main], inst->fpb_Objects[OBJNDX_WIN_Main], 0, NULL, 
		GetLocString(MSGID_ABOUTREQOK), 
		GetLocString(MSGID_ABOUTREQFORMAT), 
		MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE);

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Clear, NULL, 0);
	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG;

	InitDefIcons(inst, NULL);

	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE);

	return 0;
}


static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	d1(KPrintF(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__));

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE);

	ReadPrefs(inst, ENVARC_FILETYPES_DIR, ENVARC_DEFICONS_PREFS);

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE);
	inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG;

	return 0;
}

static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE);

	ReadPrefs(inst, ENV_FILETYPES_DIR, ENV_DEFICONS_PREFS);

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE);
	inst->fpb_SaveFlags = FTWRITEFLAG_CLEAR_CHANGE_FLAG;

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT HideEmptyEntriesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	ULONG Checked = FALSE;

	get(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, &Checked);
	inst->fpb_HideEmptyNodes = Checked;

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, TRUE);
	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	if (inst->fpb_HideEmptyNodes)
		HideEmptyNodes(inst);
	else
		ShowHiddenNodes(inst);

	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Sleep, FALSE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT CollapseHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry,
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		struct MUI_NListtree_TreeNode *tnChild;

		tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry,
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);
		d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) ""));

		if (tnChild)
			{
			set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (IPTR) tnChild);

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Close,
				MUIV_NListtree_Close_ListNode_Active,
				MUIV_NListtree_Close_TreeNode_All,
				0);
			}

		set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (IPTR) tn);
		}

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_Close,
		MUIV_NListtree_Close_ListNode_Active,
		tn,
		0);

	set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
		MUIM_NListtree_Open, 
		MUIV_NListtree_Open_ListNode_Active,
		MUIV_NListtree_Open_TreeNode_Active,
		0);

	if (tn)
		{
		struct MUI_NListtree_TreeNode *tnChild;

		tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);
		d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) ""));

		if (tnChild)
			{
			set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (IPTR) tnChild);

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
				MUIM_NListtree_Open, 
				MUIV_NListtree_Open_ListNode_Active,
				MUIV_NListtree_Open_TreeNode_All,
				0);
			}

		set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (IPTR) tn);
		}

	set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT CollapseAllHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Close, 
		MUIV_NListtree_Close_ListNode_Root,
		MUIV_NListtree_Close_TreeNode_All,
		0);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandAllHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], MUIM_NListtree_Open, 
		MUIV_NListtree_Open_ListNode_Root,
		MUIV_NListtree_Open_TreeNode_All,
		0);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
		MUIM_NListtree_Close,
		MUIV_NListtree_Close_ListNode_Active,
		MUIV_NListtree_Close_TreeNode_All,
		0);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
		MUIM_NListtree_GetEntry,
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
		MUIM_NListtree_Open,
		MUIV_NListtree_Open_ListNode_Active,
		MUIV_NListtree_Open_TreeNode_Active,
		0);

	if (tn)
		{
		struct MUI_NListtree_TreeNode *tnChild;

		tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
			MUIM_NListtree_GetEntry,
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);
		d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) ""));

		if (tnChild)
			{
			set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, (IPTR) tnChild);

			DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
				MUIM_NListtree_Open,
				MUIV_NListtree_Open_ListNode_Active,
				MUIV_NListtree_Open_TreeNode_All,
				0);
			}

		set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, (IPTR) tn);
		}

	set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_NListtree_Close,
		MUIV_NListtree_Close_ListNode_Root,
		MUIV_NListtree_Close_TreeNode_All,
		0);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIM_NListtree_Open,
		MUIV_NListtree_Open_ListNode_Root,
		MUIV_NListtree_Open_TreeNode_All,
		0);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT CopyHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], MUIM_NListtree_Clear);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		CopyFileTypesEntry(inst, 
			(struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_ListNode_Root, 
			(struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail,
			tn, 
			OBJNDX_ShadowListTree, OBJNDX_MainListTree);
		}

	EnablePasteMenuEntry(inst);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT CutHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree], MUIM_NListtree_Clear);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		CopyFileTypesEntry(inst, 
			(struct MUI_NListtree_TreeNode *) MUIV_NListtree_GetEntry_ListNode_Root, 
			(struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail,
			tn, 
			OBJNDX_ShadowListTree, OBJNDX_MainListTree);

		EntryHasChanged(inst, tn);

		DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
			MUIM_NListtree_Remove, 
			MUIV_NListtree_Remove_ListNode_Active,
			MUIV_NListtree_Remove_TreeNode_Active,
			0);
		}

	EnablePasteMenuEntry(inst);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT PasteHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		struct MUI_NListtree_TreeNode *tnParent;
		struct MUI_NListtree_TreeNode *tnShadow;

		tnParent = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Parent,
			0);

		tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree],
			MUIM_NListtree_GetEntry, 
			MUIV_NListtree_Insert_ListNode_Root,
			MUIV_NListtree_GetEntry_Position_Head,
			0);

		set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

		if (MayPasteBelow(inst, tn, tnShadow))
			{
			CopyFileTypesEntry(inst, 
				tnParent, tn,
				tnShadow,
				OBJNDX_MainListTree, OBJNDX_ShadowListTree);

			EntryHasChanged(inst, tnParent);
			}
		else if (MayPasteOnto(inst, tn, tnShadow))
			{
			CopyFileTypesEntry(inst, 
				tn, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail,
				tnShadow,
				OBJNDX_MainListTree, OBJNDX_ShadowListTree);

			EntryHasChanged(inst, tn);
			}

		set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

		DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_Redraw, 
			tn,
			0);
		}

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT CopyAttrHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], MUIM_NList_Clear);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);

	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);

		d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr));
		}
	if (Attr)
		{
		d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr));

		DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList],
			MUIM_NList_InsertSingle, 
			&Attr->ale_Attribute,
			MUIV_NList_Insert_Bottom);
		}

	EnablePasteAttrMenuEntry(inst);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT CutAttrHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList], MUIM_NList_Clear);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);
		}
	if (Attr)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

		DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList],
			MUIM_NList_InsertSingle, 
			&Attr->ale_Attribute,
			MUIV_NList_Insert_Bottom);

		// Remove attribute from fte's list
		RemoveAttribute(fte, Attr->ale_Attribute.fta_Type);

		DoMethod(inst->fpb_Objects[OBJNDX_AttrList], 
			MUIM_NList_Remove, 
			MUIV_NList_Remove_Active);

		EntryHasChanged(inst, tn);
		}

	EnablePasteAttrMenuEntry(inst);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT PasteAttrHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;
		struct AttrListEntry *Attr = NULL;

		DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList],
			MUIM_NList_GetEntry, 
			0,
			&Attr);

		if (Attr)
			{
			set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

			if (MayPasteAttr(inst, fte, Attr))
				{
				struct FtAttribute *ftaNew;

				ftaNew = AddAttribute(fte, Attr->ale_Attribute.fta_Type, 
					Attr->ale_Attribute.fta_Length, Attr->ale_Attribute.fta_Data);

				if (ftaNew)
					{
					DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle,
						ftaNew, MUIV_NList_Insert_Bottom);
					}

				UpdateMenuImage(inst, OBJNDX_MainListTree, fte);
				EntryHasChanged(inst, tn);
				}

			set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
			EnablePasteAttrMenuEntry(inst);
			}
		}

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AddEntryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct AddEntryListEntry *ael = NULL;

	DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], 
		MUIM_NList_GetEntry, 
		MUIV_NList_GetEntry_Active,
		&ael);

	d1(kprintf("%s/%ld:  inst=%08lx  ael=%08lx\n", __FUNC__, __LINE__, inst, ael));

	DoMethod(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIM_Popstring_Close, TRUE);

	if (ael)
		{
		struct MUI_NListtree_TreeNode *tn;

		d1(kprintf("%s/%ld:  EntryType=%lu\n", __FUNC__, __LINE__, ael->ael_EntryType));

		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			MUIV_NListtree_GetEntry_ListNode_Active,
			MUIV_NListtree_GetEntry_Position_Active,
			0);

		if (tn)
			{
			struct FileTypesListEntry *fte;
			struct MUI_NListtree_TreeNode *tnNew;

			d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

			set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

			tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Insert, 
				GetNameFromEntryType(ael->ael_EntryType), NULL,
				tn,
				MUIV_NListtree_Insert_PrevNode_Tail,
				TNF_LIST | TNF_OPEN);

			fte = (struct FileTypesListEntry *) tnNew->tn_User;
			fte->ftle_EntryType = ael->ael_EntryType;

			AddDefaultAttributes(inst, fte);

			set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Redraw, 
				tn,
				0);

			UpdateAttributes(inst, (struct FileTypesListEntry *) tn->tn_User);

			// Make sure the new entry is the active one
			set(inst->fpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Active, (IPTR) tnNew);

			EntryHasChanged(inst, tnNew);
			}
		}

	return NULL;
}


static SAVEDS(APTR) INTERRUPT AddAttributeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);

	d1(kprintf("%s/%ld:  inst=%08lx  tn=%08lx\n", __FUNC__, __LINE__, inst, tn));

	if (tn)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;
		struct AddAttrListEntry *aal = NULL;

		DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], 
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&aal);

		d1(kprintf("%s/%ld:  inst=%08lx  aal=%08lx\n", __FUNC__, __LINE__, inst, aal));

		if (aal)
			{
			const struct AttributeDef *atd;
			ULONG n;

			atd = GetAttributeDef(aal->aal_EntryType, fte->ftle_EntryType);

			// remove all attributes which are excluded by the new one
			for (n = 0; atd && n < atd->atd_ExcludeCount; n++)
				{
				const struct FtAttribute *fta;

				fta = FindAttribute(fte, atd->atd_Exclude[n]);

				if (fta)
					{
					ULONG Entries = 0;
					ULONG pos;

					// Remove attribute from fte's list
					RemoveAttribute(fte, fta->fta_Type);

					get(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Entries, &Entries);

					// Remove Attribute from Attribute List
					for (pos = 0; pos < Entries; pos++)
						{
						struct AttrListEntry *Attr = NULL;

						DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
							MUIM_NList_GetEntry, 
							pos,
							&Attr);
						if (Attr && Attr->ale_Attribute.fta_Type == atd->atd_Exclude[n])
							{
							DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
								MUIM_NList_Remove, 
								pos);
							}
						}
					}
				}

			AddNewAttribute(inst, fte, aal->aal_EntryType);
			SetAddableAttributes(inst, fte);

			UpdateMenuImage(inst, OBJNDX_MainListTree, fte);

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Redraw, 
				tn,
				0);

			if (ATTRTYPE_MenuDefaultAction == aal->aal_EntryType)
				BeginSetMenuDefaultAction(inst, tn);

			EntryHasChanged(inst, tn);
			}
		}

	DoMethod(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIM_Popstring_Close, TRUE);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT RemoveEntryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;

	d1(kprintf("%s/%ld:  inst=%08lx\n", __FUNC__, __LINE__, inst));

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);

	if (tn)
		{
		EntryHasChanged(inst, tn);

		DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
			MUIM_NListtree_Remove, 
			MUIV_NListtree_Remove_ListNode_Active,
			MUIV_NListtree_Remove_TreeNode_Active,
			0);
		}

	return NULL;
}

static SAVEDS(APTR) INTERRUPT RemoveAttributeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	d1(kprintf("%s/%ld:  inst=%08lx\n", __FUNC__, __LINE__, inst));

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);

	d1(kprintf("%s/%ld:  inst=%08lx  tn=%08lx\n", __FUNC__, __LINE__, inst, tn));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);
		}

	d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr));
	if (Attr)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

		// Remove attribute from fte's list
		RemoveAttribute(fte, Attr->ale_Attribute.fta_Type);

		DoMethod(inst->fpb_Objects[OBJNDX_AttrList], 
			MUIM_NList_Remove, 
			MUIV_NList_Remove_Active);

		UpdateMenuImage(inst, OBJNDX_MainListTree, fte);

		DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_Redraw, 
			tn,
			0);

		EntryHasChanged(inst, tn);

		set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE);

		EnablePasteAttrMenuEntry(inst);
		}

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT ChangeAttributeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);
		}

	d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr));
	if (Attr)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;
		const struct AttributeDef *atd;

		d1(kprintf("%s/%ld: active fte=%08lx\n", __FUNC__, __LINE__, fte));

		atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType);
		d1(kprintf("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd));
		if (atd)
			{
			CONST_STRPTR ValueString = "";
			ULONG ValueULong = 0;

			switch (atd->atd_DefaultContents.avd_Type)
				{
			case ATTRDEFTYPE_ULong:
				if (atd->atd_NumberOfValues > 0)
					{
					get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue],
						MUIA_String_Contents, &ValueString);
					}
				else
					{
					get(inst->fpb_Objects[OBJNDX_String_AttributeValue],
						MUIA_String_Contents, &ValueString);
					}

				if (atd->atd_DefaultContents.avd_ConvertValueFromString)
					ValueULong = (atd->atd_DefaultContents.avd_ConvertValueFromString)(ValueString);
				else
					{
					unsigned long ulong1;
					sscanf(ValueString, "%lu", &ulong1);
					ValueULong = ulong1;
					}
				// Remove attribute from fte's list
				RemoveAttribute(fte,  atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, sizeof(ValueULong), &ValueULong);
				break;

			case ATTRDEFTYPE_FileName:
				get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile],
					MUIA_String_Contents, &ValueString);

				// Remove attribute from fte's list
				RemoveAttribute(fte, atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString);
				break;

			case ATTRDEFTYPE_PathName:
				get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath],
					MUIA_String_Contents, &ValueString);

				// Remove attribute from fte's list
				RemoveAttribute(fte, atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString);
				break;

			case ATTRDEFTYPE_FontString:
				get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont],
					MUIA_String_Contents, &ValueString);

				// Remove attribute from fte's list
				RemoveAttribute(fte, atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString);
				break;

			case ATTRDEFTYPE_TTFontString:
				get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont],
					MUIA_String_Contents, &ValueString);

				// Remove attribute from fte's list
				RemoveAttribute(fte, atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString);
				break;

			case ATTRDEFTYPE_LocString:
			case ATTRDEFTYPE_String:
			case ATTRDEFTYPE_String2:
				if (atd->atd_NumberOfValues > 0)
					{
					get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue],
						MUIA_String_Contents, &ValueString);
					}
				else
					{
					get(inst->fpb_Objects[OBJNDX_String_AttributeValue],
						MUIA_String_Contents, &ValueString);
					}
				// Remove attribute from fte's list
				RemoveAttribute(fte, atd->atd_Type);
				AddAttribute(fte, atd->atd_Type, 1 + strlen(ValueString), ValueString);
				break;
			default:
				break;
				}

			d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__));

			UpdateAttributes(inst, fte);
			UpdateMenuImage(inst, OBJNDX_MainListTree, fte);

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Redraw, 
				tn,
				0);

			EntryHasChanged(inst, tn);
			}
		}

	// Close "Edit Attribute" window
	set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Open, FALSE);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SelectAttributeValueHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct EditAttrListEntry *eal = NULL;

	DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], 
		MUIM_NList_GetEntry, 
		MUIV_NList_GetEntry_Active,
		&eal);

	if (eal)
		{
		set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue],
			MUIA_String_Contents, (IPTR) eal->eal_ValueString);
		}

	d1(kprintf("%s/%ld: eal=%08lx\n", __FUNC__, __LINE__, eal));

	DoMethod(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue], MUIM_Popstring_Close, TRUE);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(ULONG) INTERRUPT EditAttributePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct TagItem *TagList = (struct TagItem *) msg;
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	CONST_STRPTR ValueString = NULL;
	STRPTR lp;

	d1(KPrintF("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst));

	get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile], MUIA_String_Contents, &ValueString);

	d1(KPrintF("%s/%ld: ValueString=<%s>\n", __FUNC__, __LINE__, ValueString));

	while (TAG_END != TagList->ti_Tag)
		TagList++;

	stccpy(inst->fpb_FileName, FilePart(ValueString), sizeof(inst->fpb_FileName));
	stccpy(inst->fpb_Path, ValueString, sizeof(inst->fpb_Path));

	lp = PathPart(inst->fpb_Path);
	*lp = '\0';

	TagList->ti_Tag = ASLFR_DrawersOnly;
	TagList->ti_Data = FALSE;
	TagList++;

	TagList->ti_Tag = ASLFR_InitialFile;
	TagList->ti_Data = (IPTR) inst->fpb_FileName;
	TagList++;

	TagList->ti_Tag = ASLFR_InitialDrawer;
	TagList->ti_Data = (IPTR) inst->fpb_Path;
	TagList++;

	TagList->ti_Tag = TAG_END;

	d1(KPrintF("%s/%ld: ASLFR_InitialFile=<%s>  ASLFR_InitialDrawer=<%s>\n", __FUNC__, __LINE__, inst->fpb_FileName, inst->fpb_Path));

	return TRUE;
}

//----------------------------------------------------------------------------

static SAVEDS(ULONG) INTERRUPT EditAttributePopAslPathStartHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct TagItem *TagList = (struct TagItem *) msg;
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	CONST_STRPTR ValueString = NULL;
	STRPTR lp;

	d1(kprintf("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst));

	get(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath], MUIA_String_Contents, &ValueString);

	while (TAG_END != TagList->ti_Tag)
		TagList++;

	stccpy(inst->fpb_FileName, FilePart(ValueString), sizeof(inst->fpb_FileName));
	stccpy(inst->fpb_Path, ValueString, sizeof(inst->fpb_Path));

	lp = PathPart(inst->fpb_Path);
	*lp = '\0';

	TagList->ti_Tag = ASLFR_DrawersOnly;
	TagList->ti_Data = TRUE;
	TagList++;

	TagList->ti_Tag = ASLFR_InitialFile;
	TagList->ti_Data = (IPTR) inst->fpb_FileName;
	TagList++;

	TagList->ti_Tag = ASLFR_InitialDrawer;
	TagList->ti_Data = (IPTR) inst->fpb_Path;
	TagList++;

	TagList->ti_Tag = TAG_END;

	return TRUE;
}

//----------------------------------------------------------------------------

static SAVEDS(ULONG) INTERRUPT EditAttrTTFontOpenHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	APTR ttRequest;
	ULONG Success = 0;

	ttRequest = TT_AllocRequest();

	if (ttRequest)
		{
		struct Window *PrefsWindow = NULL;
		struct TagItem *AttrList;
		char FontName[MAX_ATTRVALUE];
		IPTR FontStyle, FontWeight, FontSize;
		STRPTR FontDesc = NULL;

		get(o, MUIA_String_Contents, &FontDesc);

		ParseTTFontFromDesc(FontDesc, &FontStyle, &FontWeight, 
			&FontSize, FontName, sizeof(FontName));

//		set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Sleep, TRUE);
		get(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Window, &PrefsWindow);

		//TT_RequestA()
		AttrList = TT_Request(ttRequest,
			TTRQ_Window, (IPTR) PrefsWindow,
			TTRQ_TitleText, (IPTR) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASLTITLE),
			TTRQ_PositiveText, (IPTR) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASL_OKBUTTON),
			TTRQ_NegativeText, (IPTR) GetLocString(MSGID_EDITATTRIBUTE_TTFONT_ASL_CANCELBUTTON),
			TTRQ_DoSizes, TRUE,
			TTRQ_DoStyle, TRUE,
			TTRQ_DoWeight, TRUE,
			TTRQ_Activate, TRUE,
			TTRQ_DoPreview, TRUE,
			TTRQ_InitialName, (IPTR) FontName,
			TTRQ_InitialSize, FontSize,
			TTRQ_InitialStyle, FontStyle,
			TAG_END);

		d1(kprintf("%s/%ld: AttrList=%08lx\n", __FUNC__, __LINE__, AttrList));

		if (AttrList)
			{
			char buffer[MAX_ATTRVALUE];

			BuildTTDescFromAttrList(buffer, sizeof(buffer), AttrList);

			d1(kprintf("%s/%ld: FontDesc=<%s>\n", __FUNC__, __LINE__, buffer));

			set(o, MUIA_String_Contents, (IPTR) buffer);
			set(inst->fpb_Objects[OBJNDX_TTFont_Sample], MUIA_FontSample_TTFontDesc, (IPTR) buffer);

			Success = 1;
			}

		TT_FreeRequest(ttRequest);
		}

	DoMethod(o, MUIM_Popstring_Close, Success);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(ULONG) INTERRUPT EditAttrTTFontCloseHookFunc(struct Hook *hook, Object *o, Msg msg)
{
//	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

//	set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Sleep, FALSE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SelectEntryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
//	struct MUI_NListtree_TreeNode *tn1;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));
#if 0
	tn1 = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		tn,
		MUIV_NListtree_GetEntry_Position_Head,
		0);
	d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn1, tn1 ? tn1->tn_Name : (STRPTR) ""));

	tn1 = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		tn,
		MUIV_NListtree_GetEntry_Position_Tail,
		0);
	d1(kprintf("%s/%ld: Tail tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn1, tn1 ? tn1->tn_Name : (STRPTR) ""));
#endif
	if (tn)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

		set(inst->fpb_Objects[OBJNDX_Menu_Expand], MUIA_Menuitem_Enabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_Menu_Collapse], MUIA_Menuitem_Enabled, TRUE);

		switch (fte->ftle_EntryType)
			{
		case ENTRYTYPE_FileType:
		set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE);
			set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE);
			set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE);
			break;
		case ENTRYTYPE_PopupMenu:
		case ENTRYTYPE_PopupMenu_SubMenu:
		case ENTRYTYPE_PopupMenu_MenuItem:
		case ENTRYTYPE_PopupMenu_InternalCmd:
		case ENTRYTYPE_PopupMenu_WbCmd:
		case ENTRYTYPE_PopupMenu_ARexxCmd:
		case ENTRYTYPE_PopupMenu_CliCmd:
		case ENTRYTYPE_PopupMenu_PluginCmd:
		case ENTRYTYPE_PopupMenu_IconWindowCmd:
		case ENTRYTYPE_PopupMenu_MenuSeparator:
		case ENTRYTYPE_ToolTip:
		case ENTRYTYPE_ToolTip_Group:
		case ENTRYTYPE_ToolTip_Member:
		case ENTRYTYPE_ToolTip_HBar:
		case ENTRYTYPE_ToolTip_String:
		case ENTRYTYPE_ToolTip_Space:
		case ENTRYTYPE_ToolTip_DtImage:
		default:
			set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, TRUE);
			set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, TRUE);
			set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, FALSE);
			break;
			}

		UpdateAttributes(inst, fte);
		}
	else
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_Clear);
		set(inst->fpb_Objects[OBJNDX_Menu_Expand], MUIA_Menuitem_Enabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_Menu_Collapse], MUIA_Menuitem_Enabled, FALSE);

		set(inst->fpb_Objects[OBJNDX_Menu_Copy], MUIA_Menuitem_Enabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_Menu_Cut], MUIA_Menuitem_Enabled, FALSE);

		set(inst->fpb_Objects[OBJNDX_ButtonRemoveEntry], MUIA_Disabled, TRUE);
		}


	EnablePasteMenuEntry(inst);
	EnablePasteAttrMenuEntry(inst);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SelectAttributeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);
		}

	d1(kprintf("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr));
	if (Attr)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;
		const struct AttributeDef *atd;

		d1(kprintf("%s/%ld: active fte=%08lx\n", __FUNC__, __LINE__, fte));

		set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, TRUE);

		atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType);
		d1(kprintf("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd));
		if (atd)
			{
			set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, IsAttrRequired(fte, atd));

			// "Edit Attribute" button stays disabled when attribute has type ATTRDEFTYPE_None
			set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, 
				ATTRDEFTYPE_None == atd->atd_DefaultContents.avd_Type);
			}
		}
	else
		{
		set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE);
		}

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT EditAttributeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	d1(KPrintF("%s/%ld: START\n", __FUNC__, __LINE__));

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(KPrintF("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList],
			MUIM_NList_GetEntry, 
			MUIV_NList_GetEntry_Active,
			&Attr);
		}

	d1(KPrintF("%s/%ld: active Attr=%08lx\n", __FUNC__, __LINE__, Attr));
	if (Attr)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;
		const struct AttributeDef *atd;

		atd = GetAttributeDef(Attr->ale_Attribute.fta_Type, fte->ftle_EntryType);
		d1(KPrintF("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd));
		if (atd)
			{
			char ValueString[MAX_ATTRVALUE];

			set(inst->fpb_Objects[OBJNDX_Text_AttributeName],
				MUIA_Text_Contents, (IPTR) GetAttributeName(atd->atd_Type));

			GetAttributeValueString(&Attr->ale_Attribute, ValueString, sizeof(ValueString));

			d1(KPrintF("%s/%ld: avd_Type=%ld\n", __FUNC__, __LINE__, atd->atd_DefaultContents.avd_Type));

			switch (atd->atd_DefaultContents.avd_Type)
				{
			case ATTRDEFTYPE_None:
				// nothing to edit here...
				return NULL;
				break;

			case ATTRDEFTYPE_PathName:
				set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],    		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath],		MUIA_ShowMe, TRUE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont],  		MUIA_ShowMe, FALSE);

				set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslPath],
					MUIA_String_Contents, (IPTR) ValueString);

				set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
					MUIA_Window_ActiveObject,
                                        inst->fpb_Objects[OBJNDX_Group_AttributeAslPath]);
				break;

			case ATTRDEFTYPE_FileName:
				set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile],		MUIA_ShowMe, TRUE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont],  		MUIA_ShowMe, FALSE);

				switch (atd->atd_Type)
					{
				case ATTRTYPE_DtImageName:
				case ATTRTYPE_UnselIconName:
				case ATTRTYPE_SelIconName:
					d1(KPrintF("%s/%ld: OBJNDX_DtPic_AttributeSelectAslFile=%08lx  ValueString=<%s>\n", \
						__FUNC__, __LINE__, inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], ValueString));
					set(inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], MUIA_ScaDtpic_Name, ValueString);
					break;
				default:
					set(inst->fpb_Objects[OBJNDX_DtPic_AttributeSelectAslFile], MUIA_ScaDtpic_Name, "");
					break;
					}

				set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFile],
					MUIA_String_Contents, (IPTR) ValueString);

				set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
					MUIA_Window_ActiveObject,
					inst->fpb_Objects[OBJNDX_Group_AttributeAslFile]);
				break;

			case ATTRDEFTYPE_FontString:
				set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont],		MUIA_ShowMe, TRUE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont],		MUIA_ShowMe, FALSE);

				set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectAslFont],
					MUIA_String_Contents, (IPTR) ValueString);
				set(inst->fpb_Objects[OBJNDX_AslFont_Sample], 
					MUIA_FontSample_StdFontDesc, (IPTR) ValueString);

				set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
					MUIA_Window_ActiveObject,
					inst->fpb_Objects[OBJNDX_Group_AttributeAslFont]);
				break;

			case ATTRDEFTYPE_TTFontString:
				set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont],		MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont],		MUIA_ShowMe, TRUE);

				set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectTTFont],
					MUIA_String_Contents, (IPTR) ValueString);
				set(inst->fpb_Objects[OBJNDX_TTFont_Sample],
					MUIA_FontSample_TTFontDesc, (IPTR) ValueString);

				set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
					MUIA_Window_ActiveObject,
					inst->fpb_Objects[OBJNDX_Group_AttributeTTFont]);
				break;

			case ATTRDEFTYPE_ULong:
				//... TBD
			case ATTRDEFTYPE_LocString:
			case ATTRDEFTYPE_String:
			case ATTRDEFTYPE_String2:
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFile],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslPath],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeAslFont],	MUIA_ShowMe, FALSE);
				set(inst->fpb_Objects[OBJNDX_Group_AttributeTTFont],	MUIA_ShowMe, FALSE);

				d1(KPrintF("%s/%ld: atd_NumberOfValues=%ld\n", __FUNC__, __LINE__, atd->atd_NumberOfValues));
				if (atd->atd_NumberOfValues > 0)
					{
					set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, TRUE);
					set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],		MUIA_ShowMe, FALSE);

					FillListOfAttributeValues(inst, fte, atd, Attr);

					set(inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue],
						MUIA_String_Contents, (IPTR) ValueString);

					set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
						MUIA_Window_ActiveObject,
						inst->fpb_Objects[OBJNDX_Pop_AttributeSelectValue]);
					}
				else
					{
					set(inst->fpb_Objects[OBJNDX_Group_AttributeSelectValue],	MUIA_ShowMe, FALSE);
					set(inst->fpb_Objects[OBJNDX_Group_AttributeValue],		MUIA_ShowMe, TRUE);

					set(inst->fpb_Objects[OBJNDX_String_AttributeValue],
						MUIA_String_Contents, (IPTR) ValueString);

					set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute],
						MUIA_Window_ActiveObject,
						inst->fpb_Objects[OBJNDX_String_AttributeValue]);
					}
				break;
				}

			DoMethod(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIM_Notify, MUIA_Window_Open, TRUE, 
				inst->fpb_Objects[OBJNDX_WIN_Main], 3, MUIM_Set, MUIA_Window_Sleep, TRUE);
			DoMethod(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIM_Notify, MUIA_Window_Open, FALSE, 
				inst->fpb_Objects[OBJNDX_WIN_Main], 3, MUIM_Set, MUIA_Window_Sleep, FALSE);

			d1(KPrintF("%s/%ld: atd=%08lx  OBJNDX_WIN_EditAttribute=%08lx\n", __FUNC__, __LINE__, atd, inst->fpb_Objects[OBJNDX_WIN_EditAttribute]));

			set(inst->fpb_Objects[OBJNDX_WIN_EditAttribute], MUIA_Window_Open, TRUE);

			d1(KPrintF("%s/%ld: atd=%08lx\n", __FUNC__, __LINE__, atd));
			}
		}

	d1(KPrintF("%s/%ld: END\n", __FUNC__, __LINE__));

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT ContextMenuTriggerHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	Object *MenuObj = *((Object **) msg);
	ULONG MenuHookIndex = 0;
	struct Hook *MenuHook = NULL;

	d1(KPrintF("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
	d1(KPrintF("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((IPTR *) msg)));

	get(MenuObj, MUIA_UserData, &MenuHookIndex);

	if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX)
		MenuHook = &inst->fpb_Hooks[MenuHookIndex];

	d1(KPrintF("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
	if (MenuHook)
		DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj);

	return NULL;
}

//----------------------------------------------------------------------------

static LONG ReadPrefs(struct FileTypesPrefsInst *inst,
	CONST_STRPTR LoadFileName, CONST_STRPTR DefIconPrefsName)
{
	d1(time_t now = time(NULL));

	d1(KPrintF(__FILE__ "/%s/%ld: LoadFileName=<%s>  DefIconPrefsName=<%s>\n", __FUNC__, __LINE__, LoadFileName, DefIconPrefsName));

	ReadFileTypes(inst, LoadFileName, DefIconPrefsName);

	d1(kprintf(__FILE__ "/%s/%ld: \n", __FUNC__, __LINE__));
	d1(kprintf(__FILE__ "/%s/%ld: ReadFileTypes took %lu s\n", __FUNC__, __LINE__, time(NULL) - now));

	return RETURN_OK;
}


static LONG WritePrefs(struct FileTypesPrefsInst *inst,
	CONST_STRPTR SaveName, CONST_STRPTR DefIconPrefsName, ULONG Flags)
{
	LONG Result;

	d1(time_t now = time(NULL));

	WriteDefIconsPrefs(inst, DefIconPrefsName);

	Result = WriteFileTypes(inst, SaveName, Flags);

	d1(kprintf(__FILE__ "/%s/%ld: WriteFileTypes took %lu s\n", __FUNC__, __LINE__, time(NULL) - now));

	if (RETURN_OK == Result)
		{
		}
	else
		{
		char Buffer[120];

		Fault(Result, "", Buffer, sizeof(Buffer) - 1);

		// MUI_RequestA()
		MUI_Request(inst->fpb_Objects[OBJNDX_APP_Main], inst->fpb_Objects[OBJNDX_WIN_Main], 0, NULL, 
			GetLocString(MSGID_ABOUTREQOK), 
			GetLocString(MSGID_REQTITLE_SAVEERROR), 
			SaveName,
			Buffer);
		}

	return Result;
}

//----------------------------------------------------------------------------

DISPATCHER(myNListTree)
{
	struct FileTypesPrefsInst *inst = NULL;
	IPTR Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		ULONG MenuHookIndex = 0;
		struct Hook *MenuHook = NULL;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((IPTR *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHookIndex);

		if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX)
			MenuHook = &inst->fpb_Hooks[MenuHookIndex];

		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0);

		Result = 0;
		}
		break;

	case MUIM_NList_TestPos:
		{
		struct TestPosArg
			{
			ULONG MethodID;
			LONG x, y;
			struct MUI_NList_TestPos_Result *res;
			};
		struct TestPosArg *tpa = (struct TestPosArg *) msg;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		if (inst->fpb_PageIsActive)
			Result = DoSuperMethodA(cl, obj, msg);
		else
			{
			Result = 0;
			tpa->res->entry = tpa->res->column = -1;
			}

		d1(kprintf("%s/%ld: MUIM_NList_TestPos  Result=%08lx  x=%ld  y=%ld  tpr=%08lx  entry=%ld  column=%ld\n", \
			__FUNC__, __LINE__, Result, tpa->x, tpa->y, tpa->res, tpa->res->entry, tpa->res->column));
		}
		break;

	case MUIM_DragQuery:
		{
		struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(kprintf("%s/%ld: MUIM_DragQuery obj=%08lx\n", __FUNC__, __LINE__, dq->obj));

		if (inst->fpb_Objects[OBJNDX_MainListTree] == dq->obj)
			Result = MUIV_DragQuery_Accept;
		else
			Result = MUIV_DragQuery_Refuse;
		}
		break;

	case MUIM_DragDrop:
		Result = DoDragDrop(cl, obj, msg);
		break;

	case MUIM_NList_DropType:
		{
		struct MUIP_NList_DropType *dr = (struct MUIP_NList_DropType *)msg;
		struct MUI_NListtree_TreeNode *tnTo, *tnFrom;
		struct MUI_NListtree_TestPos_Result res;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		inst->fpb_MenuTreeMayDrop = FALSE;

		Result = DoSuperMethodA(cl, obj, msg);
		d1(KPrintF("%s/%ld: DropType=%ld  pos=%ld\n", __FUNC__, __LINE__, *(dr->type), *(dr->pos)));

		DoMethod(obj, MUIM_NListtree_TestPos, dr->mousex, dr->mousey, &res);

		tnTo = res.tpr_TreeNode;

		tnFrom = MUIV_NListtree_Active_Off;
		get(obj, MUIA_NListtree_Active, &tnFrom);

		d1(KPrintF("%s/%ld: tnFrom=%08lx  tnTo=%08lx\n", __FUNC__, __LINE__, tnFrom, tnTo));

		if (tnTo && tnFrom)
			{
			switch (*(dr->type))
				{
			case MUIV_NListtree_DropType_None:
			case MUIV_NListtree_DropType_Sorted:
			default:
				break;
			case MUIV_NListtree_DropType_Above:
			case MUIV_NListtree_DropType_Below:
				if (MayPasteBelow(inst, tnTo, tnFrom))
					inst->fpb_MenuTreeMayDrop = TRUE;
				break;
			case MUIV_NListtree_DropType_Onto:
				if (MayPasteOnto(inst, tnTo, tnFrom))
					inst->fpb_MenuTreeMayDrop = TRUE;
				break;
				}
			d1(KPrintF("%s/%ld: DropType=%ld\n", __FUNC__, __LINE__, *(dr->type)));
			}
		}
		break;

	// we catch MUIM_DragReport because we want to restrict some dragging for some special objects
	case MUIM_DragReport:
		{
		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__));

		Result = DoSuperMethodA(cl, obj, msg);
		if (!inst->fpb_MenuTreeMayDrop)
			Result = MUIV_DragReport_Abort;

		d1(KPrintF("%s/%ld: MUIM_DragReport\n", __FUNC__, __LINE__));
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myFileTypesNListTree)
{
	struct FileTypesPrefsInst *inst = NULL;
	IPTR Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		ULONG MenuHookIndex = 0;
		struct Hook *MenuHook = NULL;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((IPTR *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHookIndex);

		if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX)
			MenuHook = &inst->fpb_Hooks[MenuHookIndex];

		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, 0);

		Result = 0;
		}
		break;

	case MUIM_DragQuery:
		{
		struct MUIP_DragQuery *dq = (struct MUIP_DragQuery *) msg;

		d1(kprintf("%s/%ld: MUIM_DragQuery obj=%08lx\n", __FUNC__, __LINE__, dq->obj));

		// only accept objects from ourselves
		if (obj == dq->obj)
			Result = MUIV_DragQuery_Accept;
		else
			Result = MUIV_DragQuery_Refuse;
		}
		break;

	case MUIM_DragDrop:
		{
		//struct MUIP_DragDrop *dq = (struct MUIP_DragDrop *) msg;
		struct MUI_NListtree_TreeNode *ln;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);
		d1(kprintf("%s/%ld: MUIP_DragDrop obj=%08lx\n", __FUNC__, __LINE__, obj));

		Result = DoSuperMethodA(cl, obj, msg);

		ln = (struct MUI_NListtree_TreeNode *) DoMethod(obj,
			MUIM_NListtree_GetEntry,
			MUIV_NListtree_GetEntry_ListNode_Active,
			MUIV_NListtree_GetEntry_Position_Active,
			0);

		d1(kprintf("%s/%ld: ln=%08lx  tn_User=%08lx\n", __FUNC__, __LINE__, ln, ln->tn_User));

		if (ln)
			{
			SetFileTypesIcon(inst, ln);
			}
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myNList)
{
	struct FileTypesPrefsInst *inst = NULL;
	IPTR Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		ULONG MenuHookIndex = 0;
		struct Hook *MenuHook = NULL;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((IPTR *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHookIndex);

		if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX)
			MenuHook = &inst->fpb_Hooks[MenuHookIndex];

		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj);

		Result = 0;
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myFileTypesActionsNList)
{
	struct FileTypesPrefsInst *inst = NULL;
	IPTR Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_DragDrop:
		Result = DoSuperMethodA(cl, obj, msg);
		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);
		CallHookPkt(&inst->fpb_Hooks[HOOKNDX_DragDropSort_FileTypesAction], obj, msg);
		break;

	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		ULONG MenuHookIndex = 0;
		struct Hook *MenuHook = NULL;

		get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((IPTR *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHookIndex);

		if (MenuHookIndex > 0 && MenuHookIndex < HOOKNDX_MAX)
			MenuHook = &inst->fpb_Hooks[MenuHookIndex];

		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(inst->fpb_Objects[OBJNDX_Group_Main], MUIM_CallHook, MenuHook, MenuObj);

		Result = 0;
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

struct FtAttribute *AddAttribute(struct FileTypesListEntry *fte,
	enum ftAttributeType AttrType, ULONG DataLength, const void *AttrData)
{
	struct FtAttribute *fta;

	fta = malloc(sizeof(struct FtAttribute) + DataLength);
	d1(kprintf(__FILE__ "/%s/%ld: fta=%08lx  size=%lu\n", __FUNC__, __LINE__, \
		fta, sizeof(struct FtAttribute) + DataLength));

	if (fta)
		{
		AddTail(&fte->ftle_AttributesList, &fta->fta_Node);

		fta->fta_Type = AttrType;
		fta->fta_Length = DataLength;
		memcpy(fta->fta_Data, AttrData, DataLength);
		}

	return fta;
}

static void DisposeAttribute(struct FtAttribute *fta)
{
	free(fta);
}

static void CleanupAttributes(struct List *AttributesList)
{
	struct FtAttribute *fta;

	while ((fta = (struct FtAttribute *) RemHead(AttributesList)))
		{
		DisposeAttribute(fta);
		}
}

//----------------------------------------------------------------------------

CONST_STRPTR GetAttributeName(enum ftAttributeType Type)
{
	CONST_STRPTR Name;

	switch (Type)
		{
	case ATTRTYPE_FtDescription:
		Name = "DESCRIPTION";
		break;

	case ATTRTYPE_PvPluginName:
		Name = "PREVIEWPLUGIN";
		break;

	case ATTRTYPE_GroupOrientation:
		Name = "ORIENTATION";
		break;

	case ATTRTYPE_MemberHideString:
		Name = "HIDE";
		break;

	case ATTRTYPE_StringHAlign:
		Name = "HALIGN";
		break;

	case ATTRTYPE_StringVAlign:
		Name = "VALIGN";
		break;

	case ATTRTYPE_StringStyle:
		Name = "STYLE";
		break;

	case ATTRTYPE_StringFont:
		Name = "FONT";
		break;

	case ATTRTYPE_StringTTFont:
		Name = "TTFONT";
		break;

	case ATTRTYPE_StringPen:
		Name = "TEXTPEN";
		break;

	case ATTRTYPE_StringId:
		Name = "ID";
		break;

	case ATTRTYPE_StringText:
		Name = "TEXT";
		break;

	case ATTRTYPE_StringSrc:
		Name = "SRC";
		break;

	case ATTRTYPE_SpaceSize:
		Name = "SIZE";
		break;

	case ATTRTYPE_DtImageName:
		Name = "FILENAME";
		break;

	case ATTRTYPE_UnselIconName:
		Name = "UNSELECTEDICON";
		break;

	case ATTRTYPE_SelIconName:
		Name = "SELECTEDICON";
		break;

	case ATTRTYPE_MenuItemName:
		Name = "NAME";
		break;

	case ATTRTYPE_MenuCommKey:
		Name = "KEY";
		break;

	case ATTRTYPE_MenuDefaultAction:
		Name = "DEFAULTACTION";
		break;

	case ATTRTYPE_CommandName:
		Name = "NAME";
		break;

	case ATTRTYPE_CommandStacksize:
		Name = "STACK";
		break;

	case ATTRTYPE_CommandPriority:
		Name = "PRIORITY";
		break;

	case ATTRTYPE_CommandWbArgs:
		Name = "WBARGS";
		break;

	default:
		Name = "??unknown_Name??";
		break;
		}

	return Name;
}

STRPTR GetAttributeValueString(const struct FtAttribute *fta, char *Buffer, size_t BuffLen)
{
	if (NULL == fta)
		strcpy(Buffer, "");
	else
		{
		switch (fta->fta_Type)
			{
		case ATTRTYPE_FtDescription:
		case ATTRTYPE_PvPluginName:
		case ATTRTYPE_StringHAlign:
		case ATTRTYPE_StringVAlign:
		case ATTRTYPE_StringStyle:
		case ATTRTYPE_StringFont:
		case ATTRTYPE_StringTTFont:
		case ATTRTYPE_StringPen:
		case ATTRTYPE_StringId:
		case ATTRTYPE_StringText:
		case ATTRTYPE_StringSrc:
		case ATTRTYPE_DtImageName:
		case ATTRTYPE_UnselIconName:
		case ATTRTYPE_SelIconName:
		case ATTRTYPE_MenuItemName:
		case ATTRTYPE_MenuCommKey:
		case ATTRTYPE_CommandName:
		case ATTRTYPE_MemberHideString:
			stccpy(Buffer, (char *)fta->fta_Data, BuffLen);
			break;

		case ATTRTYPE_GroupOrientation:
			{
			enum TTLayoutMode *goEnum = (enum TTLayoutMode *)fta->fta_Data;
			switch (*goEnum)
				{
				case TTL_Horizontal:
					stccpy(Buffer, "horizontal", BuffLen);
					break;
				case TTL_Vertical:
					stccpy(Buffer, "vertical", BuffLen);
					break;
				default:
					sprintf(Buffer, "??unknown_Orientation??:%d", *goEnum);
					break;
				}
			}
			break;

		case ATTRTYPE_CommandStacksize:
		case ATTRTYPE_CommandPriority:
		case ATTRTYPE_SpaceSize:
			sprintf(Buffer, "%ld", *((ULONG *) fta->fta_Data));
			break;

		case ATTRTYPE_CommandWbArgs:
		case ATTRTYPE_MenuDefaultAction:
			strcpy(Buffer, "");
			break;

		default:
			stccpy(Buffer, "??unknown_AttrType??", BuffLen);
			break;
			}
		}

	return Buffer;
}


static const struct FtAttribute *FindAttribute(const struct FileTypesListEntry *fte, enum FtEntryType AttrType)
{
	struct FtAttribute *fta;

	for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head;
		fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail;
		fta = (struct FtAttribute *) fta->fta_Node.ln_Succ)
		{
		if (AttrType == (enum FtEntryType)fta->fta_Type)
			return fta;
		}

	return NULL;
}


static void RemoveAttribute(struct FileTypesListEntry *fte, enum ftAttributeType AttrType)
{
	struct FtAttribute *fta;

	for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head;
		fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail;
		fta = (struct FtAttribute *) fta->fta_Node.ln_Succ)
		{
		if (AttrType == fta->fta_Type)
			{
			Remove(&fta->fta_Node);
			free(fta);
			break;
			}
		}

}


static struct FileTypesListEntry *FindChildByType(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tn, enum FtEntryType RequestedType)
{
	struct FileTypesListEntry *fte = NULL;

	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);

		fte = tn ? ((struct FileTypesListEntry *) tn->tn_User) : NULL;

		while (fte && fte->ftle_EntryType != RequestedType)
			{			
			tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_GetEntry, 
				tn,
				MUIV_NListtree_GetEntry_Position_Next,
				0);

			fte = tn ? ((struct FileTypesListEntry *) tn->tn_User) : NULL;
			}
		}

	return fte;
}


static BOOL HasChildren(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn)
{
	BOOL HasChildren = FALSE;

	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);

		if (tn)
			HasChildren = TRUE;
		}

	return HasChildren;
}

//----------------------------------------------------------------------------

CONST_STRPTR GetNameFromEntryType(enum ftAttributeType EntryType)
{
	if (EntryType >= 0 && EntryType < Sizeof(EntryTypeNames))
		return GetLocString(EntryTypeNames[EntryType]);
	else
		return "??unknown_EntryType??";
}

//----------------------------------------------------------------------------

static void AddDefaultAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte)
{
	ULONG n;

	for (n = 0; n < Sizeof(AllEntryAttributes); n++)
		{
		if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType)
			{
			ULONG m;

			d1(kprintf("%s/%ld:  EntryType=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_EntryType));

			for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++)
				{
				if (IsAttrRequired(fte, &AllEntryAttributes[n].eat_AttrArray[m]))
					{
					d1(kprintf("%s/%ld:  Add AttrType=%lu\n", __FUNC__, __LINE__, \
						AllEntryAttributes[n].eat_AttrArray[m].atd_Type));

					AddNewAttribute(inst, fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type);
					}
				}
			break;
			}
		}
}

//----------------------------------------------------------------------------

static void SetAddableAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte)
{
	ULONG Added = 0;
	ULONG n;

	set(inst->fpb_Objects[OBJNDX_AddAttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_Clear);

	for (n = 0; n < Sizeof(AllEntryAttributes); n++)
		{
		if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType)
			{
			ULONG m;

			for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++)
				{
				if (NULL == FindAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type))
					{
					Added++;
					DoMethod(inst->fpb_Objects[OBJNDX_AddAttrList], MUIM_NList_InsertSingle,
						AllEntryAttributes[n].eat_AttrArray[m].atd_Type, 
						MUIV_NList_Insert_Sorted);
					}
				}
			break;
			}
		}

	d1(kprintf("%s/%ld:  Added=%lu\n", __FUNC__, __LINE__, Added));

	set(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIA_Disabled, 0 == Added);

	set(inst->fpb_Objects[OBJNDX_AddAttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
}

//----------------------------------------------------------------------------

static void UpdateAttributes(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte)
{
	struct FtAttribute *fta;
	struct FileTypesListEntry *ftePopupMenu;
	struct FileTypesListEntry *fteToolTip;
	const ULONG *AddEntryList;
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	DoMethod(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIM_Popstring_Close, FALSE);
	DoMethod(inst->fpb_Objects[OBJNDX_AddAttrPopObject], MUIM_Popstring_Close, FALSE);

	set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);
	set(inst->fpb_Objects[OBJNDX_AddEntryList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_Clear);
	DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], MUIM_NList_Clear);

	set(inst->fpb_Objects[OBJNDX_ButtonRemoveAttribute], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_ButtonEditAttribute], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Menu_CopyAttr], MUIA_Menuitem_Enabled, FALSE);
	set(inst->fpb_Objects[OBJNDX_Menu_CutAttr], MUIA_Menuitem_Enabled, FALSE);

	for (fta = (struct FtAttribute *) fte->ftle_AttributesList.lh_Head;
		fta != (struct FtAttribute *) &fte->ftle_AttributesList.lh_Tail;
		fta = (struct FtAttribute *) fta->fta_Node.ln_Succ)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle,
			fta, MUIV_NList_Insert_Bottom);
		}

	switch (fte->ftle_EntryType)
		{
	case ENTRYTYPE_FileType:
		ftePopupMenu = FindChildByType(inst, tn, ENTRYTYPE_PopupMenu);
		fteToolTip = FindChildByType(inst, tn, ENTRYTYPE_ToolTip);

		if (ftePopupMenu)
			{
			if (fteToolTip)
				AddEntryList = NULL;
			else
				AddEntryList = AddFiletypeStringsTT;
			}
		else
			{
			if (fteToolTip)
				AddEntryList = AddFiletypeStringsPM;
			else
				AddEntryList = AddFiletypeStringsPMTT;
			}
		break;

	case ENTRYTYPE_PopupMenu:
		AddEntryList = AddPopupMenuStrings;
		break;

	case ENTRYTYPE_PopupMenu_SubMenu:
		AddEntryList = AddSubMenuStrings;
		break;

	case ENTRYTYPE_PopupMenu_MenuItem:
		AddEntryList = AddMenuItemStrings;
		break;

	case ENTRYTYPE_ToolTip:
		AddEntryList = AddToolTipStrings;
		break;

	case ENTRYTYPE_ToolTip_Group:
		AddEntryList = AddGroupStrings;
		break;

	case ENTRYTYPE_ToolTip_Member:
		// only 1 child allowed
		if (HasChildren(inst, tn))
			AddEntryList = NULL;
		else
			AddEntryList = AddMemberStrings;
		break;

	default:
		AddEntryList = NULL;
		break;
		}

	SetAddableAttributes(inst, fte);

	if (AddEntryList)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_AddEntryList], MUIM_NList_Insert,
			AddEntryList, -1, MUIV_NList_Insert_Sorted);
		}

	set(inst->fpb_Objects[OBJNDX_AddEntryList], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
	set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	set(inst->fpb_Objects[OBJNDX_AddEntryPopObject], MUIA_Disabled, NULL == AddEntryList);
}

//----------------------------------------------------------------------------

static void AddNewAttribute(struct FileTypesPrefsInst *inst, struct FileTypesListEntry *fte, enum ftAttributeType AttrType)
{
	ULONG n;

	d1(kprintf("%s/%ld:  inst=%08lx  EntryType=%ld  AttrType=%ld\n", __FUNC__, __LINE__, inst, fte->ftle_EntryType, AttrType));

	set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	for (n = 0; n < Sizeof(AllEntryAttributes); n++)
		{
		if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType)
			{
			ULONG m;

			d1(kprintf("%s/%ld:  AttrCount=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrCount));

			for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++)
				{
				const struct AttrDefaultValue *avd = &AllEntryAttributes[n].eat_AttrArray[m].atd_DefaultContents;

				d1(kprintf("%s/%ld:  atd_Type=%lu\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrArray[m].atd_Type));

				if (AllEntryAttributes[n].eat_AttrArray[m].atd_Type == AttrType)
					{
					struct FtAttribute *ftaNew = NULL;

					switch (avd->avd_Type)
						{
					case ATTRDEFTYPE_None:
						ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type,
							0, NULL);
						break;
					case ATTRDEFTYPE_ULong:
						ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type,
							sizeof(ULONG), &avd->avd_ULongValue);
						break;
					case ATTRDEFTYPE_LocString:
						ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type,
							1 + strlen(GetLocString(avd->avd_ULongValue)), GetLocString(avd->avd_ULongValue));
						break;
					case ATTRDEFTYPE_String:
					case ATTRDEFTYPE_String2:
					case ATTRDEFTYPE_PathName:
					case ATTRDEFTYPE_FileName:
					case ATTRDEFTYPE_FontString:
					case ATTRDEFTYPE_TTFontString:
						ftaNew = AddAttribute(fte, AllEntryAttributes[n].eat_AttrArray[m].atd_Type,
							1 + strlen(avd->avd_StringValue), avd->avd_StringValue);
						break;
						}

					if (ftaNew)
						{
						DoMethod(inst->fpb_Objects[OBJNDX_AttrList], MUIM_NList_InsertSingle,
							ftaNew, MUIV_NList_Insert_Bottom);
						}
					break;
					}
				}
			}
		}

	set(inst->fpb_Objects[OBJNDX_AttrList], MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	EnablePasteAttrMenuEntry(inst);
}

//----------------------------------------------------------------------------

static void BeginSetMenuDefaultAction(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tnMenuItem)
{
	struct MUI_NListtree_TreeNode *tn = tnMenuItem;
	struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

	// Find root of PopupMenu
	while (tn && ENTRYTYPE_PopupMenu != fte->ftle_EntryType)
		{
		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Parent,
			0);

		if (tn)
			fte = (struct FileTypesListEntry *) tn->tn_User;
		}

	d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	// Now walk through entire Menu and remove "DefaultAction" atrribute from every MenuItem
	// except <tnMenuItem>
	SetMenuDefaultAction(inst, tn, tnMenuItem);
}


static void SetMenuDefaultAction(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnMenu, struct MUI_NListtree_TreeNode *tnNewDefault)
{
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		tnMenu,
		MUIV_NListtree_GetEntry_Position_Head,
		0);

	d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	while (tn)
		{
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

		d1(kprintf("%s/%ld: tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

		switch (fte->ftle_EntryType)
			{
		case ENTRYTYPE_PopupMenu_MenuItem:
			if (tn != tnNewDefault)
				{
				const struct FtAttribute *fta = FindAttribute(fte, ATTRTYPE_MenuDefaultAction);

				d1(kprintf("%s/%ld: fta=%08lx\n", __FUNC__, __LINE__, fta));
				if (fta)
					{
					RemoveAttribute(fte, ATTRTYPE_MenuDefaultAction);

					DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
						MUIM_NListtree_Redraw, 
						tn,
						0);
					}
				}
			break;

		case ENTRYTYPE_PopupMenu_SubMenu:
			SetMenuDefaultAction(inst, tn, tnNewDefault);
			break;

		default:
			break;
			}

		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Next,
			0);
		}
}

//----------------------------------------------------------------------------

static const struct AttributeDef *GetAttributeDef(enum ftAttributeType AttrType, enum FtEntryType fteEntryType)
{
	const struct EntryAttributes *eat;
	ULONG n;

	for (n = 0, eat = AllEntryAttributes; n < Sizeof(AllEntryAttributes); n++, eat++)
		{
		if (fteEntryType == eat->eat_EntryType)
			{
			const struct AttributeDef *atd = eat->eat_AttrArray;
			ULONG m;

			for (m = 0; m < eat->eat_AttrCount; m++, atd++)
				{
				if (atd->atd_Type == AttrType)
					return atd;
				}
			break;
			}
		}

	return NULL;
}

//----------------------------------------------------------------------------

static void FillListOfAttributeValues(struct FileTypesPrefsInst *inst, 
	const struct FileTypesListEntry *fte, const struct AttributeDef *atd, 
	const struct AttrListEntry *Attr)
{
	ULONG n;

	set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);
	DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIM_NList_Clear);

	d1(KPrintF("%s/%ld:  atd_NumberOfValues=%ld\n", __FUNC__, __LINE__, atd->atd_NumberOfValues));

	if (ATTRDEFTYPE_String2 == atd->atd_PossibleContents[0].avd_Type)
		{
		set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue],
			MUIA_NList_Format, ",");
		}
	else
		{
		set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue],
			MUIA_NList_Format, "");
		}

	for (n = 0; n < atd->atd_NumberOfValues; n++)
		{
		size_t len;
		struct EditAttrListEntry *eal;

		len = sizeof(struct EditAttrListEntry);

		switch (atd->atd_PossibleContents[n].avd_Type)
			{
		case ATTRDEFTYPE_ULong:
			len += sizeof(atd->atd_PossibleContents[n].avd_ULongValue);
			break;
		case ATTRDEFTYPE_LocString:
		case ATTRDEFTYPE_String:
		case ATTRDEFTYPE_String2:
		case ATTRDEFTYPE_PathName:
		case ATTRDEFTYPE_FileName:
		case ATTRDEFTYPE_FontString:
		case ATTRDEFTYPE_TTFontString:
			len += 1 + strlen(atd->atd_PossibleContents[n].avd_StringValue);
			break;
		default:
			break;
			}

		eal = malloc(len);

		if (eal)
			{
			d1(KPrintF("%s/%ld:  avd_Type=%ld\n", __FUNC__, __LINE__, atd->atd_PossibleContents[n].avd_Type));

			eal->eal_fta = Attr->ale_Attribute;
			eal->eal_fta.fta_Value2 = 0;

			switch (atd->atd_PossibleContents[n].avd_Type)
				{
			case ATTRDEFTYPE_ULong:
				memcpy(eal->eal_fta.fta_Data, &atd->atd_PossibleContents[n].avd_ULongValue, sizeof(ULONG));
				eal->eal_fta.fta_Length = sizeof(ULONG);
				break;
			case ATTRDEFTYPE_LocString:
			case ATTRDEFTYPE_String:
			case ATTRDEFTYPE_PathName:
			case ATTRDEFTYPE_FileName:
			case ATTRDEFTYPE_FontString:
			case ATTRDEFTYPE_TTFontString:
				strcpy((char *)eal->eal_fta.fta_Data, atd->atd_PossibleContents[n].avd_StringValue);
				eal->eal_fta.fta_Length = strlen(atd->atd_PossibleContents[n].avd_StringValue);
				break;
			case ATTRDEFTYPE_String2:
				eal->eal_fta.fta_Value2 = atd->atd_PossibleContents[n].avd_ULongValue;
				strcpy((char *)eal->eal_fta.fta_Data, atd->atd_PossibleContents[n].avd_StringValue);
				eal->eal_fta.fta_Length = strlen(atd->atd_PossibleContents[n].avd_StringValue);
				break;
			default:
				break;
				}

			DoMethod(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], 
				MUIM_NList_InsertSingle,
				eal,
				MUIV_NList_Insert_Bottom);

			free(eal);
			}
		}

	set(inst->fpb_Objects[OBJNDX_List_AttributeSelectValue], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
}

//----------------------------------------------------------------------------

static ULONG ConvertGroupOrientationFromString(CONST_STRPTR DisplayString)
{
	ULONG Result = TTL_Horizontal;

	if (0 == Stricmp(DisplayString, "horizontal"))
		Result = TTL_Horizontal;
	else if (0 == Stricmp(DisplayString, "vertical"))
		Result = TTL_Vertical;

	return Result;
}

//----------------------------------------------------------------------------

static struct MUI_NListtree_TreeNode *CopyFileTypesEntry(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnToListNode, struct MUI_NListtree_TreeNode *tnToPrevNode, 
	struct MUI_NListtree_TreeNode *tnFrom, ULONG destList, ULONG srcList)
{
	struct FileTypesListEntry *fteFrom = (struct FileTypesListEntry *) tnFrom->tn_User;
	struct FileTypesListEntry *fteTo;
	struct MUI_NListtree_TreeNode *tnNew;
	struct MUI_NListtree_TreeNode *tnChild;
	const struct FtAttribute *fta;

	if (NULL == tnFrom)
		return NULL;

	tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[srcList],
		MUIM_NListtree_GetEntry, 
		tnFrom,
		MUIV_NListtree_GetEntry_Position_Head,
		0);

	tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[destList],
		MUIM_NListtree_Insert, 
		tnFrom->tn_Name, NULL,
		tnToListNode,
		tnToPrevNode,
		TNF_LIST | TNF_OPEN);

	fteTo = (struct FileTypesListEntry *) tnNew->tn_User;
	fteTo->ftle_EntryType = fteFrom->ftle_EntryType;

	fteTo->fte_ImageObject = NULL;	// do not try to copy fte_ImageObject !!
	fteTo->fte_ImageIndex = 0;

	// Copy Attributes
	for (fta = (const struct FtAttribute *) fteFrom->ftle_AttributesList.lh_Head;
		fta != (const struct FtAttribute *) &fteFrom->ftle_AttributesList.lh_Tail;
		fta = (const struct FtAttribute *) fta->fta_Node.ln_Succ)
		{
		AddAttribute(fteTo, fta->fta_Type, fta->fta_Length, fta->fta_Data);
		}

	UpdateMenuImage(inst, destList, fteTo);

	// Copy Children
	while (tnChild)
		{
		d1(kprintf("%s/%ld: tnChild=%08lx <%s>\n", __FUNC__, __LINE__, tnChild, tnChild->tn_Name));

		CopyFileTypesEntry(inst, 
			tnNew, (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail, 
			tnChild, destList, srcList);

		tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[srcList],
			MUIM_NListtree_GetEntry, 
			tnChild,
			MUIV_NListtree_GetEntry_Position_Next,
			0);
		}

	return tnNew;
}

//----------------------------------------------------------------------------

static BOOL MayPasteOnto(struct FileTypesPrefsInst *inst, 
	struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom)
{
	const struct FileTypesListEntry *fteFrom = (const struct FileTypesListEntry *) tnFrom->tn_User;
	const struct FileTypesListEntry *fteTo = (const struct FileTypesListEntry *) tnTo->tn_User;
	BOOL MayPaste = FALSE;

	d1(kprintf("%s/%ld: fteTo=%08lx <%s> %ld  fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \
		fteTo, tnTo->tn_Name, fteTo->ftle_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->ftle_EntryType));

	if (fteTo->ftle_EntryType >= ENTRYTYPE_MAX || fteFrom->ftle_EntryType >= ENTRYTYPE_MAX)
		return FALSE;

	d1(kprintf("%s/%ld: MayPaste=%ld\n", __FUNC__, __LINE__, \
		MayPasteIntoMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType]));

	if (MayPasteIntoMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType])
		{
		switch (fteTo->ftle_EntryType)
			{
		case ENTRYTYPE_FileType:
			// There is only one Popupmenu and one Tooltip allowed!
			switch (fteFrom->ftle_EntryType)
				{
			case ENTRYTYPE_PopupMenu:
				if (NULL == FindChildByType(inst, tnTo, ENTRYTYPE_PopupMenu))
					MayPaste = TRUE;
				break;
			case ENTRYTYPE_ToolTip:
				if (NULL == FindChildByType(inst, tnTo, ENTRYTYPE_ToolTip))
					MayPaste = TRUE;
				break;
			default:				
				break;
				}
			break;

		case ENTRYTYPE_ToolTip_Member:
			// only 1 child allowed
			if (!HasChildren(inst, tnTo))
				MayPaste = TRUE;
			break;

		default:
			MayPaste = TRUE;
			break;
			}
		}

	return MayPaste;
}


static struct MUI_NListtree_TreeNode *MayPasteBelow(struct FileTypesPrefsInst *inst,
	struct MUI_NListtree_TreeNode *tnTo, struct MUI_NListtree_TreeNode *tnFrom)
{
	const struct FileTypesListEntry *fteFrom = (const struct FileTypesListEntry *) tnFrom->tn_User;
	const struct FileTypesListEntry *fteTo = (const struct FileTypesListEntry *) tnTo->tn_User;
	struct MUI_NListtree_TreeNode *tn;
	BOOL Result = FALSE;

	d1(KPrintF("%s/%ld: START fteTo=%08lx <%s> %ld  fteFrom=%08lx <%s> %ld\n", __FUNC__, __LINE__, \
		fteTo, tnTo->tn_Name, fteTo->ftle_EntryType, fteFrom, tnFrom->tn_Name, fteFrom->ftle_EntryType));

	do	{
		if (fteTo->ftle_EntryType >= ENTRYTYPE_MAX || fteFrom->ftle_EntryType >= ENTRYTYPE_MAX)
			break;

		if (tnTo->tn_Flags & TNF_OPEN)
			{
			tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_GetEntry,
				tnTo,
				MUIV_NListtree_GetEntry_Position_Head,
				MUIV_NListtree_GetEntry_Flag_Visible);
			d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));

			if (tn)
				break;
			}

		do	{
			tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_GetEntry,
				tnTo,
				MUIV_NListtree_GetEntry_Position_Next,
				MUIV_NListtree_GetEntry_Flag_SameLevel | MUIV_NListtree_GetEntry_Flag_Visible);
			d1(KPrintF("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));
			if (tn)
				break;

			tnTo = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_GetEntry,
				tnTo,
				MUIV_NListtree_GetEntry_Position_Parent,
				MUIV_NListtree_GetEntry_Flag_Visible);
			d1(KPrintF("%s/%ld: tnTo=%08lx\n", __FUNC__, __LINE__, tnTo));

			if (tnTo)
				{
				fteTo = (const struct FileTypesListEntry *) tnTo->tn_User;

				Result =  MayPasteAfterMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType];
				}
			} while (tnTo && !Result);

		if (NULL == tnTo)
			break;

		Result =  MayPasteAfterMatrix[fteTo->ftle_EntryType][fteFrom->ftle_EntryType];
		} while (0);

	d1(KPrintF("%s/%ld: END MayPaste=%ld\n", __FUNC__, __LINE__, Result));

	return Result ? tnTo : NULL;
}

//----------------------------------------------------------------------------

static void EnablePasteMenuEntry(struct FileTypesPrefsInst *inst)
{
	struct MUI_NListtree_TreeNode *tnMain;
	struct MUI_NListtree_TreeNode *tnShadow;

	tnMain = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);

	tnShadow = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_ShadowListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_Insert_ListNode_Root,
		MUIV_NListtree_GetEntry_Position_Head,
		0);

	if (tnMain && tnShadow &&
		( MayPasteBelow(inst, tnMain, tnShadow) || MayPasteOnto(inst, tnMain, tnShadow) ))
		{
		set(inst->fpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, TRUE);
		}
	else
		{
		set(inst->fpb_Objects[OBJNDX_Menu_Paste], MUIA_Menuitem_Enabled, FALSE);
		}
}

//----------------------------------------------------------------------------

static BOOL MayPasteAttr(struct FileTypesPrefsInst *inst, const struct FileTypesListEntry *fte, const struct AttrListEntry *Attr)
{
	d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__));

	if (NULL == Attr)
		return FALSE;

	if (NULL == FindAttribute(fte, Attr->ale_Attribute.fta_Type))
		{
		ULONG n;

		d1(kprintf("%s/%ld: Attr=%08lx  Type=%ld\n", __FUNC__, __LINE__, Attr, Attr->ale_Attribute.fta_Type));

		for (n = 0; n < Sizeof(AllEntryAttributes); n++)
			{
			if (AllEntryAttributes[n].eat_EntryType == fte->ftle_EntryType)
				{
				ULONG m;

				d1(kprintf("%s/%ld: AttrCount=%ld\n", __FUNC__, __LINE__, AllEntryAttributes[n].eat_AttrCount));

				for (m = 0; m < AllEntryAttributes[n].eat_AttrCount; m++)
					{
					if (Attr->ale_Attribute.fta_Type == AllEntryAttributes[n].eat_AttrArray[m].atd_Type)
						{
						d1(kprintf("%s/%ld: Found!\n", __FUNC__, __LINE__));
						return TRUE;
						}
					}
				break;
				}
			}
		}

	d1(kprintf("%s/%ld: May not paste!\n", __FUNC__, __LINE__));

	return FALSE;
}

//----------------------------------------------------------------------------

static void EnablePasteAttrMenuEntry(struct FileTypesPrefsInst *inst)
{
	struct MUI_NListtree_TreeNode *tn;
	struct AttrListEntry *Attr = NULL;

	set(inst->fpb_Objects[OBJNDX_Menu_PasteAttr], MUIA_Menuitem_Enabled, FALSE);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	if (tn)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_ShadowAttrList],
			MUIM_NList_GetEntry, 
			0,
			&Attr);

		d1(kprintf("%s/%ld: Attr=%08lx\n", __FUNC__, __LINE__, Attr));

		if (Attr)
			{
			struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

			if (MayPasteAttr(inst, fte, Attr))
				set(inst->fpb_Objects[OBJNDX_Menu_PasteAttr], MUIA_Menuitem_Enabled, TRUE);
			}
		}
}

//----------------------------------------------------------------------------

static BOOL IsAttrRequired(struct FileTypesListEntry *fte, const struct AttributeDef *atd)
{
	ULONG n;

	if (!atd->atd_Required)
		return FALSE;

	for (n = 0; n < atd->atd_ExcludeCount; n++)
		{
		if (NULL != FindAttribute(fte, atd->atd_Exclude[n]))
			{
			// if one of the atd_Exclude[] members is already present 
			// in the Attribute list, this Attribute is NOT required
			return FALSE;
			}
		}

	return TRUE;
}

//----------------------------------------------------------------------------

static void EntryHasChanged(struct FileTypesPrefsInst *inst, struct MUI_NListtree_TreeNode *tn)
{
	struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	SetChangedFlag(inst, TRUE);
	fte->ftle_Changed = TRUE;

	DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_Redraw, 
		tn,
		0);

	// set CHANGED flag for all parent entries up to the ENTRYTYPE_FileType
	while (tn && ENTRYTYPE_FileType != fte->ftle_EntryType)
		{
		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn,
			MUIV_NListtree_GetEntry_Position_Parent,
			0);
		if (tn)
			{
			fte = (struct FileTypesListEntry *) tn->tn_User;
			fte->ftle_Changed = TRUE;

			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
				MUIM_NListtree_Redraw, 
				tn,
				0);
			}
		}

	set(inst->fpb_Objects[OBJNDX_MainListView], MUIA_NList_Quiet, MUIV_NList_Quiet_None);
}

//----------------------------------------------------------------------------

static void SetChangedFlag(struct FileTypesPrefsInst *inst, BOOL changed)
{
	if (changed != inst->fpb_Changed)
		{
		set(inst->fpb_Objects[OBJNDX_Lamp_Changed], 
			MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off);
		inst->fpb_Changed = changed;
		}
}

//----------------------------------------------------------------------------

static void BuildTTDescFromAttrList(char *buffer, size_t length, struct TagItem *AttrList)
{
	IPTR FontStyle;
	IPTR FontWeight;
	IPTR FontSize;
	const STRPTR *FontFamilyTable;

	FontStyle = GetTagData(TT_FontStyle, TT_FontStyle_Regular, AttrList);
	FontWeight = GetTagData(TT_FontWeight, TT_FontWeight_Normal, AttrList);
	FontSize = GetTagData(TT_FontSize, 12, AttrList);
	FontFamilyTable = (const STRPTR *) GetTagData(TT_FamilyTable, (IPTR) NULL, AttrList);

	sprintf(buffer, "%ld/%ld/%ld/%s", FontStyle, FontWeight, FontSize, FontFamilyTable[0]);
}

//-----------------------------------------------------------------

static BOOL ParseTTFontFromDesc(CONST_STRPTR FontDesc, 
	IPTR *FontStyle, IPTR *FontWeight, IPTR *FontSize,
	STRPTR FontName, size_t FontNameSize)
{
	CONST_STRPTR lp;

	strcpy(FontName, "");
	*FontStyle = 0;
	*FontWeight = 0;
	*FontSize = 0;

	// Font Desc format:
	// "style/weight/size/fontname"

	if (3 != sscanf(FontDesc, "%ld/%ld/%ld", FontStyle, FontWeight, FontSize))
		return FALSE;

	lp = strchr(FontDesc, '/');	// Find "/" between style and weight
	if (NULL == lp)
		return FALSE;

	lp = strchr(lp + 1, '/');	// Find "/" between weight and size
	if (NULL == lp)
		return FALSE;

	lp = strchr(lp + 1, '/');	// Find "/" between size and name
	if (NULL == lp)
		return FALSE;

	// copy font name
	stccpy(FontName, 1 + lp, FontNameSize);

	return TRUE;
}

//-----------------------------------------------------------------

void HideEmptyNodes(struct FileTypesPrefsInst *inst)
{
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Root,
		MUIV_NListtree_GetEntry_Position_Head,
		0);
	d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));

	while (tn)
		{
		struct MUI_NListtree_TreeNode *tnNext;
		struct FileTypesListEntry *fte = (struct FileTypesListEntry *) tn->tn_User;

		d1(kprintf("%s/%ld: tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn->tn_Name));

		if (!HasChildren(inst, tn) && IsListEmpty(&fte->ftle_AttributesList))
			{
			struct MUI_NListtree_TreeNode *tnNew;
			struct FileTypesListEntry *fteNew;

			d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));
			d1(kprintf("%s/%ld:  filetype <%s>  \n", __FUNC__, __LINE__, tn->tn_Name));

			tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], 
				MUIM_NListtree_Insert,
				tn->tn_Name, NULL,
				MUIV_NListtree_Insert_ListNode_Root,
				MUIV_NListtree_Insert_PrevNode_Sorted,
				TNF_LIST);

			d1(kprintf("%s/%ld:  tnNew=%08lx\n", __FUNC__, __LINE__, tnNew));

			fteNew = (struct FileTypesListEntry *) tnNew->tn_User;
			fteNew->ftle_EntryType = ENTRYTYPE_FileType;
			}

		tnNext = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree],
			MUIM_NListtree_GetEntry, 
			tn, 
			MUIV_NListtree_GetEntry_Position_Next,
			MUIV_NListtree_GetEntry_Flag_SameLevel);

		if (!HasChildren(inst, tn) && IsListEmpty(&fte->ftle_AttributesList))
			{
			DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
				MUIM_NListtree_Remove, 
				MUIV_NListtree_Remove_ListNode_Active,
				tn,
				0);
			}

		tn = tnNext;
		}
}

//-----------------------------------------------------------------

static void ShowHiddenNodes(struct FileTypesPrefsInst *inst)
{
	struct MUI_NListtree_TreeNode *tn;

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree],
		MUIM_NListtree_GetEntry, 
		MUIV_NListtree_GetEntry_ListNode_Root,
		MUIV_NListtree_GetEntry_Position_Head,
		0);
	d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));

	while (tn)
		{
		struct MUI_NListtree_TreeNode *tnNew;
		struct FileTypesListEntry *fteNew;

		d1(kprintf("%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, tn));
		d1(kprintf("%s/%ld:  filetype <%s>  \n", __FUNC__, __LINE__, tn->tn_Name));

		tnNew = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_MainListTree], 
			MUIM_NListtree_Insert,
			tn->tn_Name, NULL,
			MUIV_NListtree_Insert_ListNode_Root,
			MUIV_NListtree_Insert_PrevNode_Sorted,
			TNF_LIST);

		d1(kprintf("%s/%ld:  tnNew=%08lx\n", __FUNC__, __LINE__, tnNew));

		fteNew = (struct FileTypesListEntry *) tnNew->tn_User;
		fteNew->ftle_EntryType = ENTRYTYPE_FileType;

		tn = (struct MUI_NListtree_TreeNode *) DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree],
			MUIM_NListtree_GetEntry, 
			tn, 
			MUIV_NListtree_GetEntry_Position_Next,
			MUIV_NListtree_GetEntry_Flag_SameLevel);
		}

	DoMethod(inst->fpb_Objects[OBJNDX_HiddenListTree], 
		MUIM_NListtree_Remove, 
		MUIV_NListtree_Remove_ListNode_Root,
		MUIV_NListtree_Remove_TreeNode_All,
		0);

}

//-----------------------------------------------------------------

static void ParseToolTypes(struct FileTypesPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt)
{
	STRPTR tt;

	d1(kprintf("%s/%ld: start  ptt=%08lx  tooltypes=%08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes));
	d1(kprintf("%s/%ld: start  tooltypes=%08lx %08lx %08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2]));

	tt = FindToolType(ptt->ToolTypes, "HIDEEMPTYENTRIES");
	d1(kprintf("%s/%ld: tt=%08lx\n", __FUNC__, __LINE__, tt));
	if (tt)
		{
		d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__));

		if (MatchToolValue(tt, "YES"))
			inst->fpb_HideEmptyNodes = TRUE;
		else if (MatchToolValue(tt, "NO"))
			inst->fpb_HideEmptyNodes = FALSE;

		d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__));
		}

	if (inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries])
		set(inst->fpb_Objects[OBJNDX_Menu_HideEmptyEntries], MUIA_Menuitem_Checked, inst->fpb_HideEmptyNodes);

	d1(kprintf("%s/%ld: end\n", __FUNC__, __LINE__));
}

//----------------------------------------------------------------------------

static LONG ReadScalosPrefs(struct FileTypesPrefsInst *inst, CONST_STRPTR PrefsFileName)
{
	LONG lID;
	APTR p_MyPrefsHandle;

	p_MyPrefsHandle = AllocPrefsHandle("ScalosPrefs");
	lID = ID_MAIN;

	if (p_MyPrefsHandle)
		{
		CONST_STRPTR prefDefIconPath;

		ReadPrefsHandle(p_MyPrefsHandle, PrefsFileName);

		GetPreferences(p_MyPrefsHandle, lID, SCP_TTfAntialiasing, (APTR)&inst->fpb_TTfAntialias, sizeof(inst->fpb_TTfAntialias) );
		// BYTE

		GetPreferences(p_MyPrefsHandle, lID, SCP_TTfGamma, (APTR)&inst->fpb_TTfGamma, sizeof(inst->fpb_TTfGamma) );
		inst->fpb_TTfGamma = SCA_BE2WORD(inst->fpb_TTfGamma);

		prefDefIconPath = GetPrefsConfigString(p_MyPrefsHandle, SCP_PathsDefIcons, "ENV:sys");
		stccpy(inst->fpb_DefIconPath, prefDefIconPath, sizeof(inst->fpb_DefIconPath));

		FreePrefsHandle(p_MyPrefsHandle);
		}

	return RETURN_OK;
}

//----------------------------------------------------------------------------

static CONST_STRPTR GetPrefsConfigString(APTR prefsHandle, ULONG Id, CONST_STRPTR DefaultString)
{
	struct PrefsStruct *ps = FindPreferences(prefsHandle, ID_MAIN, Id);

	if (ps)
		return (CONST_STRPTR) PS_DATA(ps);

	return DefaultString;
}


//---------------------------------------------------------------

BOOL initPlugin(struct PluginBase *PluginBase)
{
	MajorVersion = PluginBase->pl_LibNode.lib_Version;
	MinorVersion = PluginBase->pl_LibNode.lib_Revision;

	d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__));

	d1(kprintf("%s/%ld:   PluginBase=%08lx  procName=<%s>\n", __FUNC__, __LINE__, \
		PluginBase, FindTask(NULL)->tc_Node.ln_Name));

	d1(kprintf("%s/%ld:\n", __FUNC__, __LINE__));

	if (!OpenLibraries())
		return FALSE;

#if !defined(__amigaos4__) && !defined(__AROS__)
	if (_STI_240_InitMemFunctions())
		return FALSE;
#endif

	FontSampleClass = InitFontSampleClass();
	if (NULL == FontSampleClass)
		return FALSE;

	FileTypesPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group,
			NULL, sizeof(struct FileTypesPrefsInst), DISPATCHER_REF(FileTypesPrefs));

	d1(kprintf("%s/%ld:  FileTypesPrefsClass=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsClass));
	if (NULL == FileTypesPrefsClass)
		return FALSE;

	d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog));

	d1(kprintf("%s/%ld: LocaleBase=%08lx\n", __FUNC__, __LINE__, LocaleBase));

	if (LocaleBase)
		{
		d1(kprintf("%s/%ld: FileTypesPrefsLocale=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsLocale));

		if (NULL == FileTypesPrefsLocale)
			FileTypesPrefsLocale = OpenLocale(NULL);

		d1(kprintf("%s/%ld: FileTypesPrefsLocale=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsLocale));

		if (FileTypesPrefsLocale)
			{
			d1(kprintf("%s/%ld: FileTypesPrefsCatalog=%08lx\n", __FUNC__, __LINE__, FileTypesPrefsCatalog));

			if (NULL == FileTypesPrefsCatalog)
				{
				FileTypesPrefsCatalog = OpenCatalog(FileTypesPrefsLocale,
					(STRPTR) "Scalos/ScalosFileTypes.catalog", NULL);

				d1(kprintf("%s/%ld: \n", __FUNC__, __LINE__));
				}
			}
		}

	if (!StaticsTranslated)
		{
		StaticsTranslated = TRUE;

		TranslateNewMenu(ContextMenuFileTypes);
		TranslateNewMenu(ContextMenuFileTypesActions);
		TranslateNewMenu(ContextMenus);
		TranslateNewMenu(ContextMenusAttrList);
		TranslateStringArray(RegisterTitles);
		TranslateStringArray(AddFileTypeActionStrings);
		TranslateStringArray(AddFileTypeActionStringsProject);
		TranslateStringArray(AddFileTypeActionStringsDisk);
		TranslateStringArray(FileTypeActionProtectionStrings);
		}

	if (NULL == myFileTypesNListTreeClass)
		{
		myFileTypesNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree,
			NULL, 0, DISPATCHER_REF(myFileTypesNListTree));
		}
	if (NULL == myFileTypesNListTreeClass)
		return FALSE;	// Failure

	if (NULL == myNListTreeClass)
		{
		myNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree,
			NULL, 0, DISPATCHER_REF(myNListTree));
		}
	if (NULL == myNListTreeClass)
		return FALSE;	// Failure

	if (NULL == myFileTypesActionsNListClass)
		{
		myFileTypesActionsNListClass = MUI_CreateCustomClass(NULL, MUIC_NList,
			NULL, 0, DISPATCHER_REF(myFileTypesActionsNList));
		}
	if (NULL == myFileTypesActionsNListClass)
		return FALSE;	// Failure

	if (NULL == myNListClass)
		{
		myNListClass = MUI_CreateCustomClass(NULL, MUIC_NList,
			NULL, 0, DISPATCHER_REF(myNList));
		}
	if (NULL == myNListClass)
		return FALSE;	// Failure

	if (NULL == IconobjectClass)
		{
		IconobjectClass = InitIconobjectClass();
		}
	if (NULL == IconobjectClass)
		return FALSE;	// Failure

	if (NULL == DataTypesImageClass)
		DataTypesImageClass = InitDtpicClass();
	d1(KPrintF(__FUNC__ "/%ld: DataTypesImageClass=%08lx\n", __LINE__, DataTypesImageClass));
	if (NULL == DataTypesImageClass)
		return FALSE;	// Failure

	d1(KPrintF("%s/%ld: Success\n", __FUNC__, __LINE__));

	return TRUE;	// Success
}

//----------------------------------------------------------------------------

static ULONG DoDragDrop(Class *cl, Object *obj, Msg msg)
{
	struct FileTypesPrefsInst *inst = NULL;
	struct MUI_NListtree_TreeNode *tnTo = NULL, *tnFrom;

	get(obj, MUIA_NList_PrivateData, (IPTR *)&inst);

	get(obj, MUIA_NListtree_DropTarget, &tnTo);

	tnFrom = MUIV_NListtree_Active_Off;
	get(obj, MUIA_NListtree_Active, &tnFrom);

	d1(kprintf(__FILE__ "/%s/%ld: tnFrom=%08lx  tnTo=%08lx\n", __FUNC__, __LINE__, tnFrom, tnTo));

	if (tnTo && tnFrom && tnTo != tnFrom && MUIV_NListtree_Active_Off != tnFrom)
		{
		struct MUI_NListtree_TreeNode *oldListNode;

		oldListNode = (struct MUI_NListtree_TreeNode *) DoMethod(obj,
			MUIM_NListtree_GetEntry,
			tnFrom,
			MUIV_NListtree_GetEntry_Position_Parent,
			0);

		if (MayPasteOnto(inst, tnTo, tnFrom))
			{
			DoMethod(obj, MUIM_NListtree_Move,
				oldListNode,
				tnFrom,
				tnTo,
				MUIV_NListtree_Move_NewTreeNode_Tail,
				0);
			EntryHasChanged(inst, tnFrom);
			EntryHasChanged(inst, tnTo);
			}
		else
			{
			tnTo = MayPasteBelow(inst, tnTo, tnFrom);
			if (tnTo)
				{
				struct MUI_NListtree_TreeNode *newListNode;

				newListNode = (struct MUI_NListtree_TreeNode *) DoMethod(obj,
					MUIM_NListtree_GetEntry,
					tnTo,
					MUIV_NListtree_GetEntry_Position_Parent,
					0);

				DoMethod(obj, MUIM_NListtree_Move,
					oldListNode,
					tnFrom,
					newListNode,
					tnTo,
					0);
				EntryHasChanged(inst, tnFrom);
				EntryHasChanged(inst, tnTo);
				}
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	if (NULL == inst->fpb_LoadReq)
		{
		inst->fpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest,
			ASLFR_InitialFile, "deficons.prefs",
			ASLFR_Flags1, FRF_DOPATTERNS,
			ASLFR_InitialDrawer, "SYS:Prefs/presets",
			ASLFR_InitialPattern, "#?.(pre|prefs)",
			ASLFR_UserData, inst,
			ASLFR_IntuiMsgFunc, (IPTR)&inst->fpb_Hooks[HOOKNDX_AslIntuiMsg],
			TAG_END);
		}

	if (inst->fpb_LoadReq)
		{
		BOOL Result;
		struct Window *win = NULL;

		get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win);

		//AslRequest(
		Result = MUI_AslRequestTags(inst->fpb_LoadReq,
			ASLFR_Window, win,
			ASLFR_SleepWindow, TRUE,
			ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN),
			TAG_END);

		if (Result)
			{
			BPTR dirLock = Lock(inst->fpb_LoadReq->fr_Drawer, ACCESS_READ);

			if (dirLock)
				{
				BPTR oldDir = CurrentDir(dirLock);

				InitDefIcons(inst, inst->fpb_LoadReq->fr_File);

				CurrentDir(oldDir);
				UnLock(dirLock);
				}
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	if (NULL == inst->fpb_SaveReq)
		{
		inst->fpb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest,
			ASLFR_InitialFile, (IPTR)"deficons.prefs",
			ASLFR_DoSaveMode, TRUE,
			ASLFR_InitialDrawer, (IPTR)"SYS:Prefs/presets",
			ASLFR_UserData, (IPTR)inst,
			ASLFR_IntuiMsgFunc, (IPTR)&inst->fpb_Hooks[HOOKNDX_AslIntuiMsg],
			TAG_END);
		}

	if (inst->fpb_SaveReq)
		{
		BOOL Result;
		struct Window *win = NULL;

		get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win);

		//AslRequest(
		Result = MUI_AslRequestTags(inst->fpb_SaveReq,
			ASLFR_TitleText, (IPTR)GetLocString(MSGID_MENU_PROJECT_SAVEAS),
			ASLFR_Window, (IPTR)win,
			ASLFR_SleepWindow, TRUE,
			TAG_END);

		if (Result)
			{
			BPTR dirLock = Lock(inst->fpb_SaveReq->fr_Drawer, ACCESS_READ);

			if (dirLock)
				{
				BPTR oldDir = CurrentDir(dirLock);

				WriteDefIconsPrefs(inst, inst->fpb_SaveReq->fr_File);

				CurrentDir(oldDir);
				UnLock(dirLock);
				}
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	struct IntuiMessage *iMsg = (struct IntuiMessage *) msg;

	if (IDCMP_REFRESHWINDOW == iMsg->Class)
		{
		DoMethod(inst->fpb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT ShowFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	(void) hook;
	(void) o;
	(void) msg;

	CleanupFoundNodes(inst);

	setstring(inst->fpb_Objects[OBJNDX_String_FindFileType], "");

	set(inst->fpb_Objects[OBJNDX_Menu_Find], MUIA_Menuitem_Enabled, FALSE);
	set(inst->fpb_Objects[OBJNDX_Group_FindFiletype], MUIA_ShowMe, TRUE);

	set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject,
		inst->fpb_Objects[OBJNDX_String_FindFileType]);

}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT HideFindGroupHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	(void) hook;
	(void) o;
	(void) msg;

	CleanupFoundNodes(inst);

	set(inst->fpb_Objects[OBJNDX_Menu_Find], MUIA_Menuitem_Enabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Group_FindFiletype], MUIA_ShowMe, FALSE);
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT IncrementalFindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	CONST_STRPTR FindString = NULL;

	(void) hook;
	(void) o;
	(void) msg;

	get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString);

	if (FindString && strlen(FindString) > 0)
		{
		set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, FALSE);
		set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, FALSE);
                
		IncrementalSearchFileType(inst, FindString, FINDDIR_First);
		}
	else
		{
		CleanupFoundNodes(inst);
		set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE);
		set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, "");
		}
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT IncrementalFindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	CONST_STRPTR FindString = NULL;

	(void) hook;
	(void) o;
	(void) msg;

	get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString);

	if (FindString && strlen(FindString) > 0)
		{
		IncrementalSearchFileType(inst, FindString, FINDDIR_Next);
		}

}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT IncrementalFindPrevFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct FileTypesPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;
	CONST_STRPTR FindString = NULL;

	(void) hook;
	(void) o;
	(void) msg;

	get(inst->fpb_Objects[OBJNDX_String_FindFileType], MUIA_String_Contents, &FindString);

	if (FindString && strlen(FindString) > 0)
		{
		IncrementalSearchFileType(inst, FindString, FINDDIR_Prev);
		}

}

//----------------------------------------------------------------------------

static BOOL IncrementalSearchFileType(struct FileTypesPrefsInst *inst,
	CONST_STRPTR SearchString, enum FindDir dir)
{
	BOOL Found = FALSE;
	BOOL CaseSensitive = FALSE;

	do	{
		struct MUI_NListtree_TreeNode *tn = NULL;
		Object *ActiveObject;

		if (SearchString == NULL || strlen(SearchString) < 1)
			{
			CleanupFoundNodes(inst);
			break;
			}

		get(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, &ActiveObject);

		/*
		 * When searching for next one, fetch selected one first.
		 */

		if (FINDDIR_Next == dir)
			{
			d1(kprintf(__FILE__ "/%s/%ld:  fpb_CurrentFound=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound));

			if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Tail)
				inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_CurrentFound->fdn_Node.ln_Succ;

			if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Tail)
				tn = inst->fpb_CurrentFound->fdn_TreeNode;
			else
				tn = NULL;

			d1(kprintf(__FILE__ "/%s/%ld:  fpb_CurrentFound=%08lx  tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn));
			}
		else if (FINDDIR_Prev == dir)
			{
			d1(kprintf(__FILE__ "/%s/%ld:  fpb_CurrentFound=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound));

			if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Head)
				inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_CurrentFound->fdn_Node.ln_Pred;

			if (inst->fpb_CurrentFound != (struct FoundNode *) &inst->fpb_FoundList.lh_Head)
				tn = inst->fpb_CurrentFound->fdn_TreeNode;
			else
				tn = NULL;

			d1(kprintf(__FILE__ "/%s/%ld:  fpb_CurrentFound=%08lx  tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn));
			}
		else
			{
			ULONG dosearch = TRUE;

			d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__));

			CleanupFoundNodes(inst);

			BuildFindTree(inst,
				inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
				MUIV_NListtree_GetEntry_ListNode_Root,
				SearchString,
				MUIV_NListtree_GetEntry_Position_Head,
				&dosearch, CaseSensitive);

			if (IsListEmpty(&inst->fpb_FoundList))
				{
				d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__));
				tn = NULL;
				inst->fpb_CurrentFound = (struct FoundNode *) &inst->fpb_FoundList.lh_Tail;
				}
			else
				{
				d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__));
				inst->fpb_CurrentFound = (struct FoundNode *) inst->fpb_FoundList.lh_Head;
				tn = inst->fpb_CurrentFound->fdn_TreeNode;
				}
			d1(kprintf(__FILE__ "/%s/%ld:  fpb_CurrentFound=%08lx  tn=%08lx\n", __FUNC__, __LINE__, inst->fpb_CurrentFound, tn));

			snprintf(inst->fpb_FindHitCount, sizeof(inst->fpb_FindHitCount),
				GetLocString(MSGID_FIND_HITCOUNT_FMT), inst->fpb_FoundCount);
			set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, inst->fpb_FindHitCount);
			}

		if (NULL == tn)
			{
			// nothing found
			set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE);
			set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE);
			set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, "");
			break;
			}

		Found = TRUE;
		/*
		 * Open node if needed and select.
		 */
		DoMethod(inst->fpb_Objects[OBJNDX_NListtree_FileTypes],
			MUIM_NListtree_Open,
			MUIV_NListtree_Open_ListNode_Parent,
			tn,
			0);
		set(inst->fpb_Objects[OBJNDX_NListtree_FileTypes], MUIA_NListtree_Active, tn);

		set(inst->fpb_Objects[OBJNDX_WIN_Main], MUIA_Window_ActiveObject, ActiveObject);

		set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled,
			inst->fpb_CurrentFound->fdn_Node.ln_Succ == (struct Node *) &inst->fpb_FoundList.lh_Tail);

		set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled,
			inst->fpb_CurrentFound->fdn_Node.ln_Pred == (struct Node *) &inst->fpb_FoundList.lh_Head);
		} while (0);

	return Found;
}

//----------------------------------------------------------------------------

static void BuildFindTree(struct FileTypesPrefsInst *inst,
	Object *ListTree,
	struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern,
	struct MUI_NListtree_TreeNode *startnode,
	ULONG *dosearch, BOOL CaseSensitive)
{
	ULONG pos;

	for (pos = 0; ; pos++)
		{
		struct MUI_NListtree_TreeNode *tn;

		tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree,
			MUIM_NListtree_GetEntry,
                        list,
			pos,
			MUIV_NListtree_GetEntry_Flag_SameLevel);

		if (NULL == tn)
			break;

		if (tn->tn_Flags & TNF_LIST)
			{
			// Current node is a list
			if (*dosearch)
				{
				// Check if list node matches
				CONST_STRPTR Found;

				Found = FindString(tn->tn_Name, pattern, CaseSensitive);

				if (Found)
					{
					struct FileTypesEntry *fte = (struct FileTypesEntry *) tn->tn_User;

					fte->fte_FindLength = strlen(pattern);
					fte->fte_FindStart = Found - tn->tn_Name;

					DoMethod(ListTree, MUIM_NListtree_Redraw, tn, 0);
					AddFoundNode(inst, ListTree, tn);
					}
				}

			// check children for matches
			BuildFindTree(inst,
				ListTree,
				tn,
				pattern,
				startnode,
				dosearch,
				CaseSensitive);
			}

		if ( tn == startnode )
			*dosearch = TRUE;
		}
}

//----------------------------------------------------------------------------

static CONST_STRPTR FindString(CONST_STRPTR string, CONST_STRPTR pattern, BOOL CaseSensitive)
{
	while (*string)
		{
		size_t i;

		for(i = 0 ; ; i++)
			{
			char c = pattern[i];

			/* End of substring? We got a match... */
			if ('\0' == c)
				{
				return string;
				}

			if (CaseSensitive)
				{
				if (c != string[i])
					break;
				}
			else
				{
				if (ToLower(c) != ToLower(string[i]))
					break;
				}
			}

		string++;
		}

	return NULL;
}

//----------------------------------------------------------------------------

static struct FoundNode *AddFoundNode(struct FileTypesPrefsInst *inst, Object *ListTree, struct MUI_NListtree_TreeNode *tn)
{
	struct FoundNode *fdn;

	d1(kprintf(__FILE__ "/%s/%ld: <%s>\n", __FUNC__, __LINE__, tn->tn_Name));

	fdn = malloc(sizeof(struct FoundNode));
	if (fdn)
		{
		fdn->fdn_ListTree = ListTree;
		fdn->fdn_TreeNode = tn;
		fdn->fdn_Index = ++inst->fpb_FoundCount;

		AddTail(&inst->fpb_FoundList, &fdn->fdn_Node);
		}

	return fdn;
}

//----------------------------------------------------------------------------

void CleanupFoundNodes(struct FileTypesPrefsInst *inst)
{
	struct FoundNode *fdn;

	d1(kprintf(__FILE__ "/%s/%ld:\n", __FUNC__, __LINE__));

	while ( (fdn = (struct FoundNode *) RemHead(&inst->fpb_FoundList)) )
		{
		struct FileTypesEntry *fte = (struct FileTypesEntry *) fdn->fdn_TreeNode->tn_User;

		fte->fte_FindLength = 0;
		fte->fte_FindStart = 0;
		DoMethod(fdn->fdn_ListTree, MUIM_NListtree_Redraw, fdn->fdn_TreeNode, 0);

		free(fdn);
		}

	inst->fpb_FoundCount = 0;

	set(inst->fpb_Objects[OBJNDX_Button_FindNextFileType], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Button_FindPrevFileType], MUIA_Disabled, TRUE);
	set(inst->fpb_Objects[OBJNDX_Button_FindHitCount], MUIA_Text_Contents, "");
}

//----------------------------------------------------------------------------

void UpdateMenuImage(struct FileTypesPrefsInst *inst, ULONG ListTree, struct FileTypesListEntry *fte)
{
	char UnSelIconName[MAX_ATTRVALUE];

	if (fte->fte_ImageObject)
		{
		DoMethod(inst->fpb_Objects[ListTree],
			MUIM_NList_UseImage, NULL, fte->fte_ImageIndex, 0);

		MUI_DisposeObject(fte->fte_ImageObject);
		fte->fte_ImageObject = NULL;
		}

	GetAttributeValueString(FindAttribute(fte, ATTRTYPE_UnselIconName), UnSelIconName, sizeof(UnSelIconName));
	if (strlen(UnSelIconName) > 0)
		{
		fte->fte_ImageObject = DataTypesImageObject,
			MUIA_ScaDtpic_Name, (IPTR) UnSelIconName,
			MUIA_ScaDtpic_FailIfUnavailable, TRUE,
			End; //DataTypesMCCObject

		if (fte->fte_ImageObject)
			{
			if (0 == fte->fte_ImageIndex)
				fte->fte_ImageIndex = ++inst->fpb_MenuImageIndex;

			DoMethod(inst->fpb_Objects[ListTree],
				MUIM_NList_UseImage, fte->fte_ImageObject, fte->fte_ImageIndex, 0);
			}
		}
}

//----------------------------------------------------------------------------

#if !defined(__SASC) && ! defined(__amigaos4__)
// Replacement for SAS/C library functions

#if !defined(__MORPHOS__) && !defined(__AROS__)
static size_t stccpy(char *dest, const char *src, size_t MaxLen)
{
	size_t Count = 0;

	while (*src && MaxLen > 1)
		{
		*dest++ = *src++;
		MaxLen--;
		Count++;
		}
	*dest = '\0';
	Count++;

	return Count;
}
#endif /* __MORPHOS__ */

void exit(int x)
{
   (void) x;
   while (1)
      ;
}

APTR _WBenchMsg;

#endif /* !__SASC && !__amigaos4__ */

//----------------------------------------------------------------------------

#if defined(__AROS__)

#include "aros/symbolsets.h"

ADD2EXPUNGELIB(closePlugin, 0);
ADD2OPENLIB(initPlugin, 0);

#endif

//----------------------------------------------------------------------------


Prefs

...to the top

// PopupMenuPrefs.c
// $Date$
// $Revision$

#ifdef __AROS__
#define MUIMASTER_YES_INLINE_STDARG
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/resident.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <libraries/mui.h>
#include <libraries/iffparse.h>
#include <libraries/pm.h>
#include <devices/clipboard.h>
#include <utility/utility.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <intuition/intuition.h>
#include <intuition/classusr.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <prefs/prefhdr.h>
#include <prefs/popupmenu.h>

#include <clib/alib_protos.h>

#define	__USE_SYSBASE

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/preferences.h>
#include <proto/utility.h>
#include <proto/asl.h>
#ifdef __AROS__
#include <proto/popupmenu.h>
#else
#include <proto/pm.h>
#endif
#include <proto/locale.h>
#include <proto/iffparse.h>
#define	NO_INLINE_STDARG
#include <proto/muimaster.h>

#include <mui/NListview_mcc.h>
#include <mui/NListtree_mcc.h>
#include <mui/Lamp_mcc.h>
#include <scalos/scalosprefsplugin.h>
#include <defs.h>
#include <Year.h>

#include "PopupMenuPrefs.h"
#include "DataTypesMCC.h"
#include "FrameButtonMCC.h"

#define	ScalosPopupMenu_NUMBERS
#define	ScalosPopupMenu_ARRAY
#define	ScalosPopupMenu_CODE
#include STR(SCALOSLOCALE)

#include "plugin.h"

//----------------------------------------------------------------------------

// local data structures

#define CheckMarkHelp(selected, HelpTextID)\
	ImageObject,\
		ImageButtonFrame,\
		MUIA_InputMode        , MUIV_InputMode_Toggle,\
		MUIA_Image_Spec       , MUII_CheckMark,\
		MUIA_Image_FreeVert   , TRUE,\
		MUIA_Selected         , selected,\
		MUIA_Background       , MUII_ButtonBack,\
		MUIA_ShowSelState     , FALSE,\
		MUIA_CycleChain       , TRUE,\
		MUIA_ShortHelp	      , (IPTR)GetLocString(HelpTextID), \
		End

#define IMG(prefix1,PREFIX2) \
  BodychunkObject,\
    MUIA_FixWidth             , PREFIX2##_WIDTH ,\
    MUIA_FixHeight            , PREFIX2##_HEIGHT,\
    MUIA_Bitmap_Width         , PREFIX2##_WIDTH ,\
    MUIA_Bitmap_Height        , PREFIX2##_HEIGHT,\
    MUIA_Bodychunk_Depth      , PREFIX2##_DEPTH ,\
    MUIA_Bodychunk_Body       , (IPTR)  prefix1##_body,\
    MUIA_Bodychunk_Compression, PREFIX2##_COMPRESSION,\
    MUIA_Bodychunk_Masking    , PREFIX2##_MASKING,\
    MUIA_Bitmap_SourceColors  , (IPTR) prefix1##_colors,\
    MUIA_Bitmap_Transparent   , 0,\
  End

#define KeyButtonHelp(name,key,HelpText)\
	TextObject,\
		ButtonFrame,\
		MUIA_CycleChain, TRUE, \
		MUIA_Font, MUIV_Font_Button,\
		MUIA_Text_Contents, (IPTR)(name),\
		MUIA_Text_PreParse, (IPTR)"\33c",\
		MUIA_Text_HiChar  , (IPTR)(key),\
		MUIA_ControlChar  , (IPTR)(key),\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
		MUIA_ShortHelp, (IPTR)HelpText,\
		End

#define FrameButton(objindex, frame, text, selected, raised)\
	VGroup, \
		MUIA_ShowSelState, FALSE, \
		Child, (IPTR)(FrameButtonObject, \
			MUIA_Frame, MUIV_Frame_None, \
			MUIA_Text_Contents, (IPTR)(text),\
			MUIA_Text_PreParse, (IPTR)"\33c", \
			MUIA_Font, MUIV_Font_Button,\
			MUIA_InputMode, MUIV_InputMode_None,\
			MUIA_Background, MUII_ButtonBack,\
			MUIA_ScaFrameButton_FrameType, (frame),\
			MUIA_ScaFrameButton_Selected, (selected), \
			MUIA_ScaFrameButton_Raised, (raised), \
                End), \
		Child, (IPTR)(HGroup, \
			Child, (IPTR)HVSpace, \
			Child, (IPTR)(inst->mpb_Objects[objindex] = ImageObject,\
				ImageButtonFrame,\
				MUIA_InputMode        , MUIV_InputMode_Immediate,\
				MUIA_Image_Spec       , MUII_CheckMark,\
				MUIA_Image_FreeVert   , TRUE,\
				MUIA_Selected         , FALSE,\
				MUIA_Background       , MUII_ButtonBack,\
				MUIA_ShowSelState     , FALSE,\
				MUIA_CycleChain       , TRUE,\
                        End), /* ImageObject */ \
                        Child, (IPTR)HVSpace, \
                End), /* HGroup */ \
        End /* VGroup */

#define	Application_Return_EDIT	0
#define	Application_Return_USE	1001
#define	Application_Return_SAVE	1002

//----------------------------------------------------------------------------

// imported from mempools.lib

extern int _STI_240_InitMemFunctions(void);
extern void _STD_240_TerminateMemFunctions(void);

//----------------------------------------------------------------------------

// local functions

static BOOL OpenLibraries(void);
static void CloseLibraries(void);

DISPATCHERPROTO(PopupMenuPrefs);
static Object *CreatePrefsGroup(struct PopupMenuPrefsInst *inst);

static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg);

static STRPTR GetLocString(ULONG MsgId);
static void TranslateStringArray(STRPTR *stringArray);

static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg);

static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT FrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT SelFrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg);

static LONG ReadPrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR FilenameOld, CONST_STRPTR FilenameNew, BOOL Quiet);
static LONG WritePrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR Filename);
static LONG SaveIcon(struct PopupMenuPrefsInst *inst, CONST_STRPTR IconName);
static Object *CreatePrefsImage(void);
static void InitHooks(struct PopupMenuPrefsInst *inst);
static void SetChangedFlag(struct PopupMenuPrefsInst *inst, BOOL changed);
static void ParseToolTypes(struct PopupMenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt);
static void PrefsToGUI(struct PopupMenuPrefsInst *inst, const struct PopupMenuPrefs *pmPrefs);
static void GUItoPrefs(struct PopupMenuPrefsInst *inst, struct PopupMenuPrefs *pmPrefs);
static IPTR getv(APTR obj, ULONG attr);
static LONG ReadOldPrefsFile(CONST_STRPTR Filename, struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defaultPrefs);
static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew);

#if !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) && !defined(__AROS__)
static size_t stccpy(char *dest, const char *src, size_t MaxLen);
#endif /* !defined(__SASC) && !defined(__MORPHOS__) && !defined(__amigaos4__) */

//----------------------------------------------------------------------------

// local data items

#ifndef __AROS__
struct Library *MUIMasterBase;
T_LOCALEBASE LocaleBase;
struct GfxBase *GfxBase;
struct Library *IconBase;
struct Library *IFFParseBase;
T_UTILITYBASE UtilityBase;
struct IntuitionBase *IntuitionBase;
#endif
struct PopupMenuBase *PopupMenuBase;
struct Library *PreferencesBase;
struct Library *DataTypesBase;

#ifdef __amigaos4__
struct Library *DOSBase;
struct DOSIFace *IDOS;
struct MUIMasterIFace *IMUIMaster;
struct LocaleIFace *ILocale;
struct GraphicsIFace *IGraphics;
struct IconIFace *IIcon;
struct IFFParseIFace *IIFFParse;
struct UtilityIFace *IUtility;
struct IntuitionIFace *IIntuition;
struct PopupMenuIFace *IPopupMenu;
struct DataTypesIFace *IDataTypes;
struct Library *NewlibBase;
struct Interface *INewlib;
struct PreferencesIFace *IPreferences;
#endif

#ifdef __AROS__
struct DosLibrary *DOSBase;
#endif

#include "PopupMenuPrefsImage.h"

static ULONG SIgnature = 0x4711;

static ULONG MajorVersion, MinorVersion;

static const struct MUIP_ScalosPrefs_MCCList RequiredMccList[] =
	{
	{ MUIC_Lamp, 11, 1 },
	{ MUIC_NListtree, 18, 18 },
	{ MUIC_NListview, 18, 0 },
	{ NULL, 0, 0 }
	};

static const struct Hook PopupMenuPrefsHooks[] =
{
	{ { NULL, NULL }, HOOKFUNC_DEF(ImagePopAslFileStartHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(ResetToDefaultsHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(OpenHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(LastSavedHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(RestoreHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SaveAsHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(AboutHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SettingsChangedHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(AslIntuiMsgHookFunc), NULL },

	{ { NULL, NULL }, HOOKFUNC_DEF(FrameTypeSelectHookFunc), NULL },
	{ { NULL, NULL }, HOOKFUNC_DEF(SelFrameTypeSelectHookFunc), NULL },
};

static struct Locale *PopupMenuPrefsLocale;
static struct Catalog *PopupMenuPrefsCatalog;

struct MUI_CustomClass *PopupMenuPrefsClass;
struct MUI_CustomClass *FrameButtonClass;
struct MUI_CustomClass *DataTypesImageClass;

static const LONG StopChunkList[] =
	{
	ID_PREF, ID_PMNU,
	};

static STRPTR PrefsPageNames[] =
	{
	(STRPTR) MSGID_PREFSPAGES_MISC,
	(STRPTR) MSGID_PREFSPAGES_BORDERS,
	(STRPTR) MSGID_PREFSPAGES_SPACING,
	(STRPTR) MSGID_PREFSPAGES_TEXT,
	(STRPTR) MSGID_PREFSPAGES_TRANSPARENCY,
	NULL
	};

static STRPTR AnimationNames[] =
	{
	(STRPTR) MSGID_ANIMATION_NONE,
	(STRPTR) MSGID_ANIMATION_ZOOM,
	(STRPTR) MSGID_ANIMATION_FADE,
	(STRPTR) MSGID_ANIMATION_EXPLODE,
	NULL
	};

static const struct PopupMenuPrefs DefaultPMPrefs =
	{
	1,			/* pmp_Flags		*/
	0,			/* pmp_SubMenuDelay	*/
	PMP_ANIM_NONE,		/* pmp_Animation	*/
	PMP_PD_SCREENBAR,	/* pmp_PulldownPos	*/
	FALSE,			/* pmp_Sticky		*/
	0,			/* pmp_MenuBorder	*/
	0,			/* pmp_SelItemBorder	*/
	0,			/* pmp_SeparatorBar	*/
	0,			/* pmp_MenuTitles	*/
	0,			/* pmp_MenuItems	*/
	2,			/* pmp_XOffset		*/
	2,			/* pmp_YOffset		*/
	2,			/* pmp_XSpace		*/
	2,			/* pmp_YSpace		*/
	2,			/* pmp_Intermediate	*/
	0,			/* pmp_TextDisplace	*/
	0,			/* pmp_TransparencyBlur	*/
	};

//----------------------------------------------------------------------------

BOOL closePlugin(struct PluginBase *PluginBase)
{
	d1(kprintf("%s/%s/%ld: start\n", __FILE__, __FUNC__, __LINE__));

	if (DataTypesImageClass)
		{
		CleanupDtpicClass(DataTypesImageClass);
		DataTypesImageClass = NULL;
		}
	if (FrameButtonClass)
		{
		CleanupFrameButtonClass(FrameButtonClass);
		FrameButtonClass = NULL;
		}
	if (PopupMenuPrefsCatalog)
		{
		CloseCatalog(PopupMenuPrefsCatalog);
		PopupMenuPrefsCatalog = NULL;
		}
	if (PopupMenuPrefsLocale)
		{
		CloseLocale(PopupMenuPrefsLocale);
		PopupMenuPrefsLocale = NULL;
		}

	if (PopupMenuPrefsClass)
		{
		MUI_DeleteCustomClass(PopupMenuPrefsClass);
		PopupMenuPrefsClass = NULL;
		}

	CloseLibraries();

	d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

#if !defined(__amigaos4__) && !defined(__AROS__)
	_STD_240_TerminateMemFunctions();
#endif

	d1(kprintf("%s/%s/%ld: endt\n", __FILE__, __FUNC__, __LINE__));
	return TRUE;
}


LIBFUNC_P2(IPTR, LIBSCAGetPrefsInfo,
	D0, ULONG, which,
	A6, struct PluginBase *, PluginBase, 5);
{
	IPTR result;

	d1(kprintf("%s/%s/%ld: which=%ld\n", __FILE__, __FUNC__, __LINE__, which));

	(void) PluginBase;

	switch(which)
		{
	case SCAPREFSINFO_GetClass:
		result = (IPTR) PopupMenuPrefsClass;
		break;

	case SCAPREFSINFO_GetTitle:
		result = (IPTR) GetLocString(MSGID_PLUGIN_LIST_TITLE);
		break;

	case SCAPREFSINFO_GetTitleImage:
		result = (IPTR) CreatePrefsImage();
		break;

	default:
		result = (IPTR) NULL;
		break;
		}

	d1(kprintf("%s/%s/%ld: result=%lu\n", __FILE__, __FUNC__, __LINE__, result));

	return result;
}
LIBFUNC_END

//----------------------------------------------------------------------------

DISPATCHER(PopupMenuPrefs)
{
	struct PopupMenuPrefsInst *inst;
	IPTR result = 0;

	switch(msg->MethodID)
		{
	case OM_NEW:
		obj = (Object *) DoSuperMethodA(cl, obj, msg);
		d1(kprintf("%s/%s/%ld: OM_NEW obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj));
		if (obj)
			{
			Object *prefsobject;
			struct opSet *ops = (struct opSet *) msg;

			inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);

			memset(inst, 0, sizeof(struct PopupMenuPrefsInst));

			inst->mpb_Changed = FALSE;
			inst->mpb_PMPrefs = DefaultPMPrefs;
			inst->mpb_WBScreen = LockPubScreen("Workbench");

			InitHooks(inst);

			inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, TRUE, ops->ops_AttrList);
			inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (IPTR) "", ops->ops_AttrList);
			inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, (IPTR) NULL, ops->ops_AttrList);
			inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, (IPTR) NULL, ops->ops_AttrList);

			prefsobject = CreatePrefsGroup(inst);
			d1(kprintf("%s/%s/%ld: prefsobject=%08lx\n", __FILE__, __FUNC__, __LINE__, prefsobject));
			if (prefsobject)
				{
				DoMethod(obj, OM_ADDMEMBER, prefsobject);

				result = (IPTR) obj;
				}
			else
				{
				CoerceMethod(cl, obj, OM_DISPOSE);
				}
			}
		break;

	case OM_DISPOSE:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		d1(kprintf("%s/%s/%ld: OM_DISPOSE obj=%08lx\n", __FILE__, __FUNC__, __LINE__, obj));
		if (inst->mpb_WBScreen)
			{
			UnlockPubScreen(NULL, inst->mpb_WBScreen);
			inst->mpb_WBScreen = NULL;
			}
		if (inst->mpb_SaveReq)
			{
			MUI_FreeAslRequest(inst->mpb_SaveReq);
			inst->mpb_SaveReq = NULL;
			}
		if (inst->mpb_LoadReq)
			{
			MUI_FreeAslRequest(inst->mpb_LoadReq);
			inst->mpb_LoadReq = NULL;
			}
		return DoSuperMethodA(cl, obj, msg);
		break;

	case OM_SET:
		{
		struct opSet *ops = (struct opSet *) msg;

		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);

		inst->mpb_fCreateIcons = GetTagData(MUIA_ScalosPrefs_CreateIcons, inst->mpb_fCreateIcons, ops->ops_AttrList);
		inst->mpb_ProgramName = (CONST_STRPTR) GetTagData(MUIA_ScalosPrefs_ProgramName, (IPTR) inst->mpb_ProgramName, ops->ops_AttrList);
		inst->mpb_Objects[OBJNDX_WIN_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_MainWindow, 
			(IPTR) inst->mpb_Objects[OBJNDX_WIN_Main], ops->ops_AttrList);
		inst->mpb_Objects[OBJNDX_APP_Main] = (APTR) GetTagData(MUIA_ScalosPrefs_Application, 
			(IPTR) inst->mpb_Objects[OBJNDX_APP_Main], ops->ops_AttrList);

		return DoSuperMethodA(cl, obj, msg);
		}
		break;

	case OM_GET:
		{
		struct opGet *opg = (struct opGet *) msg;

		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		switch (opg->opg_AttrID)
			{
		case MUIA_ScalosPrefs_CreateIcons:
			*opg->opg_Storage = inst->mpb_fCreateIcons;
			result = 0;
			break;
		default:
			result = DoSuperMethodA(cl, obj, msg);
			}
		}
		break;

	case MUIM_ScalosPrefs_ParseToolTypes:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		d1(kprintf(__FILE__ "/%s/%ld: before ParseToolTypes\n", __FUNC__, __LINE__));
		ParseToolTypes(inst, (struct MUIP_ScalosPrefs_ParseToolTypes *) msg);
		d1(kprintf(__FILE__ "/%s/%ld: after ParseToolTypes\n", __FUNC__, __LINE__));
		 break;

	case MUIM_ScalosPrefs_LoadConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		ReadPrefsFile(inst, PMP_PATH_OLD, PMP_PATH_NEW, TRUE);
		PrefsToGUI(inst, &inst->mpb_PMPrefs);
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_UseConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		WritePrefsFile(inst, PMP_PATH_NEW);
		PM_ReloadPrefs();
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_UseConfigIfChanged:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		if (inst->mpb_Changed)
			{
			WritePrefsFile(inst, PMP_PATH_NEW);
			PM_ReloadPrefs();
			SetChangedFlag(inst, FALSE);
			}
		break;

	case MUIM_ScalosPrefs_SaveConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		WritePrefsFile(inst, PMP_S_PATH_NEW);
		WritePrefsFile(inst, PMP_PATH_NEW);
		PM_ReloadPrefs();
		SetChangedFlag(inst, FALSE);
		break;

	case MUIM_ScalosPrefs_SaveConfigIfChanged:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		if (inst->mpb_Changed)
			{
			WritePrefsFile(inst, PMP_S_PATH_NEW);
			WritePrefsFile(inst, PMP_PATH_NEW);
			PM_ReloadPrefs();
			SetChangedFlag(inst, FALSE);
			}
		break;

	case MUIM_ScalosPrefs_RestoreConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Restore], 0);
		break;

	case MUIM_ScalosPrefs_ResetToDefaults:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_ResetToDefaults], 0);
		break;

	case MUIM_ScalosPrefs_LastSavedConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_LastSaved], 0);
		break;

	case MUIM_ScalosPrefs_PageActive:
		{
		struct MUIP_ScalosPrefs_PageActive *spa = (struct MUIP_ScalosPrefs_PageActive *) msg;

		d1(kprintf("%s/%s/%ld: MUIM_ScalosPrefs_PageActive  isActive=%08lx\n", __FILE__, __FUNC__, __LINE__, spa->isActive));
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		inst->mpb_PageIsActive = spa->isActive;
		}
		break;

	case MUIM_ScalosPrefs_OpenConfig:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_Open], 0);
		break;

	case MUIM_ScalosPrefs_SaveConfigAs:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SaveAs], 0);
		break;

	case MUIM_ScalosPrefs_About:
		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		DoMethod(obj, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_About], 0);
		break;

	case MUIM_ScalosPrefs_LoadNamedConfig:
		{
		struct MUIP_ScalosPrefs_LoadNamedConfig *lnc = (struct MUIP_ScalosPrefs_LoadNamedConfig *) msg;

		inst = (struct PopupMenuPrefsInst *) INST_DATA(cl, obj);
		ReadPrefsFile(inst, "", lnc->ConfigFileName, FALSE);
		PrefsToGUI(inst, &inst->mpb_PMPrefs);
		}
		break;

	case MUIM_ScalosPrefs_CreateSubWindows:
		result = (IPTR) NULL;
		break;

	case MUIM_ScalosPrefs_GetListOfMCCs:
		result = (IPTR) RequiredMccList;
		break;

	default:
		d1(kprintf("%s/%s/%ld: MethodID=%08lx\n", __FILE__, __FUNC__, __LINE__, msg->MethodID));
		result = DoSuperMethodA(cl, obj, msg);
		break;
		}

	return result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

static Object *CreatePrefsGroup(struct PopupMenuPrefsInst *inst)
{
	d1(kprintf("%s/%s/%ld:  inst=%08lx\n", __FILE__, __FUNC__, __LINE__, inst));

	inst->mpb_Objects[OBJNDX_Group_Main] = VGroup,
		MUIA_Background, MUII_PageBack,

		Child, (IPTR)(RegisterObject,
			MUIA_Register_Titles, (IPTR)PrefsPageNames,
			MUIA_CycleChain, TRUE,

			//------ Misc. ----------------------
			Child, (IPTR)(VGroup,
				MUIA_Background, MUII_RegisterBack,
				MUIA_FrameTitle, (IPTR) GetLocString(MSGID_MISCPAGE_TITLE),

				Child, (IPTR)HVSpace,

				Child, (IPTR)(HGroup,
					Child, (IPTR)Label1(GetLocString(MSGID_MISCPAGE_DELAY_SUBMENUS)),
					Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus] = SliderObject,
						MUIA_CycleChain, TRUE,
						MUIA_Slider_Min, 0,
						MUIA_Slider_Max, 10,
						MUIA_Slider_Horiz, TRUE,
						MUIA_Numeric_Value, 0,
                                        End), //SliderObject
					MUIA_ShortHelp, (IPTR) GetLocString(MSGID_MISCPAGE_DELAY_SUBMENUS_SHORTHELP),
                                End), //HGroup

				Child, (IPTR)HVSpace,

				Child, (IPTR)(VGroup,
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_MISCPAGE_ANIMATION),

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)Label1(GetLocString(MSGID_MISCPAGE_ANIMATION_TYPE)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Cycle_AnimationType] = CycleObject,
							MUIA_CycleChain, TRUE,
							MUIA_Cycle_Entries, (IPTR)AnimationNames,
							MUIA_ShortHelp, (IPTR) GetLocString(MSGID_MISCPAGE_ANIMATION_TYPE_SHORTHELP),
                                                End), //Cycle
                                        End), //ColGroup
                                End), //VGroup

				Child, (IPTR)HVSpace,


				Child, (IPTR)HVSpace,

				Child, (IPTR)(ColGroup(4),
					GroupFrame,
					MUIA_Background, MUII_GroupBack,

					Child, (IPTR)HVSpace,

					Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_MENUSHADOWS_SHORTHELP)),
					Child, (IPTR)LLabel1(GetLocString(MSGID_MISCPAGE_MENUSHADOWS)),

					Child, (IPTR)HVSpace,
					Child, (IPTR)HVSpace,

					Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_RealShadows] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_REALSHADOWS_SHORTHELP)),
					Child, (IPTR)LLabel1(GetLocString(MSGID_MISCPAGE_REALSHADOWS)),

					Child, (IPTR)HVSpace,
					Child, (IPTR)HVSpace,

					Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_Sticky] = CheckMarkHelp(TRUE, MSGID_MISCPAGE_STICKY_SHORTHELP)),
					Child, (IPTR)LLabel1(GetLocString(MSGID_MISCPAGE_STICKY)),

					Child, (IPTR)HVSpace,
                                End), //ColGroup

				Child, (IPTR)HVSpace,
                        End), //VGroup

			//------ Borders ----------------------
			Child, (IPTR)(VGroup,
				MUIA_Background, MUII_RegisterBack,
				MUIA_FrameTitle, (IPTR) GetLocString(MSGID_BORDERSPAGE_TITLE),

				Child, (IPTR)HVSpace,

				Child, (IPTR)(HGroup,
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_BORDERSPAGE_MENUBORDER),

					Child, (IPTR)FrameButton(OBJNDX_Button_FrameThin, PMP_MENUBORDER_THIN, "", FALSE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_FrameMM, PMP_MENUBORDER_MM, "", FALSE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_FrameThick, PMP_MENUBORDER_THICK, "", FALSE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_FrameRidge, PMP_MENUBORDER_RIDGE, "", FALSE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_FrameDropBox, PMP_MENUBORDER_DROPBOX, "", FALSE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_FrameOldStyle, PMP_MENUBORDER_OLDSTYLE, "", FALSE, FALSE),
                                End), //HGroup

				Child, (IPTR)HVSpace,

				Child, (IPTR)(HGroup,
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_BORDERSPAGE_SELECTEDITEM),

					Child, (IPTR)FrameButton(OBJNDX_Button_Normal, PMP_MENUBORDER_NONE, GetLocString(MSGID_BORDERSPAGE_NORMAL), TRUE, FALSE),
					Child, (IPTR)FrameButton(OBJNDX_Button_Raised, PMP_MENUBORDER_THIN, GetLocString(MSGID_BORDERSPAGE_RAISED), TRUE, TRUE),
					Child, (IPTR)FrameButton(OBJNDX_Button_Recessed, PMP_MENUBORDER_THIN, GetLocString(MSGID_BORDERSPAGE_RECESSED), TRUE, FALSE),
                                End), //HGroup

				Child, (IPTR)HVSpace,

				Child, (IPTR)(HGroup,
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_BORDERSPAGE_SEPARATORS),

					Child, (IPTR)HVSpace,

					Child, (IPTR)(ColGroup(4),
						Child, (IPTR)(HGroup,
							Child, (IPTR)HVSpace,
							Child, (IPTR)(IMG(NewStyle, NEWSTYLE)),
							Child, (IPTR)HVSpace,
                                                End), //HGroup
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_NewLook] = ImageObject,
							ImageButtonFrame,
							MUIA_InputMode, MUIV_InputMode_Toggle,
							MUIA_Image_Spec, MUII_CheckMark,
							MUIA_Image_FreeVert, TRUE,
							MUIA_Background, MUII_ButtonBack,
							MUIA_ShowSelState, FALSE,
							MUIA_CycleChain, TRUE,
                                                End), //ImageObject
						Child, (IPTR)CLabel(GetLocString(MSGID_BORDERSPAGE_NEW_LOOK)),
						Child, (IPTR)HVSpace,

						Child, (IPTR)(HGroup,
							Child, (IPTR)HVSpace,
							Child, (IPTR)(IMG(OldStyle, OLDSTYLE)),
							Child, (IPTR)HVSpace,
                                                End), //HGroup
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_OldLook] = ImageObject,
							ImageButtonFrame,
							MUIA_InputMode, MUIV_InputMode_Toggle,
							MUIA_Image_Spec, MUII_CheckMark,
							MUIA_Image_FreeVert, TRUE,
							MUIA_Background, MUII_ButtonBack,
							MUIA_ShowSelState, FALSE,
							MUIA_CycleChain, TRUE,
                                                End), //ImageObject
						Child, (IPTR)CLabel(GetLocString(MSGID_BORDERSPAGE_OLD_LOOK)),
						Child, (IPTR)HVSpace,
                                        End), //ColGroup

					Child, (IPTR)HVSpace,
                                End), //HGroup

				Child, (IPTR)HVSpace,
                        End), //VGroup

			//------ Spacing ----------------------
			Child, (IPTR)(VGroup,
				MUIA_Background, MUII_RegisterBack,
				MUIA_FrameTitle, (IPTR) GetLocString(MSGID_SPACINGPAGE_TITLE),

				Child, (IPTR)HVSpace,
				
				Child, (IPTR)(ColGroup(5),
					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_HORIZONTAL_SPACE)),
						Child, (IPTR)(IMG(Horizontal_Space, HORIZONTAL_SPACE)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, 0,
							MUIA_Numeric_Max, 10,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 2,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_VERTICAL_SPACE)),
						Child, (IPTR)(IMG(Vertical_Space, VERTICAL_SPACE)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, 0,
							MUIA_Numeric_Max, 10,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 1,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,
					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_HORIZONTAL)),
						Child, (IPTR)(IMG(Horizontal, HORIZONTAL)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_Horizontal] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, 0,
							MUIA_Numeric_Max, 10,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 0,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_VERTICAL_OFFSET)),
						Child, (IPTR)(IMG(Vertical_Offset, VERTICAL_OFFSET)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_VerticalOffset] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, 0,
							MUIA_Numeric_Max, 10,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 0,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,
					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_INTERMEDIATE_SPACING)),
						Child, (IPTR)(IMG(Intermediate_Spacing, INTERMEDIATE_SPACING)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, 0,
							MUIA_Numeric_Max, 10,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 0,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,

					Child, (IPTR)(VGroup,
						GroupFrame,
						MUIA_Background, MUII_GroupBack,
						Child, (IPTR)HVSpace,
						Child, (IPTR)CLabel(GetLocString(MSGID_SPACINGPAGE_TEXT_DISPLACEMENT)),
						Child, (IPTR)(IMG(Text_Displacement, TEXT_DISPLACEMENT)),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_TextDisplacement] = SliderObject,
							MUIA_CycleChain, TRUE,
							MUIA_Numeric_Min, -5,
							MUIA_Numeric_Max, 5,
							MUIA_Slider_Horiz, TRUE,
							MUIA_Numeric_Value, 0,
                                                End), //SliderObject
						Child, (IPTR)HVSpace,
                                        End), //VGroup

					Child, (IPTR)HVSpace,
                                End), //ColGroup

				Child, (IPTR)HVSpace,
                        End), //VGroup

			//------ Text ----------------------
			Child, (IPTR)(VGroup,
				MUIA_Background, MUII_RegisterBack,
				MUIA_FrameTitle, (IPTR) GetLocString(MSGID_TEXTPAGE_TITLE),

				Child, (IPTR)HVSpace,

				Child, (IPTR)(ColGroup(4),
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_TEXTPAGE_MENU_TITLES),

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_ITALIC_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_ITALIC)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_UNDERLINED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_UNDERLINED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_BOLD_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_BOLD)),

                                        End), //ColGroup

					Child, (IPTR)HVSpace,

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_SHADOWED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_SHADOWED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_OUTLINED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_OUTLINED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUTITLES_EMBOSSED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUTITLES_EMBOSSED)),

                                        End), //ColGroup

					Child, (IPTR)HVSpace,

                                End), //ColGroup

				Child, (IPTR)(ColGroup(4),
					GroupFrame,
					MUIA_Background, MUII_GroupBack,
					MUIA_FrameTitle, (IPTR) GetLocString(MSGID_TEXTPAGE_MENU_ITEMS),

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_ITALIC_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_ITALIC)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_UNDERLINED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_UNDERLINED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_BOLD_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_BOLD)),

                                        End), //ColGroup

					Child, (IPTR)HVSpace,

					Child, (IPTR)(ColGroup(2),
						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_SHADOWED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_SHADOWED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_OUTLINED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_OUTLINED)),

						Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed] = CheckMarkHelp(TRUE, MSGID_TEXTPAGE_MENUITEMS_EMBOSSED_SHORTHELP)),
						Child, (IPTR)LLabel1(GetLocString(MSGID_TEXTPAGE_MENUITEMS_EMBOSSED)),

                                        End), //ColGroup

					Child, (IPTR)HVSpace,

                                End), //ColGroup

				Child, (IPTR)HVSpace,

                        End), //VGroup

			//------ Transparency ----------------------
			Child, (IPTR)(VGroup,
				MUIA_Background, MUII_RegisterBack,
				MUIA_FrameTitle, (IPTR) GetLocString(MSGID_TRANSPARENCYPAGE_TITLE),

				Child, (IPTR)HVSpace,

				Child, (IPTR)(ColGroup(4),
					GroupFrame,
					MUIA_Background, MUII_GroupBack,

					Child, (IPTR)HVSpace,

					Child, (IPTR)(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable] = CheckMarkHelp(TRUE, MSGID_TRANSPARENCYPAGE_ENABLE_SHORTHELP)),
					Child, (IPTR)LLabel1(GetLocString(MSGID_TRANSPARENCYPAGE_ENABLE)),

					Child, (IPTR)HVSpace,
                                End), //ColGroup

				Child, (IPTR)HVSpace,

				Child, (IPTR)(inst->mpb_Objects[OBJNDX_Group_Transp_Blur] = ColGroup(2),
					Child, (IPTR)Label1(GetLocString(MSGID_TRANSPARENCYPAGE_BLUR)),
					Child, (IPTR)(inst->mpb_Objects[OBJNDX_Slider_Transp_Blur] = SliderObject,
						MUIA_CycleChain, TRUE,
						MUIA_Numeric_Min, 0,
						MUIA_Numeric_Max, 100,
						MUIA_Slider_Horiz, TRUE,
						MUIA_Numeric_Value, -16,
						MUIA_Numeric_Format, (IPTR) GetLocString(MSGID_TRANSPARENCYPAGE_BLUR_NUMERIC_FORMAT),
						MUIA_ShortHelp, (IPTR) GetLocString(MSGID_TRANSPARENCYPAGE_BLUR_SHORTHELP),
                                        End), //SliderObject
                                End), //ColGroup

				Child, (IPTR)HVSpace,

                        End), //VGroup

                End), //RegisterObject

        End; //VGroup

	if (NULL == inst->mpb_Objects[OBJNDX_Group_Main])
		return NULL;

	PrefsToGUI(inst, &inst->mpb_PMPrefs);

	DoMethod(inst->mpb_Objects[OBJNDX_Group_Main], MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
		inst->mpb_Objects[OBJNDX_Group_Main], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_AppMessage], MUIV_TriggerValue);

	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameThin], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);

	// Mutual exclusion for frame type buttons
	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameMM], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameThick], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameRidge], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameDropBox], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_FrameSelected], MUIV_TriggerValue);

	// Mutual exclusion for selected frame type buttons
	DoMethod(inst->mpb_Objects[OBJNDX_Button_Normal], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_Normal], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_Raised], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_Raised], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue);
	DoMethod(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_Button_Recessed], 3, MUIM_CallHook, &inst->mpb_Hooks[HOOKNDX_SelFrameSelected], MUIV_TriggerValue);

	// Mutual exclusion for separator style buttons
	DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_NewLook], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_CheckMark_OldLook], 3, MUIM_Set, MUIA_Selected, FALSE);
	DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIM_Notify, MUIA_Selected, TRUE,
		inst->mpb_Objects[OBJNDX_CheckMark_NewLook], 3, MUIM_Set, MUIA_Selected, FALSE);

	// Disable transparency settings if transparency is disabled
	DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
		inst->mpb_Objects[OBJNDX_Group_Transp_Blur], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue);

	// Disable "real shadows" settings if shadow is disabled
	DoMethod(inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows], MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
		inst->mpb_Objects[OBJNDX_CheckMark_RealShadows], 3, MUIM_Set, MUIA_Disabled, MUIV_NotTriggerValue);

	d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));
	d1(kprintf("%s/%s/%ld:  LocaleBase=%08lx  IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase));

	return inst->mpb_Objects[OBJNDX_Group_Main];
}


static BOOL OpenLibraries(void)
{
	d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

	DOSBase = (APTR) OpenLibrary( "dos.library", 39 );
	if (NULL == DOSBase)
		return FALSE;
#ifdef __amigaos4__
	IDOS = (struct DOSIFace *)GetInterface((struct Library *)DOSBase, "main", 1, NULL);
	if (NULL == IDOS)
		return FALSE;
#endif

	IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
	if (NULL == IntuitionBase)
		return FALSE;
#ifdef __amigaos4__
	IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
	if (NULL == IIntuition)
		return FALSE;
#endif

	MUIMasterBase = OpenLibrary("zune.library", 0);
	if (NULL == MUIMasterBase)
		MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1);
	if (NULL == MUIMasterBase)
		return FALSE;
#ifdef __amigaos4__
	IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL);
	if (NULL == IMUIMaster)
		return FALSE;
#endif

	IFFParseBase = OpenLibrary("iffparse.library", 36);
	if (NULL == IFFParseBase)
		return FALSE;
#ifdef __amigaos4__
	IIFFParse = (struct IFFParseIFace *)GetInterface((struct Library *)IFFParseBase, "main", 1, NULL);
	if (NULL == IIFFParse)
		return FALSE;
#endif

	IconBase = OpenLibrary("icon.library", 0);
	if (NULL == IconBase)
		return FALSE;
#ifdef __amigaos4__
	IIcon = (struct IconIFace *)GetInterface((struct Library *)IconBase, "main", 1, NULL);
	if (NULL == IIcon)
		return FALSE;
#endif

	GfxBase = (struct GfxBase *) OpenLibrary(GRAPHICSNAME, 39);
	if (NULL == GfxBase)
		return FALSE;
#ifdef __amigaos4__
	IGraphics = (struct GraphicsIFace *)GetInterface((struct Library *)GfxBase, "main", 1, NULL);
	if (NULL == IGraphics)
		return FALSE;
#endif

	UtilityBase = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39);
	if (NULL == UtilityBase)
		return FALSE;
#ifdef __amigaos4__
	IUtility = (struct UtilityIFace *)GetInterface((struct Library *)UtilityBase, "main", 1, NULL);
	if (NULL == IUtility)
		return FALSE;
#endif

	PreferencesBase	= OpenLibrary("preferences.library", 39);
	if (NULL == PreferencesBase)
		return FALSE;
	d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld  PreferencesBase=%08lx\n", __LINE__, PreferencesBase));
#ifdef __amigaos4__
	IPreferences = (struct PreferencesIFace *) GetInterface(PreferencesBase, "main", 1, NULL);
	if (NULL == IPreferences)
		return FALSE;
#endif

	PopupMenuBase = (struct PopupMenuBase *) OpenLibrary(POPUPMENU_NAME, POPUPMENU_VERSION);
	if (NULL == PopupMenuBase)
		return FALSE;

	DataTypesBase = OpenLibrary("datatypes.library", 39);
	if (NULL == DataTypesBase)
		return FALSE;
#ifdef __amigaos4__
	IDataTypes = (struct DataTypesIFace *)GetInterface((struct Library *)DataTypesBase, "main", 1, NULL);
	if (NULL == IDataTypes)
		return FALSE;
#endif

#ifdef __amigaos4__
	NewlibBase = OpenLibrary("newlib.library", 0);
	if (NULL == NewlibBase)
		return FALSE;
	INewlib = GetInterface(NewlibBase, "main", 1, NULL);
	if (NULL == INewlib)
		return FALSE;
#endif

	// LocaleBase is optional
	LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39);
#ifdef __amigaos4__
	if (LocaleBase)
		ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL);
#endif

#ifdef __amigaos4__
	if (PopupMenuBase)
		IPopupMenu = (struct PopupMenuIFace *)GetInterface((struct Library *)PopupMenuBase, "main", 1, NULL);
#endif

	d1(kprintf("%s/%s/%ld:  LocaleBase=%08lx  IFFParseBase=%08lx\n", __FILE__, __FUNC__, __LINE__, LocaleBase, IFFParseBase));

	return TRUE;
}


static void CloseLibraries(void)
{
	d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

#ifdef __amigaos4__
	if (INewlib)
		{
		DropInterface(INewlib);
		INewlib = NULL;
		}
	if (NewlibBase)
		{
		CloseLibrary(NewlibBase);
		NewlibBase = NULL;
		}
	if (IDOS)
		{
		DropInterface((struct Interface *)IDOS);
		IDOS = NULL;
		}
#endif
	if (DOSBase)
		{
		CloseLibrary((struct Library *) DOSBase);
		DOSBase = NULL;
		}
#ifdef __amigaos4__
	if (PreferencesBase)
		{
#ifdef __amigaos4__
		DropInterface((struct Interface *)IPreferences);
#endif
		CloseLibrary(PreferencesBase);
		}
	if (IDataTypes)
		{
		DropInterface((struct Interface *)IDataTypes);
		IDataTypes = NULL;
		}
#endif
	if (DataTypesBase)
		{
		CloseLibrary(DataTypesBase);
		DataTypesBase = NULL;
		}
#ifdef __amigaos4__
	if (ILocale)
		{
		DropInterface((struct Interface *)ILocale);
		ILocale = NULL;
		}
#endif
	if (LocaleBase)
		{
		CloseLibrary((struct Library *) LocaleBase);
		LocaleBase = NULL;
		}
#ifdef __amigaos4__
	if (IUtility)
		{
		DropInterface((struct Interface *)IUtility);
		IUtility = NULL;
		}
#endif
	if (UtilityBase)
		{
		CloseLibrary((struct Library *) UtilityBase);
		UtilityBase = NULL;
		}
#ifdef __amigaos4__
	if (IGraphics)
		{
		DropInterface((struct Interface *)IGraphics);
		IGraphics = NULL;
		}
#endif
	if (GfxBase)
		{
		CloseLibrary((struct Library *) GfxBase);
		GfxBase = NULL;
		}
#ifdef __amigaos4__
	if (IIcon)
		{
		DropInterface((struct Interface *)IIcon);
		IIcon = NULL;
		}
#endif
	if (IconBase)
		{
		CloseLibrary(IconBase);
		IconBase = NULL;
		}
#ifdef __amigaos4__
	if (IIFFParse)
		{
		DropInterface((struct Interface *)IIFFParse);
		IIFFParse = NULL;
		}
#endif
	if (IFFParseBase)
		{
		CloseLibrary(IFFParseBase);
		IFFParseBase = NULL;
		}
#ifdef __amigaos4__
	if (IMUIMaster)
		{
		DropInterface((struct Interface *)IMUIMaster);
		IMUIMaster = NULL;
		}
#endif
	if (MUIMasterBase)
		{
		CloseLibrary(MUIMasterBase);
		MUIMasterBase = NULL;
		}
#ifdef __amigaos4__
	if (IIntuition)
		{
		DropInterface((struct Interface *)IIntuition);
		IIntuition = NULL;
		}
#endif
	if (IntuitionBase)
		{
		CloseLibrary((struct Library *) IntuitionBase);
		IntuitionBase = NULL;
		}
#ifdef __amigaos4__
	if (IPopupMenu)
		{
		DropInterface((struct Interface *)IPopupMenu);
		IPopupMenu = NULL;
		}
#endif
	if (PopupMenuBase)
		{
		CloseLibrary((struct Library *) PopupMenuBase);
		PopupMenuBase = NULL;
		}
}

//----------------------------------------------------------------------------

static SAVEDS(ULONG) INTERRUPT ImagePopAslFileStartHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct TagItem *TagList = (struct TagItem *) msg;
//	  struct PopupMenuPrefsInst *inst = (struct FileTypesPrefsInst *) hook->h_Data;

	d1(KPrintF("%s/%ld: inst=%08lx\n", __FUNC__, __LINE__, inst));

	while (TAG_END != TagList->ti_Tag)
		TagList++;

	TagList->ti_Tag = ASLFR_DrawersOnly;
	TagList->ti_Data = FALSE;
	TagList++;

//	  TagList->ti_Tag = ASLFR_InitialFile;
//	  TagList->ti_Data = (IPTR) inst->fpb_FileName;
//	  TagList++;

	TagList->ti_Tag = ASLFR_InitialDrawer;
	TagList->ti_Data = (IPTR) "THEME:FileTypes/";
	TagList++;

	TagList->ti_Tag = TAG_END;

	return TRUE;
}

//----------------------------------------------------------------------------

static STRPTR GetLocString(ULONG MsgId)
{
	struct ScalosPopupMenu_LocaleInfo li;

	li.li_Catalog = PopupMenuPrefsCatalog;	     
#ifndef __amigaos4__
	li.li_LocaleBase = LocaleBase;
#else
	li.li_ILocale = ILocale;
#endif

	return (STRPTR) GetScalosPopupMenuString(&li, MsgId);
}

static void TranslateStringArray(STRPTR *stringArray)
{
	while (*stringArray)
		{
		*stringArray = GetLocString((IPTR) *stringArray);
		stringArray++;
		}
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT ResetToDefaultsHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));

	inst->mpb_PMPrefs = DefaultPMPrefs;
	PrefsToGUI(inst, &inst->mpb_PMPrefs);

	d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT OpenHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	if (NULL == inst->mpb_LoadReq)
		{
		inst->mpb_LoadReq = MUI_AllocAslRequestTags(ASL_FileRequest,
			ASLFR_InitialFile, "PopupMenu.pre",
			ASLFR_Flags1, FRF_DOPATTERNS,
			ASLFR_InitialDrawer, "SYS:Prefs/presets",
			ASLFR_InitialPattern, "#?.(pre|prefs)",
			ASLFR_UserData, inst,
			ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg],
			TAG_END);
		}
	if (inst->mpb_LoadReq)
		{
		BOOL Result;
		struct Window *win = NULL;

		get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win);

		//AslRequest(
		Result = MUI_AslRequestTags(inst->mpb_LoadReq,
			ASLFR_Window, win,
			ASLFR_SleepWindow, TRUE,
			ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_OPEN),
			TAG_END);

		if (Result)
			{
			BPTR dirLock = Lock(inst->mpb_LoadReq->fr_Drawer, ACCESS_READ);

			if (dirLock)
				{
				BPTR oldDir = CurrentDir(dirLock);

				ReadPrefsFile(inst, "", inst->mpb_LoadReq->fr_File, FALSE);
				PrefsToGUI(inst, &inst->mpb_PMPrefs);

				CurrentDir(oldDir);
				UnLock(dirLock);
				}
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT LastSavedHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	ReadPrefsFile(inst, PMP_S_PATH_OLD, PMP_S_PATH_NEW, FALSE);
	PrefsToGUI(inst, &inst->mpb_PMPrefs);
	SetChangedFlag(inst, TRUE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT RestoreHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	ReadPrefsFile(inst, PMP_PATH_OLD, PMP_PATH_NEW, FALSE);
	PrefsToGUI(inst, &inst->mpb_PMPrefs);
	SetChangedFlag(inst, TRUE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SaveAsHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	if (NULL == inst->mpb_SaveReq)
		{
		inst->mpb_SaveReq = MUI_AllocAslRequestTags(ASL_FileRequest,
			ASLFR_InitialFile, "PopupMenu.pre",
			ASLFR_DoSaveMode, TRUE,
			ASLFR_InitialDrawer, "SYS:Prefs/presets",
			ASLFR_UserData, inst,
			ASLFR_IntuiMsgFunc, &inst->mpb_Hooks[HOOKNDX_AslIntuiMsg],
			TAG_END);
		}
	if (inst->mpb_SaveReq)
		{
		BOOL Result;
		struct Window *win = NULL;

		get(inst->mpb_Objects[OBJNDX_WIN_Main], MUIA_Window_Window, &win);

		//AslRequest(
		Result = MUI_AslRequestTags(inst->mpb_SaveReq,
			ASLFR_TitleText, GetLocString(MSGID_MENU_PROJECT_SAVEAS),
			ASLFR_Window, win,
			ASLFR_SleepWindow, TRUE,
			TAG_END);

		if (Result)
			{
			BPTR dirLock = Lock(inst->mpb_SaveReq->fr_Drawer, ACCESS_READ);

			if (dirLock)
				{
				BPTR oldDir = CurrentDir(dirLock);

				WritePrefsFile(inst, inst->mpb_SaveReq->fr_File);

				CurrentDir(oldDir);
				UnLock(dirLock);
				}
			}
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT AboutHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL, 
		GetLocString(MSGID_ABOUTREQOK), 
		GetLocString(MSGID_ABOUTREQFORMAT), 
		MajorVersion, MinorVersion, COMPILER_STRING, CURRENTYEAR);

	return 0;
}

//----------------------------------------------------------------------------

static LONG ReadPrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR FilenameOld, CONST_STRPTR FilenameNew, BOOL Quiet)
{
	LONG Result = RETURN_OK;
	APTR myPrefsHandle;

	d1(KPrintF("%s/%s/%ld:  Filename=<%s>  LocaleBase=%08lx  IFFParseBase=%08lx\n", \
		__FILE__, __FUNC__, __LINE__, Filename, LocaleBase, IFFParseBase));

	ConvertPmPrefs(FilenameOld, FilenameNew);

	myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs");
	if (myPrefsHandle)
		{
		LONG lID = MAKE_ID('M', 'A', 'I', 'N');

		ReadPrefsHandle(myPrefsHandle, FilenameNew);

		GetPreferences(myPrefsHandle, lID, PMP_Flags, &inst->mpb_PMPrefs.pmp_Flags, sizeof(inst->mpb_PMPrefs.pmp_Flags) );
		GetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &inst->mpb_PMPrefs.pmp_SubMenuDelay, sizeof(inst->mpb_PMPrefs.pmp_SubMenuDelay) );
		GetPreferences(myPrefsHandle, lID, PMP_AnimationType, &inst->mpb_PMPrefs.pmp_Animation, sizeof(inst->mpb_PMPrefs.pmp_Animation) );
		GetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &inst->mpb_PMPrefs.pmp_PulldownPos, sizeof(inst->mpb_PMPrefs.pmp_PulldownPos) );
		if (GetPreferences(myPrefsHandle, lID, PMP_Sticky, &inst->mpb_PMPrefs.pmp_Sticky, sizeof(inst->mpb_PMPrefs.pmp_Sticky) ))
			{
			inst->mpb_PMPrefs.pmp_Sticky = SCA_BE2WORD(inst->mpb_PMPrefs.pmp_Sticky);
			}
		GetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &inst->mpb_PMPrefs.pmp_MenuBorder, sizeof(inst->mpb_PMPrefs.pmp_MenuBorder) );
		GetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &inst->mpb_PMPrefs.pmp_SelItemBorder, sizeof(inst->mpb_PMPrefs.pmp_SelItemBorder) );
		GetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &inst->mpb_PMPrefs.pmp_SeparatorBar, sizeof(inst->mpb_PMPrefs.pmp_SeparatorBar) );
		GetPreferences(myPrefsHandle, lID, PMP_XOffset, &inst->mpb_PMPrefs.pmp_XOffset, sizeof(inst->mpb_PMPrefs.pmp_XOffset) );
		GetPreferences(myPrefsHandle, lID, PMP_YOffset, &inst->mpb_PMPrefs.pmp_YOffset, sizeof(inst->mpb_PMPrefs.pmp_YOffset) );
		GetPreferences(myPrefsHandle, lID, PMP_XSpace, &inst->mpb_PMPrefs.pmp_XSpace, sizeof(inst->mpb_PMPrefs.pmp_XSpace) );
		GetPreferences(myPrefsHandle, lID, PMP_YSpace, &inst->mpb_PMPrefs.pmp_YSpace, sizeof(inst->mpb_PMPrefs.pmp_YSpace) );
		GetPreferences(myPrefsHandle, lID, PMP_Intermediate, &inst->mpb_PMPrefs.pmp_Intermediate, sizeof(inst->mpb_PMPrefs.pmp_Intermediate) );
		GetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &inst->mpb_PMPrefs.pmp_TransparencyBlur, sizeof(inst->mpb_PMPrefs.pmp_TransparencyBlur) );
		GetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &inst->mpb_PMPrefs.pmp_TextDisplace, sizeof(inst->mpb_PMPrefs.pmp_TextDisplace) );
		GetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &inst->mpb_PMPrefs.pmp_MenuTitles, sizeof(inst->mpb_PMPrefs.pmp_MenuTitles) );
		GetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &inst->mpb_PMPrefs.pmp_MenuItems, sizeof(inst->mpb_PMPrefs.pmp_MenuItems) );

		FreePrefsHandle(myPrefsHandle);
		}

	if (RETURN_OK == Result)
		{
		if (inst->mpb_fCreateIcons)
			SaveIcon(inst, FilenameNew);
		}
	else
		{
		char Buffer[120];

		Fault(Result, "", Buffer, sizeof(Buffer) - 1);

		// MUI_RequestA()
		MUI_Request(inst->mpb_Objects[OBJNDX_APP_Main], inst->mpb_Objects[OBJNDX_WIN_Main], 0, NULL,
			GetLocString(MSGID_ABOUTREQOK),
			GetLocString(MSGID_REQTITLE_SAVEERROR),
			FilenameNew,
			Buffer);
		}

	d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuTitles));
	d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuItems));
	d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));

	return Result;
}


static LONG WritePrefsFile(struct PopupMenuPrefsInst *inst, CONST_STRPTR Filename)
{
	APTR myPrefsHandle;
	LONG Result = RETURN_OK;
	WORD wValue;

	GUItoPrefs(inst, &inst->mpb_PMPrefs);

	myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs");
	if (myPrefsHandle)
		{
		LONG lID = MAKE_ID('M', 'A', 'I', 'N');

		SetPreferences(myPrefsHandle, lID, PMP_Flags, &inst->mpb_PMPrefs.pmp_Flags, sizeof(inst->mpb_PMPrefs.pmp_Flags) );
		SetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &inst->mpb_PMPrefs.pmp_SubMenuDelay, sizeof(inst->mpb_PMPrefs.pmp_SubMenuDelay) );
		SetPreferences(myPrefsHandle, lID, PMP_AnimationType, &inst->mpb_PMPrefs.pmp_Animation, sizeof(inst->mpb_PMPrefs.pmp_Animation) );
		SetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &inst->mpb_PMPrefs.pmp_PulldownPos, sizeof(inst->mpb_PMPrefs.pmp_PulldownPos) );

		wValue = SCA_WORD2BE(inst->mpb_PMPrefs.pmp_Sticky);
		SetPreferences(myPrefsHandle, lID, PMP_Sticky, &wValue, sizeof(wValue) );

		SetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &inst->mpb_PMPrefs.pmp_MenuBorder, sizeof(inst->mpb_PMPrefs.pmp_MenuBorder) );
		SetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &inst->mpb_PMPrefs.pmp_SelItemBorder, sizeof(inst->mpb_PMPrefs.pmp_SelItemBorder) );
		SetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &inst->mpb_PMPrefs.pmp_SeparatorBar, sizeof(inst->mpb_PMPrefs.pmp_SeparatorBar) );
		SetPreferences(myPrefsHandle, lID, PMP_XOffset, &inst->mpb_PMPrefs.pmp_XOffset, sizeof(inst->mpb_PMPrefs.pmp_XOffset) );
		SetPreferences(myPrefsHandle, lID, PMP_YOffset, &inst->mpb_PMPrefs.pmp_YOffset, sizeof(inst->mpb_PMPrefs.pmp_YOffset) );
		SetPreferences(myPrefsHandle, lID, PMP_XSpace, &inst->mpb_PMPrefs.pmp_XSpace, sizeof(inst->mpb_PMPrefs.pmp_XSpace) );
		SetPreferences(myPrefsHandle, lID, PMP_YSpace, &inst->mpb_PMPrefs.pmp_YSpace, sizeof(inst->mpb_PMPrefs.pmp_YSpace) );
		SetPreferences(myPrefsHandle, lID, PMP_Intermediate, &inst->mpb_PMPrefs.pmp_Intermediate, sizeof(inst->mpb_PMPrefs.pmp_Intermediate) );
		SetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &inst->mpb_PMPrefs.pmp_TransparencyBlur, sizeof(inst->mpb_PMPrefs.pmp_TransparencyBlur) );
		SetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &inst->mpb_PMPrefs.pmp_TextDisplace, sizeof(inst->mpb_PMPrefs.pmp_TextDisplace) );
		SetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &inst->mpb_PMPrefs.pmp_MenuTitles, sizeof(inst->mpb_PMPrefs.pmp_MenuTitles) );
		SetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &inst->mpb_PMPrefs.pmp_MenuItems, sizeof(inst->mpb_PMPrefs.pmp_MenuItems) );

		WritePrefsHandle(myPrefsHandle, Filename);

		FreePrefsHandle(myPrefsHandle);
		}

	return Result;
}


static LONG SaveIcon(struct PopupMenuPrefsInst *inst, CONST_STRPTR IconName)
{
	struct DiskObject *icon, *allocIcon;

	static UBYTE ImageData[] =
		{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x07, 0xFF, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x60, 0x00, 0x10, 0x00,
		0x00, 0x00, 0x20, 0xFC, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x02, 0x08, 0x00, 0x0C, 0x00, 
		0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x40, 0x82, 0x08, 0x00, 0x0C, 0x00, 
		0x00, 0x00, 0x21, 0x04, 0x08, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x1E, 0x18, 0x10, 0x00, 0x0C, 0x00,
		0x00, 0x00, 0x00, 0x60, 0x20, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x00, 0x0C, 0x00, 
		0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x0C, 0x00, 
		0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 
		0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x0C, 0x00, 
		0x40, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x0C, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
		0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 
		0xD5, 0x55, 0x55, 0x55, 0x55, 0x56, 0x00, 0x00, 0xD5, 0x55, 0x50, 0x00, 0x55, 0x55, 0x80, 0x00, 
		0xD5, 0x55, 0x47, 0xFF, 0x95, 0x55, 0x60, 0x00, 0xD5, 0x55, 0x5F, 0x03, 0xE5, 0x55, 0x50, 0x00, 
		0xD5, 0x55, 0x3E, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00,
		0xD5, 0x55, 0x3F, 0x55, 0xF5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x5E, 0x53, 0xF5, 0x55, 0x50, 0x00, 
		0xD5, 0x55, 0x41, 0x47, 0xE5, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x55, 0x1F, 0xD5, 0x55, 0x50, 0x00, 
		0xD5, 0x55, 0x55, 0x7F, 0x15, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xFC, 0x55, 0x55, 0x50, 0x00, 
		0xD5, 0x55, 0x55, 0xE1, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 
		0xD5, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00,
		0xD5, 0x55, 0x54, 0xF5, 0x55, 0x55, 0x50, 0x00, 0x35, 0x55, 0x55, 0x05, 0x55, 0x55, 0x50, 0x00, 
		0x0D, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 0x03, 0x55, 0x55, 0x55, 0x55, 0x55, 0x50, 0x00, 
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		};

	static struct Image NormalImage =
		{
		0, 0, 54, 23,
		2,
		(UWORD *)ImageData,
		3, 0,
		NULL
		};

	static STRPTR defToolTypes[] =
		{
		"ACTION=USE",
		NULL
		};

	static struct DiskObject DefaultIcon =
		{
		WB_DISKMAGIC, WB_DISKVERSION,

		{
		NULL, 
		0, 0, 54, 24,
		GFLG_GADGIMAGE | GFLG_GADGHBOX,
		GACT_RELVERIFY | GACT_IMMEDIATE,
		GTYP_BOOLGADGET,
		&NormalImage, NULL,
		NULL,
		0,
		NULL,
		0,
		NULL
		},

		WBPROJECT,
		NULL,
		defToolTypes,
		NO_ICON_POSITION, NO_ICON_POSITION,
		NULL,
		NULL,
		8192
		};

	icon = allocIcon = GetDiskObject("ENV:sys/def_ScaPopupMenuPrefs");
	if (NULL == icon)
		icon = allocIcon = GetDiskObject("ENV:sys/def_pref");
	if (NULL == icon)
		icon = &DefaultIcon;

	if (icon)
		{
		STRPTR oldDefaultTool = icon->do_DefaultTool;

		icon->do_DefaultTool = (STRPTR) inst->mpb_ProgramName;

		PutDiskObject((STRPTR) IconName, icon);

		icon->do_DefaultTool = oldDefaultTool;

		if (allocIcon)
			FreeDiskObject(allocIcon);
		}

	return 0;
}


static SAVEDS(APTR) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg)
{
#if 0
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;
	struct AppMessage *AppMsg = *(struct AppMessage **) msg;
	struct MUI_NListtree_TreeNode *TreeNode = NULL;

	set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, TRUE);

	TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree],
		MUIM_NListtree_GetEntry, MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active, 0);

	if (TreeNode)
		{
		struct MUI_NListtree_TreeNode *ParentNode = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_Insert_PrevNode_Tail;
		LONG n;

		for (n=0; n<AppMsg->am_NumArgs; )
			{
			struct PopupMenuListEntry *mle = (struct PopupMenuListEntry *) TreeNode->tn_User;
			char Buffer[1000];
			STRPTR FileName;

			if (!NameFromLock(AppMsg->am_ArgList[n].wa_Lock, Buffer, sizeof(Buffer)))
				break;
			if (AppMsg->am_ArgList[n].wa_Name && strlen(AppMsg->am_ArgList[n].wa_Name) > 0)
				AddPart(Buffer, AppMsg->am_ArgList[n].wa_Name, sizeof(Buffer));

			FileName = FilePart(Buffer);

			switch (mle->llist_EntryType)
				{
			case SCAPopupMenuTYPE_MainPopupMenu:
				d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_MainPopupMenu\n", __FILE__, __FUNC__, __LINE__));
				if (mle->llist_Flags & LLISTFLGF_MayNotHaveChildren)
					{
					AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName);
					n++;
					}
				else
					{
					TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree],
						MUIM_NListtree_Insert, "DragIn PopupMenu",
						CombineEntryTypeAndFlags(SCAPopupMenuTYPE_PopupMenu, 0),
						TreeNode, ParentNode, TNF_OPEN | TNF_LIST);
					}
				break;

			case SCAPopupMenuTYPE_PopupMenu:
			case SCAPopupMenuTYPE_ToolsPopupMenu:
				d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_PopupMenu\n", __FILE__, __FUNC__, __LINE__));
				AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName);
				n++;
				break;

			case SCAPopupMenuTYPE_PopupMenuItem:
				d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_PopupMenuItem\n", __FILE__, __FUNC__, __LINE__));
				ParentNode = TreeNode;
				TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree],
					MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0);

				AppMessage_PopupMenu(inst, &TreeNode, &ParentNode, &AppMsg->am_ArgList[n], Buffer, FileName);
				n++;
				break;

			case SCAPopupMenuTYPE_Command:
				d1(kprintf("%s/%s/%ld: insert at SCAPopupMenuTYPE_Command\n", __FILE__, __FUNC__, __LINE__));
				TreeNode = (struct MUI_NListtree_TreeNode *) DoMethod(inst->mpb_Objects[OBJNDX_MainListTree],
					MUIM_NListtree_GetEntry, TreeNode, MUIV_NListtree_GetEntry_Position_Parent, 0);
				break;

			default:
				break;
				}
			}
		}

	set(inst->mpb_Objects[OBJNDX_MainListTree], MUIA_NListtree_Quiet, FALSE);
#endif
	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SettingsChangedHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	d1(kprintf("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
	SetChangedFlag(inst, TRUE);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT AslIntuiMsgHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;
	struct IntuiMessage *iMsg = (struct IntuiMessage *) msg;

	if (IDCMP_REFRESHWINDOW == iMsg->Class)
		{
		DoMethod(inst->mpb_Objects[OBJNDX_APP_Main], MUIM_Application_CheckRefresh);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT FrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	// turn off selected state for all frame type buttons except <o>
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameThin])
		set(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameMM])
		set(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameThick])
		set(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameRidge])
		set(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameDropBox])
		set(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_FrameOldStyle])
		set(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected, FALSE);
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT SelFrameTypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct PopupMenuPrefsInst *inst = (struct PopupMenuPrefsInst *) hook->h_Data;

	// turn off selected state for all selected frame type buttons except <o>
	if (o != inst->mpb_Objects[OBJNDX_Button_Raised])
		set(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_Normal])
		set(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected, FALSE);
	if (o != inst->mpb_Objects[OBJNDX_Button_Recessed])
		set(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected, FALSE);
}

//----------------------------------------------------------------------------

static void PrefsToGUI(struct PopupMenuPrefsInst *inst, const struct PopupMenuPrefs *pmPrefs)
{
	switch (pmPrefs->pmp_MenuBorder)
		{
	case PMP_MENUBORDER_THIN:
	default:
		set(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected, TRUE);
		break;
	case PMP_MENUBORDER_MM:
		set(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected, TRUE);
		break;
	case PMP_MENUBORDER_THICK:
		set(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected, TRUE);
		break;
	case PMP_MENUBORDER_RIDGE:
		set(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected, TRUE);
		break;
	case PMP_MENUBORDER_DROPBOX:
		set(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected, TRUE);
		break;
	case PMP_MENUBORDER_OLDSTYLE:
		set(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected, TRUE);
		break;
		}

	switch (pmPrefs->pmp_SelItemBorder)
		{
	case PMP_SELITEM_NO_BORDER:
	default:
		set(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected, TRUE);
		break;
	case PMP_SELITEM_RAISE:
		set(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected, TRUE);
		break;
	case PMP_SELITEM_RECESS:
		set(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected, TRUE);
		break;
		}

	if (pmPrefs->pmp_SeparatorBar)
		set(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIA_Selected, TRUE);
	else
		set(inst->mpb_Objects[OBJNDX_CheckMark_NewLook], MUIA_Selected, TRUE);

	setslider(inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus], pmPrefs->pmp_SubMenuDelay);

	setslider(inst->mpb_Objects[OBJNDX_Slider_Horizontal], pmPrefs->pmp_XOffset);
	setslider(inst->mpb_Objects[OBJNDX_Slider_VerticalOffset], pmPrefs->pmp_YOffset);
	setslider(inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing], pmPrefs->pmp_XSpace);
	setslider(inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing], pmPrefs->pmp_YSpace);
	setslider(inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing], pmPrefs->pmp_Intermediate);
	setslider(inst->mpb_Objects[OBJNDX_Slider_TextDisplacement], pmPrefs->pmp_TextDisplace);

	setcycle(inst->mpb_Objects[OBJNDX_Cycle_AnimationType], pmPrefs->pmp_Animation);

	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_Sticky], pmPrefs->pmp_Sticky);

	d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuTitles));
	d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuItems));

	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed], pmPrefs->pmp_MenuTitles & PMP_TITLE_EMBOSS);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined], pmPrefs->pmp_MenuTitles & PMP_TEXT_OUTLINE);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed], pmPrefs->pmp_MenuTitles & PMP_TEXT_SHADOW);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined], pmPrefs->pmp_MenuTitles & PMP_TEXT_UNDERLINE);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold], pmPrefs->pmp_MenuTitles & PMP_TEXT_BOLD);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic], pmPrefs->pmp_MenuTitles & PMP_TEXT_ITALIC);

	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed], pmPrefs->pmp_MenuItems & PMP_TEXT_EMBOSS);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined], pmPrefs->pmp_MenuItems & PMP_TEXT_OUTLINE);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed], pmPrefs->pmp_MenuItems & PMP_TEXT_SHADOW);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined], pmPrefs->pmp_MenuItems & PMP_TEXT_UNDERLINE);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold], pmPrefs->pmp_MenuItems & PMP_TEXT_BOLD);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic], pmPrefs->pmp_MenuItems & PMP_TEXT_ITALIC);

	setslider(inst->mpb_Objects[OBJNDX_Slider_Transp_Blur], pmPrefs->pmp_TransparencyBlur);
	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], pmPrefs->pmp_Flags & PMP_FLAGS_TRANSPARENCY);
	set(inst->mpb_Objects[OBJNDX_Group_Transp_Blur], MUIA_Disabled, !(pmPrefs->pmp_Flags & PMP_FLAGS_TRANSPARENCY));

	setcheckmark(inst->mpb_Objects[OBJNDX_CheckMark_MenuShadows], pmPrefs->pmp_Flags & PMP_FLAGS_SHADOWS);
	set(inst->mpb_Objects[OBJNDX_CheckMark_RealShadows], MUIA_Disabled, !(pmPrefs->pmp_Flags & PMP_FLAGS_SHADOWS));
}

//----------------------------------------------------------------------------

static void GUItoPrefs(struct PopupMenuPrefsInst *inst, struct PopupMenuPrefs *pmPrefs)
{
	if (getv(inst->mpb_Objects[OBJNDX_Button_FrameThin], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THIN;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameMM], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_MM;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameThick], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THICK;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameRidge], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_RIDGE;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameDropBox], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_DROPBOX;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_FrameOldStyle], MUIA_Selected))
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_OLDSTYLE;
	else
		pmPrefs->pmp_MenuBorder = PMP_MENUBORDER_THIN;

	if (getv(inst->mpb_Objects[OBJNDX_Button_Normal], MUIA_Selected))
		pmPrefs->pmp_SelItemBorder = PMP_SELITEM_NO_BORDER;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_Raised], MUIA_Selected))
		pmPrefs->pmp_SelItemBorder = PMP_SELITEM_RAISE;
	else if (getv(inst->mpb_Objects[OBJNDX_Button_Recessed], MUIA_Selected))
		pmPrefs->pmp_SelItemBorder = PMP_SELITEM_RECESS;
	else
		pmPrefs->pmp_SelItemBorder = PMP_SELITEM_NO_BORDER;

	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_OldLook], MUIA_Selected))
		pmPrefs->pmp_SeparatorBar = TRUE;
	else
		pmPrefs->pmp_SeparatorBar = FALSE;

	pmPrefs->pmp_SubMenuDelay 	= getv(inst->mpb_Objects[OBJNDX_Slider_DelaySubMenus], MUIA_Numeric_Value);

	pmPrefs->pmp_XOffset		= getv(inst->mpb_Objects[OBJNDX_Slider_Horizontal], MUIA_Numeric_Value);
	pmPrefs->pmp_YOffset		= getv(inst->mpb_Objects[OBJNDX_Slider_VerticalOffset], MUIA_Numeric_Value);
	pmPrefs->pmp_XSpace		= getv(inst->mpb_Objects[OBJNDX_Slider_HorizontalSpacing], MUIA_Numeric_Value);
	pmPrefs->pmp_YSpace		= getv(inst->mpb_Objects[OBJNDX_Slider_VerticalSpacing], MUIA_Numeric_Value);
	pmPrefs->pmp_Intermediate	= getv(inst->mpb_Objects[OBJNDX_Slider_IntermediateSpacing], MUIA_Numeric_Value);
	pmPrefs->pmp_TextDisplace	= getv(inst->mpb_Objects[OBJNDX_Slider_TextDisplacement], MUIA_Numeric_Value);

	pmPrefs->pmp_Animation		= getv(inst->mpb_Objects[OBJNDX_Cycle_AnimationType], MUIA_Cycle_Active);

	pmPrefs->pmp_Sticky		= getv(inst->mpb_Objects[OBJNDX_CheckMark_Sticky], MUIA_Selected);

	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Embossed], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TITLE_EMBOSS;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TITLE_EMBOSS;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Outlined], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TEXT_OUTLINE;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_OUTLINE;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Shadowed], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TEXT_SHADOW;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_SHADOW;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Underlined], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TEXT_UNDERLINE;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_UNDERLINE;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Bold], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TEXT_BOLD;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_BOLD;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuTitles_Italic], MUIA_Selected))
		pmPrefs->pmp_MenuTitles |= PMP_TEXT_ITALIC;
	else
		pmPrefs->pmp_MenuTitles &= ~PMP_TEXT_ITALIC;
	d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuTitles));

	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Embossed], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_EMBOSS;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_EMBOSS;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Outlined], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_OUTLINE;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_OUTLINE;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Shadowed], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_SHADOW;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_SHADOW;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Underlined], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_UNDERLINE;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_UNDERLINE;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Bold], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_BOLD;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_BOLD;
	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_MenuItems_Italic], MUIA_Selected))
		pmPrefs->pmp_MenuItems |= PMP_TEXT_ITALIC;
	else
		pmPrefs->pmp_MenuItems &= ~PMP_TEXT_ITALIC;
	d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, pmPrefs->pmp_MenuItems));

	pmPrefs->pmp_TransparencyBlur	= getv(inst->mpb_Objects[OBJNDX_Slider_Transp_Blur], MUIA_Numeric_Value);

	if (getv(inst->mpb_Objects[OBJNDX_CheckMark_Transparency_Enable], MUIA_Selected))
		pmPrefs->pmp_Flags |= PMP_FLAGS_TRANSPARENCY;
	else
		pmPrefs->pmp_Flags &= ~PMP_FLAGS_TRANSPARENCY;
}

//----------------------------------------------------------------------------

void _XCEXIT(long x)
{
}


static Object *CreatePrefsImage(void)
{
	Object	*img;

	// First try to load datatypes image from THEME: tree
	img = DataTypesImageObject,
		MUIA_ScaDtpic_Name, (IPTR) "THEME:prefs/plugins/popupmenu",
		MUIA_ScaDtpic_FailIfUnavailable, TRUE,
		End; //DataTypesMCCObject

	if (NULL == img)
		img = IMG(PopupMenuPrefs, POPUPMENUPREFS);	// use built-in fallback image

	return img;
}


static void InitHooks(struct PopupMenuPrefsInst *inst)
{
	ULONG n;

	for (n=0; n<HOOKNDX_MAX; n++)
		{
		inst->mpb_Hooks[n] = PopupMenuPrefsHooks[n];
		inst->mpb_Hooks[n].h_Data = inst;
		}
}


static void SetChangedFlag(struct PopupMenuPrefsInst *inst, BOOL changed)
{
	if (changed != inst->mpb_Changed)
		{
		set(inst->mpb_Objects[OBJNDX_Lamp_Changed], 
			MUIA_Lamp_Color, changed ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Off);
		inst->mpb_Changed = changed;
		}
}

//-----------------------------------------------------------------

static void ParseToolTypes(struct PopupMenuPrefsInst *inst, struct MUIP_ScalosPrefs_ParseToolTypes *ptt)
{
#if 0
	STRPTR tt;

	d1(kprintf("%s/%ld: start  ptt=%08lx  tooltypes=%08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes));
	d1(kprintf("%s/%ld: start  tooltypes=%08lx %08lx %08lx\n", __FUNC__, __LINE__, ptt, ptt->ToolTypes[0], ptt->ToolTypes[1], ptt->ToolTypes[2]));

#endif
	d1(kprintf("%s/%ld: end\n", __FUNC__, __LINE__));
}

//----------------------------------------------------------------------------

BOOL initPlugin(struct PluginBase *PluginBase)
{
	MajorVersion = PluginBase->pl_LibNode.lib_Version;
	MinorVersion = PluginBase->pl_LibNode.lib_Revision;

	d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

	if (0x4711 == SIgnature++)
		{
		d1(kprintf("%s/%s/%ld:   PluginBase=%08lx  procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \
			PluginBase, FindTask(NULL)->tc_Node.ln_Name));

		d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

		d1(kprintf("%s/%s/%ld:   PopupMenuPrefsLibBase=%08lx  procName=<%s>\n", __FILE__, __FUNC__, __LINE__, \
			PopupMenuPrefsLibBase, FindTask(NULL)->tc_Node.ln_Name));

#ifndef __amigaos4__
		DOSBase = (struct DosLibrary *) OpenLibrary(DOSNAME, 39 );
#else
		DOSBase = OpenLibrary(DOSNAME, 39);
#endif

		d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

		if (!OpenLibraries())
			return FALSE;

		d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

#if !defined(__amigaos4__) && !defined(__AROS__)
		if (_STI_240_InitMemFunctions())
			return FALSE;
#endif

		d1(kprintf("%s/%s/%ld:\n", __FILE__, __FUNC__, __LINE__));

		PopupMenuPrefsClass = MUI_CreateCustomClass(&PluginBase->pl_LibNode, MUIC_Group,
				NULL, sizeof(struct PopupMenuPrefsInst), DISPATCHER_REF(PopupMenuPrefs));

		d1(kprintf("%s/%s/%ld:  PopupMenuPrefsClass=%08lx\n", __FILE__, __FUNC__, __LINE__, PopupMenuPrefsClass));
		if (NULL == PopupMenuPrefsClass)
			return FALSE;

		FrameButtonClass = InitFrameButtonClass();
		d1(KPrintF("%s/%s/%ld:  FrameButtonClass=%08lx\n", __FILE__, __FUNC__, __LINE__, FrameButtonClass));
		if (NULL == FrameButtonClass)
			return FALSE;

		d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));

		DataTypesImageClass = InitDtpicClass();
		d1(KPrintF(__FUNC__ "/%ld: DataTypesImageClass=%08lx\n", __LINE__, DataTypesImageClass));
		if (NULL == DataTypesImageClass)
			return FALSE;	// Failure

		if (LocaleBase)
			{
			if (NULL == PopupMenuPrefsLocale)
				PopupMenuPrefsLocale = OpenLocale(NULL);

			if (PopupMenuPrefsLocale)
				{
				if (NULL == PopupMenuPrefsCatalog)
					{
					PopupMenuPrefsCatalog = OpenCatalog(PopupMenuPrefsLocale,
						(STRPTR) "Scalos/ScalosPopupMenu.catalog", NULL);
					}
				}
			}

		TranslateStringArray(PrefsPageNames);
		TranslateStringArray(AnimationNames);
		}

	d1(KPrintF("%s/%s/%ld: success\n", __FILE__, __FUNC__, __LINE__));

	return TRUE;	// Success
}

//----------------------------------------------------------------------------

static IPTR getv(APTR obj, ULONG attr)
{
    IPTR v;
    GetAttr(attr, obj, &v);
    return (v);
}

//----------------------------------------------------------------------------

static LONG ReadOldPrefsFile(CONST_STRPTR Filename, struct oldPopupMenuPrefs *prefs, const struct oldPopupMenuPrefs *defaultPrefs)
{
	LONG Result;
	struct IFFHandle *iff;
	BOOL iffOpened = FALSE;

	d1(KPrintF("%s/%s/%ld:  Filename=<%s>  LocaleBase=%08lx  IFFParseBase=%08lx\n", \
		__FILE__, __FUNC__, __LINE__, Filename, LocaleBase, IFFParseBase));

	do	{
		*prefs = *defaultPrefs;

		iff = AllocIFF();
		if (NULL == iff)
			{
			Result = IoErr();
			break;
			}

		InitIFFasDOS(iff);

		iff->iff_Stream = (IPTR)Open(Filename, MODE_OLDFILE);
		if (BNULL == (BPTR)iff->iff_Stream)
			{
			Result = IoErr();
			break;
			}

		Result = OpenIFF(iff, IFFF_READ);
		if (RETURN_OK != Result)
			break;

		iffOpened = TRUE;

		Result = StopChunks(iff, StopChunkList, 2);
		if (RETURN_OK != Result)
			break;

		while (1)
			{
			struct ContextNode *cn;

			Result = ParseIFF(iff, IFFPARSE_SCAN);
			d1(kprintf("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
			if (RETURN_OK != Result)
				break;

			cn = CurrentChunk(iff);

			d1(KPrintF("%s/%s/%ld:  cn=%08lx\n", __FILE__, __FUNC__, __LINE__, cn));
			if (NULL == cn)
				break;

			d1(KPrintF("%s/%s/%ld:  cn=%08lx  id=%08lx\n", __FILE__, __FUNC__, __LINE__, cn, cn->cn_ID));
			if (ID_PMNU == cn->cn_ID)
				{
				LONG Actual;

				d1(KPrintF("%s/%s/%ld:  cn_Size=%lu\n", __FILE__, __FUNC__, __LINE__, cn->cn_Size));

				if (cn->cn_Size != sizeof(struct oldPopupMenuPrefs))
					break;

				Actual = ReadChunkBytes(iff, prefs, cn->cn_Size);
				d1(KPrintF("%s/%s/%ld:  Actual=%lu\n", __FILE__, __FUNC__, __LINE__, Actual));
				if (Actual != cn->cn_Size)
					break;
				}
				prefs->pmp_Sticky = SCA_BE2WORD(prefs->pmp_Sticky);
				prefs->pmp_SameHeight = SCA_BE2WORD(prefs->pmp_SameHeight);
			}

		d1(KPrintF(__FILE__ "%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));
		if (IFFERR_EOF == Result)
			Result = RETURN_OK;
		} while (0);

	if (iff)
		{
		if (iffOpened)
			CloseIFF(iff);

		if (iff->iff_Stream)
			Close((BPTR)iff->iff_Stream);

		FreeIFF(iff);
		}

	d1(KPrintF("%s/%s/%ld: pmp_MenuTitles=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuTitles));
	d1(KPrintF("%s/%s/%ld: pmp_MenuItems=%08lx\n", __FILE__, __FUNC__, __LINE__, inst->mpb_PMPrefs.pmp_MenuItems));
	d1(KPrintF("%s/%s/%ld: Result=%ld\n", __FILE__, __FUNC__, __LINE__, Result));

	return Result;
}

//----------------------------------------------------------------------------

static void ConvertPmPrefs(CONST_STRPTR prefsFileOld, CONST_STRPTR prefsFileNew)
{
	BPTR fLock;

	fLock = Lock(prefsFileNew, ACCESS_READ);
	if (fLock)
		{
		UnLock(fLock);
		}
	else
		{
		struct oldPopupMenuPrefs LoadedPrefs;
		APTR myPrefsHandle;
		static const struct oldPopupMenuPrefs DefaultPrefs =
			{
			PMP_FLAGS_SHADOWS,	/* pmp_Flags		*/
			0,			/* pmp_SubMenuDelay	*/
			PMP_ANIM_NONE,		/* pmp_Animation	*/
			PMP_PD_SCREENBAR,	/* pmp_PulldownPos	*/
			FALSE,			/* pmp_Sticky		*/
			FALSE,			/* pmp_SameHeight	unused */
			0,			/* pmp_MenuBorder	*/
			0,			/* pmp_SelItemBorder	*/
			0,			/* pmp_SeparatorBar	*/
			0,			/* pmp_MenuTitles	*/
			0,			/* pmp_MenuItems	*/
			2,			/* pmp_XOffset		*/
			2,			/* pmp_YOffset		*/
			2,			/* pmp_XSpace		*/
			2,			/* pmp_YSpace		*/
			2,			/* pmp_Intermediate	*/
			0,			/* pmp_TextDisplace	*/
			-30,			/* pmp_ShadowR		unused */
			-30,			/* pmp_ShadowG		unused */
			-30,			/* pmp_ShadowB		unused */
			0,			/* pmp_TransparencyR	unused */
			0,			/* pmp_TransparencyG	unused */
			0,			/* pmp_TransparencyB	unused */
			0,			/* pmp_TransparencyBlur	*/
			0,			/* pmp_AnimationSpeed	unused */

			{0},			/* pmp_Reserved		*/
			};

		ReadOldPrefsFile(prefsFileOld,  &LoadedPrefs, &DefaultPrefs);

		d1(KPrintF("%s/%s/%ld: pmp_Animation=%ld\n", __FILE__, __FUNC__, __LINE__, LoadedPrefs.pmp_Animation));

		myPrefsHandle = AllocPrefsHandle("PopupMenuPrefs");
		if (myPrefsHandle)
			{
			LONG lID = MAKE_ID('M', 'A', 'I', 'N');

			SetPreferences(myPrefsHandle, lID, PMP_Flags, &LoadedPrefs.pmp_Flags, sizeof(LoadedPrefs.pmp_Flags) );
			SetPreferences(myPrefsHandle, lID, PMP_SubMenuDelay, &LoadedPrefs.pmp_SubMenuDelay, sizeof(LoadedPrefs.pmp_SubMenuDelay) );
			SetPreferences(myPrefsHandle, lID, PMP_AnimationType, &LoadedPrefs.pmp_Animation, sizeof(LoadedPrefs.pmp_Animation) );
			SetPreferences(myPrefsHandle, lID, PMP_PullDownMenuPos, &LoadedPrefs.pmp_PulldownPos, sizeof(LoadedPrefs.pmp_PulldownPos) );

			LoadedPrefs.pmp_Sticky = SCA_WORD2BE(LoadedPrefs.pmp_Sticky);
			SetPreferences(myPrefsHandle, lID, PMP_Sticky, &LoadedPrefs.pmp_Sticky, sizeof(LoadedPrefs.pmp_Sticky) );

			SetPreferences(myPrefsHandle, lID, PMP_MenuBorderType, &LoadedPrefs.pmp_MenuBorder, sizeof(LoadedPrefs.pmp_MenuBorder) );
			SetPreferences(myPrefsHandle, lID, PMP_SelItemBorderType, &LoadedPrefs.pmp_SelItemBorder, sizeof(LoadedPrefs.pmp_SelItemBorder) );
			SetPreferences(myPrefsHandle, lID, PMP_SeparatorBarStyle, &LoadedPrefs.pmp_SeparatorBar, sizeof(LoadedPrefs.pmp_SeparatorBar) );
			SetPreferences(myPrefsHandle, lID, PMP_XOffset, &LoadedPrefs.pmp_XOffset, sizeof(LoadedPrefs.pmp_XOffset) );
			SetPreferences(myPrefsHandle, lID, PMP_YOffset, &LoadedPrefs.pmp_YOffset, sizeof(LoadedPrefs.pmp_YOffset) );
			SetPreferences(myPrefsHandle, lID, PMP_XSpace, &LoadedPrefs.pmp_XSpace, sizeof(LoadedPrefs.pmp_XSpace) );
			SetPreferences(myPrefsHandle, lID, PMP_YSpace, &LoadedPrefs.pmp_YSpace, sizeof(LoadedPrefs.pmp_YSpace) );
			SetPreferences(myPrefsHandle, lID, PMP_Intermediate, &LoadedPrefs.pmp_Intermediate, sizeof(LoadedPrefs.pmp_Intermediate) );
			SetPreferences(myPrefsHandle, lID, PMP_TransparencyBlur, &LoadedPrefs.pmp_TransparencyBlur, sizeof(LoadedPrefs.pmp_TransparencyBlur) );
			SetPreferences(myPrefsHandle, lID, PMP_TextDisplace, &LoadedPrefs.pmp_TextDisplace, sizeof(LoadedPrefs.pmp_TextDisplace) );
			SetPreferences(myPrefsHandle, lID, PMP_MenuTitleStyle, &LoadedPrefs.pmp_MenuTitles, sizeof(LoadedPrefs.pmp_MenuTitles) );
			SetPreferences(myPrefsHandle, lID, PMP_MenuItemStyle, &LoadedPrefs.pmp_MenuItems, sizeof(LoadedPrefs.pmp_MenuItems) );

			WritePrefsHandle(myPrefsHandle, prefsFileNew);

			FreePrefsHandle(myPrefsHandle);
			}
		}
}

//----------------------------------------------------------------------------

#if !defined(__SASC) && !defined(__amigaos4__) && !defined(__AROS__)
// Replacement for SAS/C library functions

#if !defined(__MORPHOS__)

static char *stpblk(const char *q)
{
	while (q && *q && isspace((int) *q))
		q++;

	return (char *) q;
}

static size_t stccpy(char *dest, const char *src, size_t MaxLen)
{
	size_t Count = 0;

	while (*src && MaxLen > 1)
		{
		*dest++ = *src++;
		MaxLen--;
		Count++;
		}
	*dest = '\0';
	Count++;

	return Count;
}
#endif /*__MORPHOS__*/

void exit(int x)
{
   (void) x;
   while (1)
      ;
}

APTR _WBenchMsg;

#endif /* !defined(__SASC) && !defined(__amigaos4__) */

//----------------------------------------------------------------------------

#if defined(__AROS__)

#include "aros/symbolsets.h"

ADD2EXPUNGELIB(closePlugin, 0);
ADD2OPENLIB(initPlugin, 0);

#endif

//----------------------------------------------------------------------------


Modules

[edit | edit source]

...to the top


Source examples

[edit | edit source]

...to the top

// Find.c
// $Date$
// $Revision$

#ifdef __AROS__
#define MUIMASTER_YES_INLINE_STDARG
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/exall.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/asl.h>
#include <libraries/mui.h>
#include <libraries/gadtools.h>
#include <mui/NListtree_mcc.h>
#include <mui/NListview_mcc.h>
#include <devices/clipboard.h>
#include <devices/timer.h>
#include <workbench/workbench.h>
#include <workbench/icon.h>
#include <intuition/intuition.h>
#include <intuition/classusr.h>
#include <scalos/scalos.h>

#include <clib/alib_protos.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <proto/asl.h>
#include <proto/muimaster.h>
#include <proto/locale.h>
#include <proto/scalos.h>
#include <proto/timer.h>

#include <DefIcons.h>
#include <defs.h>
#include <Year.h> // +jmc+

#include "Find.h"
#include "debug.h"

#define	Find_NUMBERS
#define	Find_ARRAY
#define	Find_CODE
#define	Find_NUMBERS
#define	Find_ARRAY
#define	Find_CODE
#include STR(SCALOSLOCALE)

//----------------------------------------------------------------------------

#if !defined(__amigaos4__) && !defined(__AROS__)
#include <dos.h>

long _stack = 16384;		// minimum stack size, used by SAS/C startup code
#endif

//----------------------------------------------------------------------------

// local data structures

#define SEARCH_PATTERN_DEFAULT	"#?"
#define SEARCH_CONTENTS_DEFAULT	""
#define SEARCH_FILETYPE_DEFAULT	""

#define BUFFERSIZE (4096*10) /* XXX: perhaps should be 8192 ? test.. */

#define USE_EXALL	1

// maximum number of popup nlist entries that will be saved persistently
#define	MAX_SAVED_NLIST_ENTRIES	10

#define KeyButtonHelp(name,key,HelpText)\
	TextObject,\
		ButtonFrame,\
		MUIA_CycleChain, TRUE, \
		MUIA_Font, MUIV_Font_Button,\
		MUIA_Text_Contents, (IPTR)name,\
		MUIA_Text_PreParse, (IPTR)"\33c",\
		MUIA_Text_HiChar  , (IPTR)key,\
		MUIA_ControlChar  , (IPTR)key,\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
		MUIA_ShortHelp, (IPTR)HelpText,\
		End

struct ResultsListEntry
	{
	STRPTR rle_Name;
	STRPTR rle_Path;
	STRPTR rle_CopyString;
	};

struct FindResult
	{
	BPTR fr_Lock;		// Lock to parent directory
	STRPTR fr_Name;		// File name
	};

struct MyNListExport
	{
	ULONG nle_Size;		// Total Size
	char nle_Data[0];	// Contents
	};

//----------------------------------------------------------------------------

// local functions

static void init(void);
static void fail(APTR APP_Main, CONST_STRPTR str);
static BOOL OpenLibraries(void);
static void CloseLibraries(void);
static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT IntuiMessageHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT SelectSourceHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT RemoveSourceHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT AddSourceHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ResultsConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm);
static SAVEDS(void) INTERRUPT ResultsDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm);
static SAVEDS(ULONG) INTERRUPT ResultsDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm);
static SAVEDS(LONG) INTERRUPT ResultsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm);
static SAVEDS(LONG) INTERRUPT ResultsCopyEntryToClipHookFunc(struct Hook *hook, Object *obj, struct NList_CopyEntryToClipMessage *ncm);
static SAVEDS(LONG) INTERRUPT StartSearchHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT StopSearchHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT OpenResultHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT CopyResultsToClipHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT OpenResultWithFindHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT OpenResultWithMultiviewHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT FileTypesConstructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm);
static SAVEDS(void) INTERRUPT FileTypesDestructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm);
static SAVEDS(ULONG) INTERRUPT FileTypesDisplayHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm);
static SAVEDS(LONG) INTERRUPT HideFindHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT PatternHistoryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT ContentsHistoryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT FiletypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT CheckEmptyStringsHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT FindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(LONG) INTERRUPT FindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(APTR) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT FileTypesPopupWindowHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(VOID) INTERRUPT ClearHistoryHookFunc(struct Hook *hook, Object *o, Msg msg);

static void StartSearch(void);
static void DoSearchPath(CONST_STRPTR Path, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype);
static void DoSearchDir(BPTR DirLock, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype);
static void SearchEntry(BPTR DirLock, CONST_STRPTR Name, LONG DirEntryType,
	CONST_STRPTR Pattern, CONST_STRPTR Contents, CONST_STRPTR Filetype);
static void SearchFile(CONST_STRPTR FileName, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype);
static void preQsBc(const UBYTE *x, LONG m, LONG qsBc[]);
static BOOL SearchTypeNodeTree(const struct TypeNode *tn, CONST_STRPTR Name);
static LONG QuickSearch(const UBYTE *x, LONG m, UBYTE *y, LONG n);
static BOOL MatchFileContents(BPTR fh, CONST_STRPTR Contents);

static STRPTR GetLocString(ULONG MsgId);
//static void TranslateStringArray(STRPTR *stringArray);
static void TranslateNewMenu(struct NewMenu *nm);

static void FillSourcesList(struct WBStartup *WBenchMsg);
static Object *MyPopButton(ULONG img);
BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev);
static BOOL SearchFileType(CONST_STRPTR SearchString, BOOL SearchNext);
static LONG GetElapsedTime(T_TIMEVAL *tv);
static struct MUI_NListtree_TreeNode *FindPatternInListtree(Object *lt,
	struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern,
	struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch);
static void AddSourcesLine(CONST_STRPTR NewSourcePath);
static void PushEntry(Object *NList, CONST_STRPTR Contents, LONG Position);
static void ExportNList(Class *cl, Object *obj, struct MUIP_Export *msg);
static void ImportNList(Class *cl, Object *obj, struct MUIP_Import *msg);

//----------------------------------------------------------------------------

static struct Hook AboutHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutFunc), NULL };
static struct Hook AboutMUIHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIFunc), NULL };
static struct Hook AppMessageHook = {{ NULL, NULL }, HOOKFUNC_DEF(AppMessageHookFunc), NULL };
static struct Hook SelectSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectSourceHookFunc), NULL };
static struct Hook RemoveSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(RemoveSourceHookFunc), NULL };
static struct Hook AddSourceHook = {{ NULL, NULL }, HOOKFUNC_DEF(AddSourceHookFunc), NULL };
static struct Hook ResultsConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsConstructHookFunc), NULL };
static struct Hook ResultsDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsDestructHookFunc), NULL };
static struct Hook ResultsDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsDisplayHookFunc), NULL };
static struct Hook ResultsCompareHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsCompareHookFunc), NULL };
static struct Hook ResultsCopyEntryToClipHook = {{ NULL, NULL }, HOOKFUNC_DEF(ResultsCopyEntryToClipHookFunc), NULL };
static struct Hook StartSearchHook = {{ NULL, NULL }, HOOKFUNC_DEF(StartSearchHookFunc), NULL };
static struct Hook StopSearchHook = {{ NULL, NULL }, HOOKFUNC_DEF(StopSearchHookFunc), NULL };
static struct Hook IntuiMessageHook = {{ NULL, NULL }, HOOKFUNC_DEF(IntuiMessageHookFunc), NULL };
static struct Hook OpenResultHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultHookFunc), NULL };
static struct Hook CopyResultsToClipHook = {{ NULL, NULL }, HOOKFUNC_DEF(CopyResultsToClipHookFunc), NULL };
static struct Hook FileTypesConstructHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesConstructHookFunc), NULL };
static struct Hook FileTypesDestructHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesDestructHookFunc), NULL };
static struct Hook FileTypesDisplayHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesDisplayHookFunc), NULL };
static struct Hook HideFindHook = {{ NULL, NULL }, HOOKFUNC_DEF(HideFindHookFunc), NULL };
static struct Hook PatternHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(PatternHistoryHookFunc), NULL };
static struct Hook ContentsHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(ContentsHistoryHookFunc), NULL };
static struct Hook FiletypeSelectHook = {{ NULL, NULL }, HOOKFUNC_DEF(FiletypeSelectHookFunc), NULL };
static struct Hook CheckEmptyStringsHook = {{ NULL, NULL }, HOOKFUNC_DEF(CheckEmptyStringsHookFunc), NULL };
static struct Hook FindFileTypeHook = {{ NULL, NULL }, HOOKFUNC_DEF(FindFileTypeHookFunc), NULL };
static struct Hook FindNextFileTypeHook = {{ NULL, NULL }, HOOKFUNC_DEF(FindNextFileTypeHookFunc), NULL };
static struct Hook CollapseFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(CollapseFileTypesHookFunc), NULL };
static struct Hook ExpandFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(ExpandFileTypesHookFunc), NULL };
static struct Hook CollapseAllFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(CollapseAllFileTypesHookFunc), NULL };
static struct Hook ExpandAllFileTypesHook = {{ NULL, NULL }, HOOKFUNC_DEF(ExpandAllFileTypesHookFunc), NULL };
static struct Hook ClearHistoryHook = {{ NULL, NULL }, HOOKFUNC_DEF(ClearHistoryHookFunc), NULL };
static struct Hook SelectFileTypesEntryHook = {{ NULL, NULL }, HOOKFUNC_DEF(SelectFileTypesEntryHookFunc), NULL };
static struct Hook FileTypesPopupWindowHook = {{ NULL, NULL }, HOOKFUNC_DEF(FileTypesPopupWindowHookFunc), NULL };
static struct Hook OpenResultWithFindHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultWithFindHookFunc), NULL };
static struct Hook OpenResultWithMultiviewHook = {{ NULL, NULL }, HOOKFUNC_DEF(OpenResultWithMultiviewHookFunc), NULL };

//----------------------------------------------------------------------------

// Context menu in "results" list
static struct NewMenu NewContextMenuResults[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_MENU_RESULTS_TITLE,		NULL, 	0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_OPEN,   	NULL, 	0,	0, &OpenResultWithMultiviewHook },
	{  NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_OPENDRAWER, 	NULL, 	0,	0, &OpenResultHook },
	{  NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_COPYTOCLIP, 	NULL, 	0,	0, &CopyResultsToClipHook },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_RESULTS_FIND, 		NULL, 	0,	0, &OpenResultWithFindHook },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,	0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,	0, (APTR) &AboutHook },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

// Context menu in "filetypes" list
static struct NewMenu NewContextMenuFileTypes[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_MENU_FILETYPES_TITLE,	NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSE,	 	NULL, 	NM_ITEMDISABLED,	0, (APTR) &CollapseFileTypesHook },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPAND, 		NULL, 	NM_ITEMDISABLED,	0, (APTR) &ExpandFileTypesHook },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_COLLAPSEALL, 	NULL, 	0,			0, (APTR) &CollapseAllFileTypesHook },
	{  NM_ITEM, (STRPTR) MSGID_MENU_EDIT_EXPANDALL, 	NULL, 	0,			0, (APTR) &ExpandAllFileTypesHook },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) &AboutHook },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

// Context menu in "pattern" and "contents" history popup list
static struct NewMenu NewContextMenuHistoryPopup[] =
	{
	{ NM_TITLE, (STRPTR) MSGID_MENU_FILETYPES_TITLE,	NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_CLEARHISTORY, 		NULL, 	0,			0, (APTR) &ClearHistoryHook },
	{  NM_ITEM, NM_BARLABEL,				NULL, 	0,			0, NULL },
	{  NM_ITEM, (STRPTR) MSGID_MENU_PROJECT_ABOUT,		NULL, 	0,			0, (APTR) &AboutHook },

	{   NM_END, NULL, NULL,		0, 0, 0,},
	};

//----------------------------------------------------------------------------

// local data items

struct IntuitionBase *IntuitionBase = NULL;
struct Library *MUIMasterBase = NULL;
struct ScalosBase *ScalosBase = NULL;
T_LOCALEBASE LocaleBase = NULL;
T_TIMERBASE TimerBase;

#ifdef __amigaos4__
struct IntuitionIFace *IIntuition = NULL;
struct MUIMasterIFace *IMUIMaster = NULL;
struct ScalosIFace *IScalos = NULL;
struct LocaleIFace *ILocale = NULL;
struct TimerIFace *ITimer;
#endif

static struct Catalog *FindCatalog;

static BOOL StopSearch = FALSE;

static Object *APP_Main;
static Object *WIN_Main;
static Object *WIN_AboutMUI;
static Object *NListviewSources, *NListSources;
static Object *StringNewSource;
static Object *NListResults;
static Object *StringFilePattern, *StringFileContents, *StringFileType;
static Object *TextCurrentFile;
static Object *GroupFindFiletype;
static Object *ButtonHideFind;
static Object *PopObjectPattern, *PopObjectContents, *PopObjectFiletypes;
static Object *NListPatternHistory, *NListContentsHistory;
static Object *ButtonSearch, *ButtonStop;
static Object *StringFindFileType;
static Object *ButtonFindNextFileType;
static Object *ButtonAddSource, *ButtonRemoveSource;
static Object *PopAslNewSource;
static Object *MenuAbout, *MenuAboutMUI, *MenuQuit;
static Object *MenuExpandFileTypes, *MenuCollapseFileTypes;
static Object *ContextMenuResults;
static Object *ContextMenuFileTypes;
static Object *ContextMenuPatternPopup, *ContextMenuContentsPopup;

Object *ListtreeFileTypes;

extern struct WBStartup *WBenchMsg;

static char CurrentPath[1024];

static T_TIMEREQUEST *TimerIO;
static struct MsgPort *TimerPort;
static T_TIMEVAL LastUpdate;

DISPATCHERPROTO(myFindResultsNList);
DISPATCHERPROTO(myFileTypesNListTree);
DISPATCHERPROTO(myPersistentNList);
DISPATCHERPROTO(myPopObject);

static struct MUI_CustomClass *myFindResultsNListClass;
static struct MUI_CustomClass *myFileTypesNListTreeClass;
static struct MUI_CustomClass *myPersistentNListClass;
static struct MUI_CustomClass *myPopObjectClass;


#if defined(__AROS__)
#define FindResultsNListObject		BOOPSIOBJMACRO_START(myFindResultsNListClass->mcc_Class)
#define FileTypesNListTreeObject	BOOPSIOBJMACRO_START(myFileTypesNListTreeClass->mcc_Class)
#define PersistentNListObject		BOOPSIOBJMACRO_START(myPersistentNListClass->mcc_Class)
#define PopObject			BOOPSIOBJMACRO_START(myPopObjectClass->mcc_Class)
#else
#define FindResultsNListObject		NewObject(myFindResultsNListClass->mcc_Class, NULL
#define FileTypesNListTreeObject	NewObject(myFileTypesNListTreeClass->mcc_Class, NULL
#define PersistentNListObject		NewObject(myPersistentNListClass->mcc_Class, NULL
#define PopObject			NewObject(myPopObjectClass->mcc_Class, NULL
#endif

//----------------------------------------------------------------------------

int main(int argc, char *argv[])
{
	LONG win_opened = 0;
	
	WBenchMsg = (argc == 0) ? (struct WBStartup *)argv : NULL;

	init();

	if (!CheckMCCVersion(MUIC_NListview, 19, 66)
		|| !CheckMCCVersion(MUIC_NListtree, 18, 18))
		{
		d1(KPrintF(__FILE__ "/%s/%ld: CheckMCCVersion failed\n", __FUNC__, __LINE__));
		return 10;
		}

	ContextMenuResults = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuResults, 0);
	if (NULL == ContextMenuResults)
		{
		fail(APP_Main, "Failed to create Results Context Menu.");
		}

	ContextMenuFileTypes = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuFileTypes, 0);
	if (NULL == ContextMenuFileTypes)
		{
		fail(APP_Main, "Failed to create Filetypes Context Menu.");
		}

	ContextMenuPatternPopup	= MUI_MakeObject(MUIO_MenustripNM, NewContextMenuHistoryPopup, 0);
	if (NULL == ContextMenuPatternPopup)
		{
		fail(APP_Main, "Failed to create Pattern Popup Context Menu.");
		}

	ContextMenuContentsPopup = MUI_MakeObject(MUIO_MenustripNM, NewContextMenuHistoryPopup, 0);
	if (NULL == ContextMenuContentsPopup)
		{
		fail(APP_Main, "Failed to create Contents Popup Context Menu.");
		}

	APP_Main = ApplicationObject,
		MUIA_Application_Title,		(IPTR)GetLocString(MSGID_TITLENAME),
		MUIA_Application_Version,	(IPTR)"$VER: Scalos Find.module V" VERS_MAJOR "." VERS_MINOR " (" __DATE__ ") " COMPILER_STRING,
		MUIA_Application_Copyright,	(IPTR)"© The Scalos Team, 2008" CURRENTYEAR,
		MUIA_Application_Author,	(IPTR)"The Scalos Team",
		MUIA_Application_Description,	(IPTR)"Scalos Find module",
		MUIA_Application_Base,		(IPTR)"SCALOS_FIND_MODULE",

		SubWindow, (IPTR)(WIN_Main = WindowObject,
			MUIA_Window_Title, (IPTR)GetLocString(MSGID_TITLENAME),
			MUIA_Window_ID,	MAKE_ID('M','A','I','N'),
			MUIA_Window_AppWindow, TRUE,

			WindowContents, (IPTR)VGroup,

				Child, (IPTR)HGroup,
					Child, (IPTR)VGroup,
						Child, (IPTR)ColGroup(2),
							Child, (IPTR)Label1(GetLocString(MSGID_POPSTRING_NAME)),
							Child, (IPTR)(PopObjectPattern = PopObject,
								MUIA_Popstring_Button, (IPTR)MyPopButton(MUII_PopUp),
								MUIA_Popstring_String, (IPTR)(StringFilePattern = StringObject,
									StringFrame,
									MUIA_CycleChain, TRUE,
									MUIA_String_Contents, (IPTR)SEARCH_PATTERN_DEFAULT,
									End), //StringObject
								MUIA_ShortHelp, (IPTR)GetLocString(MSGID_POPSTRING_NAME_SHORTHELP),
								MUIA_Popobject_Object, (IPTR)VGroup,
									Child, (IPTR)NListviewObject,
										MUIA_NListview_NList, (IPTR)(NListPatternHistory = PersistentNListObject,
											MUIA_ObjectID, OBJID_NLIST_NAME,
											MUIA_ContextMenu, (IPTR)ContextMenuPatternPopup,
											MUIA_NList_Exports, MUIV_NList_Exports_All,
											MUIA_NList_Imports, MUIV_NList_Imports_All,
											MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
											MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
											End), //NListObject
										End, //NListviewObject
									End, //VGroup
								End), //PopobjectObject

							Child, (IPTR)Label1(GetLocString(MSGID_POPSTRING_TEXT)),
							Child, (IPTR)(PopObjectContents = PopObject,
								MUIA_Popstring_Button, (IPTR)MyPopButton(MUII_PopUp),
								MUIA_Popstring_String, (IPTR)(StringFileContents = StringObject,
									StringFrame,
									MUIA_CycleChain, TRUE,
									MUIA_String_Contents, (IPTR)SEARCH_CONTENTS_DEFAULT,
									End), //StringObject
								MUIA_ShortHelp, (IPTR) GetLocString(MSGID_POPSTRING_TEXT_SHORTHELP),
								MUIA_Popobject_Object, (IPTR)VGroup,
									Child, (IPTR)NListviewObject,
										MUIA_NListview_NList, (IPTR)(NListContentsHistory = PersistentNListObject,
											MUIA_ObjectID, OBJID_NLIST_TEXT,
											MUIA_ContextMenu, (IPTR)ContextMenuContentsPopup,
											MUIA_NList_Exports, MUIV_NList_Exports_All,
											MUIA_NList_Imports, MUIV_NList_Imports_All,
											MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
											MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
											End), //NListObject
										End, //NListviewObject
									End, //VGroup
								End), //PopobjectObject

							Child, (IPTR)Label1(GetLocString(MSGID_POPSTRING_TYPE)),
							Child, (IPTR)(PopObjectFiletypes = PopObject,
								MUIA_Popstring_Button, (IPTR)MyPopButton(MUII_PopUp),
								MUIA_Popstring_String, (IPTR)(StringFileType = StringObject,
									StringFrame,
									MUIA_CycleChain, TRUE,
									MUIA_String_Contents, (IPTR)SEARCH_FILETYPE_DEFAULT,
									End), //StringObject
								MUIA_ShortHelp, (IPTR) GetLocString(MSGID_POPSTRING_TYPE_SHORTHELP),
								MUIA_Popobject_WindowHook, (IPTR)&FileTypesPopupWindowHook,
								MUIA_Popobject_Object, (IPTR)VGroup,
									Child, (IPTR)NListviewObject,
										MUIA_CycleChain, TRUE,
										MUIA_ShortHelp, (IPTR) GetLocString(MSGID_SHORTHELP_LISTVIEW_FILETYPES),
										MUIA_NListview_NList, (IPTR)(ListtreeFileTypes = FileTypesNListTreeObject,
											MUIA_Background, MUII_ListBack,
											MUIA_NListtree_DisplayHook, (IPTR)&FileTypesDisplayHook,
											MUIA_NListtree_ConstructHook, (IPTR)&FileTypesConstructHook,
											MUIA_NListtree_DestructHook, (IPTR)&FileTypesDestructHook,
											MUIA_NListtree_FindNameHook, MUIV_NListtree_FindNameHook_PartCaseInsensitive,
											MUIA_NListtree_EmptyNodes, TRUE,
											MUIA_NListtree_AutoVisible, MUIV_NListtree_AutoVisible_Expand,
											MUIA_ContextMenu, (IPTR)ContextMenuFileTypes,
											End), //myFileTypesNListTreeClass
										End, //NListviewObject
									Child, (IPTR)(GroupFindFiletype = HGroup,
										GroupFrame,
										Child, (IPTR)(ButtonHideFind = TextObject,
											MUIA_Weight, 10,
											ButtonFrame,
											MUIA_CycleChain, TRUE,
#if defined(MUII_Close)
											MUIA_Text_Contents, (IPTR) MUIX_C "\33I[6:" STR(MUII_Close) "]",
#else
											MUIA_Text_Contents, (IPTR) MUIX_C "\33I[6:" STR(MUII_TapeStop) "]",
#endif
											MUIA_InputMode, MUIV_InputMode_RelVerify,
											MUIA_Background, MUII_ButtonBack,
											MUIA_ShortHelp, (IPTR)GetLocString(MSGID_BUTTON_FIND_HIDE_SHORTHELP),
											End),

										Child, (IPTR)(StringFindFileType = StringObject,
											MUIA_CycleChain, TRUE,
											StringFrame,
											End), //StringObject
										Child, (IPTR)(ButtonFindNextFileType = KeyButtonHelp(GetLocString(MSGID_BUTTON_FIND_NEXT),
											*GetLocString(MSGID_BUTTON_FIND_NEXT_KEY),
											GetLocString(MSGID_BUTTON_FIND_NEXT_SHORTHELP))),
										End), //HGroup
									End, //VGroup
								End), //PopobjectObject

							End, //ColGroup

						Child, (IPTR)VGroup,
							MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_SOURCES),
							GroupFrame,
							MUIA_Background, MUII_GroupBack,

							Child, (IPTR)(NListviewSources = NListviewObject,
								MUIA_NListview_NList, (IPTR)(NListSources = NListObject,
									MUIA_CycleChain, TRUE,
									MUIA_NList_ConstructHook, MUIV_NList_ConstructHook_String,
									MUIA_NList_DestructHook, MUIV_NList_DestructHook_String,
									End), //NListObject
								End), //NListviewObject

							Child, (IPTR)HGroup,
								Child, (IPTR)(PopAslNewSource = PopaslObject,
									MUIA_CycleChain, TRUE,
									MUIA_Popasl_Type, ASL_FileRequest,
									MUIA_Popstring_Button, (IPTR)MyPopButton(MUII_PopDrawer),
									MUIA_Popstring_String, (IPTR)(StringNewSource = StringObject,
										StringFrame,
										MUIA_CycleChain, TRUE,
									End), //StringObject

									ASLFR_TitleText, (IPTR) GetLocString(MSGID_GROUP_SOURCES_ASLTITLE),
									ASLFR_DrawersOnly, TRUE,
									ASLFR_IntuiMsgFunc, (IPTR)&IntuiMessageHook,
									End), //PopaslObject

								Child, (IPTR)(ButtonAddSource = KeyButtonHelp(GetLocString(MSGID_BUTTON_ADD),
									*GetLocString(MSGID_BUTTON_ADD_KEY),
		                                                        GetLocString(MSGID_BUTTON_ADD_SHORTHELP))),
								Child, (IPTR)(ButtonRemoveSource = KeyButtonHelp(GetLocString(MSGID_BUTTON_REMOVE),
									*GetLocString(MSGID_BUTTON_REMOVE_KEY),
									GetLocString(MSGID_BUTTON_REMOVE_SHORTHELP))),
								End, //HGroup
							End, //VGroup
						End, //VGroup

					Child, (IPTR)BalanceObject,
						End, // BalanceObject

					Child, (IPTR)VGroup,
						MUIA_FrameTitle, (IPTR) GetLocString(MSGID_GROUP_RESULTS),
						GroupFrame,
						MUIA_Background, MUII_GroupBack,

						Child, (IPTR)NListviewObject,
							//MUIA_CycleChain, TRUE,
							MUIA_NListview_Horiz_ScrollBar, MUIV_NListview_HSB_FullAuto,
							MUIA_NListview_NList, (IPTR)(NListResults = FindResultsNListObject,
								MUIA_CycleChain, TRUE,
								MUIA_NList_Format, (IPTR)"BAR,BAR,",
								MUIA_NList_ConstructHook2, (IPTR)&ResultsConstructHook,
								MUIA_NList_DestructHook2, (IPTR)&ResultsDestructHook,
								MUIA_NList_DisplayHook2, (IPTR)&ResultsDisplayHook,
								MUIA_NList_CompareHook2, (IPTR)&ResultsCompareHook,
								MUIA_NList_CopyEntryToClipHook2, (IPTR)&ResultsCopyEntryToClipHook,
								MUIA_NList_TitleSeparator, TRUE,
								MUIA_NList_Title, TRUE,
								MUIA_NList_SortType, 0,
								MUIA_ContextMenu, (IPTR)ContextMenuResults,
								MUIA_NList_TitleMark, MUIV_NList_TitleMark_Down | 0,
								End), //NListObject
							End, //NListviewObject

	                                        End, //VGroup

					End, // HGroup

				Child, (IPTR)(TextCurrentFile = TextObject,
					MUIA_Text_Contents, (IPTR)"",
					End), //TextObject

				Child, (IPTR)ColGroup(2),
					Child, (IPTR)(ButtonSearch = KeyButtonHelp(GetLocString(MSGID_BUTTON_SEARCH),
						*GetLocString(MSGID_BUTTON_SEARCH_KEY),
						GetLocString(MSGID_BUTTON_SEARCH_SHORTHELP))),
					Child, (IPTR)(ButtonStop = KeyButtonHelp(GetLocString(MSGID_BUTTON_STOP),
						*GetLocString(MSGID_BUTTON_STOP_KEY),
						GetLocString(MSGID_BUTTON_STOP_SHORTHELP))),
					End, //ColGroup
				End, //VGroup
			End), //WindowObject

		MUIA_Application_Menustrip, (IPTR)MenustripObject,
			Child, (IPTR)MenuObjectT((IPTR)GetLocString(MSGID_MENU_PROJECT)),

				Child, (IPTR)(MenuAbout = MenuitemObject,
					MUIA_Menuitem_Title, (IPTR)GetLocString(MSGID_MENU_PROJECT_ABOUT),
				End),
				Child, (IPTR)(MenuAboutMUI = MenuitemObject,
					MUIA_Menuitem_Title, (IPTR)GetLocString(MSGID_MENU_PROJECT_ABOUTMUI),
				End),
				Child, (IPTR)MenuitemObject,
					MUIA_Menuitem_Title, -1,
				End,
				Child, (IPTR)(MenuQuit = MenuitemObject,
					MUIA_Menuitem_Title, (IPTR)GetLocString(MSGID_MENU_PROJECT_QUIT),
					MUIA_Menuitem_Shortcut, (IPTR)GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT),
				End),
					
			End, //MenuObjectT

		End, //MenuStripObject

	End; //ApplicationObject

	if (NULL == APP_Main)
		{
		fail(APP_Main, "Failed to create Application.");
		}

	InitDefIcons();

	DoMethod(APP_Main, MUIM_Application_Load, MUIV_Application_Load_ENV);

	//--------------------------------------------------------------------------//

	DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, 
		WIN_Main, 3, MUIM_Set, MUIA_Window_Open, FALSE);
	DoMethod(WIN_Main, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
		APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

	DoMethod(ButtonStop, MUIM_Notify, MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &StopSearchHook);
	DoMethod(ButtonSearch, MUIM_Notify,MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &StartSearchHook);

	//--------------------------------------------------------------------------//

	// Find selected entries from context menus
	MenuExpandFileTypes = (Object *) DoMethod(ContextMenuFileTypes,
			MUIM_FindUData, &ExpandFileTypesHook);
	MenuCollapseFileTypes = (Object *) DoMethod(ContextMenuFileTypes,
			MUIM_FindUData, &CollapseFileTypesHook);

	// activate StringFilePattern on startup
	set(WIN_Main, MUIA_Window_ActiveObject, StringFilePattern);

	set(ButtonStop, MUIA_Disabled, TRUE);
	set(ButtonRemoveSource, MUIA_Disabled, TRUE);

	// Call hook whenever an entry in sources list is selected
	DoMethod(NListSources, MUIM_Notify, MUIA_NList_SelectChange, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &SelectSourceHook);
	// Call hook whenever "remove source" button is clicked
	DoMethod(ButtonRemoveSource, MUIM_Notify, MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &RemoveSourceHook);
	// Call hook whenever "add source" button is clicked
	DoMethod(ButtonAddSource, MUIM_Notify, MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &AddSourceHook);

	// Call Add Source hook whenever return is hit in source string gadget
	DoMethod(StringNewSource, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &AddSourceHook);

	// Start Search whenever return it hit in "name" string gadget
	DoMethod(StringFilePattern, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &StartSearchHook);

	// Start Search whenever return it hit in "text" string gadget
	DoMethod(StringFileContents, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &StartSearchHook);

	// Call the AppMsgHook when an icon is dropped on sources listview
	DoMethod(NListviewSources, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime,
		 NListviewSources, 3, MUIM_CallHook, &AppMessageHook, MUIV_TriggerValue);

	// Call OpenResultHook when an result entry is double-clicked
	DoMethod(NListResults, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime,
		APP_Main, 3, MUIM_CallHook, &OpenResultHook, MUIV_TriggerValue);

	// Call HideFindHook when Find Filetype Hide button is clicked
	DoMethod(ButtonHideFind, MUIM_Notify, MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &HideFindHook);

	// Call PatternHistoryHook when an entry in pattern history is double-clicked
	DoMethod(NListPatternHistory, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime,
		APP_Main, 3, MUIM_CallHook, &PatternHistoryHook, MUIV_TriggerValue);

	// Call ContentsHistoryHook when an entry in contents history is double-clicked
	DoMethod(NListContentsHistory, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime,
		APP_Main, 3, MUIM_CallHook, &ContentsHistoryHook, MUIV_TriggerValue);

	// Call FiletypeSelectHook when a filetype is double-clicked
	DoMethod(ListtreeFileTypes, MUIM_Notify, MUIA_NListtree_DoubleClick, MUIV_EveryTime,
		APP_Main, 3, MUIM_CallHook, &FiletypeSelectHook, MUIV_TriggerValue);

	// on every contents change, check all 3 search string gadgets,
	// and disable "start search" button if all strings are empty
	DoMethod(StringFilePattern, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook);
	DoMethod(StringFileContents, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook);
	DoMethod(StringFileType, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &CheckEmptyStringsHook);

	// Call FindFileTypeHook everytime the contents of StringFindFileType changes
	DoMethod(StringFindFileType, MUIM_Notify, MUIA_String_Contents, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &FindFileTypeHook);

	// Call FindNextFileTypeHook when "Next" button is clicked
	DoMethod(ButtonFindNextFileType, MUIM_Notify, MUIA_Pressed, FALSE,
		APP_Main, 2, MUIM_CallHook, &FindNextFileTypeHook);

	// call hook everytime a new filetype is selected
	DoMethod(ListtreeFileTypes, MUIM_Notify, MUIA_NListtree_Active, MUIV_EveryTime,
		ListtreeFileTypes, 3, MUIM_CallHook, &SelectFileTypesEntryHook, MUIV_TriggerValue );

	// setup sorting hooks for plugin list
	DoMethod(NListResults, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime,
		NListResults, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
	DoMethod(NListResults, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime,
		NListResults, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2);
	DoMethod(NListResults, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime,
		NListResults, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue);
	DoMethod(NListResults, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime,
		NListResults, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue);

	//--------------------------------------------------------------------------//

	DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &AboutHook);
	DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		APP_Main, 2, MUIM_CallHook, &AboutMUIHook);
	DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
		APP_Main, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

	FillSourcesList(WBenchMsg);

	set(WIN_Main, MUIA_Window_Open, TRUE);
	get(WIN_Main, MUIA_Window_Open, &win_opened);

	if (win_opened)
		{
		ULONG sigs = 0;
		BOOL Run = TRUE;

		while (Run)
			{
			ULONG Action = DoMethod(APP_Main, MUIM_Application_NewInput, &sigs);

			switch (Action)
				{
			case MUIV_Application_ReturnID_Quit:
				Run = FALSE;
				break;
			default:
				break;
				}

			if (Run && sigs)
				{
				sigs = Wait(sigs | SIGBREAKF_CTRL_C);

				if (sigs & SIGBREAKF_CTRL_C) 
					{
					Run = FALSE;
					}
				}
			}
		}
	else
		{
		printf("failed to open main window !\n");
		}

	set(WIN_Main, MUIA_Window_Open, FALSE);

	DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENV);
	DoMethod(APP_Main, MUIM_Application_Save, MUIV_Application_Save_ENVARC);

	fail(APP_Main, NULL);

	return 0;
}

//----------------------------------------------------------------------------

static VOID fail(APTR APP_Main, CONST_STRPTR str)
{
	CleanupDefIcons();

	if (APP_Main)
		{
		MUI_DisposeObject(APP_Main);
		}
	if (ContextMenuFileTypes)
		{
		MUI_DisposeObject(ContextMenuFileTypes);
		ContextMenuFileTypes = NULL;
		}
	if (ContextMenuPatternPopup)
		{
		MUI_DisposeObject(ContextMenuPatternPopup);
		ContextMenuPatternPopup	= NULL;
		}
	if (ContextMenuContentsPopup)
		{
		MUI_DisposeObject(ContextMenuContentsPopup);
		ContextMenuContentsPopup = NULL;
		}
	if (ContextMenuResults)
		{
		MUI_DisposeObject(ContextMenuResults);
		ContextMenuResults = NULL;
		}
	if (FindCatalog)
		{
		CloseCatalog(FindCatalog);
		FindCatalog = NULL;
		}
	if (myPopObjectClass)
		{
		MUI_DeleteCustomClass(myPopObjectClass);
		myPopObjectClass = 0;
		}
	if (myPersistentNListClass)
		{
		MUI_DeleteCustomClass(myPersistentNListClass);
		myPersistentNListClass = NULL;
		}
	if (myFindResultsNListClass)
		{
		MUI_DeleteCustomClass(myFindResultsNListClass);
		myFindResultsNListClass	= NULL;
		}
	if (myFileTypesNListTreeClass)
		{
		MUI_DeleteCustomClass(myFileTypesNListTreeClass);
		myFileTypesNListTreeClass = NULL;
		}

	CloseLibraries();

	if (str)
		{
		puts(str);
		exit(20);
		}

	exit(0);
}

//----------------------------------------------------------------------------

DISPATCHER(myPopObject)
{
	ULONG Result;
	Object *opop = NULL;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_Export:
		d1(KPrintF("%s/%ld:  MUIM_Export\n", __FUNC__, __LINE__));

		get(obj, MUIA_Popobject_Object, &opop);
		if (opop)
			DoMethodA(opop, msg);

		Result = DoSuperMethodA(cl, obj, msg);
		break;

	case MUIM_Import:
		d1(KPrintF("%s/%ld:  MUIM_Import\n", __FUNC__, __LINE__));

		get(obj, MUIA_Popobject_Object, &opop);
		if (opop)
			DoMethodA(opop, msg);

		Result = DoSuperMethodA(cl, obj, msg);
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myPersistentNList)
{
	ULONG Result;

	d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_Export:
		d1(KPrintF("%s/%ld:  MUIM_Export id=%08lx\n", __FUNC__, __LINE__, muiNotifyData(obj)->mnd_ObjectID));
		Result = DoSuperMethodA(cl, obj, msg);
		ExportNList(cl, obj, (struct MUIP_Export *) msg);
		d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result));
		break;

	case MUIM_Import:
		d1(KPrintF("%s/%ld:  MUIM_Import id=%08lx\n", __FUNC__, __LINE__, muiNotifyData(obj)->mnd_ObjectID));
		//Result = DoSuperMethodA(cl, obj, msg);
		ImportNList(cl, obj, (struct MUIP_Import *) msg);
		Result = 0;
		d1(KPrintF(__FILE__ "/%s/%ld: Result=%ld\n", __FUNC__, __LINE__, Result));
		break;

	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		struct Hook *MenuHook = NULL;

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHook);

		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(obj, MUIM_CallHook, MenuHook, 0);

		Result = 0;
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	d1(KPrintF(__FILE__ "/%s/%ld: MethodID=%08lx  Result=%ld\n", __FUNC__, __LINE__, msg->MethodID, Result));

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myFindResultsNList)
{
	ULONG Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_Export:
		d1(KPrintF("%s/%ld:  MUIM_Export\n", __FUNC__, __LINE__));
		Result = DoSuperMethodA(cl, obj, msg);
		break;
	case MUIM_Import:
		d1(KPrintF("%s/%ld:  MUIM_Import\n", __FUNC__, __LINE__));
		Result = DoSuperMethodA(cl, obj, msg);
		break;
	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		struct Hook *MenuHook = NULL;

		d1(KPrintF("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(KPrintF("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(KPrintF("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHook);

		d1(KPrintF("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(APP_Main, MUIM_CallHook, MenuHook, MenuObj);

		Result = 0;
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

DISPATCHER(myFileTypesNListTree)
{
	ULONG Result;

	d1(kprintf(__FILE__ "/%s/%ld: MethodID=%08lx\n", __FUNC__, __LINE__, msg->MethodID));

	switch(msg->MethodID)
		{
	case MUIM_Export:
		d1(KPrintF("%s/%ld:  MUIM_Export\n", __FUNC__, __LINE__));
		Result = DoSuperMethodA(cl, obj, msg);
		break;
	case MUIM_Import:
		d1(KPrintF("%s/%ld:  MUIM_Import\n", __FUNC__, __LINE__));
		Result = DoSuperMethodA(cl, obj, msg);
		break;
	case MUIM_ContextMenuChoice:
		{
		struct MUIP_ContextMenuChoice *cmc = (struct MUIP_ContextMenuChoice *) msg;
		Object *MenuObj;
		struct Hook *MenuHook = NULL;

		d1(kprintf("%s/%ld:  MUIM_ContextMenuChoice  item=%08lx\n", __FUNC__, __LINE__, cmc->item));

		MenuObj = cmc->item;

		d1(kprintf("%s/%ld: MenuObj=%08lx\n", __FUNC__, __LINE__, MenuObj));
		d1(kprintf("%s/%ld: msg=%08lx *msg=%08lx\n", __FUNC__, __LINE__, msg, *((ULONG *) msg)));

		get(MenuObj, MUIA_UserData, &MenuHook);


		d1(kprintf("%s/%ld: MenuHook=%08lx\n", __FUNC__, __LINE__, MenuHook));
		if (MenuHook)
			DoMethod(APP_Main, MUIM_CallHook, MenuHook, 0);

		Result = 0;
		}
		break;

	default:
		Result = DoSuperMethodA(cl, obj, msg);
		}

	return Result;
}
DISPATCHER_END

//----------------------------------------------------------------------------

static void init(void)
{
	if (!OpenLibraries())
		fail(NULL, "Failed to call OpenLibraries");

	if (LocaleBase)
		FindCatalog = OpenCatalogA(NULL, "Scalos/Find.catalog", NULL);

	TranslateNewMenu(NewContextMenuResults);
	TranslateNewMenu(NewContextMenuFileTypes);
	TranslateNewMenu(NewContextMenuHistoryPopup);

	myFindResultsNListClass	= MUI_CreateCustomClass(NULL, MUIC_NList,
		NULL, 0, DISPATCHER_REF(myFindResultsNList));

	myFileTypesNListTreeClass = MUI_CreateCustomClass(NULL, MUIC_NListtree,
		NULL, 0, DISPATCHER_REF(myFileTypesNListTree));

	myPersistentNListClass = MUI_CreateCustomClass(NULL, MUIC_NList,
		NULL, 0, DISPATCHER_REF(myPersistentNList));

	myPopObjectClass = MUI_CreateCustomClass(NULL, MUIC_Popobject,
		NULL, 0, DISPATCHER_REF(myPopObject));
}

//----------------------------------------------------------------------------

static BOOL OpenLibraries(void)
{
	IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 39);
	if (NULL == IntuitionBase)
		fail(NULL, "Failed to open intuition.library.");
#ifdef __amigaos4__
	else
		{
		IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
		if (NULL == IIntuition)
			fail(NULL, "Failed to open intuition interface.");
		}
#endif

	MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN-1);
	if (NULL == MUIMasterBase)
		fail(NULL, "Failed to open muimaster.library.");
#ifdef __amigaos4__
	else
		{
		IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL);
		if (NULL == IMUIMaster)
			fail(NULL, "Failed to open muimaster interface.");
		}
#endif

	ScalosBase = (struct ScalosBase *) OpenLibrary("scalos.library", 40);
	if (NULL == ScalosBase)
		fail(NULL, "Failed to open scalos.library.");
#ifdef __amigaos4__
	else
		{
		IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL);
		if (NULL == IScalos)
			fail(NULL, "Failed to open scalos interface.");
		}
#endif

	LocaleBase = (T_LOCALEBASE) OpenLibrary("locale.library", 39);
#ifdef __amigaos4__
	if (NULL != LocaleBase)
		{
		ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL);
		if (NULL == ILocale)
			fail(NULL, "Failed to open locale interface.");
		}
#endif

	TimerPort = CreateMsgPort();
	TimerIO = (T_TIMEREQUEST *)CreateIORequest(TimerPort, sizeof(T_TIMEREQUEST));
	if (NULL == TimerIO)
		fail(NULL, "Failed to call CreateIORequest.");

	OpenDevice("timer.device", UNIT_VBLANK, &TimerIO->tr_node, 0);
	TimerBase = (T_TIMERBASE) TimerIO->tr_node.io_Device;
	if (NULL == TimerBase)
		fail(NULL, "Failed to open timer.device.");
#ifdef __amigaos4__
	ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL);
	if (NULL == ITimer)
		fail(NULL, "Failed to open timer interface.");
#endif

	return TRUE;
}

//----------------------------------------------------------------------------

static void CloseLibraries(void)
{
	if (TimerIO)
		{
#ifdef __amigaos4__
		DropInterface((struct Interface *)ITimer);
#endif
		CloseDevice(&TimerIO->tr_node);
		DeleteIORequest(&TimerIO->tr_node);

		TimerIO	= NULL;
		TimerBase = NULL;
		}
	if (TimerPort)
		{
		DeleteMsgPort(TimerPort);
		TimerPort = NULL;
		}
	if (LocaleBase)
		{
		if (FindCatalog)
			{
			CloseCatalog(FindCatalog);
			FindCatalog = NULL;
			}
#ifdef __amigaos4__
		if (ILocale)
			{
			DropInterface((struct Interface *)ILocale);
			ILocale = NULL;
			}
#endif
		CloseLibrary((struct Library *) LocaleBase);
		LocaleBase = NULL;
		}
#ifdef __amigaos4__
	if (IScalos)
		{
		DropInterface((struct Interface *)IScalos);
		IScalos = NULL;
		}
#endif
	if (ScalosBase)
		{
		CloseLibrary((struct Library *) ScalosBase);
		ScalosBase = NULL;
		}
#ifdef __amigaos4__
	if (IMUIMaster)
		{
		DropInterface((struct Interface *)IMUIMaster);
		IMUIMaster = NULL;
		}
#endif
	if (MUIMasterBase)
		{
		CloseLibrary(MUIMasterBase);
		MUIMasterBase = NULL;
		}
#ifdef __amigaos4__
	if (IIntuition)
		{
		DropInterface((struct Interface *)IIntuition);
		IIntuition = NULL;
		}
#endif
	if (IntuitionBase)
		{
		CloseLibrary((struct Library *) IntuitionBase);
		IntuitionBase = NULL;
		}
}

//----------------------------------------------------------------------------

static STRPTR GetLocString(ULONG MsgId)
{
	struct Find_LocaleInfo li;

	li.li_Catalog = FindCatalog;  
#ifndef __amigaos4__
	li.li_LocaleBase = LocaleBase;
#else
	li.li_ILocale = ILocale;
#endif

	return (STRPTR)GetFindString(&li, MsgId);
}

//----------------------------------------------------------------------------

#if 0
static void TranslateStringArray(STRPTR *stringArray)
{
	while (*stringArray)
		{
		*stringArray = GetLocString((ULONG) *stringArray);
		stringArray++;
		}
}
#endif

//----------------------------------------------------------------------------

static void TranslateNewMenu(struct NewMenu *nm)
{
	while (nm && NM_END != nm->nm_Type)
		{
		if (NM_BARLABEL != nm->nm_Label)
			nm->nm_Label = GetLocString((IPTR) nm->nm_Label);

		if (nm->nm_CommKey)
			nm->nm_CommKey = GetLocString((IPTR) nm->nm_CommKey);

		nm++;
		}
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT OpenAboutMUIFunc(struct Hook *hook, Object *o, Msg msg)
{
	if (NULL == WIN_AboutMUI)
		{
		WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui,
			MUIA_Window_RefWindow, WIN_Main,
			MUIA_Aboutmui_Application, APP_Main,
			TAG_DONE);
		}

	if (WIN_AboutMUI)
		set(WIN_AboutMUI, MUIA_Window_Open, TRUE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT OpenAboutFunc(struct Hook *hook, Object *o, Msg msg)
{
	MUI_Request(APP_Main, WIN_Main, 0, NULL, 
		GetLocString(MSGID_ABOUTREQOK), 
		GetLocString(MSGID_ABOUTREQFORMAT), 
		VERSION_MAJOR, VERSION_MINOR, COMPILER_STRING, CURRENTYEAR);
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT IntuiMessageHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct IntuiMessage *imsg = (struct IntuiMessage *) msg;

	if (IDCMP_REFRESHWINDOW == imsg->Class)
		DoMethod(APP_Main, MUIM_Application_CheckRefresh);
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT AppMessageHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct AppMessage *AppMsg = *(struct AppMessage **) msg;
	ULONG n;

	d1(KPrintF("%s/%s/%ld: AppMsg=%08lx  am_NumArgs=%ld\n", __FILE__, __FUNC__,, __LINE__, AppMsg, AppMsg->am_NumArgs));

	for (n = 0; n < AppMsg->am_NumArgs; n++)
		{
		struct WBArg *arg = &AppMsg->am_ArgList[n];
		char Path[512];

		NameFromLock(arg->wa_Lock, Path, sizeof(Path));
		AddPart(Path, arg->wa_Name, sizeof(Path));

		d1(KPrintF("%s/%s/%ld: wa_Lock=%08lx\n", __FILE__, __FUNC__,, __LINE__, arg->wa_Lock));

		AddSourcesLine(Path);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT SelectSourceHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	STRPTR SourceEntry = NULL;

	DoMethod(NListSources, MUIM_NList_GetEntry,
		MUIV_NList_GetEntry_Active,
		&SourceEntry);

	// Enable "remove" button only if any entry is selected
	set(ButtonRemoveSource, MUIA_Disabled, NULL == SourceEntry);
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT RemoveSourceHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	LONG pos=0;

	get(NListSources, MUIA_NList_Active, &pos);

	d1(KPrintF( "%s/%s/%ld: pos=%ld\n", __FILE__, __FUNC__, __LINE__, pos));
	if (MUIV_NList_Active_Off != pos)
		{
		DoMethod(NListSources, MUIM_NList_Remove, pos);

		set(NListSources, MUIA_NList_Active, MUIV_NList_Active_Off);
		set(ButtonRemoveSource, MUIA_Disabled, TRUE);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT AddSourceHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	STRPTR NewSource = NULL;

	get(StringNewSource, MUIA_String_Contents, &NewSource);
	if (NewSource && strlen(NewSource) > 0)
		{
		AddSourcesLine(NewSource);
		setstring(StringNewSource, "");
		}
	else
		{
		DoMethod(PopAslNewSource, MUIM_Popstring_Open);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT ResultsConstructHookFunc(struct Hook *hook, APTR unused, struct NList_ConstructMessage *nlcm)
{
	struct ResultsListEntry *rle = AllocPooled(nlcm->pool, sizeof(struct ResultsListEntry));
	BOOL Success = FALSE;

	(void) unused;

	do	{
		struct FindResult *newFr = (struct FindResult *) nlcm->entry;
		STRPTR Path;
		size_t Length = 1024;

		if (NULL == rle)
			break;

		rle->rle_CopyString = NULL;

		rle->rle_Name = strdup(newFr->fr_Name);
		if (NULL == rle->rle_Name)
			break;

		Path = malloc(Length);
		if (NULL == Path)
			break;

		if (!NameFromLock(newFr->fr_Lock, Path, Length))
			break;

		rle->rle_Path = strdup(Path);
		if (NULL == rle->rle_Path)
			break;

		Success = TRUE;
		} while (0);

	if (!Success)
		{
		if (rle)
			{
			if (rle->rle_Name)
				free(rle->rle_Name);
			if (rle->rle_Path)
				free(rle->rle_Path);
			if (rle->rle_CopyString)
				free(rle->rle_CopyString);
			FreePooled(nlcm->pool, rle, sizeof(struct ResultsListEntry));
			rle = NULL;
			}
		}

	return (APTR) rle;
}


static SAVEDS(void) INTERRUPT ResultsDestructHookFunc(struct Hook *hook, APTR unused, struct NList_DestructMessage *nldm)
{
	struct ResultsListEntry *rle = (struct ResultsListEntry *) nldm->entry;

	(void) unused;

	if (rle->rle_Name)
		free(rle->rle_Name);
	if (rle->rle_Path)
		free(rle->rle_Path);
	if (rle->rle_CopyString)
		free(rle->rle_CopyString);

	FreePooled(nldm->pool, rle, sizeof(struct ResultsListEntry));
}


static SAVEDS(ULONG) INTERRUPT ResultsDisplayHookFunc(struct Hook *hook, APTR unused, struct NList_DisplayMessage *nldm)
{
	(void) unused;

	if (nldm->entry)
		{
		struct ResultsListEntry *rle = (struct ResultsListEntry *) nldm->entry;

		nldm->strings[0] = rle->rle_Name;
		nldm->strings[1] = rle->rle_Path;
		}
	else
		{
		// display titles
		nldm->strings[0] = GetLocString(MSGID_RESULTLIST_NAME);
		nldm->strings[1] = GetLocString(MSGID_RESULTLIST_LOCATION);
		}

	return 0;
}


static SAVEDS(LONG) INTERRUPT ResultsCompareHookFunc(struct Hook *hook, Object *obj, struct NList_CompareMessage *ncm)
{
	const struct ResultsListEntry *rle1 = (const struct ResultsListEntry *) ncm->entry1;
	const struct ResultsListEntry *rle2 = (const struct ResultsListEntry *) ncm->entry2;
	LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask;
	LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask;
	LONG Result = 0;

	if (ncm->sort_type != MUIV_NList_SortType_None)
		{
		// primary sorting
		switch (col1)
			{
		case 0:		// sort by name
			if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
				Result = Stricmp(rle2->rle_Name, rle1->rle_Name);
			else
				Result = Stricmp(rle1->rle_Name, rle2->rle_Name);
			break;
		case 1:		// sort by path
			if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
				Result = Stricmp(rle2->rle_Path, rle1->rle_Path);
			else
				Result = Stricmp(rle1->rle_Path, rle2->rle_Path);
			break;
		default:
			break;
			}

		if (0 == Result && col1 != col2)
			{
			// Secondary sorting
			switch (col2)
				{
			case 0:		// sort by name
				if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask)
					Result = Stricmp(rle2->rle_Name, rle1->rle_Name);
				else
					Result = Stricmp(rle1->rle_Name, rle2->rle_Name);
				break;
			case 1:		// sort by path
				if (ncm->sort_type2 & MUIV_NList_TitleMark2_TypeMask)
					Result = Stricmp(rle2->rle_Path, rle1->rle_Path);
				else
					Result = Stricmp(rle1->rle_Path, rle2->rle_Path);
				break;
			default:
				break;
				}
			}
		}

	return Result;
}


static SAVEDS(LONG) INTERRUPT ResultsCopyEntryToClipHookFunc(struct Hook *hook, Object *obj, struct NList_CopyEntryToClipMessage *ncc)
{
	struct ResultsListEntry *rle = (struct ResultsListEntry *) ncc->entry;
	LONG Result = 0;
	size_t len;

	len = strlen(rle->rle_Path)
		+ 1		// room for separator
		+ strlen(rle->rle_Name)
		+ 2;		// room for "\n" and trailing 0.

	rle->rle_CopyString = realloc(rle->rle_CopyString, len);
	if (rle->rle_CopyString)
		{
		strcpy(rle->rle_CopyString, rle->rle_Name);
		strcat(rle->rle_CopyString, "\t");
		strcat(rle->rle_CopyString, rle->rle_Path);
		strcat(rle->rle_CopyString, "\n");

		ncc->str_result = rle->rle_CopyString;
		}

	return Result;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT StartSearchHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;

	StartSearch();

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT StopSearchHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;

	StopSearch = TRUE;

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(VOID) INTERRUPT OpenResultHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;

	do	{
		struct ResultsListEntry *rle = NULL;

		DoMethod(NListResults, MUIM_NList_GetEntry,
			MUIV_NList_GetEntry_Active, &rle);

		if (NULL == rle)
			break;

		// Open result drawer in Scalos
		SCA_OpenDrawerByNameTags(rle->rle_Path,
			SCA_ShowAllMode, DDFLAGS_SHOWALL,
			TAG_END);
                } while (0);
}


static SAVEDS(VOID) INTERRUPT CopyResultsToClipHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;

	DoMethod(NListResults, MUIM_NList_CopyToClip,
		MUIV_NList_CopyToClip_All,
		0,	// clipboard number to copy to
		NULL,
		NULL );
}


static SAVEDS(VOID) INTERRUPT OpenResultWithFindHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct WBArg wbArg[2] = { { (BPTR)NULL }, { (BPTR)NULL } };
	BOOL Success = FALSE;

	(void) hook;
	(void) o;
	(void) msg;

	do	{
		struct ResultsListEntry *rle = NULL;

		if (NULL == WBenchMsg)
			break;

		DoMethod(NListResults, MUIM_NList_GetEntry,
			MUIV_NList_GetEntry_Active, &rle);

		if (NULL == rle)
			break;

		wbArg[1].wa_Name = rle->rle_Name;
		wbArg[1].wa_Lock = Lock(rle->rle_Path, ACCESS_READ);
		if ((BPTR)NULL == wbArg[1].wa_Lock)
			break;;

		wbArg[0].wa_Name = WBenchMsg->sm_ArgList[0].wa_Name;
		wbArg[0].wa_Lock = DupLock(WBenchMsg->sm_ArgList[0].wa_Lock);
		if ((BPTR) NULL == wbArg[0].wa_Lock)
			break;

		// SCA_WBStart()
		Success = SCA_WBStartTags(wbArg, 2,
				SCA_Flags, SCAF_WBStart_Wait,
				SCA_WaitTimeout, 0,
				TAG_END);
                } while (0);

	if (!Success)
		{
		if (wbArg[0].wa_Lock)
			UnLock(wbArg[0].wa_Lock);
		if (wbArg[1].wa_Lock)
			UnLock(wbArg[1].wa_Lock);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(VOID) INTERRUPT OpenResultWithMultiviewHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct WBArg wbArg[2] = { { (BPTR)NULL }, { (BPTR)NULL } };
	BOOL Success = FALSE;

	(void) hook;
	(void) o;
	(void) msg;

	do	{
		struct ResultsListEntry *rle = NULL;

		DoMethod(NListResults, MUIM_NList_GetEntry,
			MUIV_NList_GetEntry_Active, &rle);

		if (NULL == rle)
			break;

		wbArg[1].wa_Name = rle->rle_Name;
		wbArg[1].wa_Lock = Lock(rle->rle_Path, ACCESS_READ);
		if ((BPTR)NULL == wbArg[1].wa_Lock)
			break;;

		wbArg[0].wa_Name = (STRPTR) "Multiview";
		wbArg[0].wa_Lock = Lock("SYS:Utilities", ACCESS_READ);
		if ((BPTR) NULL == wbArg[0].wa_Lock)
			break;

		// SCA_WBStart()
		Success = SCA_WBStartTags(wbArg, 2,
				SCA_Flags, SCAF_WBStart_Wait,
				SCA_WaitTimeout, 0,
				TAG_END);
                } while (0);

	if (!Success)
		{
		if (wbArg[0].wa_Lock)
			UnLock(wbArg[0].wa_Lock);
		if (wbArg[1].wa_Lock)
			UnLock(wbArg[1].wa_Lock);
		}
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT FileTypesConstructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_ConstructMessage *ltcm)
{
	struct FileTypesEntry *fte;
	BOOL Success = FALSE;

	d1(kprintf(__FILE__ "/%s/%ld: obj=%08lx  ltcm=%08lx  memPool=%08lx  UserData=%08lx\n", \
		__FUNC__, __LINE__, obj, ltcm, ltcm->MemPool, ltcm->UserData));

	do	{
		const struct TypeNode *TnOrig = ltcm->UserData;

		fte = AllocPooled(ltcm->MemPool, sizeof(struct FileTypesEntry));
		d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte));
		if (NULL == fte)
			break;

		NewList(&fte->fte_MagicList);
		fte->fte_TypeNode = *TnOrig;

		fte->fte_AllocatedName = fte->fte_TypeNode.tn_Name = strdup(TnOrig->tn_Name);
		if (NULL == fte->fte_AllocatedName)
			break;

		Success = TRUE;
		} while (0);

	if (!Success && fte)
		{
		if (fte->fte_AllocatedName)
			{
			free(fte->fte_AllocatedName);
			fte->fte_AllocatedName = NULL;
			}
		FreePooled(ltcm->MemPool, fte, sizeof(struct FileTypesEntry));
		fte = NULL;
		}

	return fte;
}

static SAVEDS(void) INTERRUPT FileTypesDestructHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DestructMessage *ltdm)
{
	struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->UserData;

	d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte));

	if (fte->fte_AllocatedName)
		free(fte->fte_AllocatedName);

	FreePooled(ltdm->MemPool, fte, sizeof(struct FileTypesEntry));
	ltdm->UserData = NULL;
}

static SAVEDS(ULONG) INTERRUPT FileTypesDisplayHookFunc(struct Hook *hook, APTR obj, struct MUIP_NListtree_DisplayMessage *ltdm)
{
	struct FileTypesEntry *fte = (struct FileTypesEntry *) ltdm->TreeNode->tn_User;

	d1(KPrintF(__FILE__ "/%s/%ld: fte=%08lx\n", __FUNC__, __LINE__, fte));

	if (fte)
		{
		ltdm->Array[0] = fte->fte_TypeNode.tn_Name;
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT HideFindHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	LONG isVisible = 0;

	(void) hook;
	(void) o;
	(void) msg;

	get(GroupFindFiletype, MUIA_ShowMe, &isVisible);
	set(GroupFindFiletype, MUIA_ShowMe, !isVisible);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT PatternHistoryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	LONG *pPos = (LONG *) msg;

	(void) hook;
	(void) o;

	if (*pPos >= 0)
		{
		STRPTR entry;

		DoMethod(NListPatternHistory, MUIM_NList_GetEntry, *pPos, &entry);
		d1(KPrintF(__FILE__ "/%s/%ld: *pPos=%ld  entry=%08lx\n", __FUNC__, __LINE__, *pPos, entry));
		if (entry)
			setstring(StringFilePattern, entry);

		DoMethod(PopObjectPattern, MUIM_Popstring_Close, 1);
		}

	return 0;
}
//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT ContentsHistoryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	LONG *pPos = (LONG *) msg;

	(void) hook;
	(void) o;

	if (*pPos >= 0)
		{
		STRPTR entry;

		DoMethod(NListContentsHistory, MUIM_NList_GetEntry, *pPos, &entry);
		d1(KPrintF(__FILE__ "/%s/%ld: *pPos=%ld  entry=%08lx\n", __FUNC__, __LINE__, *pPos, entry));
		if (entry)
			setstring(StringFileContents, entry);

		DoMethod(PopObjectContents, MUIM_Popstring_Close, 1);
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT FiletypeSelectHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct MUI_NListtree_TreeNode **tn = (struct MUI_NListtree_TreeNode **) msg;

	(void) hook;
	(void) o;

	d1(KPrintF(__FILE__ "/%s/%ld: tn=%08lx\n", __FUNC__, __LINE__, *tn));
	d1(KPrintF(__FILE__ "/%s/%ld: tn_Name=<%s>\n", __FUNC__, __LINE__, (*tn)->tn_Name));

	setstring(StringFileType, (*tn)->tn_Name);

	DoMethod(PopObjectFiletypes, MUIM_Popstring_Close, 1);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT CheckEmptyStringsHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	CONST_STRPTR FilePattern = NULL;
	CONST_STRPTR FileContents = NULL;
	CONST_STRPTR FileType = NULL;
	size_t TotalLength = 0;

	(void) hook;
	(void) o;
	(void) msg;

	get(StringFilePattern, MUIA_String_Contents, &FilePattern);
	get(StringFileContents, MUIA_String_Contents, &FileContents);
	get(StringFileType, MUIA_String_Contents, &FileType);

	if (FilePattern)
		TotalLength += strlen(FilePattern);
	if (FileContents)
		TotalLength += strlen(FileContents);
	if (FileType)
		TotalLength += strlen(FileType);

	set(ButtonSearch, MUIA_Disabled, 0 == TotalLength);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT FindFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	CONST_STRPTR FindString = NULL;

	(void) hook;
	(void) o;
	(void) msg;

	get(StringFindFileType, MUIA_String_Contents, &FindString);

	if (FindString && strlen(FindString) > 0)
		{
#if 1
		SearchFileType(FindString, FALSE);
#else
		DoMethod(ListtreeFileTypes, MUIM_NListtree_FindName,
			MUIV_NListtree_FindName_ListNode_Root,
			FindString, MUIV_NListtree_FindName_Flag_Activate);
#endif
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(LONG) INTERRUPT FindNextFileTypeHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	CONST_STRPTR FindString = NULL;

	(void) hook;
	(void) o;
	(void) msg;

	get(StringFindFileType, MUIA_String_Contents, &FindString);

	if (FindString && strlen(FindString) > 0)
		{
#if 1
		SearchFileType(FindString, TRUE);
#else
		struct MUI_NListtree_TreeNode *tn = NULL;

		tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes,
			MUIM_NListtree_GetEntry,
			MUIV_NListtree_GetEntry_ListNode_Active,
			MUIV_NListtree_GetEntry_Position_Active,
			0);
		d1(KPrintF("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

		if (tn)
			{
			tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes,
				MUIM_NListtree_GetEntry,
				tn,
				MUIV_NListtree_GetEntry_Position_Next,
				0);
			d1(KPrintF("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));
			}
		if (NULL == tn)
			tn = (struct MUI_NListtree_TreeNode *) MUIV_NListtree_FindName_ListNode_Root;

		DoMethod(ListtreeFileTypes,
			MUIM_NListtree_FindName,
			MUIV_NListtree_FindName_ListNode_Active,
			FindString,
			MUIV_NListtree_FindName_Flag_StartNode | MUIV_NListtree_FindName_Flag_Activate);
#endif
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT CollapseFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;

	DoMethod(ListtreeFileTypes,
		MUIM_NListtree_Close,
		MUIV_NListtree_Close_ListNode_Active,
		MUIV_NListtree_Close_TreeNode_All,
		0);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct MUI_NListtree_TreeNode *tn;

	(void) hook;
	(void) o;
	(void) msg;

	set(ListtreeFileTypes, MUIA_NList_Quiet, MUIV_NList_Quiet_Full);

	tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes,
		MUIM_NListtree_GetEntry,
		MUIV_NListtree_GetEntry_ListNode_Active,
		MUIV_NListtree_GetEntry_Position_Active,
		0);
	d1(kprintf("%s/%ld: active tn=%08lx  <%s>\n", __FUNC__, __LINE__, tn, tn ? tn->tn_Name : (STRPTR) ""));

	DoMethod(ListtreeFileTypes,
		MUIM_NListtree_Open,
		MUIV_NListtree_Open_ListNode_Active,
		MUIV_NListtree_Open_TreeNode_Active,
		0);

	if (tn)
		{
		struct MUI_NListtree_TreeNode *tnChild;

		tnChild = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes,
			MUIM_NListtree_GetEntry,
			tn,
			MUIV_NListtree_GetEntry_Position_Head,
			0);
		d1(kprintf("%s/%ld: Head tn=%08lx  <%s>\n", __FUNC__, __LINE__, tnChild, tnChild ? tnChild->tn_Name : (STRPTR) ""));

		if (tnChild)
			{
			set(ListtreeFileTypes, MUIA_NListtree_Active, (IPTR) tnChild);

			DoMethod(ListtreeFileTypes,
				MUIM_NListtree_Open,
				MUIV_NListtree_Open_ListNode_Active,
				MUIV_NListtree_Open_TreeNode_All,
				0);
			}

		set(ListtreeFileTypes, MUIA_NListtree_Active, (IPTR) tn);
		}

	set(ListtreeFileTypes, MUIA_NList_Quiet, MUIV_NList_Quiet_None);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT CollapseAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;


	DoMethod(ListtreeFileTypes, MUIM_NListtree_Close,
		MUIV_NListtree_Close_ListNode_Root,
		MUIV_NListtree_Close_TreeNode_All,
		0);

	return NULL;
}

static SAVEDS(APTR) INTERRUPT ExpandAllFileTypesHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	(void) hook;
	(void) o;
	(void) msg;


	DoMethod(ListtreeFileTypes, MUIM_NListtree_Open,
		MUIV_NListtree_Open_ListNode_Root,
		MUIV_NListtree_Open_TreeNode_All,
		0);

	return NULL;
}

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT SelectFileTypesEntryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	struct MUI_NListtree_TreeNode **tn = (struct MUI_NListtree_TreeNode **) msg;

	if (*tn)
		{
		set(MenuExpandFileTypes, MUIA_Menuitem_Enabled, TRUE);
		set(MenuCollapseFileTypes, MUIA_Menuitem_Enabled, TRUE);
		}
	else
		{
		set(MenuExpandFileTypes, MUIA_Menuitem_Enabled, FALSE);
		set(MenuCollapseFileTypes, MUIA_Menuitem_Enabled, FALSE);
		}

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(VOID) INTERRUPT FileTypesPopupWindowHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	Object *PopWindow = (Object *) msg;

	set(PopWindow, MUIA_Window_ActiveObject, StringFindFileType);
}

//----------------------------------------------------------------------------

static SAVEDS(VOID) INTERRUPT ClearHistoryHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	DoMethod(o, MUIM_NList_Clear, 0);
}

//----------------------------------------------------------------------------

static void StartSearch(void)
{
	static ULONG Searching = 0;
	ULONG Entries = 0, n;
	CONST_STRPTR FilePattern = NULL;
	CONST_STRPTR FileContents = NULL;
	CONST_STRPTR FileType = NULL;
	STRPTR PatternBuf = NULL;
	STRPTR ContentsBuf = NULL;
	STRPTR FiletypeBuf = NULL;

	d1(KPrintF("%s/%s/%ld: START  Searching=%lu\n", __FILE__, __FUNC__, __LINE__, Searching));

	do	{
		if (++Searching > 1)
			break;

		set(ButtonSearch, MUIA_Disabled, TRUE);
		set(ButtonStop, MUIA_Disabled, FALSE);
		set(StringFilePattern, MUIA_Disabled, TRUE);
		set(StringFileContents, MUIA_Disabled, TRUE);
		set(StringFileType, MUIA_Disabled, TRUE);

		// Clear search results
		DoMethod(NListResults, MUIM_NList_Clear);

		get(StringFilePattern, MUIA_String_Contents, &FilePattern);
		get(StringFileContents, MUIA_String_Contents, &FileContents);
		get(StringFileType, MUIA_String_Contents, &FileType);

		if (FilePattern && strlen(FilePattern) > 0)
			{
			// Need to match file name
			size_t len = 2 * strlen(FilePattern) + 10;

			PushEntry(NListPatternHistory, FilePattern, MUIV_NList_Insert_Top);

			PatternBuf = malloc(len);
			if (NULL == PatternBuf)
				break;

			if (ParsePatternNoCase(FilePattern, PatternBuf, len) < 0)
				break;
			}
		if (FileContents && strlen(FileContents) > 0)
			{
			// Need to match contents
			PushEntry(NListContentsHistory, FileContents, MUIV_NList_Insert_Top);

			ContentsBuf = strdup(FileContents);
			if (NULL == ContentsBuf)
				break;

			strlwr(ContentsBuf);
			}
		if (FileType && strlen(FileType) > 0)
			{
			FiletypeBuf = strdup(FileType);
			if (NULL == FiletypeBuf)
				break;
			}

		get(NListSources, MUIA_NList_Entries, &Entries);

		for (n = 0; !StopSearch && n < Entries; n++)
			{
			STRPTR SearchPath;

			DoMethod(NListSources, MUIM_NList_GetEntry,
				n, &SearchPath);

			DoSearchPath(SearchPath, PatternBuf, ContentsBuf, FiletypeBuf);

			DoMethod(APP_Main, MUIM_Application_InputBuffered);
			}
		} while (0);

	if (PatternBuf)
		free(PatternBuf);
	if (ContentsBuf)
		free(ContentsBuf);
	if (FiletypeBuf)
		free(FiletypeBuf);

	if (0 == --Searching)
		{
		setstring(StringFilePattern, SEARCH_PATTERN_DEFAULT);
		setstring(StringFileContents, SEARCH_CONTENTS_DEFAULT);
		setstring(StringFileType, SEARCH_FILETYPE_DEFAULT);

		set(TextCurrentFile, MUIA_Text_Contents,
			GetLocString(StopSearch ? MSGID_SEARCH_ABORTED : MSGID_SEARCH_FINISHED));
		set(ButtonStop, MUIA_Disabled, TRUE);
		set(StringFilePattern, MUIA_Disabled, FALSE);
		set(StringFileContents, MUIA_Disabled, FALSE);
		set(StringFileType, MUIA_Disabled, FALSE);

		StopSearch = FALSE;
		}

	d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
}

//----------------------------------------------------------------------------

static void DoSearchPath(CONST_STRPTR Path, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype)
{
	BPTR DirLock;
	size_t PathLength = strlen(CurrentPath);

	d1(KPrintF("%s/%s/%ld: START  Path=<%s>\n", __FILE__, __FUNC__, __LINE__, Path));

	if (Pattern)
		{
		// Match file name pattern
		if (NULL == Contents && NULL == Filetype
			&& MatchPatternNoCase(Pattern, (STRPTR) Path))
			{
			struct FindResult fr;

			d1(KPrintF("%s/%s/%ld: Path=<%s>\n", __FILE__, __FUNC__, __LINE__, Path));

			fr.fr_Lock = CurrentDir((BPTR)NULL);
			CurrentDir(fr.fr_Lock);
			fr.fr_Name = (STRPTR) Path;

			DoMethod(NListResults, MUIM_NList_InsertSingle,
				&fr, MUIV_NList_Insert_Sorted);
			}
		}

	d1(KPrintF("%s/%s/%ld: PathLength=%lu  CurrentPath=<%s>  Path=<%s>\n", \
		__FILE__, __FUNC__, __LINE__, PathLength, CurrentPath, Path));

	if (PathLength)
		AddPart(CurrentPath, Path, sizeof(CurrentPath));
	else
		strcpy(CurrentPath, Path);

	d1(KPrintF("%s/%s/%ld: CurrentPath=<%s>\n", __FILE__, __FUNC__, __LINE__, CurrentPath));

	DirLock = Lock(Path, ACCESS_READ);
	if (DirLock)
		{
		DoSearchDir(DirLock, Pattern, Contents, Filetype);

		UnLock(DirLock);
		}

	CurrentPath[PathLength] = '\0';

	d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
}

//----------------------------------------------------------------------------

static void DoSearchDir(BPTR DirLock, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype)
{
	BPTR OldCurrentDir = CurrentDir(DirLock);
#if USE_EXALL
	const size_t eadSize = 32768;
	struct ExAllControl *eac = NULL;
	struct ExAllData *EAData;
	BOOL More = FALSE;
#else /* USE_EXALL */
	struct FileInfoBlock *fib = NULL;
#endif /* USE_EXALL */

	d1(KPrintF("%s/%s/%ld: START\n", __FILE__, __FUNC__, __LINE__));

	do	{
#if USE_EXALL
		EAData = malloc(eadSize);
		if (NULL == EAData)
			break;

		eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
		if (NULL == eac)
			break;

		eac->eac_MatchString = NULL;
		eac->eac_MatchFunc = NULL;
		eac->eac_LastKey = 0;
		More = TRUE;

		while (!StopSearch && More)
			{
			struct ExAllData *ead;

			DoMethod(APP_Main, MUIM_Application_InputBuffered);

			More = ExAll(DirLock, EAData, eadSize, ED_TYPE, eac);
			if (!More && (IoErr() != ERROR_NO_MORE_ENTRIES))
				break;

			if (0 == eac->eac_Entries)
				continue;

			for (ead = EAData; ead; ead = ead->ed_Next)
				{
				if (GetElapsedTime(&LastUpdate) > 100)
					{
					// Update at most every 100ms
					char FullName[512];

					strcpy(FullName, CurrentPath);
					AddPart(FullName, ead->ed_Name, sizeof(FullName));
					set(TextCurrentFile, MUIA_Text_Contents, FullName);

					GetSysTime(&LastUpdate);
					}

				SearchEntry(DirLock, ead->ed_Name, ead->ed_Type, Pattern, Contents, Filetype);

				DoMethod(APP_Main, MUIM_Application_InputBuffered);
				}
			}
#else /* USE_EXALL */
		fib = AllocDosObject(DOS_FIB, NULL);
		if (NULL == fib)
			break;

		if (!Examine(DirLock, fib))
			break;

		d1(KPrintF("%s/%s/%ld: fib_fileName=<%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName));

		while (!StopSearch)
			{
			if (GetElapsedTime(&LastUpdate) > 100)
				{
				// Update at most every 100ms
				char FullName[512];

				strcpy(FullName, Path);
				AddPart(FullName, fib->fib_FileName, sizeof(FullName));
				set(TextCurrentFile, MUIA_Text_Contents, FullName);

				GetSysTime(&LastUpdate);
				}

			if (!ExNext(DirLock, fib))
				break;

			SearchEntry(DirLock, fib->fib_FileName, fib->fib_DirEntryType, Pattern, Contents, Filetype);

			d1(KPrintF("%s/%s/%ld: fib_fileName=<%s>\n", __FILE__, __FUNC__, __LINE__, fib->fib_FileName));

			DoMethod(APP_Main, MUIM_Application_InputBuffered);
			}
#endif /* USE_EXALL */
		} while (0);

#if USE_EXALL
	if (eac)
		{
		if (More)
			ExAllEnd(DirLock, EAData, eadSize, ED_TYPE, eac);

		FreeDosObject(DOS_EXALLCONTROL, eac);
		}
	if (EAData)
		free(EAData);
#else /* USE_EXALL */
	if (fib)
		FreeDosObject(DOS_FIB, fib);
#endif /* USE_EXALL */

	CurrentDir(OldCurrentDir);
	d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));
}

//----------------------------------------------------------------------------

static void SearchEntry(BPTR DirLock, CONST_STRPTR Name, LONG DirEntryType,
	CONST_STRPTR Pattern, CONST_STRPTR Contents, CONST_STRPTR Filetype)
{
	d1(KPrintF("%s/%s/%ld: Name=<%s>  DirEntryType=%ld\n", __FILE__, __FUNC__, __LINE__, Name, DirEntryType));
	debugLock_d1(DirLock);

	switch (DirEntryType)
		{
	case ST_ROOT:
	case ST_USERDIR:
	case ST_LINKDIR:
		DoSearchPath(Name, Pattern, Contents, Filetype);
		break;

	case ST_SOFTLINK:
	case ST_FILE:
	case ST_LINKFILE:
	case ST_PIPEFILE:
		SearchFile(Name, Pattern, Contents, Filetype);
		break;

	default:
		if (DirEntryType > 0)
			DoSearchPath(Name, Pattern, Contents, Filetype);
		else if (DirEntryType < 0)
			SearchFile(Name, Pattern, Contents, Filetype);
		break;
		}
}

//----------------------------------------------------------------------------

static void SearchFile(CONST_STRPTR FileName, CONST_STRPTR Pattern,
	CONST_STRPTR Contents, CONST_STRPTR Filetype)
{
	do	{
		struct FindResult fr;

		if (Pattern)
			{
			// Match file name pattern
			if (!MatchPatternNoCase(Pattern, (STRPTR) FileName))
				break;
			}
		if (Contents)
			{
			// Match file contents
			BPTR fh;
			BOOL Match;

			fh = Open(FileName, MODE_OLDFILE);
			d1(KPrintF("%s/%s/%ld: FileName=<%s>  fh=%08lx\n", __FILE__, __FUNC__, __LINE__, FileName, fh));
			if (0 == fh)
				break;

			Match = MatchFileContents(fh, Contents);

			Close(fh);

			if (!Match)
				break;
			}
		if (Filetype)
			{
			const struct TypeNode *tn;
			BPTR dirLock;

			dirLock	= CurrentDir((BPTR)NULL);
			CurrentDir(dirLock);
			
			tn = DefIconsIdentify(dirLock, FileName);
			if (tn && IS_TYPENODE(tn))
				{
				d1(KPrintF("%s/%s/%ld: identify: tn_Name=<%s>  Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, FileName));
				if (!SearchTypeNodeTree(tn, Filetype))
					break;
				}
			else
				{
				break;
				}
			}

		fr.fr_Lock = CurrentDir((BPTR)NULL);
		CurrentDir(fr.fr_Lock);
		fr.fr_Name = (STRPTR) FileName;

		DoMethod(NListResults, MUIM_NList_InsertSingle,
			&fr, MUIV_NList_Insert_Sorted);
		} while (0);
}

//----------------------------------------------------------------------------

static BOOL SearchTypeNodeTree(const struct TypeNode *tn, CONST_STRPTR Name)
{
	if (0 == Stricmp(tn->tn_Name, Name))
		{
		d1(KPrintF("%s/%s/%ld: match: tn_Name=<%s>  Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, Name));
		return TRUE;
		}

	for  (tn = tn->tn_Parent; tn; tn = tn->tn_Parent)
		{
		if (0 == Stricmp(tn->tn_Name, Name))
			{
			d1(KPrintF("%s/%s/%ld: match: tn_Name=<%s>  Name=<%s>\n", __FILE__, __FUNC__, __LINE__, tn->tn_Name, Name));
			return TRUE;
			}
		}

	return FALSE;	// not found
}

//----------------------------------------------------------------------------

/*
 * QuickSearch algoritm (Modified Bayer-Moore).
 * http://www-igm.univ-mlv.fr/~lecroq/string/index.html
 */

#define ASIZE 256   /* alphabet size */

static void preQsBc(const UBYTE *x, LONG m, LONG qsBc[])
{
	LONG i;

	for (i = 0; i < ASIZE; ++i)
		qsBc[i] = m + 1;
	for (i = 0; i < m; ++i)
		qsBc[x[i]] = m - i;
}


static LONG QuickSearch(const UBYTE *x, LONG m, UBYTE *y, LONG n)
{
	LONG j, qsBc[ASIZE];

	// Initialize qsBc[]
	preQsBc(x, m, qsBc);

	/* Searching */
	j = 0;
	while (j <= n - m)
	{
		if (memcmp(x, y + j, m) == 0)
			return j;
		j += qsBc[y[j + m]];               /* shift */
	}

	return -1;
}


static BOOL MatchFileContents(BPTR fh, CONST_STRPTR Contents)
{
	UBYTE *ReadBuffer;
	BOOL Match = FALSE;

	do	{
		size_t ContentsLen = strlen(Contents);
		LONG offset = 0;

		ReadBuffer = malloc(1 + BUFFERSIZE);
		if (NULL == ReadBuffer)
			break;

		while (!StopSearch)
			{
			LONG BytesRead;
			ULONG n;

			BytesRead = FRead(fh, ReadBuffer + offset, 1, BUFFERSIZE - offset);
			if (0 == BytesRead)
				break;

			ReadBuffer[BytesRead + offset] = 0;

			for(n = 0; n < BytesRead + offset; n++)
				{
				ReadBuffer[n] = ToLower(ReadBuffer[n]);
				}

			if (-1 != QuickSearch((const UBYTE *)Contents, ContentsLen, ReadBuffer, BytesRead + offset))
				{
				d1(KPrintF("%s/%s/%ld: Contents=<%s>  ContentsLen=%lu\n", __FILE__, __FUNC__, __LINE__, Contents, ContentsLen));
				Match = TRUE;
				break;
				}

			// Copy end of buffer to the begining.
			if (BytesRead == BUFFERSIZE - offset)
				{
				memcpy(ReadBuffer, ReadBuffer + BUFFERSIZE - 1 - ContentsLen, ContentsLen);
				offset = ContentsLen;
				}
			else
				{
				break;
				}

			DoMethod(APP_Main, MUIM_Application_InputBuffered);
			}
		} while (0);

	if (ReadBuffer)
		free(ReadBuffer);

	return Match;
}

//----------------------------------------------------------------------------

static void FillSourcesList(struct WBStartup *WBenchMsg)
{
	if (WBenchMsg && WBenchMsg->sm_ArgList)
		{
		ULONG n;

		for (n = 1; n < WBenchMsg->sm_NumArgs; n++)
			{
			struct WBArg *arg = &WBenchMsg->sm_ArgList[n];
			char Path[512];

			NameFromLock(arg->wa_Lock, Path, sizeof(Path));
			AddPart(Path, arg->wa_Name, sizeof(Path));

			d1(KPrintF("%s/%s/%ld: wa_Lock=%08lx\n", __FILE__, __FUNC__,, __LINE__, arg->wa_Lock));

			AddSourcesLine(Path);
			}
		}
}

//----------------------------------------------------------------------------

static Object *MyPopButton(ULONG img)
{
	Object *obj;

	obj = MUI_MakeObject(MUIO_PopButton, img);

	if (obj)
		{
		set(obj, MUIA_CycleChain, TRUE);
		}

	return obj;
}

//----------------------------------------------------------------------------

//  Checks if a certain version of a MCC is available
BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev)
{
	BOOL flush = TRUE;

	d1(KPrintF(__FILE__ "/" __FUNC__ "/%ld: %s ", __LINE__, name);)

	while (1)
		{
		ULONG ver = 0;
		ULONG rev = 0;
		struct Library *base;
		char libname[256];

		// First we attempt to acquire the version and revision through MUI
		Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE);
		if (obj)
			{
			get(obj, MUIA_Version, &ver);
			get(obj, MUIA_Revision, &rev);

			MUI_DisposeObject(obj);

			if(ver > minver || (ver == minver && rev >= minrev))
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);)
				return TRUE;
				}
			}

		// If we did't get the version we wanted, let's try to open the
		// libraries ourselves and see what happens...
		stccpy(libname, "PROGDIR:mui", sizeof(libname));
		AddPart(libname, name, sizeof(libname));

		if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0)))
			{
			UWORD OpenCnt = base->lib_OpenCnt;

			ver = base->lib_Version;
			rev = base->lib_Revision;

			CloseLibrary(base);

			// we add some additional check here so that eventual broken .mcc also have
			// a chance to pass this test (i.e. Toolbar.mcc is broken)
			if (ver > minver || (ver == minver && rev >= minrev))
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);)
				return TRUE;
				}

			if (OpenCnt > 1)
				{
				if (MUI_Request(NULL, NULL, 0L,
					(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
					(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
                                        (STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE),
					name, minver, minrev, ver, rev))
					{
					flush = TRUE;
					}
				else
					break;
				}

			// Attempt to flush the library if open count is 0 or because the
			// user wants to retry (meaning there's a chance that it's 0 now)

			if (flush)
				{
				struct Library *result;
				extern struct ExecBase *SysBase;

				Forbid();
				if ((result = (struct Library *) FindName(&SysBase->LibList, name)))
					RemLibrary(result);
				Permit();
				flush = FALSE;
				}
			else
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);)

				// We're out of luck - open count is 0, we've tried to flush
				// and still haven't got the version we want
				if (MUI_Request(NULL, NULL, 0L,
					(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
					(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
                                        (STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC),
					name, minver, minrev, ver, rev))
					{
					flush = TRUE;
					}
				else
					break;
				}
			}
		else
			{
			// No MCC at all - no need to attempt flush
			flush = FALSE;
			if (!MUI_Request(NULL, NULL, 0L,
				(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
				(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
                                (STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND),
				name, minver, minrev))
				{
				break;
				}
			}
		}

	return FALSE;
}

//----------------------------------------------------------------------------

// Get elapsed time since time <tv> in milliseconds.
static LONG GetElapsedTime(T_TIMEVAL *tv)
{
	T_TIMEVAL Now;
	LONG Diff;

	GetSysTime(&Now);
	SubTime(&Now, tv);

	Diff = 1000 * Now.tv_secs + Now.tv_micro / 1000;

	d1(kprintf("%s/%s/%ld: Now s=%ld  ms=%ld   Start s=%ld  ms=%ld  Diff=%ld\n", \
		__LINE__, Now.tv_secs, Now.tv_micro, \
			tv->tv_secs, tv->tv_micro, Diff));

	return Diff;
}

//----------------------------------------------------------------------------

static BOOL SearchFileType(CONST_STRPTR SearchString, BOOL SearchNext)
{
	BOOL Found = FALSE;
	STRPTR SearchPattern = NULL;
	STRPTR PatternBuffer = NULL;

	do	{
		struct MUI_NListtree_TreeNode *tn = NULL;
		size_t SearchPatternLength;
		size_t PatternBufLength;
		ULONG dosearch;

		if (SearchString == NULL || strlen(SearchString) < 1)
			break;

		/*
		 * Search for pattern in mimetype name and description.
		 */
		SearchPatternLength = strlen(SearchString) + 2 + 2 + 1;

		SearchPattern = malloc(SearchPatternLength);
		if (NULL == SearchPattern)
			break;

		snprintf(SearchPattern, SearchPatternLength, "#?%s#?", SearchString);

		PatternBufLength = 2 * strlen(SearchPattern) + 2;

		PatternBuffer = malloc(PatternBufLength);
		if (NULL == PatternBuffer)
			break;

		if (ParsePatternNoCase(SearchPattern, PatternBuffer, PatternBufLength) < 0)
			break;

		/*
		 * When searching for next one, fetch selected one first.
		 */

		if (SearchNext)
			{
			tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListtreeFileTypes,
				MUIM_NListtree_GetEntry,
				MUIV_NListtree_GetEntry_ListNode_Active,
				MUIV_NListtree_GetEntry_Position_Active,
                                0);
			}

		dosearch = NULL == tn;

		tn = FindPatternInListtree(ListtreeFileTypes,
			MUIV_NListtree_GetEntry_ListNode_Root, PatternBuffer, tn, &dosearch);

		if (NULL == tn)
			break;

		Found = TRUE;
		/*
		 * Open node if needed and select.
		 */
		DoMethod(ListtreeFileTypes,
			MUIM_NListtree_Open,
			MUIV_NListtree_Open_ListNode_Parent,
			tn,
			0);
		set(ListtreeFileTypes, MUIA_NListtree_Active, tn);

		} while (0);

	if (SearchPattern)
		free(SearchPattern);
	if (PatternBuffer)
		free(PatternBuffer);

	return Found;
}

//----------------------------------------------------------------------------

static struct MUI_NListtree_TreeNode *FindPatternInListtree(Object *ListTree,
	struct MUI_NListtree_TreeNode *list, CONST_STRPTR pattern,
	struct MUI_NListtree_TreeNode *startnode, ULONG *dosearch)
{
	struct MUI_NListtree_TreeNode *tn;
	ULONG pos;

	for (pos = 0; ; pos++)
		{
		tn = (struct MUI_NListtree_TreeNode *) DoMethod(ListTree,
			MUIM_NListtree_GetEntry,
                        list,
			pos,
			MUIV_NListtree_GetEntry_Flag_SameLevel);

		if (NULL == tn)
			break;

		if (tn->tn_Flags & TNF_LIST)
			{
			struct MUI_NListtree_TreeNode *tnChild;

			tnChild	= FindPatternInListtree(ListTree, tn, pattern, startnode, dosearch);

			if (tnChild)
				return tnChild;

			if (*dosearch)
				{
				if (MatchPatternNoCase(pattern, tn->tn_Name))
					return tn;
				}
			}

		if ( tn == startnode )
			*dosearch = TRUE;
		}

	return NULL;
}

//----------------------------------------------------------------------------

static void AddSourcesLine(CONST_STRPTR NewSourcePath)
{
	PushEntry(NListSources, NewSourcePath, MUIV_NList_Insert_Bottom);
}

//----------------------------------------------------------------------------

static void PushEntry(Object *NList, CONST_STRPTR Contents, LONG Position)
{
	ULONG entries = 0;
	ULONG n;

	get(NList, MUIA_NList_Entries, &entries);

	for (n = 0; n < entries; n++)
		{
		STRPTR entry = NULL;

		DoMethod(NList, MUIM_NList_GetEntry,
			n,
			&entry);
		if (entry && 0 == Stricmp(entry, Contents))
			{
			DoMethod(NList,
				MUIM_NList_Remove,
				n);
			get(NList, MUIA_NList_Entries, &entries);
			n--;
			}
		}

	DoMethod(NList, MUIM_NList_InsertSingle,
		Contents,
		MUIV_NList_Insert_Top);
}

//----------------------------------------------------------------------------

static void ExportNList(Class *cl, Object *obj, struct MUIP_Export *msg)
{
	ULONG id = muiNotifyData(obj)->mnd_ObjectID;

	d1(KPrintF("%s/%ld:  START id=%08lx\n", __FUNC__, __LINE__, id));
	if (0 != id)
        {
		size_t TotalLength = 0;
		ULONG entries = 0;
		ULONG n;

		get(obj, MUIA_NList_Entries, &entries);

		if (entries > MAX_SAVED_NLIST_ENTRIES)
			entries = MAX_SAVED_NLIST_ENTRIES;

		for (n = 0; n < entries; n++)
			{
			STRPTR entry = NULL;

			DoMethod(obj, MUIM_NList_GetEntry,
				n,
				&entry);

			if (entry)
				TotalLength += 1 + strlen(entry);
			}

		if (TotalLength)
			{
			struct MyNListExport *nle;

			TotalLength += sizeof(struct MyNListExport);

			nle = malloc(TotalLength);

			if (nle)
				{
				STRPTR bp = nle->nle_Data;

				nle->nle_Size = TotalLength;
				d1(KPrintF("%s/%ld:  entries=%lu  nle_Size=%lu\n", __FUNC__, __LINE__, entries, nle->nle_Size));

				for (n = 0; n < entries; n++)
					{
					STRPTR entry = NULL;

					DoMethod(obj, MUIM_NList_GetEntry,
						n,
						&entry);

					if (entry)
						{
						d1(KPrintF("%s/%ld:  entry=<%s>\n", __FUNC__, __LINE__, entry));
						strcpy(bp, entry);
						bp += 1 + strlen(bp);
						}
					}

				DoMethod(msg->dataspace,
					MUIM_Dataspace_Add,
					nle,
					TotalLength,
	                                id);

				free(nle);
				}
			}
		else
			{
			DoMethod(msg->dataspace, MUIM_Dataspace_Remove, id);
			}
        }
}

//----------------------------------------------------------------------------

static void ImportNList(Class *cl, Object *obj, struct MUIP_Import *msg)
{
	ULONG id = muiNotifyData(obj)->mnd_ObjectID;

	d1(KPrintF("%s/%ld:  START id=%08lx\n", __FUNC__, __LINE__, id));
	if (0 != id)
        {
		struct MyNListExport *nle;

		nle = (struct MyNListExport *) DoMethod(msg->dataspace, MUIM_Dataspace_Find, id);

		d1(KPrintF("%s/%ld:  nle=%08lx\n", __FUNC__, __LINE__, nle));

		if (nle)
			{
			d1(KPrintF("%s/%ld:  nle_Size=%lu\n", __FUNC__, __LINE__, nle->nle_Size));

			if (nle->nle_Size >= sizeof(struct MyNListExport))
				{
				size_t TotalSize = nle->nle_Size - sizeof(struct MyNListExport);
				STRPTR entry = nle->nle_Data;

				while (TotalSize)
					{
					size_t len = 1 + strlen(entry);

					d1(KPrintF("%s/%ld:  TotalSize=%lu  entry=<%s>\n", __FUNC__, __LINE__, TotalSize, entry));

					DoMethod(obj, MUIM_NList_InsertSingle,
						entry,
                                                MUIV_NList_Insert_Bottom);

					entry += len;
					if (TotalSize > len)
						TotalSize -= len;
					else
						TotalSize = 0;
					}
				}
			}
        }
}

//----------------------------------------------------------------------------

...to the top

// Delete.module.c
// $Date$
// $Revision$
// $Id$

//     ___       ___
//   _/  /_______\  \_     ___ ___ __ _                       _ __ ___ ___.
//__//  / _______ \  \\___/                                               \___
//_/ | '  \__ __/  ` | \_/        © Copyright 1999, Christopher Page       \__
// \ | |    | |__  | | / \   Released as Free Software under the GNU GPL   /.
//  >| .    |  _/  . |<   >--- --- -- -                       - -- --- ---<.
// / \  \   | |   /  / \ /   This file is part of the ScalosDelete code    \.
// \  \  \_/   \_/  /  / \  and it is released under the GNU GPL. Please   /.
//  \  \           /  /   \   read the "COPYING" file which should have   /.
// //\  \_________/  /\\ //\    been included in the distribution arc.   /.
//- --\   _______   /-- - --\      for full details of the license      /-----
//-----\_/       \_/---------\   ___________________________________   /------
//                            \_/                                   \_/.
//
// Description:
//
//  Interface setup and entrypoints for ScalosDelete
//
// Functions:
//
//  int  wbmain        (WBStartup   *);
//  int  main          (int , char **);
//  void ExitMUI       (APTR, STRPTR);
//  void InitMUI       (void);
//  void SetupInterface(void);
//
// Detail:
//
//  This file contains the setup/ shutdown, interface creation and entrypoint
//  functions for ScalosDelete. It is written for StormC so some modification
//  will be required to recompile under other systems. Note that StormC uses
//  wbmain() as the entrypoint for workbench launched programs, you can probably
//  remove this if you recompile under SAS/C or similar (DiceC uses the same
//  mechanism).
//
// Modification History:
//
//  [02 June 1999, Chris <chris@worldfoundry.demon.co.uk>]
//
//  Converted header notice to GNU GPL version, checked and recommented where
//  required.
//
// Fold Markers:
//
//  Start: /*GFS*/
//    End: /*GFE*/

#define Delete_CODE
#define Delete_ARRAY
#include"Delete.module.h"

//----------------------------------------------------------------------------

/*GFE*/
// Prototypes
int  wbmain          (struct WBStartup *);
int  main            (int, char **);
void ExitMUI         (APTR, STRPTR);
void InitMUI         (void);
void SetupInterface  (void);

static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg);
static SAVEDS(void) INTERRUPT EnableTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg);
static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev);

//----------------------------------------------------------------------------

const char Version[]   = VERSTAG;

// Library bases and classes. Only hand-open the ones we really need a specific
// version of..
extern struct ExecBase *SysBase;
struct Library *MUIMasterBase = NULL;
struct Library *AslBase       = NULL;
#ifndef __amigaos4__
T_UTILITYBASE UtilityBase     = NULL;
#endif
struct ScalosBase *ScalosBase = NULL;
T_LOCALEBASE LocaleBase       = NULL;
struct Catalog *WordsCat      = NULL;
static struct Locale *DeleteLocale     = NULL;

#ifdef __amigaos4__
struct IntuitionBase *IntuitionBase = NULL;

struct MUIMasterIFace *IMUIMaster = NULL;
struct AslIFace *IAsl             = NULL;
struct ScalosIFace *IScalos       = NULL;
struct LocaleIFace *ILocale       = NULL;
struct IntuitionIFace *IIntuition = NULL;
#endif

// MUI globals
/*GFS*/
Object *MUI_App      = NULL;
Object *WI_Delete    = NULL;

Object *LV_Files     = NULL;
Object *BT_Details   = NULL;
Object *TX_ReadOut   = NULL;

Object *BT_Delete    = NULL;
Object *BT_About     = NULL;
Object *BT_Cancel    = NULL;

Object *GP_Progress  = NULL;
Object *TX_Progress  = NULL;
Object *GA_Progress  = NULL;
Object *BT_STOP      = NULL;

Object *ST_TrashDir  = NULL;
Object *CM_TrashCan  = NULL;
Object *CM_DirConf   = NULL;
Object *CM_FileConf  = NULL;
Object *CM_Quiet     = NULL;
Object *BT_Save      = NULL;
Object *BT_Use       = NULL;
Object *BT_Restore   = NULL;

CONST_STRPTR Pages[ 3] = { NULL };
CONST_STRPTR Keys [14] = { NULL };

static Object *LampUndoPossible;
static Object *TextUndoPossible;

Object *WI_About     = NULL;
Object *BT_About_MUI = NULL;
static Object *MenuAbout;
static Object *MenuAboutMUI;
static Object *MenuQuit;
static Object *WIN_AboutMUI;

static struct Hook AboutMUIHook = { { NULL, NULL }, HOOKFUNC_DEF(OpenAboutMUIHookFunc), NULL };
static struct Hook EnableTrashcanHook = { { NULL, NULL }, HOOKFUNC_DEF(EnableTrashcanHookFunc), NULL };

//----------------------------------------------------------------------------

/* void ExitMUI(APTR, STRPTR)                                                */
/* -=-=-=-=-=-=-=-=-=-=-=-=-=                                                */
/* If an error occurs, or when the window is closed, this routine is called  */
/* to clean up all the resources, display an error message if required and   */
/* then exit().                                                              */
/*                                                                           */
/* Parameters:                                                               */
/*      errApp      Pointer to the MUI Application object to close.          */
/*      errString   String to display in an EasyRequest. If this is          */
/*                  NULL then nothing is displayed                           */

/*GFS*/  void ExitMUI(APTR errApp, STRPTR errString)
{
//	LONG EntryNum = 0;

	struct EasyStruct ErrorDisplay =
		{
	        sizeof(struct EasyStruct),
	        0,
	        "Delete.module Error",      // Not localised (may not have Locale y'see..)
	        "%s",
	        "Ok",
		};

	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
	// Show the error
	if(errString)
		EasyRequest(NULL, &ErrorDisplay, NULL, errString, 0);

	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
	if(errApp)
		MUI_DisposeObject(errApp);

	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));

	// Clean up
	if(FileBuffer)
		free(FileBuffer);
	if(PathBuffer)
		free(PathBuffer);
	if(DirBuffer)
		free(DirBuffer);

	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
	if(WordsCat)
		CloseCatalog(WordsCat     );
	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
	if (DeleteLocale)
		CloseLocale(DeleteLocale);
	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));

#ifdef __amigaos4__
	if (IIntuition )
		DropInterface((struct Interface *)IIntuition  );
#endif
	if (IntuitionBase)
		CloseLibrary((struct Library *) IntuitionBase);
#ifdef __amigaos4__
	if(IMUIMaster   )
		DropInterface((struct Interface *)IMUIMaster  );
#endif
	if(MUIMasterBase)
		CloseLibrary(MUIMasterBase);
#ifdef __amigaos4__
	if(IAsl         )
		DropInterface((struct Interface *)IAsl        );
#endif
	if(AslBase      )
		CloseLibrary(AslBase      );
#ifndef __amigaos4__
	if(UtilityBase  )
		CloseLibrary((struct Library *) UtilityBase  );
#endif
#ifdef __amigaos4__
	if(IScalos      )
		DropInterface((struct Interface *)IScalos     );
#endif
	if(ScalosBase   )
		CloseLibrary(&ScalosBase->scb_LibNode);
	d1(KPrintF("%s/%s/%ld: \n", __FILE__, __FUNC__, __LINE__));
#ifdef __amigaos4__
	if(ILocale      )
		DropInterface((struct Interface *)ILocale     );
#endif
	if(LocaleBase   )
		CloseLibrary((struct Library *) LocaleBase   );

	d1(KPrintF("%s/%s/%ld: END\n", __FILE__, __FUNC__, __LINE__));

	exit(0);
}/*GFE*/


/* void InitMUI(void)                                                        */
/* -=-=-=-=-=-=-=-=-=                                                        */
/* This routine opens the libraries and locale catalog. If an error occurs   */
/* (ie: library will not open, memory allocation fails etc) then ExitMUI()   */
/* is called with an error. Note that the error messages are not localised as*/
/* locale.library may not be available when the error is encountered..       */

/*GFS*/  void InitMUI(void)
{
	if(!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME, MUIMASTER_VMIN)))
		{
	        ExitMUI(NULL, "Unable to open "MUIMASTER_NAME".");
		}
#ifdef __amigaos4__
	else
		{
		IMUIMaster = (struct MUIMasterIFace *)GetInterface((struct Library *)MUIMasterBase, "main", 1, NULL);
		}
#endif

	if(!(AslBase       = OpenLibrary(AslName , 39)))
		{
	        ExitMUI(NULL, "Unable to open "AslName".");
		}
#ifdef __amigaos4__
	else
		{
		IAsl = (struct AslIFace *)GetInterface((struct Library *)AslBase, "main", 1, NULL);
		}
#endif
	if(!(IntuitionBase       = (struct IntuitionBase *) OpenLibrary(IntuitionName , 39)))
		{
		ExitMUI(NULL, "Unable to open " IntuitionName ".");
		}
#ifdef __amigaos4__
	else
		{
		IIntuition = (struct IntuitionIFace *)GetInterface((struct Library *)IntuitionBase, "main", 1, NULL);
		}
#endif
#ifndef __amigaos4__
	if(!(UtilityBase   = (T_UTILITYBASE) OpenLibrary(UTILITYNAME, 39)))
		{
	        ExitMUI(NULL, "Unable to open "UTILITYNAME".");
		}
#endif

	if(!(ScalosBase   = (struct ScalosBase *) OpenLibrary("scalos.library", 39)))
		{
	        ExitMUI(NULL, "Unable to open scalos.library.");
		}
#ifdef __amigaos4__
	else
		{
		IScalos = (struct ScalosIFace *)GetInterface((struct Library *)ScalosBase, "main", 1, NULL);
		}
#endif

	if(!(LocaleBase    = (T_LOCALEBASE)OpenLibrary("locale.library", 37)))
		{
	        ExitMUI(NULL, "Unable to open locale.library v39+");
		}
#ifdef __amigaos4__
	else
		{
		ILocale = (struct LocaleIFace *)GetInterface((struct Library *)LocaleBase, "main", 1, NULL);
		}
#endif

	DeleteLocale = OpenLocale(NULL);
	if (DeleteLocale)
		WordsCat = OpenCatalogA(DeleteLocale, "Scalos/Delete.catalog", NULL);

        if(!(FileBuffer = malloc(MAX_FILENAME_LEN)))
		{
		ExitMUI(NULL, "Unable to allocate file buffer");
		}

        if(!(PathBuffer = malloc(MAX_FILENAME_LEN)))
		{
		ExitMUI(NULL, "Unable to allocate path buffer");
		}

        if(!(DirBuffer  = malloc(MAX_FILENAME_LEN)))
		{
		ExitMUI(NULL, "Unable to allocate directory buffer");
		}
}/*GFE*/

#if 0
/* int wbmain(WBStartup *)                                                   */
/* -=-=-=-=-=-=-=-=-=-=-=-                                                   */
/* Entry point for WB started programs. Required by StormC and DiceC but can */
/* probably be removed for other system. It just calls main() with argc set  */
/* to 0 and argv pointing to the WBStartup message.                          */

/*GFS*/  int wbmain(struct WBStartup *wb_Startup)
{
	return (main(0, (char **)wb_Startup));
}/*GFE*/
#endif

/* int main(int char **)                                                     */
/* -=-=-=-=-=-=-=-=-=-=-                                                     */
/* Eh? You want COMMENTS?? For *MAIN*??? Oh, all right then main routine..   */
/* there that's all your getting. Comments indeed..                          */

/*GFS*/  int main(int argc, char **argv)
{
	BOOL  Running = TRUE;
	ULONG  Sig     =    0;
	ULONG  Source  =    0;

	// Wake up MUI...
	InitMUI();

	if (!CheckMCCVersion(MUIC_NList, 20, 121) ||
		!CheckMCCVersion(MUIC_NListview, 19, 66) ||
		!CheckMCCVersion(MUIC_Lamp, 11, 1) )
		return 10;

	SetupInterface();

	// Bomb if the user has started the program from shell (daft user...) otherwise
	// read the filelist...
	if(argc != 0)
		{
		ExitMUI(MUI_App, "Delete.module may not be started from shell");
		}

	// Bomb out if something has gone clogs-skyward
	if(!MUI_App)
		{
		ExitMUI(MUI_App, "Unable to create application");
		}

	CallHookPkt(&EnableTrashcanHook, MUI_App,  NULL);

	// Some domethods to make processing easier.
	DoMethod(WI_Delete   , MUIM_Notify, MUIA_Window_CloseRequest, TRUE          , MUI_App    , 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
	DoMethod(BT_Cancel   , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

	DoMethod(BT_Delete   , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, DELETE_IT);
	DoMethod(BT_Details  , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, DETAIL_IT);
	DoMethod(BT_STOP     , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, STOP_IT  );

	DoMethod(BT_Save     , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, PREFSSAVE);
	DoMethod(BT_Use      , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, PREFSUSE );
	DoMethod(BT_Restore  , MUIM_Notify, MUIA_Pressed            , FALSE         , MUI_App    , 2, MUIM_Application_ReturnID, PREFSLOAD);

	DoMethod(CM_TrashCan , MUIM_Notify, MUIA_Selected           , MUIV_EveryTime,
		MUI_App, 2, MUIM_CallHook, &EnableTrashcanHook);

	// About handling...
	DoMethod(WI_About    , MUIM_Notify, MUIA_Window_CloseRequest, TRUE , WI_About, 3, MUIM_Set, MUIA_Window_Open, FALSE   );
	DoMethod(BT_About    , MUIM_Notify, MUIA_Pressed            , FALSE, WI_About, 3, MUIM_Set, MUIA_Window_Open, TRUE    );
	DoMethod(BT_About_MUI, MUIM_Notify, MUIA_Pressed            , FALSE, MUI_App , 2, MUIM_Application_AboutMUI , WI_About);

	// Menu handling
	DoMethod(MenuAbout, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		WI_About, 3, MUIM_Set, MUIA_Window_Open, TRUE);
	DoMethod(MenuAboutMUI, MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		MUI_App, 2, MUIM_CallHook, &AboutMUIHook);
	DoMethod(MenuQuit, MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
		MUI_App, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

	// Read in the settings
	DoMethod(MUI_App, MUIM_Application_Load, MUIV_Application_Load_ENV);

	// Get the show on the road...
	set(WI_Delete, MUIA_Window_Open, TRUE);

	// +jmc+ : Activate delete button gadget
	set(WI_Delete, MUIA_Window_ActiveObject, BT_Delete);

	// Open the about window & GNU GPL details....
	get(CM_Quiet , MUIA_Selected   , &Source);
	if(Source == 0)
		set(WI_About, MUIA_Window_Open, TRUE);

	if(!ListFiles((struct WBStartup *)argv))
		ExitMUI(MUI_App, NULL);

	// Main loop: Block on the MUI Notify...
	while (Running)
	{
		Source = DoMethod(MUI_App, MUIM_Application_NewInput, &Sig);
		switch(Source)
			{
		case MUIV_Application_ReturnID_Quit:
		        Running = FALSE;
		        break;
		case PREFSSAVE:
		        DoMethod(MUI_App, MUIM_Application_Save, MUIV_Application_Save_ENVARC);
		case PREFSUSE :
		        DoMethod(MUI_App, MUIM_Application_Save, MUIV_Application_Save_ENV);
		        break;
		case PREFSLOAD:
		        DoMethod(MUI_App, MUIM_Application_Load, MUIV_Application_Load_ENV);
		        break;
		case DETAIL_IT:
		        GetDetails((struct WBStartup *)argv);
		        break;
		case DELETE_IT:
			set(BT_Details, MUIA_Disabled, TRUE);
			set(BT_Delete, MUIA_Disabled, TRUE);
			set(BT_About, MUIA_Disabled, TRUE);
			set(BT_Cancel, MUIA_Disabled, TRUE);
		        KillFiles((struct WBStartup *)argv);
			Running = FALSE;
		        break;
			}
		if(Running && Sig)
			Wait(Sig);
	}

	// Clean up and begone.
	ExitMUI(MUI_App, NULL);

	return 0;
}/*GFE*/


/* void SetupInterface(void)                                                 */
/* -=-=-=-=-=-=-=-=-=-=-=-=-                                                 */
/* Sets up the interface all in one compound command. Much easier to read    */
/* than lots of small functions adding bits here and there IMO...            */

/*GFS*/  void SetupInterface(void)
{
	char VersionBuffer[64];
	char DateBuffer   [64];

	// Set up the compiled and version info...
	sprintf(VersionBuffer, "%d.%d", VERSION, REVISION);
	sprintf(DateBuffer   , "%s %s"   , __TIME__, __DATE__);

	// Localise the page names
	Pages[0] = GetLocString(MSG_PAGES_FILES);
	Pages[1] = GetLocString(MSG_PAGES_PREFS);

	// and the key shortcuts. Bit of a hack this really....
	Keys[ 0]  = GetLocString(MSG_KEY_DETAILS);
	Keys[ 1]  = GetLocString(MSG_KEY_TRASH  );
	Keys[ 2]  = GetLocString(MSG_KEY_DIRS   );
	Keys[ 3]  = GetLocString(MSG_KEY_FILES  );
	Keys[ 4]  = GetLocString(MSG_KEY_QUIET  );
	Keys[ 5]  = GetLocString(MSG_KEY_TLOC   );
	Keys[ 6]  = GetLocString(MSG_KEY_SAVE   );
	Keys[ 7]  = GetLocString(MSG_KEY_USE    );
	Keys[ 8]  = GetLocString(MSG_KEY_REST   );
	Keys[ 9]  = GetLocString(MSG_KEY_DELETE );
	Keys[10]  = GetLocString(MSG_KEY_ABOUT  );
	Keys[11]  = GetLocString(MSG_KEY_CANCEL );
	Keys[12]  = GetLocString(MSG_KEY_STOP   );
	Keys[13]  = GetLocString(MSG_KEY_AMUI   );

	MUI_App = ApplicationObject,
		MUIA_Application_Title      , GetLocString(MSG_APP_TITLE),
                MUIA_Application_Version    , &Version[1],
                MUIA_Application_Copyright  , "(C)1999 Chris Page, The World Foundry",
                MUIA_Application_Author     , "Chris Page, The World Foundry",
		MUIA_Application_Description, GetLocString(MSG_APP_DESC),
                MUIA_Application_Base       , BASENAME,
                MUIA_Application_SingleTask , TRUE,
/*GFS*/         SubWindow, WI_Delete = WindowObject,
		        MUIA_Window_Title      , GetLocString(MSG_WIN_TITLE),
                        MUIA_Window_ID         , MAKE_ID('M','A','I','N'),
                        MUIA_Window_ScreenTitle, VSTR,
                        WindowContents, VGroup,
				Child, RegisterGroup(Pages),
					MUIA_CycleChain, TRUE,
					MUIA_Background, MUII_RegisterBack,
					Child, VGroup,
						Child, HGroup,
						        GroupFrame,
						        MUIA_Background, MUII_GroupBack,
							Child, LampUndoPossible = LampObject,
								MUIA_Lamp_Type, MUIV_Lamp_Type_Huge,
								MUIA_Lamp_Color, MUIV_Lamp_Color_Off,
								End, //LampObject
							Child, TextUndoPossible = TextObject,
								MUIA_Text_Contents, GetLocString(MSGID_UNDO_NOT_POSSIBLE),
								End, //TextObject
							End, //HGroup

						Child, VGroup,
							MUIA_Group_Spacing, 0,
							Child,  LV_Files = NListviewObject,
								MUIA_CycleChain, 1,
		                                                MUIA_NListview_Vert_ScrollBar, TRUE,
		                                                MUIA_NListview_NList         , NListObject,
			                                                MUIA_CycleChain, 1,
			                                                MUIA_NList_Input         , FALSE,
			                                                MUIA_NList_DragSortable  , FALSE,
			                                                MUIA_NList_Title         , TRUE,
			                                                MUIA_NList_Format        , "BAR,BAR,BAR,",
			                                                MUIA_NList_ConstructHook , &ConList,
			                                                MUIA_NList_DestructHook  , &DesList,
			                                                MUIA_NList_DisplayHook   , &DisList,
			                                                MUIA_NList_CompareHook   , &CmpList,
									End, //NListObject
								End, //NListviewObject
							Child, BT_Details = KeyButtonChain(GetLocString(MSG_BUTTON_FULL), Keys[0][0], 1),
							End, //VGroup

	                                        Child, TX_ReadOut =  TextObject,
		                                        TextFrame,
		                                        MUIA_Background, MUII_TextBack,
		                                        MUIA_Weight    , 800,
							MUIA_Text_PreParse, "\33c",
		                                        MUIA_FixHeightTxt , " ",
							End, //TextObject

						End, //VGroup

					Child, VGroup,
						Child, ColGroup(4),
						        GroupFrame,
						        MUIA_Background, MUII_GroupBack,

							Child, HVSpace,
						        Child, KeyLabel1(GetLocString(MSG_LABEL_TRASH), Keys[1][0]),
							Child, CM_TrashCan = KeyCheckMarkHelpID(TRUE, Keys[1][0], 1, MAKE_ID('C', 'M', 'T', 'C'), GetLocString(MSG_HELP_TRASH)),
						        Child, HVSpace,

						        Child, HVSpace,
						        Child, KeyLabel1(GetLocString(MSG_LABEL_DIRS)  , Keys[2][0]),
							Child, CM_DirConf  = KeyCheckMarkHelpID(FALSE, Keys[2][0], 1, MAKE_ID('C', 'M', 'D', 'C'), GetLocString(MSG_HELP_DIRS )),
						        Child, HVSpace,

						        Child, HVSpace,
						        Child, KeyLabel1(GetLocString(MSG_LABEL_FILES), Keys[3][0]),
							Child, CM_FileConf = KeyCheckMarkHelpID(FALSE, Keys[3][0], 1, MAKE_ID('C', 'M', 'F', 'C'), GetLocString(MSG_HELP_FILES)),
						        Child, HVSpace,

						        Child, HVSpace,
						        Child, KeyLabel1(GetLocString(MSG_LABEL_QUIET), Keys[4][0]),
							Child, CM_Quiet    = KeyCheckMarkHelpID(TRUE, Keys[4][0], 1, MAKE_ID('C', 'M', 'Q', 'I'), GetLocString(MSG_HELP_QUIET)),
						        Child, HVSpace,

							End, //ColGroup

						Child, HVSpace,

						Child, HGroup,
							GroupFrameT(GetLocString(MSG_LABEL_TLOC)),

		                                        Child, ST_TrashDir = PopaslObject,
								MUIA_Popstring_String, StringObject,
		                                                        StringFrame,
		                                                        MUIA_String_MaxLen  , 128,
		                                                        MUIA_CycleChain     ,   1,
		                                                        MUIA_ControlChar    , Keys[5][0],
								        MUIA_ShortHelp      , GetLocString(MSG_HELP_TLOC),
		                                                        MUIA_ExportID       , MAKE_ID('S', 'T', 'T', 'C'),
									End, //StringObject
	                                                        MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
	                                                        MUIA_CycleChain      , 1,
							        ASLFR_TitleText      , GetLocString(MSG_ASL_TITLE),
	                                                        ASLFR_RejectIcons    , TRUE,
	                                                        ASLFR_DrawersOnly    , TRUE,
								End, //PopaslObject
							End, //HGroup
	                                        Child, VSpace(0),
	                                        Child, HGroup,
		                                        MUIA_Group_SameSize, TRUE,
						        Child, BT_Save    = KeyButtonChain(GetLocString(MSG_BUTTON_SAVE), Keys[6][0], 1),
						        Child, BT_Use     = KeyButtonChain(GetLocString(MSG_BUTTON_USE ), Keys[7][0], 1),
						        Child, BT_Restore = KeyButtonChain(GetLocString(MSG_BUTTON_REST), Keys[8][0], 1),
							End, //HGroup
						End, //VGroup
					End, //RegisterGroup

                                Child, HGroup,
	                                MUIA_Group_SameSize, TRUE,
				        Child, BT_Delete = KeyButtonChain(GetLocString(MSG_BUTTON_DEL), Keys[ 9][0], 1),
				        Child, BT_About  = KeyButtonChain(GetLocString(MSG_BUTTON_ABT), Keys[10][0], 1),
				        Child, BT_Cancel = KeyButtonChain(GetLocString(MSG_BUTTON_CAN), Keys[11][0], 1),
					End, //HGroup

				Child, GP_Progress = VGroup,
					GroupFrame,
	                                MUIA_Background, MUII_GroupBack,
	                                MUIA_ShowMe, FALSE,
	                                Child, HGroup,
	                                        Child, TX_Progress = TextObject,
							MUIA_Background, MUII_TextBack,
		                                        TextFrame,
		                                        MUIA_Weight    , 800,
		                                        MUIA_Background, MUII_TextBack,
							MUIA_Text_PreParse, "\33c",
		                                        MUIA_FixHeightTxt , " ",
							End, //TextObject
						Child, BT_STOP = KeyButtonChain(GetLocString(MSG_BUTTON_STOP), Keys[12][0], 1),
						End, //HGroup
	                                Child, VGroup,
	                                        Child, GA_Progress = GaugeObject,
		                                        GaugeFrame,
		                                        MUIA_Gauge_Current ,    0,
		                                        MUIA_Gauge_Max     ,  100,
		                                        MUIA_Gauge_Horiz   , TRUE,
		                                        MUIA_FixHeightTxt  , " ",
						        MUIA_Gauge_InfoText, GetLocString(MSG_LABEL_INFO),
							End, //GaugeObject
						Child, ScaleObject,
							MUIA_Scale_Horiz  , TRUE,
							End, //ScaleObject
						End, //VGroup
					End, //VGroup
				End, //VGroup
/*GFE*/			End, //WindowObject

/*GFS*/         SubWindow, WI_About = WindowObject,
		        MUIA_Window_Title      , GetLocString(MSG_BUTTON_ABT),
                        MUIA_Window_ID         , MAKE_ID('A','B','O','T'),
                        MUIA_Window_ScreenTitle, VSTR,
                        WindowContents, VGroup,
                                Child, TextObject,
	                                TextFrame,
	                                MUIA_Background, MUII_TextBack,
				        MUIA_Text_Contents, GetLocString(MSG_ABOUT_HEAD),
					End, //TextObject
				Child, ColGroup(7),
	                                Child, HSpace(0),
	                                Child, TextObject,
						MUIA_Text_Contents, GetLocString(MSG_LABEL_VERS),
						MUIA_Text_PreParse, "\33r",
						End, //TextObject
	                                Child, TextObject,
						MUIA_Text_Contents, VersionBuffer,
						End, //TextObject
	                                Child, HSpace(0),
	                                Child, TextObject,
						MUIA_Text_Contents, GetLocString(MSG_LABEL_COMP),
						MUIA_Text_PreParse, "\33r",
						End, //TextObject
	                                Child, TextObject,
						MUIA_Text_Contents, DateBuffer,
						End, //TextObject
	                                Child, HSpace(0),
					End, //ColGroup
				Child, ScrollgroupObject,
					MUIA_Scrollgroup_Contents, VGroupV,
						VirtualFrame ,
						Child, TextObject,
							MUIA_Background, MUII_TextBack,
							MUIA_Text_Contents, GetLocString(MSG_ABOUT_BODY),
							End, //TextObject
						End, //VGroupV
					End, //ScrollgroupObject

				Child, BT_About_MUI  = KeyButtonChain(GetLocString(MSG_BUTTON_AMUI), Keys[13][0], 1),
				End, //VGroup
/*GFE*/                 End, //WindowObject

		MUIA_Application_Menustrip, MenustripObject,
			Child, MenuObjectT(GetLocString(MSGID_MENU_PROJECT)),

				Child, MenuAbout = MenuitemObject,
					MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUT),
				End,
				Child, MenuAboutMUI = MenuitemObject,
					MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_ABOUTMUI),
				End,
				Child, MenuitemObject,
					MUIA_Menuitem_Title, -1,
				End,
				Child, MenuQuit = MenuitemObject,
					MUIA_Menuitem_Title, GetLocString(MSGID_MENU_PROJECT_QUIT),
					MUIA_Menuitem_Shortcut, GetLocString(MSGID_MENU_PROJECT_QUIT_SHORT),
				End,

			End, //MenuObjectT
		End, //MenuStripObject
	End; //ApplicationObject
}/*GFE*/

//----------------------------------------------------------------------------

CONST_STRPTR GetLocString(ULONG MsgId)
{
	struct Delete_LocaleInfo li;

	li.li_Catalog = WordsCat;
#ifndef __amigaos4__
	li.li_LocaleBase = LocaleBase;
#else
	li.li_ILocale = ILocale;
#endif

//	KPrintF(__FILE__ "%s/%ld: Catalog=%08lx  LocaleBase=%08lx\n",
//		__FUNC__, __LINE__, li.li_Catalog, li.li_LocaleBase);

	return (CONST_STRPTR) GetDeleteString(&li, MsgId);
}

//----------------------------------------------------------------------------

STRPTR safe_strcat(STRPTR dest, CONST_STRPTR src, size_t DestLen)
{
	STRPTR dst;
	size_t Len = strlen(dest);

	if (DestLen < Len)
		return dest;

	DestLen -= Len;
	dst = dest + Len;

	while (DestLen > 1 && *src)
		{
		*dst++ = *src++;
		DestLen--;
		}
	*dst = '\0';

	return dest;
}

//----------------------------------------------------------------------------

#if !defined(__SASC) &&!defined(__MORPHOS__)
// Replacement for SAS/C library functions

size_t stccpy(char *dest, const char *src, size_t MaxLen)
{
	size_t Count = 0;

	while (*src && MaxLen > 1)
		{
		*dest++ = *src++;
		MaxLen--;
		Count++;
		}
	*dest = '\0';
	Count++;

	return Count;
}

#endif /* __SASC */

//----------------------------------------------------------------------------

static SAVEDS(APTR) INTERRUPT OpenAboutMUIHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	if (NULL == WIN_AboutMUI)
		{
		WIN_AboutMUI = MUI_NewObject(MUIC_Aboutmui,
			MUIA_Window_RefWindow, WI_Delete,
			MUIA_Aboutmui_Application, MUI_App,
			End;
		}

	if (WIN_AboutMUI)
		set(WIN_AboutMUI, MUIA_Window_Open, TRUE);

	return 0;
}

//----------------------------------------------------------------------------

static SAVEDS(void) INTERRUPT EnableTrashcanHookFunc(struct Hook *hook, Object *o, Msg msg)
{
	ULONG UseTrashcan = 0;

	get(CM_TrashCan, MUIA_Selected, &UseTrashcan);

	set(ST_TrashDir, MUIA_Disabled, UseTrashcan);
	set(LampUndoPossible, MUIA_Lamp_Color, UseTrashcan ? MUIV_Lamp_Color_Ok : MUIV_Lamp_Color_Error);
	set(TextUndoPossible, MUIA_Text_Contents, GetLocString(UseTrashcan ? MSGID_UNDO_OK : MSGID_UNDO_NOT_POSSIBLE));
}

//----------------------------------------------------------------------------

//  Checks if a certain version of a MCC is available
static BOOL CheckMCCVersion(CONST_STRPTR name, ULONG minver, ULONG minrev)
{
	BOOL flush = TRUE;

	d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: %s ", name, __LINE__);)

	while (1)
		{
		ULONG ver = 0;
		ULONG rev = 0;
		struct Library *base;
		char libname[256];

		// First we attempt to acquire the version and revision through MUI
		Object *obj = MUI_NewObject((STRPTR) name, TAG_DONE);
		if (obj)
			{
			get(obj, MUIA_Version, &ver);
			get(obj, MUIA_Revision, &rev);

			MUI_DisposeObject(obj);

			if(ver > minver || (ver == minver && rev >= minrev))
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through MUIA_Version/Revision\n", __LINE__, ver, rev);)
				return TRUE;
				}
			}

		// If we did't get the version we wanted, let's try to open the
		// libraries ourselves and see what happens...
		stccpy(libname, "PROGDIR:mui", sizeof(libname));
		AddPart(libname, name, sizeof(libname));

		if ((base = OpenLibrary(&libname[8], 0)) || (base = OpenLibrary(&libname[0], 0)))
			{
			UWORD OpenCnt = base->lib_OpenCnt;

			ver = base->lib_Version;
			rev = base->lib_Revision;

			CloseLibrary(base);

			// we add some additional check here so that eventual broken .mcc also have
			// a chance to pass this test (i.e. Toolbar.mcc is broken)
			if (ver > minver || (ver == minver && rev >= minrev))
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: v%ld.%ld found through OpenLibrary()\n", __LINE__, ver, rev);)
				return TRUE;
				}

			if (OpenCnt > 1)
				{
				if (MUI_Request(NULL, NULL, 0L,
					(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
					(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
					(STRPTR) GetLocString(MSGID_STARTUP_MCC_IN_USE),
					name, minver, minrev, ver, rev))
					{
					flush = TRUE;
					}
				else
					break;
				}

			// Attempt to flush the library if open count is 0 or because the
			// user wants to retry (meaning there's a chance that it's 0 now)

			if (flush)
				{
				struct Library *result;

				Forbid();
				if ((result = (struct Library *) FindName(&((struct ExecBase *)SysBase)->LibList, name)))
					RemLibrary(result);
				Permit();
				flush = FALSE;
				}
			else
				{
				d1(kprintf(__FILE__ "/" __FUNC__ "/%ld: couldn`t find minimum required version.\n", __LINE__);)

				// We're out of luck - open count is 0, we've tried to flush
				// and still haven't got the version we want
				if (MUI_Request(NULL, NULL, 0L,
					(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
					(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
					(STRPTR) GetLocString(MSGID_STARTUP_OLD_MCC),
					name, minver, minrev, ver, rev))
					{
					flush = TRUE;
					}
				else
					break;
				}
			}
		else
			{
			// No MCC at all - no need to attempt flush
			flush = FALSE;
			if (!MUI_Request(NULL, NULL, 0L,
				(STRPTR) GetLocString(MSGID_STARTUP_FAILURE),
				(STRPTR) GetLocString(MSGID_STARTUP_RETRY_QUIT_GAD),
				(STRPTR) GetLocString(MSGID_STARTUP_MCC_NOT_FOUND),
				name, minver, minrev))
				{
				break;
				}
			}
		}

	return FALSE;
}

//----------------------------------------------------------------------------

...to the top


...to the top


Tools

[edit | edit source]

...to the top


Source examples

[edit | edit source]

...to the top

...to the top


Scalos Reference

[edit | edit source]

...to the top


Scalos SCA Messages

[edit | edit source]

...to the top

   --background
   SCA_AddBob
   SCA_AllocMessage
   SCA_AllocNode
   SCA_AllocStdNode
   SCA_CountWBArgs
   SCA_DisposeScalosObject
   SCA_DrawDrag
   SCA_EndDrag
   SCA_FreeAllNodes
   SCA_FreeMessage
   SCA_FreeNode
   SCA_FreeScalosClass
   SCA_FreeWBArgs
   SCA_GetDefIconObject
   SCA_InitDrag
   SCA_LockDrag
   SCA_LockWindowList
   SCA_MakeScalosClass
   SCA_MakeWBArgs
   SCA_MoveNode
   SCA_NewAddAppIcon
   SCA_NewAddAppMenuItem
   SCA_NewAddAppWindow
   SCA_NewScalosObject
   SCA_OpenDrawerByName
   SCA_OpenIconWindow
   SCA_RemoveAppObject
   SCA_ScalosControlA
   SCA_ScreenTitleMsg
   SCA_SortNodes
   SCA_SwapNodes
   SCA_UnlockDrag
   SCA_UnLockWindowList
   SCA_UpdateIcon
   SCA_WBStart

...to the top

       NAME --background
           DESCRIPTION
           This library is used as application interface for the Scalos
           workbenchreplacement. It's only available if Scalos is running.
           This means if the library-open fails Scalos isn't running.
           For information about NodeList see SCA_SortNodes() and Node see
           SCA_AllocStdNode().


       NAME SCA_WBStart
       SYNOPSIS
       	succ SCA_WBStart (ArgArray, Taglist, NumArgs )
       	                   A0         A1       D0
       	BOOL SCA_WBStart ( struct WBArg *ArgArray , 
       		const struct TagItem *Taglist, ULONG NumArgs );
       	BOOL SCA_WBStartTags( struct WBArg *ArgArray , ULONG NumArgs, 
       		ULONG FirstTag, ... );


       FUNCTION
           The first argument is used as filename for the to started program.
           The Locks inside the ArgArray are automatically unlocked (use DupLock)
           and the strings are copied.
           The first element in ArgArray must contain the directory lock and
           name of the icon to start.
       INPUTS
           ArgArray - Standard Workbench Args
           NumArgs - Number of Args in the ArgArray. This must be at least
           one.
           Taglist - Pointer to a taglist.
       TAGS
           SCA_IconObject (Object *) - iconobject.library - IconObject to get
           information from it. No icon will be loaded.
           SCA_Priority (LONG) - priority for the newly started process
           SCA_Stacksize (ULONG) - stack size if no icon is available
           SCA_WaitTimeout (ULONG) - wait timeout in seconds
           SCA_Flags (ULONG) - Flags
           SCAF_WBStart_NoIcon - don't read an icon.
           SCAF_WBStart_Wait - wait until the program returns
           SCAF_WBStart_PathSearch - search through paths
           SCAF_WBStart_NoIconCheck - don't check icon type
       RESULT
           succ - FALSE if the start fails. It only fails if not enough
           memory available or the WBL task couldn't be started.
           If the program couldn't be loaded it will return TRUE, because
           of it doesn't wait for the returncode of WBL task.
       NOTE
           Locks will *NOT* be unlocked if this function fails!
       SEE ALSO
           diskobject.library


       NAME SCA_SortNodes
       SYNOPSIS
       	SCA_SortNodes (NodeList, CompareFunc, SortType)
       	                 A0          A1          D0
       	void SCA_SortNodes ( struct ScalosNodeList *, struct Hook *, 
       		ULONG SortType);


       FUNCTION
           Sorts a list of MinNodes and uses the CompareFunc to find differences
           between to nodes. NodeList is a pointer to a APTR which points to the
           first node. The first node has as mln_succ a NULL and the last node
           has as mln_pred a NULL. Only mln_succ, mln_pred and the address of the
           first will changed. Nothing will be reallocated or freed.
           The CompareFunc will be called with a pointer to one node in A1 (Node0)
           and a pointer to second node in A2 (Node1). You have to return a
           specific value in D0:
           0 if Node0 = Node1
           1 if Node0 < Node1
           -1 if Node0 > Node1
       INPUTS
           NodeList - Pointer to an APTR which is a pointer to the first node
           CompareFunc - Pointer to a Hook structure for the compare function
           SortType -
           SCA_SortType_Bubble : enhanced BubbleSort
           SCA_SortType_Selection : SelectionSort
           SCA_SortType_Insertion : InsertionSort
           SCA_SortType_Quick : QuickSort
           SCA_SortType_Best : The nodes will be counted and then
           the best SortType will be used.
       SEE ALSO
           SCA_AllocNode(), SCA_AllocStdNode(), SCA_FreeNode(),
           SCA_FreeAllNodes(), SCA_MoveNode(), SCA_SwapNodes()


       NAME SCA_NewAddAppIcon  SCA_NewAddAppIconTags
       SYNOPSIS
       	AppObject = SCA_NewAddAppIcon (ID, UserData, IconObject, MessagePort, 
       	   D0                          D0     D1         A0          A1 
       		Taglist)
       	          A2
       	struct AppObject *SCA_NewAddAppIcon( ULONG ID, ULONG UserData, 
       		struct IconObject *, struct MsgPort *, 
       		const struct TagItem *Taglist);
       	struct AppObject *SCA_NewAddAppIconTags( ULONG ID, ULONG UserData, 
       		struct IconObject *, struct MsgPort *, 
       		ULONG FirstTag, ...);


       FUNCTION
           Adds an icon to the mainwindow of the Scalos-screen. See
           workbench.library/AddAppIconA() for more information.
       INPUTS
           ID, UserData - will be passed through the AppMessage
           IconObject - diskobject.library - IconObject, IDTM_Layout should not
           to be done.
           MessagePort - a MsgPort where you will receive the AppMessage
           Taglist - pointer to a taglist.
       TAGS
           Currently no tags are defined. With wb39.plugin, however, most of the
           V44 workbench tags are supported.
       RESULT
           AppObject - a private structure to be pass to SCA_RemoveAppObject()
           or NULL after failure
       SEE ALSO
           SCA_NewAddAppWindow(), SCA_NewAddAppMenuItem(), SCA_RemoveAppObject()
           workbench.library/AddAppIconA()


       NAME SCA_NewAddAppWindow  SCA_NewAddAppWindowTags
       SYNOPSIS
       	AppObject = SCA_NewAddAppWindow (ID, UserData, Window, MessagePort, 
       	   D0                            D0     D1       A0        A1
       		Taglist)
       	          A2
       	struct AppObject *SCA_NewAddAppWindow( ULONG ID, ULONG UserData, 
       		struct Window *, struct MsgPort *, 
       		const struct TagItem *Taglist);
       	struct AppObject *SCA_NewAddAppWindowTags( ULONG ID, ULONG UserData, 
       		struct Window *, struct MsgPort *, ULONG FirstTag, ...);


       FUNCTION
           Same as workbench.library/AddAppWindowA(). See there for further
           information.
       INPUTS
           ID, UserData - will be passed through the AppMessage
           Window - Intuition Window
           MessagePort - a MsgPort where you will receive the AppMessage
           Taglist - pointer to a taglist.
       TAGS
           Currently no tags are defined.
       RESULT
           AppObject - a private structure to be pass to SCA_RemoveAppObject
           or NULL on failure
       SEE ALSO
           SCA_NewAddAppIcon(), SCA_NewAddAppMenuItem(), SCA_RemoveAppObject()
           workbench.library/AddAppWindowA()


       NAME SCA_NewAddAppMenuItem  SCA_NewAddAppMenuItemTags
       SYNOPSIS
       	AppObject = SCA_NewAddAppMenuItem (ID, UserData, Text, MessagePort, 
       	   D0                              D0     D1      A0       A1
       		Taglist)
       	          A2
       	struct AppObject *SCA_NewAddAppMenuItem ( ULONG ID, ULONG UserData, 
       		CONST_STRPTR Text, struct MsgPort *, 
       		const struct TagItem *Taglist);
       	struct AppObject *SCA_NewAddAppMenuItemTags( ULONG ID, 
       		ULONG UserData, CONST_STRPTR Text, struct MsgPort *, 
       		ULONG FirstTag, ...);


       FUNCTION
           Same as workbench.library/AddAppMenuItemA(). See there for further information.
       INPUTS
           ID, UserData - will be passed through the AppMessage
           Text - a pointer to the menutext. Starting with V40, any menu
           text consisting entirely of '-', '_' or '~' characters will
           result in a separator bar to be added.
           MessagePort - a MsgPort where you will receive the AppMessage
           Taglist - pointer to a taglist.
       TAGS
           WBAPPMENUA_CommandKeyString (STRPTR) -- Command key to assign to
           this AppMenu. This must be a NUL-terminated string. If the
           string is empty, it will be ignored. Also, if the command key
           is already in use by a different menu item it will be ignored,
           too. In any case, only the first character of the string will
           be used (V40).
           This tag defaults to NULL.
           WBAPPMENUA_GetKey (ULONG *) -- To add menus with sub menu items,
           you need to add a menu item first which the sub items will
           be added to later. In order to do this, add the item the sub items
           should be attached to and use the WBAPPMENUA_GetKey tag to
           obtain a key value. This key value is to be used later with the
           WBAPPMENUA_UseKey tag (V40.20).
           This feature was introduced in Scalos 40.20, it does not work in any of the older Scalos releases.
           This tag defaults to NULL.
           WBAPPMENUA_GetTitleKey (ULONG *) -- To add new entries to the Scalos
           menu strip you first need to create a new title to which the new
           menu items can be attached later. To do this, first create a new
           menu entry and use the WBAPPMENUA_GetTitleKey tag to obtain a key
           value. This key value is to be used later with the WBAPPMENUA_UseKey tag (V40.20).
           This tag defaults to NULL.
           WBAPPMENUA_UseKey (ULONG) -- When adding a menu item with the
           WBAPPMENUA_UseKey tag, using a key value obtained by a previous
           invocation of AddAppMenuItemA(), the new menu item will be
           added as a sub item (V40.20).
           If the key you provide was obtained via the WBAPPMENUA_GetTitleKey
           tag, then the item you add will be attached to the respective
           menu entry (V40.20).
           This tag defaults to NULL.
       RESULT
           AppObject - a private structure to be pass to SCA_RemoveAppObject or
           NULL on failure
           Starting with V40, NULL will be returned if you attempt to
           add an AppMenu item to a menu which already contains 63
           menu items. Only a maximum of 15 sub items can be added
           to a menu item.
       SEE ALSO
           SCA_NewAddAppIcon(), SCA_NewAddAppWindow(), SCA_RemoveAppObject()
           workbench.library/AddAppMenuItemA()


       NAME SCA_RemoveAppObject
       SYNOPSIS
       	succ = SCA_RemoveAppObject (AppObject)
       	 D0                        A0
       	BOOL SCA_RemoveAppObject (struct AppObject *);


       FUNCTION
           Removes an AppObject from Scalos. This could be an Icon, a Window or
           a MenuItem.
       INPUTS
           AppObject - result from SCA_NewAddAppIcon(), SCA_NewAddAppWindow()
           or SCA_NewAddAppMenuItem()
       RESULT
           succ - currently it always returns TRUE
       SEE ALSO
           SCA_NewAddAppIcon(), SCA_NewAddAppWindow(), SCA_NewAddAppMenuItem()


       NAME SCA_AllocStdNode
       SYNOPSIS
       	Node = SCA_AllocStdNode (NodeList, NodeType)
       	 D0                        A0        D0
       	struct MinNode *SCA_AllocStdNode (struct ScalosNodeList *, 
       		ULONG NodeType);


       FUNCTION
           Allocates a standard Scalos-node. It's the only compatible why to
           allocate one of the standard nodes. NEVER allocate a node yourself and
           pass it to Scalos! The scalos.library will use a memorypool for all
           nodes to decrease the memoryfragmentation. The new node will be the
           last in your NodeList and it is cleared public memory. Don't change
           mln_succ and mln_pred yourself, use the node function instead.
           See SCA_SortNodes() for information about the NodeList.
       INPUTS
           NodeList - Pointer to an APTR which is a pointer to the first node
           NodeType - see scalos.(h|i)
       RESULT
           Node - Node at the end or the NodeList or NULL on failure.
       NOTE
           Node *MUST* be freed with SCA_FreeNode() or SCA_FreeAllNodes()
           This function preserves all registers except D0.
       SEE ALSO
           SCA_AllocNode(), SCA_FreeNode(), SCA_FreeAllNodes(),
           SCA_MoveNode(), SCA_SortNodes(), SCA_SwapNodes()


       NAME SCA_AllocNode
       SYNOPSIS
       	Node = SCA_AllocNode (NodeList, Size)
       	 D0                      A0      D0
       	struct MinNode *SCA_AllocNode (struct ScalosNodeList *, ULONG Size);


       FUNCTION
           Allocates a node and inserts it at the end of the NodeList. Use this
           function only for your own node-handling. Never allocate a standard
           Scalos-node, use SCA_AllocStdNode() instead. Size is the number of
           bytes that allocated after the the MinNode. This means the memsize
           of node is size+MLN_SIZE.
           See SCA_AllocStdNode() for further information.
       INPUTS
           NodeList - Pointer to an APTR which is a pointer to the first node
           Size - bytes after MLN_SIZE
       RESULT
           Node - Node at the end or the NodeList or NULL on failure.
       NOTE
           Node *MUST* be freed with SCA_FreeNode() or SCA_FreeAllNodes() !
           This function preserves all registers except D0.
       SEE ALSO
           SCA_AllocStdNode(), SCA_FreeNode(), SCA_FreeAllNodes(),
           SCA_MoveNode(), SCA_SortNodes(), SCA_SwapNodes()


       NAME SCA_FreeNode
       SYNOPSIS
       	SCA_FreeNode (NodeList, Node)
       	                 A0      A1
       	void SCA_FreeNode (struct ScalosNodeList *, struct MinNode *);


       FUNCTION
           Removes the Node out of the NodeList and Frees a node allocated with
           SCA_AllocStdNode() or SCA_AllocNode().
       INPUTS
           NodeList - pointer to an APTR which is a pointer to the first node
           Node - node to remove and free
       NOTE
           Node *MUST* be part of NodeList!
           This function preserves all registers.
       SEE ALSO
           SCA_AllocStdNode(), SCA_AllocNode(), SCA_FreeAllNodes(),
           SCA_MoveNode(), SCA_SortNodes(), SCA_SwapNodes()


       NAME SCA_FreeAllNodes
       SYNOPSIS
       	SCA_FreeAllNodes (NodeList)
       	                    A0
       	void SCA_FreeAllNodes (struct ScalosNodeList *);


       FUNCTION
           Will free the whole list of nodes.
       INPUTS
           NodeList - pointer to an APTR which is a pointer to the first node
       NOTE
           This function preserves all registers.
       SEE ALSO
           SCA_AllocStdNode(), SCA_AllocNode(), SCA_FreeNode(),
           SCA_MoveNode(), SCA_SortNodes(), SCA_SwapNodes()


       NAME SCA_MoveNode
       SYNOPSIS
       	SCA_MoveNode (SrcNodeList, DestNodeList, Node)
       	                  A0            A1        D0
       	void SCA_MoveNode (struct ScalosNodeList *, struct ScalosNodeList *, 
       		struct MinNode *);


       FUNCTION
           Will remove the Node from SrcNodeList and will insert the Node at
           the end of DestNodeList.
       INPUTS
           SrcNodeList - pointer to an APTR which is a pointer to the first node
           DestNodeList - pointer to an APTR which is a pointer to the first node
           Node - MinNode
       NOTE
           This function preserves all registers.
           WARNING: Node *MUST* be member of SrcNodeList or very nasty
           things will happen !!
       SEE ALSO
           SCA_AllocStdNode(), SCA_AllocNode(), SCA_FreeNode(),
           SCA_FreeAllNodes(), SCA_SortNodes(), SCA_SwapNodes()


       NAME SCA_SwapNodes
       SYNOPSIS
       	SCA_SwapNodes ( SrcNode, DestNode, NodeList)
       	                  A0        A1        A2
       	void SCA_SwapNodes (struct MinNode *, struct MinNode *, 
       		struct ScalosNodeList *);


       FUNCTION
           Swaps the positions of SrcNode and DestNode inside the NodeList.
       INPUTS
           SrcNode - MinNode
           DestNode - MinNode
           NodeList - pointer to an APTR which is a pointer to the first node
       NOTE
           SrcNode and DestNode *MUST* be part of NodeList!
       SEE ALSO SCA_AllocStdNode(), SCA_AllocNode(), SCA_FreeNode(), SCA_FreeAllNodes(), SCA_MoveNode(), SCA_SortNodes()


       NAME SCA_OpenIconWindow  SCA_OpenIconWindowTags
       SYNOPSIS
       	succ SCA_OpenIconWindow ( TagList )
       	 D0                         A0
       	BOOL SCA_OpenIconWindow ( const struct TagItem *TagList );
       	BOOL SCA_OpenIconWindowTags(ULONG, ...);


       FUNCTION
           opens a windowtask filled with icons. All information will be given as tags, see below.
       INPUTS
           TagList - pointer to a taglist.
       TAGS
           SCA_IconNode (struct ScaIconNode *) - fullfilled ScaIconNode
           SCA_IconObject (Object *) - iconobject.library - iconobject
           SCA_Path (CONST_STRPTR) - the path to open
           SCA_MessagePort (struct MsgPort *) - Message port for reply
           to startup message of new icon window process, or NULL.
           SCA_WindowTitle (CONST_STRPTR) - windowtitle parsestring
           ( take a look at the prefsprogram for info)
           SCA_WindowRect (struct IBox *) - rectangle with window
           dimensions (see diskobject.library).
           SCA_XOffset,SCA_YOffset (LONG) - virtual position
           SCA_PatternNumber (ULONG) - background pattern number which is
           configured in "Scalos Pattern" prefs
           SCA_ShowAllFiles (ULONG) - TRUE or FALSE
           deprecated, use SCA_ShowAllMode instead!
           SCA_ShowAllMode (ULONG) - DDFLAGS_SHOWDEFAULT,
           DDFLAGS_SHOWICONS, or DDFLAGS_SHOWALL.
           SCA_ViewModes (ULONG) - view modes for the window
           SCAV_ViewModes_Icon
           SCAV_ViewModes_Name
           SCAV_ViewModes_Size
           SCAV_ViewModes_Date
           SCAV_ViewModes_Time
           SCAV_ViewModes_Comment
           SCAV_ViewModes_Protection
           SCAV_ViewModes_Owner
           SCAV_ViewModes_Group
           SCA_Flags (ULONG) - none available yet
           SCA_Iconify (ULONG) - TRUE or FALSE for open iconified
           SCA_NoActivateWindow (ULONG) - TRUE or FALSE. The new window
           will not be activated if this tag is set to TRUE.
           Defaults to FALSE.
           SCA_WindowStruct (struct ScaWindowStruct **) - The pointer to the
           ScaWindowStruct of the new generated Scalos window will be
           returned. If the new Scalos window couldn't be opened, NULL
           is returned.
           SCA_BrowserMode (ULONG) - TRUE or FALSE. The window will be
           opened in browser mode if set to TRUE.
           SCA_NoStatusBar (ULONG) - TRUE or FALSE. The status bar will not
           be present in the new window if set to TRUE, overriding the
           global setting for status bar.
           SCA_CheckOverlappingIcons (ULONG) - TRUE or FALSE. Defines whether
           icon windows check for overlapping icons. If enabled, an icon
           overlapping any other is repositioned on directory scan.
           Default value is TRUE for MorphOS, FALSE for all other platforms.
           SCA_TransparencyActive (ULONG) - degree of opacity in active
           window state, 0=transparent, 100=opaque.
           Semi-transparent windows are not supported on all platforms.
           SCA_TransparencyInactive (ULONG) - degree of opacity in inactive
           window state, 0=transparent, 100=opaque
           Semi-transparent windows are not supported on all platforms.
       RESULT
           succ - Success
       NOTE
           One of SCA_IconNode, SCA_IconObject or SCA_Path must be given!
       SEE ALSO


       NAME SCA_LockDrag
       SYNOPSIS
       	 SCA_LockDrag ( draghandle )
       	   		   D0
       	void SCA_LockDrag ( APTR draghandle );


       FUNCTION
           Locks the screen layer info that is connected to the draghandle.
           Main purpose is to temporarily unlock and lock again the screen
           layers during a dragging operiation, in order to allow some drawing to happen.
       INPUTS
           draghandle - That drag handle that is to be locked.
       SEE ALSO  SCA_UnLockDrag(), SCA_InitDrag(), SCA_EndDrag(), SCA_DrawDrag()


       NAME SCA_LockWindowList
       SYNOPSIS
       	Windowlist SCA_LockWindowList ( accessmode )
       	 D0                                D0
       	struct ScaWindowList *SCA_LockWindowList ( LONG accessmode );


       FUNCTION
           Locks the windowlist and returns. This function is a main interface of
           the Scalos-API. The messageport should be used to comunicate with a
           windowtask. No window can be closed while the windowlist is locked.
           For more information take a look at the ScalosAPI documentation.
       INPUTS
           accessmode -
           SCA_LockWindowList_Shared - locks the window list for a read-
           only access. Shared access is sufficient if
           you just want to traverse the window list,
           and make sure nobody modifies the
           list in between.
           SCA_LockWindowList_Exclusiv - locks the window list
           exclusively for read-write access. Exclusive
           mode is required if windows are to be created
           or removed.
           SCA_LockWindowList_AttemptShared - tries to acquire a shared
           lock on the window list for read-only access.
           NULL is returned if the list cannot be locked,
           e.g. because someone else holds an exclusive
           lock on the list.
           SCA_LockWindowList_AttemptExclusive - try to acquire an
           exclusive lock on the window list.
           NULL is returned if the list cannot be locked,
           e.g. because someone else holds a lock on
           the list.
       RESULT
           windowlist - a struct ScaWindowList * - With the
           SCA_LockWindowList_Attempt*** values, it is
           possible that NULL is returned if the window
           list cannot be locked.
       NOTE
           Normally you should not use the SCA_LockWindowList_Exclusiv. If you
           lock the windowlist exclusiv you should NEVER use intuition calls!
       SEE ALSO SCA_UnLockWindowList()


       NAME SCA_UnLockWindowList
       SYNOPSIS
       	SCA_UnLockWindowList ()
       	void SCA_UnLockWindowList ( void );


       FUNCTION
           Unlocks a with SCA_LockWindowList() locked windowlist.
       SEE ALSO  SCA_LockWindowList()


       NAME SCA_AllocMessage
       SYNOPSIS
       	ScalosMessage SCA_AllocMessage( messagetype, additional_size)
       	   D0                               D0            D1
       	struct ScalosMessage *SCA_AllocMessage ( ULONG messagetype, 
       		UWORD additional_size );


       FUNCTION
           Allocates a message which could be sent to Scalos. It's the only
           future-compatible way to do this. The scalos message signature and the
           the message type will be set and the returned memory is cleared.
       INPUTS
           messagetype - see ScalosAPI.doc
           additional_size - number of bytes that will be added to the size of
           the message. Normally this should be 0.
       RESULT
           ScalosMessage - a full-filled ScalosMessage of the selected type or NULL
       NOTE
           Never try to free a message yourself, it will cause a memory trashing!
           Scalos uses fast memorypool functions for its messages.
       SEE ALSO
           SCA_FreeMessage()


       NAME SCA_FreeMessage
       SYNOPSIS
       	SCA_FreeMessage( message )
       	                   A1
       	void SCA_FreeMessage ( struct ScalosMessage *);


       FUNCTION
           Frees a with SCA_AllocMessage() allocated message.
       INPUTS
           message - struct ScalosMessage (returned from SCA_AllocMessage())
       SEE ALSO SCA_AllocMessage()


       NAME SCA_InitDrag
       SYNOPSIS
       	DragHandle SCA_InitDrag( Screen )
       	    D0                     A0
       	struct DragHandle *SCA_InitDrag ( struct Screen *);


       FUNCTION
           Inits special bobroutines. This routines are easy to use and
           support 24bit bobs.
       INPUTS
           Screen - the screen to use for the bobs or NULL for the default
           Scalos screen
       RESULT
           DragHandle - a private structure to pass it to the other Drag functions
           or NULL on failure.
       SEE ALSO SCA_DrawDrag(), SCA_EndDrag(), SCA_LockDrag(), SCA_UnlockDrag()


       NAME SCA_EndDrag
       SYNOPSIS
       	SCA_EndDrag( DragHandle )
       	                 A0
       	void SCA_EndDrag ( struct DragHandle *);


       FUNCTION
           Removes all bobs from screen and frees it, if necessary it unlocks
           the layers.
       INPUTS
           DragHandle - result from SCA_InitDrag()
       SEE ALSO SCA_DrawDrag(), SCA_InitDrag(), SCA_LockDrag(), SCA_UnlockDrag()


       NAME SCA_AddBob
       SYNOPSIS
       	succ SCA_AddBob( DragHandle, Bitmap, Mask, Width, Height, 
       	 D0                  A0        A1     A2     D0     D1
       		XOffset, YOffset )
       	           D2       D3
       	BOOL SCA_AddBob ( struct DragHandle *, struct BitMap *, APTR Mask, 
       		ULONG Width, ULONG Height, LONG XOffset, LONG YOffset );


       FUNCTION
           Addes a bitmap to the Boblist. Bitmap and Mask will be copied, it can
           be freed after calling this function. Mask is a planar bitplane the
           width divided by 8 and height. It must be in Chipram. X and Y offsets
           are the offset from movepoint give in SCA_DrawDrag(). Normally it's
           the relative position to the mouse pointer.
       INPUTS
           DragHandle - result from SCA_InitDrag()
           Bitmap - a standard bitmap structure, any depth allowed
           Mask - width/8 * height mask for the bitmap
           Width - width in pixels
           Height - height in pixels
           XOffset - relative x-position to the move point
           YOffset - relative y-position to the move point
       RESULT
           succ - TRUE if anything went well, FALSE if some problem occurred
       SEE ALSO


       NAME SCA_DrawDrag
       SYNOPSIS
       	SCA_DrawDrag( DragHandle, X, Y, Flags )
       	                  A0      D0 D1   D2
       	void SCA_DrawDrag ( struct DragHandle *, LONG X, LONG Y, ULONG Flags );


       FUNCTION
           Blits the bobs to the selected screen relative to the given position.
       INPUTS
           DragHandle - result from SCA_InitDrag()
           X - movepoint x direction
           Y - movepoint y direction
           Flags -
           SCAF_Drag_Transparent - draw all bobs transparent,
           normally it's a raster ("ghosted")
           SCAF_Drag_IndicateCopy - draw all bobs plus
           "copy" indicator
           SCAF_Drag_NoDropHere - draw all bobs plus
           "no drop" indicator
           SCAF_Drag_Hide - hide bobs
           SCAF_Drag_IndicateMakeLink - draw all bobs plus "make link"
           indicator
           SCAF_Drag_NoDrawDrag - (internal use only)
       NOTE
           Transparent drawing only works with CyberGfx installed and a
           workbench screen of more than 256 colors (depth > 8).
       SEE ALSO SCA_InitDrag(), SCA_EndDrag(), SCA_LockDrag(), SCA_UnlockDrag()


       NAME SCA_UpdateIcon
       SYNOPSIS
       	SCA_UpdateIcon( WindowType, SCA_UpdateIcon, UpdateIcon_Size )
       	                   D0           A0             D1
       	void SCA_UpdateIcon ( UBYTE WindowType, struct ScaUpdateIcon_IW *,
       		 ULONG ui_SIZE );


       FUNCTION
           Refreshes an icon specified in SCA_UpdateIcon structure. The icon
           will be loaded, removed or reloaded. The SCA_UpdateIcon struct
           depends on the windowtype.
       INPUTS
           WindowType - windowtype which should be updated
           SCA_UpdateIcon - special information, depents on WindowType
           UpdateIcon_Size - size of the SCA_UpdateIcon structure in bytes
       SEE ALSO


       NAME SCA_MakeWBArgs
       SYNOPSIS
       	number = SCA_MakeWBArgs( Buffer, Iconnode, ArgsSize )
       	                           A0       A1        D0
       	ULONG SCA_MakeWBArgs ( struct WBArg *Buffer, 
       		struct ScaIconNode *Iconnode, ULONG ArgsSize);


       FUNCTION
           Generates a WBArgs Array from all selected icons except the
           given Iconode.
           It is recommended to determine the required buffer size
           with SCA_CountWBArgs().
       INPUTS
           Buffer - Array of WBArg structures to save the Lock and
           Name pointers
           Iconnode - an iconnode to exclude or NULL
           ArgsSize - Number of WBArg's the buffer has room for
       RESULT
           number - number of args generated
       SEE ALSO SCA_FreeWBArgs() SCA_CountWBArgs()


       NAME SCA_FreeWBArgs
       SYNOPSIS
       	number = SCA_FreeWBArgs( Buffer, Number, Flags )
       	                           A0      D0     D1
       	void SCA_FreeWBArgs ( struct WBArg *Buffer, ULONG Number, 
       		ULONG Flags);


       FUNCTION
           Frees a WBArg array generated with SCA_MakeWBArgs.
       INPUTS
           Buffer - Array with WBArg structures
           Number - Number of WBArg's to free
           Flags -
           SCAB_FreeLocks - free the Locks
           SCAB_FreeName - free the namefields
       SEE ALSO SCA_MakeWBArgs(); SCA_CountWBArgs();


       NAME SCA_CountWBArgs
       SYNOPSIS
       	number = SCA_CountWBArgs( Iconnode )
       				    A0
       	ULONG SCA_CountWBArgs( struct ScaIconNode *Iconnode );


       FUNCTION
           Determines required size for WBArgs Array from all
           selected icons except the given Iconode.
           The returned count can be used to allocate a WBArg
           array for SCA_MakeWBArgs().
       INPUTS
           Iconnode - an iconnode to exclude or NULL
       RESULT
           number - number of args that will be generated
           by SCA_MakeWBArgs().
       SEE ALSO SCA_FreeWBArgs() SCA_MakeWBArgs()


       NAME SCA_ScreenTitleMsg
       SYNOPSIS
       	SCA_ScreenTitleMsg( Format, Args )
       	                      A0     A1
       	void SCA_ScreenTitleMsg ( CONST_STRPTR Format, APTR Args);
       	void SCA_ScreenTitleMsgArgs( CONST_STRPTR Format, ...);


       FUNCTION
           Show a message on ScreenTitle of all Scalos windows.
       INPUTS
           Format - FormatString. All RawDoFmt() args are allowed.
           special values :
           NULL to recover the standard title.
           ~0 to recover the last non-standard title (message).
           Args - the arguments for the formatstring
       SEE ALSO exec.library/RawDoFmt


       NAME SCA_MakeScalosClass
       SYNOPSIS
       	ScalosClass ( ClassName, SuperClassName, InstSize, DispFunc )
       	     D0           A0            A1          D0        A2
       	struct ScalosClass *SCA_MakeScalosClass ( CONST_STRPTR ClassName, 
       		CONST_STRPTR SuperClassName, UWORD InstSize, APTR DispFunc);


       FUNCTION
           Addes a new BOOPSI Class to the internal classlist. ClassName may be
           a new name or a classname that's already available. In this case the
           class will replace or enhance a known class.
       INPUTS
           ClassName - name of the new class or NULL for a private class
           SuperClassName - name of the super class for the new class
           InstSize - size of the instance variables
           DispFunc - pointer to your Dispatcher function
       RESULT
           ScalosClass - a ScalosClass structure or NULL if it fails
       NOTE
           If you like an add a subclass to your private class then use the
           intuition class functions.
       SEE ALSO SCA_FreeScalosClass(), intuition.library/MakeClass


       NAME SCA_FreeScalosClass
       SYNOPSIS
       	scc SCA_FreeScalosClass( ScalosClass )
       	D0                          A0
       	BOOL SCA_FreeScalosClass ( struct ScalosClass *);


       FUNCTION
           Removes a ScalosClass from the internal classlist.
       INPUTS
           ScalosClass - return value from SCA_MakeScalosClass()
       RESULT
           succ - FALSE if the class couldn't be removed, else TRUE
       SEE ALSO SCA_MakeScalosClass(), FreeClass()


       NAME SCA_NewScalosObject  SCA_NewScalosObjectTags
       SYNOPSIS
       	Object SCA_NewScalosObject( ClassName, TagList )
       	  D0                            A0       A1
       	Object *SCA_NewScalosObject ( CONST_STRPTR ClassName, 
       		const struct TagItem *TagList);
       	Object *SCA_NewScalosObjectTags( CONST_STRPTR ClassName, 
       		ULONG FirstTag, ...);


       FUNCTION
           Allocates and inits a new BOOPSI Object.
       INPUTS
           ClassName - Scalos Classname
           TagList - taglist (depends on the class)
       RESULT
           Object - new BOOPSI Object or NULL
       SEE ALSO  SCA_DisposeScalosObject(), NewObject()


       NAME SCA_DisposeScalosObject
       SYNOPSIS
       	SCA_DisposeScalosObject( Object )
       	                           A0
       	void SCA_DisposeScalosObject (Object *);


       FUNCTION
           Disposes an object created with SCA_NewScalosObject().
       INPUTS
           Object - BOOPSI Object
       SEE ALSO SCA_NewScalosObject(), DisposeObject()


       NAME SCA_ScalosControlA -- Query or modify Scalos options (V40)  SCA_ScalosControl
       SYNOPSIS
       	ULONG SCA_ScalosControlA( Name, TagList )
       	  D0                        A0     A1
       	ULONG SCA_ScalosControlA( CONST_STRPTR Name, 
       		const struct TagItem *TagList);
       	ULONG SCA_ScalosControl( CONST_STRPTR Name, ULONG FirstTag, ...);


       FUNCTION
           With this function you can query or modify global Scalos parameters.
       INPUTS
           name -- Name of an object to query or modify.
           tags -- Additional options.
       TAGS
           SCALOSCTRLA_GetDefaultStackSize (ULONG *) -- Get the default stack
           size used by Scalos when launching Shell programs or programs without a valid stack size number.
           The default stack size is 8192 bytes.
           SCALOSCTRLA_SetDefaultStackSize (ULONG) -- Set the default stack
           size used by Scalos when launching Shell programs
           or programs without a valid stack size number. You cannot
           set a stack size number smaller than 8192 bytes.
           SCALOSCTRLA_GetProgramList (struct List **) -- You can obtain a list
           of currently running Workbench programs; every entry of this
           list will have the complete path to the program and the
           program name in its Node->ln_Name. When you no longer need
           the list, don't forget to free it again using the tag
           WBCTRLA_FreeProgramList.
           SCALOSCTRLA_FreeProgramList (struct List *) -- With this tag you can
           free the list allocated by the SCALOSCTRLA_GetProgramList tag.
           SCALOSCTRLA_GetCloseWBDisabled (ULONG *) -- Get the current disable
           state for the intuition.library/CloseWorkBench() function.
           If TRUE, intuition.library/CloseWorkBench() always returns FALSE
           and Scalos will never close.
           SCALOSCTRLA_SetCloseWBDisabled (ULONG) -- Set the disable
           state for the intuition.library/CloseWorkBench() function.
           If TRUE, intuition.library/CloseWorkBench() always returns FALSE
           and Scalos will never close.
           SCALOSCTRLA_GetSplashEnable (ULONG *) -- Get the current disable
           state for the Scalos startup splash window. If TRUE, Scalos shows
           its splash window on startup.
           SCALOSCTRLA_SetSplashEnable (ULONG) -- Set the disable
           state for the Scalos startup splash window. If TRUE, Scalos shows
           its splash window on startup.
           SCALOSCTRLA_GetToolTipEnable (ULONG *) -- Get the current enable
           state for icon tool tips. If TRUE, icon tool tips will show up
           if the mouse pointer kept over an icon for some seconds.
           SCALOSCTRLA_SetToolTipEnable (ULONG) -- Set the enabled
           state for icon tool tips. If TRUE, icon tool tips will show up
           if the mouse pointer kept over an icon for some seconds.
           SCALOSCTRLA_GetToolTipDelay (ULONG *) -- Set the delay time until
           the icon tool tips pop up (in seconds).
           SCALOSCTRLA_SetToolTipDelay (ULONG) -- Set the delay time until
           the icon tool tips pop up (in seconds). You must specify a
           number between 1 and 599 seconds. Default delay time is 2 seconds.
           SCALOSCTRLA_GetOldDragIconMode (ULONG *) -- Enable old (workbench-
           like) icon dragging mode, i.e. all icons are visibly dragged.
           If turned OFF (=0), the new "icon stack" method is used.
           Default value is OFF (0).
           SCALOSCTRLA_SetOldDragIconMode (ULONG) -- Get the current icon dragging mode.
           0 New "icon stack" icon dragging method is used.
           1 Old (workbench-like) icon dragging mode, i.e. all icons
           are visibly dragged
           SCALOSCTRLA_GetTypeRestartTime (ULONG *) -- Get the number of seconds
           that have to pass before typing the next character in a drawer
           window will restart with a new file name.
           SCALOSCTRLA_SetTypeRestartTime (ULONG) -- Set the number of seconds
           that have to pass before typing the next character in a drawer
           window will restart with a new file name. You must specify a
           number greater than 0. Default type restart time is 3 seconds.
           SCALOSCTRLA_GetEmulationMode (ULONG *) -- get a BOOL variable telling
           whether which mode Scalos is running in.
           TRUE emulation mode
           FALSE preview mode
           SCALOSCTRLA_GetStatusBarEnable (ULONG *) -- get a BOOL variable
           telling whether Scalos displays a status bar in every non-backdrop window.
           SCALOSCTRLA_SetStatusBarEnable (ULONG) -- Telling whether Scalos to
           display a status bar in every non-backdrop window (any non-zero
           value) or to display no status bars. Changes only apply to windows opened thereafter.
           TRUE show status bar
           FALSE don't show status bar
           NOTE: Changes only apply to windows opened thereafter.
           SCALOSCTRLA_GetStripedTextWindows (ULONG *) -- get a BOOL variable
           telling whether Scalos displays horizontally striped lines in text windows.
           SCALOSCTRLA_SetStripedTextWindows (ULONG) -- Tell whether Scalos to
           display horizontally striped lines in text windows.
           TRUE show stripes in text window
           FALSE show standard background.
           NOTE: Changes only apply to windows opened thereafter.
           SCALOSCTRLA_GetDisplayDragCount (ULONG *) -- get a BOOL variable
           telling whether Scalos shows the number of dragged objects
           during Drag and Drop.
           SCALOSCTRLA_SetDisplayDragCount (ULONG) -- Tell whether Scalos to
           display the number of dragged objects during Drag and Drop.
           TRUE show number of objects while dragging
           FALSE don't show number of objects
           SCALOSCTRLA_GetWindowDropMarkMode (ULONG *) - get a ULONG variable
           telling when Scalos shows window drop marks during D&D
           IDTV_WinDropMark_Never - never
           IDTV_WinDropMark_WindowedOnly - only on non-backdrop windows
           IDTV_WinDropMark_Always - always
           SCALOSCTRLA_SetWindowDropMarkMode (ULONG) - Set when Scalos will
           show window drop marks during D&D
           IDTV_WinDropMark_Never - never
           IDTV_WinDropMark_WindowedOnly - only on non-backdrop windows
           IDTV_WinDropMark_Always - always
           SCALOSCTRLA_GetCopyHook (struct Hook **) - Obtain the current hook
           that will be invoked when Scalos starts copying files and
           data (V40).
           SCALOSCTRLA_SetCopyHook (struct Hook *) - Install a new hook that
           will be invoked when Scalos starts copying files and data (V40).
           The hook will be invoked exactly the same way as Workbench
           does with its WBCTRLA_SetCopyHook hook.
           SCALOSCTRLA_GetDeleteHook (struct Hook **) - Obtain the current hook
           that will be invoked when Scalos deletes files and drawers or
           empties the trashcan (V40).
           SCALOSCTRLA_SetDeleteHook (struct Hook *) - Install a new hook that
           will be invoked when Scalos deletes files and drawers or empties
           the trashcan (V40).
           The hook will be invoked exactly the same way as Workbench
           does with its WBCTRLA_SetDeleteHook hook.
           NOTE: this hook will take precedence over the
           installed "Delete.module".
           SCALOSCTRLA_GetTextInputHook (struct Hook **) - Obtain the current
           hook that will be invoked when Scalos requests the user to enter
           text, i.e. when a file is to be renamed or a new drawer is to
           be created (V40).
           SCALOSCTRLA_SetTextInputHook (struct Hook *) - Install a new hook
           that will be invoked when Scalos requests the user to enter text,
           i.e. when a file is to be renamed or a new drawer is to
           be created (V40).
           The hook will be invoked exactly the same way as Workbench
           does with its WBCTRLA_SetTextInputHook hook.
           NOTE: this hook will take precedence over the installed
           "NewDrawer.module", "Execute.module" and "Rename.module".
           SCALOSCTRLA_AddCloseWBHook (struct Hook *) - Add a hook that will
           be invoked when Scalos is about to close (cleanup), and when
           Scalos has opened again (setup) (V40).
           The hook will be invoked exactly the same way as Workbench
           does with its WBCTRLA_AddSetupCleanupHook hook.
           SCALOSCTRLA_RemCloseWBHook (struct Hook *) - Remove a hook that has
           been installed with the SCALOSCTRLA_AddCloseWBHook tag (V40).
           SCALOSCTRLA_GetSupportedIconTypes (ULONG *) - Get bit mask
           of all currently enabled icon types
           IDTV_IconType_NewIcon - display NewIcons
           IDTV_IconType_ColorIcon - display OS3.5 color icons
           SCALOSCTRLA_SetSupportedIconTypes (ULONG) - Select which
           icon types are enabled :
           IDTV_IconType_NewIcon - display NewIcons
           IDTV_IconType_ColorIcon - display OS3.5 color icons
           SCALOSCTRLA_GetMenuCommandList (struct List **) -- You can obtain a list
           of all supported menu command names. When you no longer need
           the list, don't forget to free it again using the tag
           WBCTRLA_FreeMenuCommandList.
           SCALOSCTRLA_FreeMenuCommandList (struct List *) -- With this tag you can
           free the list allocated by the SCALOSCTRLA_GetMenuCommandList tag.
           SCALOSCTRLA_GetCopyBuffSize (ULONG *) -- Query the size of the buffer
           used for moving and copying files.
           SCALOSCTRLA_SetCopyBuffSize (ULONG) -- Set the size of the buffer used
           for moving and copying files. The size can be changed
           between 4 KBytes and 4 MBytes (40.30).


       RESULT
           Returns the number of tags successfully processed. If the returned
           value is less than the number of tags supplied, you can query the error
           code using dos.library/IoErr().
           NOTES
           This function may only be called by a Process.


       SEE ALSO  dos.library/IoErr   <dos/dosextens.h>


       NAME  SCA_GetDefIconObject  SCA_GetDefIconObjectA  SCA_GetDefIconObjectTags
       SYNOPSIS
       	IconObject SCA_GetDefIconObject( dirLock, name )
       	  D0                              A0       A1
       	IconObject SCA_GetDefIconObjectA( dirLock, name, tagList )
       	  D0                               A0       A1    A2
       	Object *SCA_GetDefIconObject(BPTR dirLock, CONST_STRPTR name)
       	Object *SCA_GetDefIconObjectA(BPTR dirLock,
       		CONST_STRPTR name, struct TagItem *tagList)
       	Object *SCA_GetDefIconObjectTags(BPTR dirLock, CONST_STRPTR name, ...)


       FUNCTION
           Returns default IconObject for the file system object
           (tool/project/drawer/device) described by dirLock and name.
           A filetype-specific default icon is selected according to the object type.
       INPUTS
           dirlock - Lock on the parent directory of the object.
           name - Name of the object.
           tagList - additional tags for creation of IconObject.
       RESULT
           IconObject - new IconObject or NULL


       NAME  SCA_OpenDrawerByName  SCA_OpenDrawerByNameTags
       SYNOPSIS
       	ScaWindow = SCA_OpenDrawerByName( path, tagList )
       	  D0                             A0    A1
       	struct ScaWindowStruct *SCA_OpenDrawerByName(CONST_STRPTR path,
       		struct TagItem *tagList);
       	struct ScaWindowStruct *SCA_OpenDrawerByNameTags(CONST_STRPTR path,
       		ULONG firstTag, ...);


       FUNCTION
           Tries to open the named drawer.
       INPUTS
           path - Full path name of the drawer to be opened.
           TagList - taglist
       RESULT
           ScaWindow - ScaWindowStruct of the newly opened drawer window or NULL.
       SEE ALSO  SCA_OpenIconWindow()


       NAME  SCA_UnlockDrag
       SYNOPSIS
       	 wasLocked = SCA_UnlockDrag ( draghandle )
       	   		   D0
       	ULONG SCA_LockDrag ( APTR draghandle );


       FUNCTION
           Unlocks the screen layer info that is connected to the draghandle.
           Main purpose is to temporarily unlock and lock again the screen
           layers during a dragging operiation, in order to allow some drawing to happen.
       INPUTS
           draghandle - That drag handle that is to be locked.
       RESULT
           wasLocked - Flag that indicated whether the screen layer was locked
           before calling. The result can be used to decide if you need to
           call SCA_LockDrag() when you are finished drawing.
       SEE ALSO SCA_LockDrag(), SCA_InitDrag(), SCA_EndDrag(), SCA_DrawDrag()


Scalos GFX

[edit | edit source]
   ScalosGfxCreateEmptySAC
   ScalosGfxCreateSAC
   ScalosGfxFreeSAC
   ScalosGfxCreateARGB
   ScalosGfxFreeARGB
   ScalosGfxARGBSetAlpha
   ScalosGfxARGBSetAlphaMask
   ScalosGfxCreateARGBFromBitMap
   ScalosGfxFillARGBFromBitMap
   ScalosGfxWriteARGBToBitMap
   ScalosGfxMedianCut
   ScalosGfxScaleARGBArray
   ScalosGfxScaleBitMap
   ScalosGfxCalculateScaleAspect
   ScalosGfxBlitARGB
   ScalosGfxFillRectARGB
   ScalosGfxSetARGB
   ScalosGfxNewColorMap
   ScalosGfxARGBRectMult
   ScalosGfxBlitARGBAlpha
   ScalosGfxBlitARGBAlphaTagList
   ScalosGfxBlitIcon


       NAME ScalosGfxCreateEmptySAC -- Allocate an empty ScalosBitMapAndColor
       SYNOPSIS
       	sac = ScalosGfxCreateEmptySAC( )
       	D0
       	struct ScalosBitMapAndColor *ScalosGfxCreateEmptySAC( void );


       FUNCTION
           Allocates an empty ScalosBitMapAndColor structure, with NULL
           sca_BitMap and sac_ColorTable.
       INPUTS
           none
       RESULT
           sac - new created ScalosBitMapAndColor, or NULL on failure
       SEE ALSO  ScalosGfxFreeSAC(), ScalosGfxCreateSAC()


       NAME  ScalosGfxCreateSAC -- Allocate ScalosBitMapAndColor
       SYNOPSIS
       	sac = ScalosGfxCreateSAC(width, height, depth, friendBM, tagList);
       	D0                       D0     D1      D2     A0        A1
       	struct ScalosBitMapAndColor *ScalosGfxCreateSAC(ULONG, ULONG, ULONG,
       		struct BitMap *, struct TagItem *)
       	struct ScalosBitMapAndColor *ScalosGfxCreateSACTags(ULONG, ULONG, ULONG,
       		struct BitMap *, ULONG, ...)


       FUNCTION
           Allocate a ScalosBitMapAndColor structure. sac_BitMap and sac_ColorTable
           are allocated according to specified dimensions.
       INPUTS
           width - Desired width of new ScalosBitMapAndColor BitMap.
           height - Desired height of new ScalosBitMapAndColor BitMap.
           depth - Desired depth of new ScalosBitMapAndColor BitMap. Must be less
           than 256. sac_ColorTable will be allocated to hold 2^depth entries.
           friendBM - Friend BitMap to use for BitMap allocation.
           tagList - pointer to list of Tags, or NULL.
       TAGS
           None defined yet.
       RESULT
           sac - new created ScalosBitMapAndColor, or NULL on failure
       SEE ALSO  ScalosGfxFreeSAC(), ScalosGfxCreateEmptySAC()


       NAME ScalosGfxFreeSAC -- free a previously allocated ScalosBitMapAndColor
       SYNOPSIS
       	ScalosGfxFreeSAC(sac);
       	                A0
       	void ScalosGfxFreeSAC((struct ScalosBitMapAndColor *);


       FUNCTION
           Frees and deallocates a previously allocated ScalosBitMapAndColor,
           including sac_BitMap and sac_ColorTable.
       INPUTS
           sac - previously allocated ScalosBitMapAndColor, or NULL
       RESULT
           nothing
       SEE ALSO ScalosGfxCreateSAC(), ScalosGfxCreateEmptySAC()


       NAME ScalosGfxCreateARGB -- Allocate a gfxARGB with specified size
       SYNOPSIS
       	argb = ScalosGfxCreateARGB(width, height, tagList)
       	D0                         D0     D1      A0
       	struct gfxARGB *ScalosGfxCreateARGB(ULONG, ULONG, struct TagItem *)


       FUNCTION
           Allocates an array of struct gfxARGB with sufficient size for
           specified width and height.
       INPUTS
           width - width of gfxARGB array
           height - height of gfxARGB array
           tagList - pointer to list of Tags, or NULL.
       TAGS
           None defined yet.
       RESULT
           argb - new allocated gfxARGB, or NULL on failure.
       SEE ALSO


       NAME ScalosGfxFreeARGB -- Free a previously allocated gfxARGB
       SYNOPSIS
       	ScalosGfxFreeARGB(argb)
       	D0                A0
       	VOID ScalosGfxFreeARGB(struct gfxARGB **)


       FUNCTION
       INPUTS
           argb - pointer to storage of previously allocated gfxARGB.
           argb may point to NULL.
       RESULT
           nothing
       SEE ALSO  ScalosGfxCreateARGB()


       NAME  ScalosGfxARGBSetAlpha -- Set all pixels to specified Alpha value.
       SYNOPSIS
       	ScalosGfxARGBSetAlpha(src, alpha);
       			      A0   D0
       	VOID ScalosGfxARGBSetAlpha(struct ARGBHeader *, UBYTE)


       FUNCTION
           Alpha value of all pixels in the ARGBHeader and its previously
           allocated gfxARGB array is set to the specified value.
       INPUTS
           src - Header of gfxARGB rectangle to modify.
           alpha - Alpha (transparency) value to set.
       RESULT
       SEE ALSO  ScalosGfxARGBSetAlphaMask()


       NAME ScalosGfxARGBSetAlphaMask -- Set alpha value according to mask plane
       SYNOPSIS
       	ScalosGfxARGBSetAlphaMask(argbh, maskPlane)
       				  A0     A1
       	VOID ScalosGfxARGBSetAlphaMask(struct ARGBHeader *, PLANEPTR)


       FUNCTION
           Alpha values of all pixels in the ARGBHeader and its previously
           allocated gfxARGB array are set according to mask plane, i.e. for
           every bit set in mask plane, alpha is maximum (255), and for every
           cleared bit, alpha is set to minimum (0).
       INPUTS
           argbh - Header of gfxARGB rectangle to modify.
           maskPlane - Single bit mask plane. Dimensions must match size of argbh, with
           width rounded up to next 16-bit.
       RESULT
           nothing
       SEE ALSO ScalosGfxARGBSetAlpha()


       NAME ScalosGfxCreateARGBFromBitMap -- Create gfxARGB array from a BitMap
       SYNOPSIS
       	argb = ScalosGfxCreateARGBFromBitMap(bm, width, height, numberOfColors, colorTable, maskPlane
       	D0                                   A0  D0     D1      D2              A1          A2
       	struct gfxARGB *ScalosGfxCreateARGBFromBitMap(struct BitMap *, ULONG, ULONG, ULONG,
       		const ULONG *, PLANEPTR)


       FUNCTION
           Allocates and a gfxARGB array with specified dimensions, and fills it from
           provided BitMap, with optional mask plane. Works only with standard BitMaps with
           less than 256 colors.
       INPUTS
           bm - source BitMap to fill gfxARGB array from,
           Depth must be less than 256 colors.
           width - Width of gfxARGB array
           height - Height of gfxARGB array
           numberOfColors - number of entries in colorTable
           colorTable - Color table to use for BitMap
           maskPlane - Single bit mask plane. Dimensions must match width and
           height, with width rounded up to next 16-bit. May be NULL.
       RESULT
           argb - allocated gfxARGB array or NULL on failure.
           NOTES
           Use ScalosGfxFillARGBFromBitMap() for high-color or true-color BitMaps.
       SEE ALSO
           ScalosGfxFillARGBFromBitMap()


       NAME  ScalosGfxFillARGBFromBitMap -- Fill previously allocated gfxARGB array from CGFX BitMap
       SYNOPSIS
       	ScalosGfxFillARGBFromBitMap(argbh, srcBM, maskPlane)
       				    A0     A1     A2
       	VOID ScalosGfxFillARGBFromBitMap(struct ARGBHeader *, struct BitMap *, PLANEPTR)


       FUNCTION
           Fill a previously allocated gfxARGB array from a CyberGraphics BitMap. Can only
           be used for high-color or true-color BitMaps.
           If maskPlane if given, alpha information in argbh is created from maskPlane. If
           maskPlane if NULL, alpha channel from source BitMap is used if available,
           otherwise alpha is set to opaque.
       INPUTS
           argbh - completely initialized gfxARGB array
           srcBM - source BitMap to use for filling, depth must be at least 65536 colors
           maskPlane - Single bit mask plane. Dimensions must match width and height, with
           width rounded up to next 16-bit. May be NULL.
       RESULT
           nothing
           NOTES
           Use ScalosGfxARGBSetAlpha() for standard BitMaps (i.e. less than 256 colors).
       SEE ALSO  ScalosGfxCreateARGBFromBitMap()


       NAME  ScalosGfxWriteARGBToBitMap -- Copy gfxARGB array to BitMap
       SYNOPSIS
       	ScalosGfxWriteARGBToBitMap(argbh, bm, numberOfColors, colorTable)
       				   A0     A1  D0              A2)
       	VOID ScalosGfxWriteARGBToBitMap(struct ARGBHeader *, struct BitMap *, ULONG, const ULONG *)


       FUNCTION
           Creates a copy of gfxARGB array in destination BitMap,
           using pre-defined colorTable. Works only with standard BitMaps, i.e. with
           less than 256 colors. No sophisticated color reduction is performed, but
           bit-fit pens are decided via FindBestPen().
       INPUTS
           argbh - gfxARGB array to read from
           bm - Standard BitMap to write to. BitMap must
           have less than 256 colors.
           numberOfColors - Number of entries in colorTable
           colorTable - color table to use for BitMap.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxMedianCut -- Create color-reduced BitMap from gfxARGB array
       SYNOPSIS
       	sac = ScalosGfxMedianCut(argbh, depth, tagList)
       	D0                       A0     D0     A1
       	struct ScalosBitMapAndColor *ScalosGfxMedianCut(struct ARGBHeader *, ULONG, struct TagItem *)
       	struct ScalosBitMapAndColor *ScalosGfxMedianCutTags(struct ARGBHeader *, ULONG, ULONG, ...)


       FUNCTION
           Allocate and fill a color-reduced BitMap and a best-match color table from gfxARGB array.
           Either ordered dithering or Floyd-Steinberg dithering will be used for best results.
       INPUTS
           argbh - gfxARGB array to read from
           depth - desired depth of generated BitMap, must be less than 256.
           tagList - array of tagItems, as described below, or NULL.
       TAGS
           SCALOSGFX_MedianCutFlags - Flags as described below.
           SCALOSGFX_MedianCutFriendBitMap - struct BitMap *, friend BitMap to use
           for allocating result BitMap
           SCALOSGFX_MedianCutReservedColors - ULONG, number of reserved (unused) color
           entries at start of generated color table.
           FLAGS
           SCALOSGFXFLAGF_MedianCut_FloydSteinberg - If set, Floyd-Steinberg dithering
           will be used for color reduction.
       RESULT
           sac - created ScalosBitMapAndColor pointer, or NULL on failure.
       SEE ALSO


       NAME  ScalosGfxScaleARGBArray -- Scale given gfxARGB array
       SYNOPSIS
       	argb = ScalosGfxScaleARGBArray(src, destWidth, destHeight, tagList)
       	D0                             A0   A1         A2          A3
       	struct gfxARGB *ScalosGfxScaleARGBArray(const struct ARGBHeader *, ULONG *,
       		ULONG *, struct TagItem *)
       	struct gfxARGB *ScalosGfxScaleARGBArrayTags(const struct ARGBHeader *, ULONG *,
       		ULONG *, ULONG, ...)


       FUNCTION
           Scales given gfxARGB array to a new size. Supports both enlarging and shrinking
           gfxARGB arrays.
       INPUTS
           src - source gfxARGB array, will not be modified
           destWidth - desired width, might be internally corrected
           if SCALEFLAGF_CORRECTASPECT is set.
           destHeight - desired height, might be internally corrected
           if SCALEFLAGF_CORRECTASPECT is set.
           tagList - pointer to list of Tags, or NULL.
       TAGS
           SCALOSGFX_ScaleARGBArrayFlags - ULONG, specify some operation flags as listed below.
           FLAGS
           SCALEFLAGF_BICUBIC - allow bicubic scaling
           SCALEFLAGF_BILINEAR - allow bilinear scaling
           SCALEFLAGF_AVERAGE - allow average scaling
           SCALEFLAGF_DOUBLESIZE - allow intermediate step via double size, to improve quality
           SCALEFLAGF_CORRECTASPECT - allow correction of destWidth and destHeight to
           meet source aspect ratio.
       RESULT
           argb - Scaled copy of the source gfxARGB array
       SEE ALSO


       NAME  ScalosGfxScaleBitMap -- Scale given BitMap
       SYNOPSIS
       	bm = ScalosGfxScaleBitMap(sbma, tagList)
       	D0                        A0    A1
       	struct BitMap *ScalosGfxScaleBitMap(struct ScaleBitMapArg *, struct TagItem *)
       	struct BitMap *ScalosGfxScaleBitMapTags(struct ScaleBitMapArg *, ULONG, ...)


       FUNCTION
           Scales given gfxARGB array to a new size. Supports both enlarging and shrinking
           gfxARGB arrays.
       INPUTS
           sbma - Structure with scaling parameters:
           sbma_SourceBM - The original BitMap. This BitMap is not modified.
           sbma_SourceWidth - Width of the source BitMap.
           sbma_SourceHeight - Height of the source BitMap
           sbma_DestWidth - Pointer to Width of resized BitMap, might be internally
           corrected if SCALEFLAGF_CORRECTASPECT is set.
           sbma_DestHeight - Pointer to Height of resized BitMap, might be internally
           corrected if SCALEFLAGF_CORRECTASPECT is set.
           sbma_NumberOfColors - number of entries in color table
           sbma_ColorTable - Color table for both source and resized BitMap.
           sbma_Flags - scaling flags:
           SCALEFLAGF_BICUBIC - allow bicubic scaling
           SCALEFLAGF_BILINEAR - allow bilinear scaling
           SCALEFLAGF_AVERAGE - allow average scaling
           SCALEFLAGF_DOUBLESIZE - allow intermediate scaling step with
           double size, to improve quality
           SCALEFLAGF_CORRECTASPECT - allow correction of destWidth and
           destHeight to meet source aspect ratio.
           sbma_ScreenBM - Friend BitMap used when allocating resized BitMap.
           tagList - pointer to list of Tags, or NULL.
       TAGS
           none defined yet.
       RESULT
           bm - Scaled copy of the original BitMap
       SEE ALSO


       NAME  ScalosGfxCalculateScaleAspect -- Adjust scaling dimensions to source aspect
       SYNOPSIS
       	ScalosGfxCalculateScaleAspect(sourceWidth, sourceHeight, *destWidth, *destHeight)
       				      D0           D1            A0          A1
       	VOID ScalosGfxCalculateScaleAspect(ULONG, ULONG, ULONG *, ULONG *)


       FUNCTION
           Adjusts either destWidth or destHeight according to aspect ratio of
           sourceWidth and soureHeight.
       INPUTS
           sourceWidth - Unscaled width.
           sourceHeight - Unscaled Height;
           destWidth - Pointer to desired scaled width.
           destHeight - Pointer to desired scaled width.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxBlitARGB -- Blit rectangle between two gfxARGB array rectangles.
       SYNOPSIS
       	ScalosGfxBlitARGB(destARGB, srcARGB, destLeft, destTop, srcLeft, srcTop, width, height)
       			  A0        A1       D0        D1       D2       D3      D4     D5
       	VOID ScalosGfxBlitARGB(struct ARGBHeader *, const struct ARGBHeader *,
       		LONG, LONG, LONG, LONG, LONG, LONG)


       FUNCTION
           Blits user-defined rectangle from srcARGB at specified position into destARGB.
           No alpha handling is performed, destination pixel values are simply
           replaced by source pixels.
       INPUTS
           destARGB - destination gfxARGB array
           srcARGB - source gfxARGB array
           destLeft - Left start position in destARGB.
           destTop - Top start position in destARGB.
           srcLeft - Left start position in srcARGB.
           srcTop - Top start position in srcARGB.
           width - Width of blitted rectangle.
           height - Height of blitted rectangle.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxFillRectARGB -- Blit two gfxARGB array rectangles
       SYNOPSIS
       	ScalosGfxFillRectARGB(destARGB, fillARGB, left, top, width, height)
       			      A0        A1        D0    D1   D2     D3
       	VOID ScalosGfxFillRectARGB(struct ARGBHeader *, const struct gfxARGB *,
       		LONG, LONG, LONG, LONG)


       FUNCTION
           Blits fillARGB at specified position into destARGB. No alpha handling is
           performed, destination pixel values are just replaced by source pixels.
           Blit always starts at (0,0) in fillARGB.
       INPUTS
           destARGB - destination gfxARGB array.
           fillARGB - source gfxARGB array.
           left - Left start position in destARGB.
           top - Top start position in destARGB.
           width - Width of blitted rectangle.
           height - Height of blitted rectangle.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxSetARGB -- Set entire gfxARGB array to given ARGB color
       SYNOPSIS
       	ScalosGfxSetARGB(destARGB, fillARGB)
       			A0         A1
       	VOID ScalosGfxSetARGB(struct ARGBHeader *, const struct gfxARGB *)


       FUNCTION
           Set all pixels in entire gfxARGB array to the given ARGB color.
       INPUTS
           destARGB - gfxARGB array to be changed.
           fillARGB - ARGB value to set pixels to.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxNewColorMap -- Allocate new color table for ScalosBitMapAndColor
       SYNOPSIS
       	success = ScalosGfxNewColorMap(sac, colorMap, colorEntries)
       	D0                             A0   A1        D0
       	BOOL ScalosGfxNewColorMap(struct ScalosBitMapAndColor *, const ULONG *, ULONG)


       FUNCTION
           Allocates a new color table for ScalosBitMapAndColor. The new color table is
           filled with the RGB values from colorMap.
           Any previously color table in ScalosBitMapAndColor is freed.
       INPUTS
           sac - ScalosBitMapAndColor where to store new color table.
           colorMap - RGB values for new color table
           colorEntries - Desired number of entries in new color table
       RESULT
           success - TRUE if new color table was successfully allocated,
           FALSE on failure.
       SEE ALSO


       NAME  ScalosGfxARGBRectMult -- Multiply RGB value with given factor
       SYNOPSIS
       	ScalosGfxARGBRectMult(rp, numerator, denominator, xMin, yMin, xMax, yMax)
       			      A0  A1         A2           D0    D1    D2    D3
       	VOID ScalosGfxARGBRectMult(struct RastPort *, const struct gfxARGB *,
       		const struct gfxARGB *, WORD, WORD, WORD, WORD)


       FUNCTION
           Multiplies RGB values of pixels within a specified rectangle
           with (numerator/denominator). Overflow is clipped to maximum RGB value (255).
           Works only with CyberGraphics generated, high-color or true-color BitMaps.
           Takes Layers in RastPort into account.
       INPUTS
           rp - RastPort with the BitMap to be modified.
           numerator - Scaling factor as numerator:denominator
           denominator - Scaling factor as numerator:denominator
           xMin - Left start of modified rectangle.
           yMin - Top start of modified rectangle.
           xMax - Right end of modified rectangle.
           yMax - Bottom end of modified rectangle.
       RESULT
           nothing
       SEE ALSO


       NAME  ScalosGfxBlitARGBAlpha -- Alpha blit from gfxARGB array into RastPort
       SYNOPSIS
       	ScalosGfxBlitARGBAlpha(rp, srcH, destLeft, destTop, srcLeft, srcTop, width, height)
       			       A0  A1    D0        D1       D2       D3      D4     D5
       	VOID ScalosGfxBlitARGBAlpha (struct RastPort *, const struct ARGBHeader *,
       		ULONG, ULONG, ULONG, ULONG, ULONG, ULONG)


       FUNCTION
           Blit a rectangular area from source gfxARGB array into
           destination RastPort. Alpha (transparency) information in
           source gfxARGB array is fully accounted for.
           Destination RastPort may have Layers.
       INPUTS
           rp - Destination, this RastPort is been drawn to.
           srcH - Source gfxARGB array
           destLeft - Left offset in destination RastPort.
           destTop - Top offset in destination RastPort.
           srcLeft - Left offset in source gfxARGB array.
           srcTop - Left offset in source gfxARGB array.
           width - Width of blit rectangle.
           height - Height of blit rectangle.
       RESULT
           nothing
           NOTES
       SEE ALSO  ScalosGfxBlitARGBAlphaTagList()


       NAME  ScalosGfxBlitARGBAlphaTagList -- Alpha blit from gfxARGB array into RastPort
       SYNOPSIS
       	ScalosGfxBlitARGBAlphaTagList(rp, srcH, destLeft, destTop, srcSize, tagList)
       				      A0  A1    D0        D1       A3       A2
       	VOID ScalosGfxBlitARGBAlphaTagList(struct RastPort *, const struct ARGBHeader *,
       		ULONG, ULONG, const struct IBox *, struct TagItem *)
       	VOID ScalosGfxBlitARGBAlphaTags(struct RastPort *, const struct ARGBHeader *,
       		ULONG, ULONG, const struct IBox *, ULONG, ...)


       FUNCTION
       INPUTS
           rp - Destination, this RastPort is been drawn to.
           srcH - Source gfxARGB array
           destLeft - Left offset in destination RastPort.
           destTop - Top offset in destination RastPort.
           srcSize - IBox defining both left/top offset in source gfxARGB
           array, and size of blit rectangle.
           tagList - pointer to list of Tags, or NULL.
       TAGS
           SCALOSGFX_BlitIconHilight - const struct ARGB *, ARGB value to use
           for highlighting.Its RGB values are added
           to the destination pixels, with clipping
           to 0..255 range.
           SCALOSGFX_BlitIconAlpha - const UBYTE *, specify alpha array for icon.
           SCALOSGFX_BlitIconTransparency - ULONG, specify alpha for icon, 0...255.
       RESULT
           nothing
       SEE ALSO  ScalosGfxBlitARGBAlpha()


       NAME  ScalosGfxBlitIcon -- Alpha blit from RastPort to RastPort
       SYNOPSIS
       	ScalosGfxBlitIcon(rpBackground, rpIcon, left, top, width, height, tagList)
       			  A0            A1      D0    D1   D2     D3      A2
       	VOID ScalosGfxBlitIcon(struct RastPort *, struct RastPort *,
       		ULONG, ULONG, ULONG, ULONG, struct TagItem *)
       	VOID ScalosGfxBlitIconTags(struct RastPort *, struct RastPort *,
       		ULONG, ULONG, ULONG, ULONG, ULONG, ...)


       FUNCTION
           Blit a rectangular area from rpIcon into rpBackground, with full
           alpha (transparency) support.
           This function supports RastPorts with Layers.
       INPUTS
           rpBackground - Target RastPort.
           rpIcon - Source RastPort. The BitMap of this RastPort is
           not modified.
           left - left start of blit in rpBackground
           top - top start of blit in rpBackground
           width - width of the blitting rectangle
           height - height of the blitting rectangle
           tagList - pointer to list of Tags, or NULL.
       TAGS
           SCALOSGFX_BlitIconHilight - const struct ARGB *, ARGB value to use
           for highlighting. Its RGB values are
           added to the destination pixels, with
           clipping to 0..255 range.
           SCALOSGFX_BlitIconAlpha - const UBYTE *, specify alpha array for icon.
           SCALOSGFX_BlitIconTransparency - ULONG, specify alpha for icon, 0...255.
       RESULT
           nothing
       SEE ALSO



Scalos Messaging

[edit | edit source]

...to the top

   --background
   --Scalos_Message
   --Modules
   --PlugIn's
   --MenuPlugIn's
   SM_AddIcon
   SM_AppSleep
   SM_AppWakeup
   SM_CloseWindow
   SM_DeltaMove
   SM_DoPopupMenu
   SM_Iconify
   SM_NewPreferences
   SM_NewPattern
   SM_NewWindowPath
   SM_PrefsChanged
   SM_Redraw
   SM_RedrawIcon
   SM_RedrawIconObj
   SM_RemIcon
   SM_Requester
   SM_RunMenuCmd
   SM_RunProcess
   SM_SetThumbnailImage_ARGB
   SM_SetThumbnailImage_Remapped
   SM_ShowPopupMenu
   SM_ShowStatusBar
   SM_ShowTitle
   SM_Sleep
   SM_UnIconify
   SM_Update
   SM_UpdateIcon
   SM_Wakeup


       NAME
           --background
           DESCRIPTION
           This documentation gives you information how to communicate with
           Scalos and its windowtasks. There are not many MessageTypes
           currently available, but it will be more in future.


       NAME  --Scalos_Message
           DESCRIPTION
           If you send a message to scalos you should use the SCA_AllocMessage()
           and SCA_FreeMessage() calls from the scalos.library. The returned
           message will look like this:
           struct ScalosMessage
           {
           struct Message sm_Message;
           ULONG sm_Signature; /* "IMSG" */
           ULONG sm_MessageType;
           };
           The message ports where to sent the messages to are available via
           the SCA_LockWindowList() / SCA_UnLockWindowList() calls from
           scalos.library.
           Additional data depends upon MessageType.
           SYNOPSIS will give you information about this data. INPUTS means the
           message for PutMsg() and RESULT the one that was replied.


       NAME  --Modules
           DESCRIPTION
           Modules are programs with a standard wb-start environment. The
           arguments are additional values (e.g. Execute_Command: the dir and
           the filename as default value for the string-gadget).


       NAME  --PlugIn's
           DESCRIPTION
           PlugIn's are external BOOPSI Classes that will enhance or replace
           internal classes. The only thing you have to do is to write a little
           shared library with only one offset. The library base should have at
           least a structure of a Library structure followed by a longword
           (four bytes). These four bytes are used to store an identifier so that
           Scalos can know that it is a Scalos plugin. The value for these four
           bytes should be 'PLUG' (which you should set in the initialisation
           routine of your plugin, or the auto initialisation).
           The one specific offset (it must be the first public function of your
           library if you decide to have more functions) has to return a ScaClassInfo
           struct. Your PlugIn can be added automatically on startup if you
           add it to the PlugIn list in Scalos Prefs.
       SYNOPSIS
       	ScaClassInfo SCAGetClassInfo()
       		D0
       	struct ScaClassInfo *SCAGetClassInfo( void );


   NAME  --MenuPlugIn's
       DESCRIPTION
       A MenuPlugIn is a little library with one function. As with the standard
       plugins, your plugin function must be the first public function of the
       library. Menu plugins also require an identifier in the four bytes
       following the Library structure of the library base. In the case of menu
       plugins, the value for these four bytes should be 'OOPP'.
       This functions have to be full reentrant. The windowtask is blocked until
       your function returns. Never open a requester or block the task for a
       long time use SCCM_AsyncRoutine instead.
   SYNOPSIS
   	SCAMenuFunction( WindowTask, IconNode)
   					 A0          A1
   	void SCAMenuFunction( struct ScaWindowTask *, struct ScaIconNode *);
       NOTES
   	In order to get a pointer to the IconNode, your plugin must be
   	called from an popup menu. When called from a screen menu, the IconNode
   	pointer is always NULL.


NAME SM_DeltaMove

SYNOPSIS

LONG smdm_DeltaX; LONG smdm_DeltaY; ULONG smdm_AdjustSlider;


FUNCTION

   Moves window interior by (deltaX,deltaY) and adjusts
   scrollers accordingly.

INPUTS

   smdm_DeltaX - number of pixels to scroll the window contents
   in horizontal direction.
   smdm_DeltaY - number of pixels to scroll the window contents
   in vertical direction.
   smdm_AdjustSlider - Flags to use for correction of virtual size
   SETVIRTF_AdjustRightSlider = adjust right (vertical) slider
   SETVIRTF_AdjustBottomSlider = set bottom (horizontal) slider

RESULT

   nothing

SEE ALSO IconWindow.sca/SCCM_IconWin_DeltaMove IconWindow.sca/SCCM_IconWin_SetVirtSize


NAME SM_CloseWindow

SYNOPSIS



FUNCTION

   Closes the window of the selected messageport.

INPUTS

   none

RESULT

   nothing

SEE ALSO



NAME SM_DoPopupMenu

SYNOPSIS



FUNCTION

   Trigger opening of a window or icon popup menu.

INPUTS

   smdpm_InputEvent - InputEvent that triggered the popup menu.
   The mouse coordinates from the InputEvent are ignored,
   and the screen->MouseX, MouseY are used instead.

RESULT

   nothing

SEE ALSO



NAME SM_NewPattern

SYNOPSIS

APTR nmnp_PatternNode


FUNCTION

   Sets a new pattern for the window

INPUTS

   snmp_PatternNode - the new pattern or NULL for no pattern.

RESULT

   nothing

SEE ALSO



NAME SM_NewWindowPath

SYNOPSIS



FUNCTION

   Change contents in existing window to display the given new path.

INPUTS

   STRPTR smnwp_Path - Path of the new drawer to display in the window
   struct TagItem *smnwp_TagList - additional tags
   Supported tags are:
   SCA_ShowAllMode - one of the workbench DDFLAGS_* values.
   SCA_ViewModes - one of the workbench DDVM_BY* values
   SCA_XOffset - (LONG) Window X offset
   SCA_YOffset - (LONG) Window Y offset
   SCA_IconList - (struct ScaIconNode *) pregenerated icon list

RESULT

   nothing

SEE ALSO IconWindow.sca/SCCM_IconWin_NewPath


NAME SM_PrefsChanged

SYNOPSIS

ULONG Flags


FUNCTION

   Inform existing window about changed preferences. The window is
   responsible to perform any required updating.

INPUTS

   ULONG Flags - future flags. Set to 0 for upwards compatibility.

RESULT

   nothing

SEE ALSO


NAME SM_Sleep

SYNOPSIS



FUNCTION

   The windowtask that receives this message will be sleep. Only the
   window will be closed, no icon will be displayed.

INPUTS

   none

RESULT

   nothing
   NOTES
   Never send this message to a the main_messageport!

SEE ALSO SM_Wakeup


NAME SM_Wakeup

SYNOPSIS

ULONG smwu_ReLayout


FUNCTION

   Wakeup the selected window_task. It's the opposite to SM_Sleep.

INPUTS

   smwu_ReLayout - BOOL
   TRUE if all icons of the window should be relayouted.
   This is especially important when WorkBench screen has changed.

RESULT

   nothing
   NOTES
   Never send this message to a the main_messageport!

SEE ALSO SM_Sleep


NAME SM_AppSleep

SYNOPSIS



FUNCTION

   All windowtasks and all ScalosApplications will fall asleep.

INPUTS

   none

RESULT

   nothing
   NOTES
   This message must be sent to the main_messageport!

SEE ALSO SM_AppWakeup


NAME SM_AppWakeup

SYNOPSIS

ULONG smaw_ReLayout


FUNCTION

   Wakeup all thing that sleeps since SM_AppSleep.

INPUTS

   smaw_ReLayout - TRUE if all icons should be relayouted.
   This is especially important when WorkBench screen has changed.

RESULT

   nothing
   NOTES
   This message must be sent to the main_messageport!

SEE ALSO SM_AppSleep


NAME SM_Redraw

SYNOPSIS

ULONG smmr_Flags


FUNCTION

   Redraws the icons inside of the window. This method could be uses to
   refresh the window after adding or selecting/deselecting icons.

INPUTS

   smmr_Flags -
   REDRAWB_DontEraseWindow : don't erase window before redraw
   REDRAWB_ReLayoutIcons : relayout icons

RESULT

   nothing

SEE ALSO



NAME SM_RedrawIcon

SYNOPSIS

struct ScaIconObject *smri_Icon


FUNCTION

   Redraws the specified icon inside of the window.
   The window icon list semaphore must not be kept locked for this
   message to work! Before actually trying to redraw, an explicit
   check is done whether the icon is really member of the
   window's icon list.

INPUTS

   smri_Icon - the icvon to be redrawn

RESULT

   nothing

SEE ALSO



NAME SM_RedrawIconObj

SYNOPSIS

Object *smrio_IconObject ULONG smrio_Flags


FUNCTION

   Redraws the specified iconobject inside of the window.
   The window icon list semaphore must not be kept locked for this
   message to work! Before actually trying to redraw, an explicit
   check is done whether the icon is really member of the
   window's icon list.
   Optionally, the icon can be explicitly erased before redrawing,
   and a new icon icon layout may be requested (IDTM_FreeLayout
   / IDTM_Layout).

INPUTS

   smrio_IconObject - the iconobject to be redrawn
   smrio_Flags
   SMRIOFLAGF_EraseIcon - the iconobject is erased before redraw
   SMRIOFLAGF_FreeLayout - the iconobject is forced to refresh its
   layout (with IDTM_FreeLayout and IDTM_Layout).
   SMRIOFLAGF_Highlight - indicates that there is only a change
   in icon highlighting state.
   SMRIOFLAGF_IconListLocked - the window icon list is
   currently locked.
   SMRIOFLAGB_HightlightOn - set ICONOBJ_USERFLAGF_DrawHighlite
   before drawing. Useful in combination
   with SMRIOFLAGF_Highlight.
   SMRIOFLAGB_HightlightOff - clear ICONOBJ_USERFLAGF_DrawHighlite
   before drawing. Useful in combination
   with SMRIOFLAGF_Highlight.

RESULT

   nothing

SEE ALSO



NAME SM_SetThumbnailImage_ARGB

SYNOPSIS

Object *smtia_IconObject struct ARGBHeader smtia_NewImage


FUNCTION

   Attach a new ARGB image to an existing icon. The sender of this
   message is responsible to make sure that destination icon is able
   to handle true-color ARGB images.

INPUTS

   smtia_IconObject - the icon to attach the new image to.
   smtia_NewImage -- the new ARGB image.
   ARGBHeader contents (BitMap) is supposed to be freed
   by message receiver.

RESULT

   nothing

SEE ALSO



NAME SM_SetThumbnailImage_Remapped

SYNOPSIS

Object *smtir_IconObject; // the icon to attach the new image to struct ScalosBitMapAndColor *smtir_NewImage; // the new image. ScalosBitMapAndColor contents is freed by message handler


FUNCTION

   Attach a new color-mapped image to an existing icon.
   The sender of this message is responsible to make sure
   that destination icon is able to handle the color-mapped image.

INPUTS

   smtir_IconObject -- the icon to attach the new image to.
   smtir_NewImage -- the new image. ScalosBitMapAndColor
   contents is supposed to be freed by message receiver.

RESULT

   nothing

SEE ALSO



NAME SM_ShowPopupMenu

SYNOPSIS

struct PopupMenu *pm struct ScaIconNode *in ULONG Flags struct FileTypeDef *fType


FUNCTION

   Show a popup menu and execute the user's menu command.

INPUTS

   pm - Popup menu to display.
   in - Scalos icon node the popup menu should be associated to.
   Can be NULL for window popup menus.
   Flags - Show which items are still locked and HAVE TO BE UNLOCKED
   during processing.
   SHOWPOPUPFLGF_IconSemaLocked - wt_IconSemaphore is still locked
   SHOWPOPUPFLGF_WinListLocked - Scalos window list is still locked.
   fType - Private data structure for support of file type specific
   popup menus. Should be NULL if unused.

RESULT

   nothing

SEE ALSO



NAME SM_ShowStatusBar

SYNOPSIS

BOOL Visible


FUNCTION

   Show or hide the status bar on a Scalos window.

INPUTS

   Visible - TRUE to display the status bar, FALSE to hide it.

RESULT

   nothing

SEE ALSO



NAME SM_Update

SYNOPSIS



FUNCTION

   Causes the window to reread its icons.

INPUTS

   none

RESULT

   nothing

SEE ALSO



NAME SM_UpdateIcon

SYNOPSIS

BPTR smui_DirLock CONST_STRPTR smui_IconName


FUNCTION

   Refresh a selected icon.

INPUTS

   smui_DirLock - Lock to parent dir of icon.
   smui_IconName - Name of the icon.

RESULT

   nothing
   NOTES
   You must create copies of smui_DirLock and smui_IconName before
   sending this message. Those copies will be deleted by Scalos.
   Example:
   smui_DirLock = DupLock(myLock);
   smui_IconName = AllocVec(1 + strlen(myName), MEMF_PUBLIC);


SEE ALSO scalos.library/SCA_UpdateIcon()


NAME SM_AddIcon

SYNOPSIS

UWORD smai_x UWORD smai_y BPTR smai_DirLock STRPTR smai_IconName


FUNCTION

   Causes a window task to load a selected icon.

INPUTS

   smai_x
   smai_y - the position where the icon should appear or 0x8000 for any
   smai_DirLock - Lock to parent dir of icon.
   smai_IconName - Name of the icon.

RESULT

   nothing

SEE ALSO



NAME SM_RemIcon

SYNOPSIS

BPTR smri_DirLock STRPTR smri_IconName


FUNCTION

   Removes an icon from window.

INPUTS

   smri_DirLock - Lock to parent dir of icon.
   smri_IconName - Name of the icon.

RESULT

   nothing

SEE ALSO



NAME SM_Iconify

SYNOPSIS



FUNCTION

   Set the window to sleep and adds an icon to the main window.

INPUTS

   none
   NOTES
   Never send this message to the main window!

RESULT

   nothing

SEE ALSO SM_UnIconify


NAME SM_UnIconify

SYNOPSIS



FUNCTION

   Removes the appicon from main window and reopens the window.

INPUTS

   none

RESULT

   nothing
   NOTES
   Never send this message to the main window!

SEE ALSO SM_Iconify


NAME SM_RunMenuCmd

SYNOPSIS

APTR smrm_MenuItem struct ScaIconNode *smrm_IconNode ULONG smrm_Flags


FUNCTION

   This message is used to execute a Scalos menu command in some
   other window task's context.

INPUTS

   smrm_MenuItem - internal Scalos menu item descriptor
   smrm_IconNode - Iconnode to execute the command with.
   smrm_Flags - none defined yet.

RESULT

   nothing

SEE ALSO


NAME SM_ShowTitle

SYNOPSIS

ULONG smst_showTitle


FUNCTION

   This message is used to set the screen title bar display mode.

INPUTS

   smst_showTitle - Screen title bar mode
   If TRUE, the screen's title bar will be shown in front of
   WFLG_BACKDROP windows.
   If FALSE, the title bar will be rendered behind all windows.


RESULT

   nothing

SEE ALSO


NAME SM_Requester

SYNOPSIS

union { ULONG smrq_ReqResult; struct Window *smrq_ParentWindow; }; APTR smrq_ArgList; struct EasyStruct smrq_ez; UBYTE smrq_ArgListBuffer[0];


FUNCTION

   Asynchronously pops up a requester and returns the result.

INPUTS

   smrq_ParentWindow - designates which screen to open the requester on.
   smrq_ReqResult - Here the result from EaysRequest() is returned.
   smrq_ArgList - pointer to ArgList for EasyRequestArgs().
   smrq_ez - Contains information for EasyRequestArgs()
   smrq_ArgListBuffer - buffer for ArgList - allocated as large as needed.
   Put the required buffer length into the additional_size
   parameter of the SCA_AllocMessage() call.

RESULT

   nothing

SEE ALSO intuition.library/EasyRequestArgs() scalos/SCA_AllocMessage()


NAME SM_NewPreferences

SYNOPSIS

ULONG smnp_PrefsFlags


FUNCTION

   Triggers re-reading and checking of preferences files used by
   Scalos. Multiple invocations of SM_NewPreferences accumulate
   the bits for changes subsystems.
   When there are no more SM_NewPreferences for 0.5s, all marked
   preferences are re-read and check for changes. If changes are
   detected, Scalos reinitializes subsystems as required by the
   preferences changes.

INPUTS

   smnp_PrefsFlags - Bitmask with one bit set for each changed
   preferences file. .

RESULT

   nothing

SEE ALSO


Device List

[edit | edit source]

...to the top

   --background
   SCCM_DeviceList_Generate
   SCCM_DeviceList_FreeDevNode
   SCCM_DeviceList_Filter


       NAME  --background
           DESCRIPTION
           This class is used to generate a list of all currently available
           devices. The list will be used to load or update diskicons. You may
           use this class to filter the devices.


       NAME
           SCCM_DeviceList_Generate
       SYNOPSIS
       	DoMethod(obj,SCCM_DeviceList_Generate,APTR NodeList);


       FUNCTION
           Generates the full list of devices.
           Scans through the DosList and adds a ScaDeviceIcon to the
           NodeList for every appropriate device/volume found.
           When finished scanning, applies SCCM_DeviceList_Filter to the
           NodeList of generated icons.
       INPUTS
           NodeList - pointer to an empty ScalosNodeList
       SEE ALSO


       NAME  SCCM_DeviceList_FreeDevNode
       SYNOPSIS
       	DoMethod(obj,SCCM_DeviceList_FreeDevNode,APTR Node);


       FUNCTION
           Frees anything inside of this node, but not the node itself.
       INPUTS
           Node - DeviceNode
       SEE ALSO


       NAME
           SCCM_DeviceList_Filter
       SYNOPSIS
       	DoMethod(obj,SCCM_DeviceList_Filter,APTR NodeList);


       FUNCTION
           Filters the list of DeviceNodes. You can hide some devices or restore
           the nodelist. Default: all DOS-Devices without a volume will be
           filtered. Checkout the flags field in the DeviceNode structure.
       INPUTS
           NodeList - pointer to a ScalosNodeList
       SEE ALSO


Scalos Device Windows

[edit | edit source]

...to the top

Content-Type: text/html DeviceWin.sca

   --background
   SCCM_DeviceWin_ReadIcon
   SCCM_DeviceWin_RemIcon


       NAME  --background
           DESCRIPTION
           This class implements the main Workbench (= root) window, which
           shows the icons for the mounted devices and volumes.


       NAME  SCCM_DeviceWin_ReadIcon
       SYNOPSIS
       	void DoMethod(obj,SCCM_DeviceWin_ReadIcon,
       		struct ScaDeviceIcon *DeviceNode);


       FUNCTION
           Read icon for device (DeviceNode) into window. Depending on prefs
           settings "DefIcons First", it tries to read :
           DefIconsFirst enabled:
           1. default volume icon "<DefIconPath>/def_<VolumeName>.info"
           2. default device icon "<DefIconPath>/def_<DeviceName>.info"
           3. disk icon "<VolumeName>:disk.info"
           DefIconsFirst disabled:
           1. disk icon "<VolumeName>:disk.info"
           2. default volume icon "<DefIconPath>/def_<VolumeName>.info"
           3. default device icon "<DefIconPath>/def_<DeviceName>.info"
           If everything else fails, a default icon if type WBDISK is read.
       INPUTS
           DeviceNode - info about what device to read icon for.
       RESULT
           nothing
       SEE ALSO


       NAME  SCCM_DeviceWin_RemIcon
       SYNOPSIS
       	void DoMethod(obj,SCCM_DeviceWin_RemIcon,struct ScaIconNode *icon);


       FUNCTION
           Remove specified icon from window
       INPUTS
           icon - Icon to remove from window
       RESULT
           nothing
       SEE ALSO


filetrans

[edit | edit source]

...to the top

...to the top

Scalos window

[edit | edit source]

...to the top

   --background
   SCCM_Window_ChangeWindow
   SCCM_Window_Close
   SCCM_Window_DynamicResize
   SCCM_Window_GetIconFileType
   SCCM_Window_Iconify
   SCCM_Window_InitClipRegion
   SCCM_Window_LockUpdate
   SCCM_Window_NewPath
   SCCM_Window_RemClipRegion
   SCCM_Window_Open
   SCCM_Window_SetTitle
   SCCM_Window_SetInnerSize
   SCCM_Window_UnIconify
   SCCM_Window_UnlockUpdate


       NAME  -background
           DESCRIPTION
           This class implements all common window functionality used for icon
           windows, text windows and device windows.
           All window methods are invoked with mt_WindowObject.


       NAME
           SCCM_Window_ChangeWindow
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_ChangeWindow);


       FUNCTION
           Notifies that a Scalos window may have changed either
           position, or size, or both.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_Close
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_Close);


       FUNCTION
           Closes a scalos window
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_DynamicResize
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_DynamicResize);


       FUNCTION
           Handles dynamic window resizing, including recalculation of window
           inner size, and re-sorting of unpositioned icons (if enabled).
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_GetIconFileType
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_GetIconFileType, struct ScaIconNode *in);


       FUNCTION
           Fills the in_FileType element of the Scalos icon with a TypeNode
           according to the file type of the icon.
       INPUTS
           in - Scalos icon that gets its in_FileType updated.
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_Iconify
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_Iconify);


       FUNCTION
           Iconifies a scalos window
       INPUTS
           none
       RESULT
           TRUE if window could be iconified successfully or
           has already been iconified.
           FALSE if something went wrong.
       SEE ALSO


       NAME
           SCCM_Window_UnIconify
       SYNOPSIS
       	DoMethod(obj,SCCM_Window_UnIconify);


       FUNCTION
           Uniconifies an iconified scalos window
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_InitClipRegion
       SYNOPSIS
       	struct Region *oldRegion = DoMethod(obj,SCCM_Window_InitClipRegion);


       FUNCTION
           Initializes window clip region so that all rendering is limited to
           the window interior.
           All window drawing - especially icon rendering - should be done
           inside a SCCM_Window_InitClipRegion / SCCM_Window_RemClipRegion call.
       INPUTS
           none
       RESULT
           oldRegion - original clip region (to be supplied
           to SCCM_Window_RemClipRegion)
       SEE ALSO
           SCCM_Window_RemClipRegion


       NAME
           SCCM_Window_LockUpdate
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_LockUpdate)


       FUNCTION
           Holds all icon updates for that window.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_Window_UnlockUpdate


       NAME
           SCCM_Window_NewPath
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_NewPath,CONST_STRPTR path,ULONG tags,...);


       FUNCTION
           Inform window object about new path.
           No-op in standard window classes.
       INPUTS
           path - command name
           tags - tag list. Supported tags are:
           SCA_ShowAllMode - one of the workbench DDFLAGS_* values.
           SCA_ViewModes - one of the workbench DDVM_BY* values
           SCA_XOffset - (LONG) Window X offset
           SCA_YOffset - (LONG) Window Y offset
           SCA_IconList - (struct ScaIconNode *) pregenerated icon list
       RESULT
           Success - FALSE on failure, TRUE to indiciate success.
       SEE ALSO
           scalosAPI/SM_NewWindowPath
           IconWindow.sca/SCCM_IconWin_NewPath


       NAME
           SCCM_Window_RemClipRegion
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_RemClipRegion, 
       		struct Region *oldRegion);


       FUNCTION
           Resets window clip region to oldRegion.
       INPUTS
           oldRegion - original clip region
           (Result from SCCM_Window_InitClipRegion)
       RESULT
           nothing
       SEE ALSO
           SCCM_Window_InitClipRegion


       NAME
           SCCM_Window_Open
       SYNOPSIS
       	struct Window *win = DoMethod(obj,SCCM_Window_Open);


       FUNCTION
           Opens a scalos window
       INPUTS
           none
       RESULT
           win - Pointer to Intuition Window if window could be opened,
           NULL if something went wrong.
       SEE ALSO


       NAME
           SCCM_Window_SetTitle
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_SetTitle, CONST_STRPTR title)


       FUNCTION
           Sets window title to (title).
       INPUTS
           title - window title string.
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_SetInnerSize
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_SetInnerSize)


       FUNCTION
           Update internal Scalos variables according to the current
           window size and setup a new window clip region.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_Window_UnlockUpdate
       SYNOPSIS
       	void DoMethod(obj,SCCM_Window_UnlockUpdate)


       FUNCTION
           Enabled window updates stopped by SCCM_Window_LockUpdate.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_Window_LockUpdate


Scalos SCCM iconwindow

[edit | edit source]

...to the top

   --background
   SCCM_IconWin_ActivateIconDown
   SCCM_IconWin_ActivateIconLeft
   SCCM_IconWin_ActivateIconNext
   SCCM_IconWin_ActivateIconPrevious
   SCCM_IconWin_ActivateIconRight
   SCCM_IconWin_ActivateIconUp
   SCCM_IconWin_AddGadget
   SCCM_IconWin_AddIcon
   SCCM_IconWin_AddToControlBar
   SCCM_IconWin_AddToStatusBar
   SCCM_IconWin_Browse
   SCCM_IconWin_CleanUp
   SCCM_IconWin_CleanUpByDate
   SCCM_IconWin_CleanUpByName
   SCCM_IconWin_CleanUpBySize
   SCCM_IconWin_CleanUpByType
   SCCM_IconWin_ClearIconFileTypes
   SCCM_IconWin_CountWBArg
   SCCM_IconWin_DeltaMove
   SCCM_IconWin_DragDrop
   SCCM_IconWin_DragEnter
   SCCM_IconWin_DragQuery
   SCCM_IconWin_DragLeave
   SCCM_IconWin_DrawIcon
   SCCM_IconWin_GetDefIcon
   SCCM_IconWin_GetIconFileType
   SCCM_IconWin_History_Back
   SCCM_IconWin_History_Forward
   SCCM_IconWin_ImmediateCheckUpdate
   SCCM_IconWin_LayoutIcon
   SCCM_IconWin_MakeWBArg
   SCCM_IconWin_MenuCommand
   SCCM_IconWin_NewPath
   SCCM_IconWin_NewPatternNumber
   SCCM_IconWin_NewViewMode
   SCCM_IconWin_Open
   SCCM_IconWin_RawKey
   SCCM_IconWin_ReadIcon
   SCCM_IconWin_ReadIconList
   SCCM_IconWin_Redraw
   SCCM_IconWin_RemFromControlBar
   SCCM_IconWin_RemFromStatusBar
   SCCM_IconWin_RemIcon
   SCCM_IconWin_ScheduleUpdate
   SCCM_IconWin_SetVirtSize
   SCCM_IconWin_ShowGadgetToolTip
   SCCM_IconWin_ShowIconToolTip
   SCCM_IconWin_ShowPopupMenu
   SCCM_IconWin_Sleep
   SCCM_IconWin_StartNotify
   SCCM_IconWin_Update
   SCCM_IconWin_UpdateIcon
   SCCM_IconWin_UpdateControlBar
   SCCM_IconWin_UpdateStatusBar
   SCCM_IconWin_WakeUp


       NAME
           --background
           DESCRIPTION
           This class implements the functionality for the common workbench
           icon windows.
           ATTRIBUTES
           SCCA_IconWin_Reading - (BOOL) [SG]
           currently reading directory
           SCCA_IconWin_SelectedCount - (ULONG) [SG]
           number of selected icons in window
           SCCA_IconWin_Typing - (BOOL) [SG]
           user is currently tying icon name
           SCCA_IconWin_ShowType - (ULONG) [SG]
           DDFLAGS_SHOWDEFAULT, DDFLAGS_SHOWICONS, or DDFLAGS_SHOWALL
           SCCA_IconWin_InnerWidth - (ULONG) [.G]
           icon window inner width
           SCCA_IconWin_InnerHeight - (ULONG) [.G]
           icon window inner height
           SCCA_IconWin_IconFont - (struct TextFont *) [.G]
           icon window icon font
           SCCA_IconWin_LayersLocked - (ULONG) [.G]
           Flag: icon window has Layers locked
           SCCA_IconWin_StatusBar - (BOOL) [SG]
           Flag: Status bar is present
           SCCA_IconWin_ThumbnailView - (ULONG) [SG]
           Thumbnail display mode. One of THUMBNAILS_Never,
           THUMBNAILS_Always, or THUMBNAILS_AsDefault.
           Any other value makes the window use the default value,
           as set in Scalos preferences.


       NAME
           SCCM_IconWin_ActivateIconDown
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconDown);


       FUNCTION
           Starting from the first icon currently selected, the icon located
           directly below the selected will be activated.
           If there is no icon selected, or the selected icon is located in
           the bottommost row, the method is a no-op.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconUp
           SCCM_IconWin_ActivateIconLeft
           SCCM_IconWin_ActivateIconRight


       NAME
           SCCM_IconWin_ActivateIconLeft
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconLeft);


       FUNCTION
           Starting from the first icon currently selected, the icon located
           directly left of the selected will be activated.
           If there is no icon selected, or the selected icon is located in
           the leftmost column, the method is a no-op.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconDown
           SCCM_IconWin_ActivateIconUp
           SCCM_IconWin_ActivateIconRight


       NAME
           SCCM_IconWin_ActivateIconNext
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconNext);


       FUNCTION
           Starting from the first icon currently selected, the icon which
           alphabetically follows the name of the selected one
           will be activated.
           If there is no icon selected, the alphabetically first
           icon will be selected.
           If the currently activated icon is the alphabetically last one in
           the window, this method will wrap around and activate the
           alphabetically first one.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconPrevious


       NAME
           SCCM_IconWin_ActivateIconPrevious
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconPrevious);


       FUNCTION
           Starting from the first icon currently selected, the icon which
           alphabetically precedes the name of the selected one
           will be activated.
           If there is no icon selected, the alphabetically last
           icon will be selected.
           If the currently activated icon is the alphabetically first one in
           the window, this method will wrap around and activate the
           alphabetically last one.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconNext


       NAME
           SCCM_IconWin_ActivateIconRight
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconRight);


       FUNCTION
           Starting from the first icon currently selected, the icon located
           directly right of the selected will be activated.
           If there is no icon selected, or the selected icon is located in
           the rightmost column, the method is a no-op.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconDown
           SCCM_IconWin_ActivateIconUp
           SCCM_IconWin_ActivateIconLeft


       NAME
           SCCM_IconWin_ActivateIconUp
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_ActivateIconUp);


       FUNCTION
           Starting from the first icon currently selected, the icon located
           directly above the selected will be activated.
           If there is no icon selected, or the selected icon is located in
           the topmost row, the method is a no-op.
       INPUTS
           None
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ActivateIconDown
           SCCM_IconWin_ActivateIconLeft
           SCCM_IconWin_ActivateIconRight


       NAME
           SCCM_IconWin_AddGadget
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_AddGadget,struct Gadget *g);


       FUNCTION
           Inserts a user-supplied Intuition Gadget at the front
           of the internal Gadget list.
       INPUTS
           Gadget - User-supplied Gadget
       SEE ALSO


       NAME
           SCCM_IconWin_AddIcon
       SYNOPSIS
       	struct ScaIconNode *icon = DoMethod(obj,SCCM_IconWin_AddIcon,
       		WORD x,WORD y,BPTR Lock,CONST_STRPTR Name);


       FUNCTION
           Causes a window task to load the specified selected icon.
       INPUTS
           x - icon x position or $8000 for any position
           y - icon y position
           Lock - Lock on icon directory
           Name - icon name
       RESULT
           icon - newly added ScaIconNode or NULL if something went wrong.
       SEE ALSO


       NAME
           SCCM_IconWin_AddToControlBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_AddToControlBar,struct Gadget *g,
       		ULONG Tag, ...);


       FUNCTION
           Adds a new BOOPSI gadget to the window control bar.
       INPUTS
           g - new Gadget to be added
           Tag - Taglist
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_RemFromControlBar


       NAME
           SCCM_IconWin_AddToStatusBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_AddToStatusBar,struct Gadget *g,
       		ULONG Tag, ...);


       FUNCTION
           Adds a new BOOPSI gadget to the window status bar.
       INPUTS
           g - new Gadget to be added
           Tag - Taglist
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_RemFromStatusBar


       NAME
           SCCM_IconWin_Browse
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_Browse);


       FUNCTION
           Opens an ASL requester that allows selection of a new
           path to display in the current window.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_ScheduleUpdate
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_ScheduleUpdate);


       FUNCTION
           Schedule a check of the window for updated files and perform
           updates, including adding and removing icons.
           This real update check will be delayed for about 2 seconds in
           order to avoid many rapidly repeated window updates, and is done
           via the SCCM_IconWin_ImmediateCheckUpdate method.
           These 2 seconds are restarted with each new
           SCCM_IconWin_ScheduleUpdate invokation.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_ImmediateCheckUpdate


       NAME
           SCCM_IconWin_CleanUp
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_CleanUp);


       FUNCTION
           Fits all window icons to free positions, including icons in
           wt_LateIconList. Prevents icons from overlapping each other.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_CleanUpByDate
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_CleanUpByDate);


       FUNCTION
           Sorts all window icons descending by date, and fits them to free
           positions, including icons in wt_LateIconList.
           Prevents icons from overlapping each other.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_CleanUpByName
           SCCM_IconWin_CleanUpBySize
           SCCM_IconWin_CleanUpByType


       NAME
           SCCM_IconWin_CleanUpByName
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_CleanUpByName);


       FUNCTION
           Sorts all window icons ascending by name, and fits them to free
           positions, including icons in wt_LateIconList.
           Prevents icons from overlapping each other.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_CleanUpByDate
           SCCM_IconWin_CleanUpBySize
           SCCM_IconWin_CleanUpByType


       NAME
           SCCM_IconWin_CleanUpBySize
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_CleanUpBySize);


       FUNCTION
           Sorts all window icons ascending by size, and fits them to free
           positions, including icons in wt_LateIconList.
           Prevents icons from overlapping each other.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_CleanUpByDate
           SCCM_IconWin_CleanUpByName
           SCCM_IconWin_CleanUpByType


       NAME
           SCCM_IconWin_CleanUpByType
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_CleanUpByType);


       FUNCTION
           Sorts all window icons ascending by type, and fits them to free
           positions, including icons in wt_LateIconList.
           Prevents icons from overlapping each other.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_IconWin_CleanUpByDate
           SCCM_IconWin_CleanUpByName
           SCCM_IconWin_CleanUpBySize


       NAME
           SCCM_IconWin_ClearIconFileTypes
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_ClearIconFileTypes);


       FUNCTION
           Clears the filetype information for all windows in the icon
           window. Useful if filetype information hasd changed
           and has to be re-read.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_CountWBArg
       SYNOPSIS
       	ULONG Count = DoMethod(obj,SCCM_IconWin_CountWBArg,
       		struct ScaIconNode *icon);


       FUNCTION
           Count arguments that will be crated by SCCM_IconWin_MakeWBArg.
           Useful to allocate a WBArg buffer for SCCM_IconWin_MakeWBArg.
       INPUTS
           icon - icon to make WBArg from
           if icon = NULL, return WBArg with wa_Lock = copy of
           window lock and wa_Name = NULL
       RESULT
           Count - number of WBArg's that SCCM_IconWin_MakeWBArg will create
       SEE ALSO
           SCCM_IconWin_MakeWBArg


       NAME
           SCCM_IconWin_DeltaMove
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_DeltaMove,LONG deltaX,LONG deltaY);


       FUNCTION
           Moves window interior by (deltaX,deltaY) and adjusts
           scrollers accordingly.
       INPUTS
           deltaX - movement in horizontal direction
           deltaY - movement in vertical direction
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_DragDrop
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_DragDrop,struct Window *dropWindow,
       		ULONG mouseX,ULONG mouseY,ULONG Qualifier);


       FUNCTION
           Drops all dragged icons into (dropWindow) at coordinates
           (mouseX,MouseY).
       INPUTS
           dropWindow - Intuition window to drop in
           mouseX - mouse x position from IntuiMessage
           mouseY - mouse y position from IntuiMessage
           Qualifier - qualifier position from IntuiMessage
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_DragEnter
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_DragEnter, struct ScaWindowStruct *StartWin,
       		struct ScaIconNode *Icon, ULONG MouseX, ULONG MouseY)


       FUNCTION
           Signals destination window that mouse pointer with attached
           icons has entered the window area (drage_Icon = NULL) or
           now points to icon (drage_Icon).
       INPUTS
           StartWin - scalos window from which dragging started
           Icon -icon under mouse pointer
           MouseX, MouseY - mouse coordinates.
       RESULT
           nothing
       NOTE
           It is VERY IMPORTANT that every SCCM_IconWin_DragEnter (icon
           or window) is paired with a corresponding
           SCCM_IconWin_DragLeave method (icon or window) call !!!
       SEE ALSO
           SCCM_IconWin_DragLeave


       NAME
           SCCM_IconWin_DragQuery
       SYNOPSIS
       	BOOL DoMethod(obj,SCCM_IconWin_DragQuery, struct ScaWindowStruct *StartWin,
       		struct ScaIconNode *Icon, ULONG MouseX, ULONG MouseY)


       FUNCTION
           Check whether icons may be dropped into our window
           or onto specified icon.
       INPUTS
           StartWin - scalos window from which dragging started
           Icon -icon under mouse pointer
           MouseX, MouseY - mouse coordinates.
       RESULT
           BOOL
           TRUE yes, we may drop here
           FALSE no, dropping not allowed
       SEE ALSO


       NAME
           SCCM_IconWin_DragLeave
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_DragLeave, struct ScaWindowStruct *StartWin,
       		struct ScaIconNode *Icon, ULONG MouseX, ULONG MouseY);


       FUNCTION
           Signals destination window that mouse pointer with attached
           icons has left the window area (drage_Icon = NULL) or
           now points no longer to icon (drage_Icon).
       INPUTS
           StartWin - scalos window from which dragging started
           Icon -icon under mouse pointer
           MouseX, MouseY - mouse coordinates.
       RESULT
           nothing
       NOTE
           It is VERY IMPORTANT that every SCCM_IconWin_DragEnter (icon
           or window) is paired with a corresponding
           SCCM_IconWin_DragLeaveDrag method (icon or window) call !!!
       SEE ALSO
           SCCM_IconWin_DragEnter


       NAME
           SCCM_IconWin_DrawIcon
       SYNOPSIS
       	ULONG Result = DoMethod(obj,SCCM_IconWin_DrawIcon,Object *IconObject);


       FUNCTION
           Draws (IconObject) in window by invoking IDTM_Draw method with icon
       INPUTS
           IconObject - Icon to be drawn
       RESULT
           Result - result from IDTM_Draw
       SEE ALSO


       NAME
           SCCM_IconWin_GetDefIcon
       SYNOPSIS
       	Object *icon = DoMethod(obj,SCCM_IconWin_GetDefIcon,CONST_STRPTR Name,
       		LONG Type,ULONG Protection);


       FUNCTION
           Tries to get a default icon for the specified file. Calls
           iconobject.library/GetDefIconObject and returns result.
       INPUTS
           Name - file name
           Type - file type (fib_DirEntryType from FileInfoBlock)
           Protection - file protection (fib_Protection from FileInfoBlock)
       RESULT
           icon - default Icon IconObject
       SEE ALSO
           iconobject.library/GetDefIconObject


       NAME
           SCCM_IconWin_GetIconFileType
       SYNOPSIS
       	Object *icon = DoMethod(obj,SCCM_IconWin_GetIconFileType,
       		struct ScaIconNode *icon);


       FUNCTION
           Identifies object for icon, find the appropriate filetype
           and setup the in_FileType member of ScaIconNode.
       INPUTS
           icon - icon to find filetype for.
       RESULT
           icon - default Icon IconObject
       SEE ALSO
           iconobject.library/GetDefIconObject


       NAME
           SCCM_IconWin_History_Back
       SYNOPSIS
       	Object *icon = DoMethod(obj,SCCM_IconWin_History_Back);


       FUNCTION
           Move one step backwards in the history of the window contents,
           and switch to display the contents of the path from the history
           using the current view mode.
           Does nothing if the current view is already the oldest one
           in the window history.
       INPUTS
           None.
       RESULT
           None.
       SEE ALSO
           SCCM_IconWin_History_Forward


       NAME
           SCCM_IconWin_History_Forward
       SYNOPSIS
       	Object *icon = DoMethod(obj,SCCM_IconWin_History_Forward);


       FUNCTION
           Move one step forward in the history of the window contents,
           and switch to display the contents of the path from the history
           using the current view mode.
           Does nothing if the current view is already the most recent one
           in the window history.
       INPUTS
           None.
       RESULT
           None.
       SEE ALSO
           SCCM_IconWin_History_Back


       NAME
           SCCM_IconWin_ImmediateCheckUpdate
       SYNOPSIS
       	Object *icon = DoMethod(obj,SCCM_IconWin_ImmediateCheckUpdate);


       FUNCTION
           Scan directory associated to this window and check for any changes
           between the display and the disk contents. If any changes are found,
           icons are added, removed, or replaced as necessary.
       INPUTS
           None
       SEE ALSO
           SCCM_IconWin_ScheduleUpdate


       NAME
           SCCM_IconWin_LayoutIcon
       SYNOPSIS
       	ULONG Result = DoMethod(obj,SCCM_IconWin_LayoutIcon,Object *IconObject,
       		ULONG LayoutFlags);


       FUNCTION
           Prepares an IconObject to be rendered.
       INPUTS
           IconObject - icon to be layouted
           LayoutFlags
           IOLAYOUTB_NormalImage // Layout normal Image
           IOLAYOUTB_SelectedImage // Layout selected Image
       RESULT
           Result - result from IDTM_Layout
       SEE ALSO


       NAME
           SCCM_IconWin_MakeWBArg
       SYNOPSIS
       	ULONG Count = DoMethod(obj,SCCM_IconWin_MakeWBArg,
       		struct ScaIconNode *icon, struct WBArg *Buffer);


       FUNCTION
           Fill a WBArg structure (wa_Lock and wa_Name) from the given icon or
           from the window.
       INPUTS
           icon - icon to make WBArg from
           if icon = NULL, return WBArg with wa_Lock = copy of
           window lock and wa_Name = NULL
           Buffer - Result buffer with at least enough room for one WBArg.
       RESULT
           Count - number of successfully created WBArg's in (Buffer)
       SEE ALSO
           SCCM_IconWin_CountWBArg


       NAME
           SCCM_IconWin_MenuCommand
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_MenuCommand,CONST_STRPTR CmdName, 
       		struct ScaIconNode *icon, BOOL state);


       FUNCTION


       INPUTS
           CmdName - command name
           icon - icon to apply command to
           state - ?
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_NewPath
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_NewPath,CONST_STRPTR path,ULONG tags,...);


       FUNCTION
           Change contents in existing window to display the given new path.
       INPUTS
           path - command name
           tags - tag list. Supported tags are:
           SCA_ShowAllMode - one of the workbench DDFLAGS_* values.
           SCA_ViewModes - one of the workbench DDVM_BY* values
           SCA_XOffset - (LONG) Window X offset
           SCA_YOffset - (LONG) Window Y offset
           SCA_IconList - (struct ScaIconNode *) pregenerated icon list
       RESULT
           Success - FALSE on failure, TRUE to indiciate success.
       SEE ALSO
           scalosAPI/SM_NewWindowPath


       NAME
           SCCM_IconWin_NewPatternNumber
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_NewPatternNumber,ULONG NewPatternNumber);


       FUNCTION


       INPUTS
           NewPatternNumber - Instruct Scalos to use a new background for the
           current icon window. Special constant can be specified to
           use one of the predefined default patterns:
           PATTERNNR_WorkbenchDefault use default Workbench
           window background.
           PATTERNNR_IconWindowDefault use default icon window
           background pattern.
           PATTERNNR_TextWindowDefault use default text window
           pattern.
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_NewViewMode
       SYNOPSIS
       	Object *WindowObj = DoMethod(obj,SCCM_IconWin_NewViewMode,
       		ULONG ViewMode);


       FUNCTION
           changes window view mode from text to icon and vice versa.
       INPUTS
           ViewMode - new window view mode
       RESULT
           WindowObj - IconWindow.sca subclass object if window class
           changes from text to icon or vice versa
           NULL if window class is not changed.
       SEE ALSO


       NAME
           SCCM_IconWin_Open
       SYNOPSIS
       	BOOL Success = DoMethod(obj, SCCM_IconWin_Open, struct ScaIconNode *icon, ULONG Flags);


       FUNCTION
           perform "open" function on (icon)
       INPUTS
           icon - icon to open
           Flags - ICONWINOPENF_IgnoreFileTypes -- always OPEN icon, ignore
           file type settings.
           ICONWINOPENF_NewWindow -- open drawers in new window, regardless
           of browser mode.
       RESULT
           Success - TRUE if new window could be opened
           FALSE if anything went wrong
       SEE ALSO


       NAME
           SCCM_IconWin_RawKey
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_RawKey,struct IntuiMessage *iMsg);


       FUNCTION
           Processes Intuition IDCMP_RAWKEY events.
       INPUTS
           iMsg - IntuiMessage
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_ReadIcon
       SYNOPSIS
       	struct ScaIconNode *icon = DoMethod(obj,SCCM_IconWin_ReadIcon,
       			CONST_STRPTR name, struct ScaReadIconArg *ria);


       FUNCTION
           Read one icon, add it to the window icon list, and display it.
           If an icon with the same name already exists it is replaced.
           If no icon could be created, i.e. because the file system
           object is no longer present, any existing icon is removed
           from the window.
           The intended use of this method is to update icon window after
           change in file system, i.e. add file, remove file, or change file.
       INPUTS
           name - name of the icon
           ria - pointer to struct ScaReadIconArg with information about x/y icon
           position, and optional Lock on parent directory.
           ria may be NULL.
       RESULT
           icon - newly created ScaIconNode or NULL if something went wrong.
       SEE ALSO


       NAME
           SCCM_IconWin_ReadIconList
       SYNOPSIS
       	BOOL Error = DoMethod(obj,SCCM_IconWin_ReadIconList,ULONG flags);


       FUNCTION
           Read all icons in directory into window.
       INPUTS
           flags - SCCV_IconWin_ReadIconList_ShowAll = show all files
       RESULT
           Error - non-zero value if anything went wrong
       SEE ALSO


       NAME
           SCCM_IconWin_Redraw
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_Redraw,ULONG flags);


       FUNCTION
           redraws window
       INPUTS
           flags
           REDRAWB_DontEraseWindow : don't erase window before redraw
           REDRAWB_ReLayoutIcons : relayout icons
           REDRAWB_DontRefreshWindowFrame : do not refresh window frame
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_RemIcon
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_RemIcon,BPTR Lock, CONSTR_STRPTR Name);


       FUNCTION
           Remove specified icon from window
       INPUTS
           Lock - Lock on icon directory
           Name - Name of icon to remove
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_RemFromControlBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_RemFromControlBar,struct Gadget *g);


       FUNCTION
           Remove specified Gadget from window control bar, and disposes it.
       INPUTS
           g - Gadget to remove from control bar
       SEE ALSO
           SCCM_IconWin_AddToControlBar


       NAME
           SCCM_IconWin_RemFromStatusBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_RemFromStatusBar,struct Gadget *g);


       FUNCTION
           Remove specified Gadget from window status bar, and disposes it.
       INPUTS
           g - Gadget to remove from status bar
       SEE ALSO
           SCCM_IconWin_AddToStatusBar


       NAME
           SCCM_IconWin_SetVirtSize
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_SetVirtSize,ULONG Flags);


       FUNCTION
           Calculate bounding rectangle of all icons in window and optionally
           adjust window scrollers accordingly.
       INPUTS
           Flags
           SETVIRTF_AdjustRightSlider = adjust right (vertical) slider
           SETVIRTF_AdjustBottomSlider = set bottom (horizontal) slider
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_ShowIconToolTip
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_ShowGadgetToolTip, ULONG gadgetID);


       FUNCTION
           Display tool tip window for (gadgetID).
       INPUTS
           gadgetID - GadgetID of gadget to display tool tip for.
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_ShowIconToolTip
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_ShowIconToolTip,
       		struct ScaIconNode *icon);


       FUNCTION
           Display icon tool tip window for (icon).
       INPUTS
           icon - icon to display tool tip for.
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_Sleep
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_Sleep);


       FUNCTION
           Iconify window and add AppIcon to Workbench.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_StartNotify
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_StartNotify);


       FUNCTION
           Cancel any existing drawer notification for this window,
           and install a new notification.
       INPUTS
           none
       RESULT
           Success - TRUE if notification successfully started, FALSE on failure.
       SEE ALSO


       NAME
           SCCM_IconWin_Update
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_Update);


       FUNCTION
           Re-read all icons into window and redraw window.
       INPUTS
           none
       RESULT
           ?
       SEE ALSO


       NAME
           SCCM_IconWin_UpdateIcon
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_UpdateIcon,BPTR Lock,CONST_STRPTR Name);


       FUNCTION
           Update and redisplay icon.
       INPUTS
           Lock - Lock to icon directory
           Name - name of icon
       RESULT
           ?
       SEE ALSO


       NAME
           SCCM_IconWin_UpdateControlBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_UpdateControlBar,struct Gadget *g,ULONG Tags,...);


       FUNCTION
           Update window control bar member gadget. Applies OM_SET method with
           the supplied taglist to member gadget.
       INPUTS
           g - Control bar member gadget to update
           Tags - Taglist
       SEE ALSO


       NAME
           SCCM_IconWin_UpdateStatusBar
       SYNOPSIS
       	DoMethod(obj,SCCM_IconWin_UpdateStatusBar,struct Gadget *g,ULONG Tags,...);


       FUNCTION
           Update window status bar member gadget. Applies OM_SET method with
           the supplied taglist to member gadget.
       INPUTS
           g - Status bar member gadget to update
           Tags - Taglist
       SEE ALSO


       NAME
           SCCM_IconWin_WakeUp
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_WakeUp,ULONG ReLayout);


       FUNCTION
           Uniconify and open iconified window.
       INPUTS
           ReLayout - TRUE if all icons of the window should be relayouted
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_IconWin_ShowPopupMenu
       SYNOPSIS
       	void DoMethod(obj,SCCM_IconWin_ShowPopupMenu,
       		struct PopupMenu *pm, struct ScaIconNode *in, 
       		ULONG Flags, struct FileTypeDef *fType);


       FUNCTION
           Show a popup menu and execute the user's menu command.
       INPUTS
           pm - Popup menu to display.
           in - Scalos icon node the popup menu should be associated to.
           Can be NULL for window popup menus.
           Flags - Show which items are still locked and HAVE TO BE UNLOCKED
           during processing.
           SHOWPOPUPFLGF_IconSemaLocked - wt_IconSemaphore is still locked
           SHOWPOPUPFLGF_WinListLocked - Scalos window list is still locked.
           fType - Private data structure for support of file type specific
           popup menus. Should be NULL if unused.
       RESULT
           nothing
       SEE ALSO



Scalos SCCM textwindow

[edit | edit source]

...to the top

   --background
   SCCM_TextWin_BeginUpdate
   SCCM_TextWin_DrawColumnHeaders
   SCCM_TextWin_EndUpdate
   SCCM_TextWin_InsertIcon
   SCCM_TextWin_ReAdjust


       NAME
           --background
           DESCRIPTION
           This class implements the text-only Scalos windows. Most
           functionality is derived from IconWindow.sca but there are
           some special methods described below.


       NAME
           SCCM_TextWin_BeginUpdate
       SYNOPSIS
       	DoMethod(obj,SCCM_TextWin_BeginUpdate);


       FUNCTION
           hold all visible updates until SCCM_TextWin_EndUpdate
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO
           SCCM_TextWin_EndUpdate


       NAME
           SCCM_TextWin_DrawColumnHeaders
       SYNOPSIS
       	DoMethod(obj,SCCM_TextWin_DrawColumnHeaders);


       FUNCTION
           Redraws text window column headers.
       INPUTS
           nothing
       RESULT
           nothing
       SEE ALSO


       NAME
           SCCM_TextWin_EndUpdate
       SYNOPSIS
       	DoMethod(obj,SCCM_TextWin_EndUpdate,ULONG RefreshFlag);


       FUNCTION
           Unlock window updates and optionally rebuild window contents.
       INPUTS
           RefreshFlag - if TRUE,
           forces window to perform SCCM_TextWin_ReAdjust.
       RESULT
           nothing
       SEE ALSO
           SCCM_TextWin_BeginUpdate


       NAME
           SCCM_TextWin_InsertIcon
       SYNOPSIS
       	DoMethod(obj,SCCM_TextWin_InsertIcon,struct ScaIconNode *in);


       FUNCTION
           The ScaIconNode is inserted into the text window icon list,
           according to the current sorting order.
           If an icon with the same name already exists, it is replaced.
       INPUTS
           in - ScaIconNode which is to inserted into the
           sorted icon list if the text window.
       RESULT
           nothing


       NAME
           SCCM_TextWin_ReAdjust
       SYNOPSIS
       	void DoMethod(obj,SCCM_TextWin_ReAdjust);


       FUNCTION
           Rebuilds text window. Entries are re-sorted, all column headers
           and text gadgets are redrawn and the scrollers are adjusted.
       INPUTS
           none
       RESULT
           nothing
       SEE ALSO



Scalos SCCM title

[edit | edit source]

...to the top

   --background
   SCCM_Title_Generate
   SCCM_Title_Query
   SCCM_Title_QueryTitle
   SCCM_Title_Translate


       NAME
           --background
           DESCRIPTION
           This class implements the screen title and window title functionality.


       TAGS
           SCCA_Title_Format (CONST_STRPTR) -- Format string for the title.
           This string is processed, replacing all the "%" variables
           with their values.
           Standard title variables:
           "%os" Kickstart release (e.g. "3.1")
           "%wb" Scalos release (e.g. "1.3")
           "%ov" Kickstart version (e.g. "40.68")
           "%wv" Scalos version (e.g. "40.6")
           "%fc" * Free chip RAM in bytes
           "%ff" * Free fast RAM in bytes
           "%ft" * Total free RAM in bytes
           "%pa" Window's path
           "%df" * Free disk space in bytes
           "%DF" Free disk space, displayed in GBytes/MBytes/KBytes
           "%du" * Used disk space in bytes
           "%DU" Used disk space, displayed in GBytes/MBytes/KBytes
           "%d(" start: don't show if no disk inserted
           "%d)" stop: don't show if no disk inserted
           "%dp" percentage of disk space used
           "%cs" Chip set
           "%cp" Processor
           "%pr" CoProzessor
           "%nt" number of tasks
           "%nl" number of libraries
           "%np" number of message ports
           "%nd" number of devices
           "%ns" number of screens
           Variables marked with "*" may optionally immediately be followed
           by a scaling modifier "0" .. "6" :
           0 Values is displayed in bytes.
           1 Values is displayed in KBytes.
           2 Values is displayed in MBytes.
           3 Values is displayed in GBytes.
           4 Values is displayed in TBytes.
           5 Values is displayed in PBytes.
           6 Values is displayed in HBytes.
           Applicability is (IS).


           SCCA_Title_Type (ULONG) -- type of title
           SCCV_Title_Type_Screen -- Screen title (default)
           SCCV_Title_Type_Window -- Window title
           Applicability is (I).


       NAME
           SCCM_Title_Generate
       SYNOPSIS
       	STRPTR GeneratedTitle = DoMethod(obj,SCCM_Title_Generate);


       FUNCTION
           Parses internal TitleFormat string and generates ready-to-use title
           text in internal buffer.
       INPUTS
           -
       RESULT
           GeneratedTitle - String pointer to generated title
       SEE ALSO


       NAME
           SCCM_Title_Query
       SYNOPSIS
       	BOOL NeedRefresh = DoMethod(obj,SCCM_Title_Query, UWORD ParseID);


       FUNCTION
           Check whether variable text has changed and needs to be refreshed.
       INPUTS
           ParseID - contains the two-character variable name, e.g. "os"
       RESULT
           NeedRefresh - non-zero value if title string has changed, i.e.
           needs to be refreshed.
       SEE ALSO


       NAME
           SCCM_Title_QueryTitle
       SYNOPSIS
       	BOOL NeedRefresh = DoMethod(obj,SCCM_Title_QueryTitle);


       FUNCTION
           Check whether title has changed and needs to bed refreshed.
       INPUTS
           -
       RESULT
           NeedRefresh - non-zero value if title string has changed, i.e.
           needs to be refreshed.
       SEE ALSO


       NAME
           SCCM_Title_Translate
       SYNOPSIS
       	BOOL Success = DoMethod(obj,SCCM_Title_Translate, STRPTR Buffer, 
       		CONST_STRPTR TitleFormat, UWORD ParseID, UWORD Length);


       FUNCTION
           Processes one title format variable and generates expanded text
           into buffer provided by caller.
       INPUTS
           Buffer - Pointer to a buffer where the expanded text will be stored.
           This pointer gets updated during method execution !!
           TitleFormat - pointer into title format string, immediately after the
           variable name.
           This pointer gets updated during method execution !!
           ParseID - contains the two-character variable name, e.g. "os"
           Length - The number of bytes that fit into Buffer. Beware of writing
           more than (Length) Bytes into Buffer!
       RESULT
           Success - a non-zero value indicates translation was successful.
           a zero value signals some kind of error (e.g. unknown
           ParseID or insufficient Length).
       SEE ALSO


preferences.library

[edit | edit source]

...to the top

iconobject.library

[edit | edit source]

...to the top

iconobject.datatype

[edit | edit source]

...to the top


Scalos

[edit | edit source]

...to the top


...to the top


Content-Type: text/html scalosgfx.library

    ScalosGfxCreateEmptySAC
    ScalosGfxCreateSAC
    ScalosGfxFreeSAC
    ScalosGfxCreateARGB
    ScalosGfxFreeARGB
    ScalosGfxARGBSetAlpha
    ScalosGfxARGBSetAlphaMask
    ScalosGfxCreateARGBFromBitMap
    ScalosGfxFillARGBFromBitMap
    ScalosGfxWriteARGBToBitMap
    ScalosGfxMedianCut
    ScalosGfxScaleARGBArray
    ScalosGfxScaleBitMap
    ScalosGfxCalculateScaleAspect
    ScalosGfxBlitARGB
    ScalosGfxFillRectARGB
    ScalosGfxSetARGB
    ScalosGfxNewColorMap
    ScalosGfxARGBRectMult
    ScalosGfxBlitARGBAlpha
    ScalosGfxBlitARGBAlphaTagList
    ScalosGfxBlitIcon


        NAME

            ScalosGfxCreateEmptySAC -- Allocate an empty ScalosBitMapAndColor

        SYNOPSIS

        	sac = ScalosGfxCreateEmptySAC( )
        	D0

        	struct ScalosBitMapAndColor *ScalosGfxCreateEmptySAC( void );

         

        FUNCTION
            Allocates an empty ScalosBitMapAndColor structure, with NULL
            sca_BitMap and sac_ColorTable.

        INPUTS
            none

        RESULT
            sac - new created ScalosBitMapAndColor, or NULL on failure

        SEE ALSO
            ScalosGfxFreeSAC(), ScalosGfxCreateSAC()



        NAME

            ScalosGfxCreateSAC -- Allocate ScalosBitMapAndColor

        SYNOPSIS

        	sac = ScalosGfxCreateSAC(width, height, depth, friendBM, tagList);
        	D0                       D0     D1      D2     A0        A1

        	struct ScalosBitMapAndColor *ScalosGfxCreateSAC(ULONG, ULONG, ULONG,
        		struct BitMap *, struct TagItem *)

        	struct ScalosBitMapAndColor *ScalosGfxCreateSACTags(ULONG, ULONG, ULONG,
        		struct BitMap *, ULONG, ...)

         

        FUNCTION
            Allocate a ScalosBitMapAndColor structure. sac_BitMap and sac_ColorTable
            are allocated according to specified dimensions.

        INPUTS
            width - Desired width of new ScalosBitMapAndColor BitMap.
            height - Desired height of new ScalosBitMapAndColor BitMap.
            depth - Desired depth of new ScalosBitMapAndColor BitMap. Must be less
            than 256. sac_ColorTable will be allocated to hold 2^depth entries.
            friendBM - Friend BitMap to use for BitMap allocation.
            tagList - pointer to list of Tags, or NULL.

        TAGS
            None defined yet.

        RESULT
            sac - new created ScalosBitMapAndColor, or NULL on failure

        SEE ALSO
            ScalosGfxFreeSAC(), ScalosGfxCreateEmptySAC()



        NAME

            ScalosGfxFreeSAC -- free a previously allocated ScalosBitMapAndColor

        SYNOPSIS

        	ScalosGfxFreeSAC(sac);
        	                A0

        	void ScalosGfxFreeSAC((struct ScalosBitMapAndColor *);

         

        FUNCTION
            Frees and deallocates a previously allocated ScalosBitMapAndColor,
            including sac_BitMap and sac_ColorTable.

        INPUTS
            sac - previously allocated ScalosBitMapAndColor, or NULL

        RESULT
            nothing

        SEE ALSO
            ScalosGfxCreateSAC(), ScalosGfxCreateEmptySAC()



        NAME

            ScalosGfxCreateARGB -- Allocate a gfxARGB with specified size

        SYNOPSIS

        	argb = ScalosGfxCreateARGB(width, height, tagList)
        	D0                         D0     D1      A0

        	struct gfxARGB *ScalosGfxCreateARGB(ULONG, ULONG, struct TagItem *)

         

        FUNCTION
            Allocates an array of struct gfxARGB with sufficient size for
            specified width and height.

        INPUTS
            width - width of gfxARGB array
            height - height of gfxARGB array
            tagList - pointer to list of Tags, or NULL.

        TAGS
            None defined yet.

        RESULT
            argb - new allocated gfxARGB, or NULL on failure.

        SEE ALSO



        NAME

            ScalosGfxFreeARGB -- Free a previously allocated gfxARGB

        SYNOPSIS

        	ScalosGfxFreeARGB(argb)
        	D0                A0

        	VOID ScalosGfxFreeARGB(struct gfxARGB **)

         

        FUNCTION

        INPUTS
            argb - pointer to storage of previously allocated gfxARGB.
            argb may point to NULL.

        RESULT
            nothing

        SEE ALSO
            ScalosGfxCreateARGB()



        NAME

            ScalosGfxARGBSetAlpha -- Set all pixels to specified Alpha value.

        SYNOPSIS

        	ScalosGfxARGBSetAlpha(src, alpha);
        			      A0   D0

        	VOID ScalosGfxARGBSetAlpha(struct ARGBHeader *, UBYTE)

         

        FUNCTION
            Alpha value of all pixels in the ARGBHeader and its previously
            allocated gfxARGB array is set to the specified value.

        INPUTS
            src - Header of gfxARGB rectangle to modify.
            alpha - Alpha (transparency) value to set.

        RESULT

        SEE ALSO
            ScalosGfxARGBSetAlphaMask()



        NAME

            ScalosGfxARGBSetAlphaMask -- Set alpha value according to mask plane

        SYNOPSIS

        	ScalosGfxARGBSetAlphaMask(argbh, maskPlane)
        				  A0     A1

        	VOID ScalosGfxARGBSetAlphaMask(struct ARGBHeader *, PLANEPTR)

         

        FUNCTION
            Alpha values of all pixels in the ARGBHeader and its previously
            allocated gfxARGB array are set according to mask plane, i.e. for
            every bit set in mask plane, alpha is maximum (255), and for every
            cleared bit, alpha is set to minimum (0).

        INPUTS
            argbh - Header of gfxARGB rectangle to modify.
            maskPlane - Single bit mask plane. Dimensions must match size of argbh, with
            width rounded up to next 16-bit.

        RESULT
            nothing

        SEE ALSO
            ScalosGfxARGBSetAlpha()


        NAME

            ScalosGfxCreateARGBFromBitMap -- Create gfxARGB array from a BitMap

        SYNOPSIS

        	argb = ScalosGfxCreateARGBFromBitMap(bm, width, height, numberOfColors, colorTable, maskPlane
        	D0                                   A0  D0     D1      D2              A1          A2

        	struct gfxARGB *ScalosGfxCreateARGBFromBitMap(struct BitMap *, ULONG, ULONG, ULONG,
        		const ULONG *, PLANEPTR)

         

        FUNCTION
            Allocates and a gfxARGB array with specified dimensions, and fills it from
            provided BitMap, with optional mask plane. Works only with standard BitMaps with
            less than 256 colors.

        INPUTS
            bm - source BitMap to fill gfxARGB array from,
            Depth must be less than 256 colors.
            width - Width of gfxARGB array
            height - Height of gfxARGB array
            numberOfColors - number of entries in colorTable
            colorTable - Color table to use for BitMap
            maskPlane - Single bit mask plane. Dimensions must match width and
            height, with width rounded up to next 16-bit. May be NULL.
        RESULT
            argb - allocated gfxARGB array or NULL on failure.

            NOTES
            Use ScalosGfxFillARGBFromBitMap() for high-color or true-color BitMaps.

        SEE ALSO
            ScalosGfxFillARGBFromBitMap()



        NAME

            ScalosGfxFillARGBFromBitMap -- Fill previously allocated gfxARGB array from CGFX BitMap

        SYNOPSIS

        	ScalosGfxFillARGBFromBitMap(argbh, srcBM, maskPlane)
        				    A0     A1     A2

        	VOID ScalosGfxFillARGBFromBitMap(struct ARGBHeader *, struct BitMap *, PLANEPTR)

         

        FUNCTION
            Fill a previously allocated gfxARGB array from a CyberGraphics BitMap. Can only
            be used for high-color or true-color BitMaps.
            If maskPlane if given, alpha information in argbh is created from maskPlane. If
            maskPlane if NULL, alpha channel from source BitMap is used if available,
            otherwise alpha is set to opaque.

        INPUTS
            argbh - completely initialized gfxARGB array
            srcBM - source BitMap to use for filling, depth must be at least 65536 colors
            maskPlane - Single bit mask plane. Dimensions must match width and height, with
            width rounded up to next 16-bit. May be NULL.
        RESULT
            nothing

            NOTES
            Use ScalosGfxARGBSetAlpha() for standard BitMaps (i.e. less than 256 colors).

        SEE ALSO
            ScalosGfxCreateARGBFromBitMap()



        NAME

            ScalosGfxWriteARGBToBitMap -- Copy gfxARGB array to BitMap

        SYNOPSIS

        	ScalosGfxWriteARGBToBitMap(argbh, bm, numberOfColors, colorTable)
        				   A0     A1  D0              A2)

        	VOID ScalosGfxWriteARGBToBitMap(struct ARGBHeader *, struct BitMap *, ULONG, const ULONG *)

         

        FUNCTION
            Creates a copy of gfxARGB array in destination BitMap,
            using pre-defined colorTable. Works only with standard BitMaps, i.e. with
            less than 256 colors. No sophisticated color reduction is performed, but
            bit-fit pens are decided via FindBestPen().

        INPUTS
            argbh - gfxARGB array to read from
            bm - Standard BitMap to write to. BitMap must
            have less than 256 colors.
            numberOfColors - Number of entries in colorTable
            colorTable - color table to use for BitMap.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxMedianCut -- Create color-reduced BitMap from gfxARGB array

        SYNOPSIS

        	sac = ScalosGfxMedianCut(argbh, depth, tagList)
        	D0                       A0     D0     A1

        	struct ScalosBitMapAndColor *ScalosGfxMedianCut(struct ARGBHeader *, ULONG, struct TagItem *)

        	struct ScalosBitMapAndColor *ScalosGfxMedianCutTags(struct ARGBHeader *, ULONG, ULONG, ...)

         

        FUNCTION
            Allocate and fill a color-reduced BitMap and a best-match color table from gfxARGB array.
            Either ordered dithering or Floyd-Steinberg dithering will be used for best results.

        INPUTS
            argbh - gfxARGB array to read from
            depth - desired depth of generated BitMap, must be less than 256.
            tagList - array of tagItems, as described below, or NULL.

        TAGS
            SCALOSGFX_MedianCutFlags - Flags as described below.
            SCALOSGFX_MedianCutFriendBitMap - struct BitMap *, friend BitMap to use
            for allocating result BitMap
            SCALOSGFX_MedianCutReservedColors - ULONG, number of reserved (unused) color
            entries at start of generated color table.

            FLAGS
            SCALOSGFXFLAGF_MedianCut_FloydSteinberg - If set, Floyd-Steinberg dithering
            will be used for color reduction.

        RESULT
            sac - created ScalosBitMapAndColor pointer, or NULL on failure.

        SEE ALSO


        NAME

            ScalosGfxScaleARGBArray -- Scale given gfxARGB array

        SYNOPSIS

        	argb = ScalosGfxScaleARGBArray(src, destWidth, destHeight, tagList)
        	D0                             A0   A1         A2          A3

        	struct gfxARGB *ScalosGfxScaleARGBArray(const struct ARGBHeader *, ULONG *,
        		ULONG *, struct TagItem *)

        	struct gfxARGB *ScalosGfxScaleARGBArrayTags(const struct ARGBHeader *, ULONG *,
        		ULONG *, ULONG, ...)

         

        FUNCTION
            Scales given gfxARGB array to a new size. Supports both enlarging and shrinking
            gfxARGB arrays.

        INPUTS
            src - source gfxARGB array, will not be modified
            destWidth - desired width, might be internally corrected
            if SCALEFLAGF_CORRECTASPECT is set.
            destHeight - desired height, might be internally corrected
            if SCALEFLAGF_CORRECTASPECT is set.
            tagList - pointer to list of Tags, or NULL.

        TAGS
            SCALOSGFX_ScaleARGBArrayFlags - ULONG, specify some operation flags as listed below.

            FLAGS
            SCALEFLAGF_BICUBIC - allow bicubic scaling
            SCALEFLAGF_BILINEAR - allow bilinear scaling
            SCALEFLAGF_AVERAGE - allow average scaling
            SCALEFLAGF_DOUBLESIZE - allow intermediate step via double size, to improve quality
            SCALEFLAGF_CORRECTASPECT - allow correction of destWidth and destHeight to
            meet source aspect ratio.

        RESULT
            argb - Scaled copy of the source gfxARGB array

        SEE ALSO


        NAME

            ScalosGfxScaleBitMap -- Scale given BitMap

        SYNOPSIS

        	bm = ScalosGfxScaleBitMap(sbma, tagList)
        	D0                        A0    A1

        	struct BitMap *ScalosGfxScaleBitMap(struct ScaleBitMapArg *, struct TagItem *)

        	struct BitMap *ScalosGfxScaleBitMapTags(struct ScaleBitMapArg *, ULONG, ...)

         

        FUNCTION
            Scales given gfxARGB array to a new size. Supports both enlarging and shrinking
            gfxARGB arrays.
        INPUTS
            sbma - Structure with scaling parameters:
            sbma_SourceBM - The original BitMap. This BitMap is not modified.
            sbma_SourceWidth - Width of the source BitMap.
            sbma_SourceHeight - Height of the source BitMap
            sbma_DestWidth - Pointer to Width of resized BitMap, might be internally
            corrected if SCALEFLAGF_CORRECTASPECT is set.
            sbma_DestHeight - Pointer to Height of resized BitMap, might be internally
            corrected if SCALEFLAGF_CORRECTASPECT is set.
            sbma_NumberOfColors - number of entries in color table
            sbma_ColorTable - Color table for both source and resized BitMap.
            sbma_Flags - scaling flags:
            SCALEFLAGF_BICUBIC - allow bicubic scaling
            SCALEFLAGF_BILINEAR - allow bilinear scaling
            SCALEFLAGF_AVERAGE - allow average scaling
            SCALEFLAGF_DOUBLESIZE - allow intermediate scaling step with
            double size, to improve quality
            SCALEFLAGF_CORRECTASPECT - allow correction of destWidth and
            destHeight to meet source aspect ratio.
            sbma_ScreenBM - Friend BitMap used when allocating resized BitMap.
            tagList - pointer to list of Tags, or NULL.

        TAGS
            none defined yet.

        RESULT
            bm - Scaled copy of the original BitMap

        SEE ALSO


        NAME

            ScalosGfxCalculateScaleAspect -- Adjust scaling dimensions to source aspect

        SYNOPSIS

        	ScalosGfxCalculateScaleAspect(sourceWidth, sourceHeight, *destWidth, *destHeight)
        				      D0           D1            A0          A1

        	VOID ScalosGfxCalculateScaleAspect(ULONG, ULONG, ULONG *, ULONG *)

         

        FUNCTION
            Adjusts either destWidth or destHeight according to aspect ratio of
            sourceWidth and soureHeight.

        INPUTS
            sourceWidth - Unscaled width.
            sourceHeight - Unscaled Height;
            destWidth - Pointer to desired scaled width.
            destHeight - Pointer to desired scaled width.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxBlitARGB -- Blit rectangle between two gfxARGB array rectangles.

        SYNOPSIS

        	ScalosGfxBlitARGB(destARGB, srcARGB, destLeft, destTop, srcLeft, srcTop, width, height)
        			  A0        A1       D0        D1       D2       D3      D4     D5

        	VOID ScalosGfxBlitARGB(struct ARGBHeader *, const struct ARGBHeader *,
        		LONG, LONG, LONG, LONG, LONG, LONG)

         

        FUNCTION
            Blits user-defined rectangle from srcARGB at specified position into destARGB.
            No alpha handling is performed, destination pixel values are simply
            replaced by source pixels.

        INPUTS
            destARGB - destination gfxARGB array
            srcARGB - source gfxARGB array
            destLeft - Left start position in destARGB.
            destTop - Top start position in destARGB.
            srcLeft - Left start position in srcARGB.
            srcTop - Top start position in srcARGB.
            width - Width of blitted rectangle.
            height - Height of blitted rectangle.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxFillRectARGB -- Blit two gfxARGB array rectangles

        SYNOPSIS

        	ScalosGfxFillRectARGB(destARGB, fillARGB, left, top, width, height)
        			      A0        A1        D0    D1   D2     D3

        	VOID ScalosGfxFillRectARGB(struct ARGBHeader *, const struct gfxARGB *,
        		LONG, LONG, LONG, LONG)

         

        FUNCTION
            Blits fillARGB at specified position into destARGB. No alpha handling is
            performed, destination pixel values are just replaced by source pixels.
            Blit always starts at (0,0) in fillARGB.

        INPUTS
            destARGB - destination gfxARGB array.
            fillARGB - source gfxARGB array.
            left - Left start position in destARGB.
            top - Top start position in destARGB.
            width - Width of blitted rectangle.
            height - Height of blitted rectangle.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxSetARGB -- Set entire gfxARGB array to given ARGB color

        SYNOPSIS

        	ScalosGfxSetARGB(destARGB, fillARGB)
        			A0         A1

        	VOID ScalosGfxSetARGB(struct ARGBHeader *, const struct gfxARGB *)

         

        FUNCTION
            Set all pixels in entire gfxARGB array to the given ARGB color.

        INPUTS
            destARGB - gfxARGB array to be changed.
            fillARGB - ARGB value to set pixels to.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxNewColorMap -- Allocate new color table for ScalosBitMapAndColor

        SYNOPSIS

        	success = ScalosGfxNewColorMap(sac, colorMap, colorEntries)
        	D0                             A0   A1        D0

        	BOOL ScalosGfxNewColorMap(struct ScalosBitMapAndColor *, const ULONG *, ULONG)

         

        FUNCTION
            Allocates a new color table for ScalosBitMapAndColor. The new color table is
            filled with the RGB values from colorMap.
            Any previously color table in ScalosBitMapAndColor is freed.

        INPUTS
            sac - ScalosBitMapAndColor where to store new color table.
            colorMap - RGB values for new color table
            colorEntries - Desired number of entries in new color table

        RESULT
            success - TRUE if new color table was successfully allocated,
            FALSE on failure.

        SEE ALSO


        NAME

            ScalosGfxARGBRectMult -- Multiply RGB value with given factor

        SYNOPSIS

        	ScalosGfxARGBRectMult(rp, numerator, denominator, xMin, yMin, xMax, yMax)
        			      A0  A1         A2           D0    D1    D2    D3

        	VOID ScalosGfxARGBRectMult(struct RastPort *, const struct gfxARGB *,
        		const struct gfxARGB *, WORD, WORD, WORD, WORD)

         

        FUNCTION
            Multiplies RGB values of pixels within a specified rectangle
            with (numerator/denominator). Overflow is clipped to maximum RGB value (255).
            Works only with CyberGraphics generated, high-color or true-color BitMaps.
            Takes Layers in RastPort into account.

        INPUTS
            rp - RastPort with the BitMap to be modified.
            numerator - Scaling factor as numerator:denominator
            denominator - Scaling factor as numerator:denominator
            xMin - Left start of modified rectangle.
            yMin - Top start of modified rectangle.
            xMax - Right end of modified rectangle.
            yMax - Bottom end of modified rectangle.

        RESULT
            nothing

        SEE ALSO


        NAME

            ScalosGfxBlitARGBAlpha -- Alpha blit from gfxARGB array into RastPort

        SYNOPSIS

        	ScalosGfxBlitARGBAlpha(rp, srcH, destLeft, destTop, srcLeft, srcTop, width, height)
        			       A0  A1    D0        D1       D2       D3      D4     D5

        	VOID ScalosGfxBlitARGBAlpha (struct RastPort *, const struct ARGBHeader *,
        		ULONG, ULONG, ULONG, ULONG, ULONG, ULONG)

         

        FUNCTION
            Blit a rectangular area from source gfxARGB array into
            destination RastPort. Alpha (transparency) information in
            source gfxARGB array is fully accounted for.
            Destination RastPort may have Layers.

        INPUTS
            rp - Destination, this RastPort is been drawn to.
            srcH - Source gfxARGB array
            destLeft - Left offset in destination RastPort.
            destTop - Top offset in destination RastPort.
            srcLeft - Left offset in source gfxARGB array.
            srcTop - Left offset in source gfxARGB array.
            width - Width of blit rectangle.
            height - Height of blit rectangle.

        RESULT
            nothing

            NOTES

        SEE ALSO
            ScalosGfxBlitARGBAlphaTagList()


        NAME

            ScalosGfxBlitARGBAlphaTagList -- Alpha blit from gfxARGB array into RastPort

        SYNOPSIS

        	ScalosGfxBlitARGBAlphaTagList(rp, srcH, destLeft, destTop, srcSize, tagList)
        				      A0  A1    D0        D1       A3       A2

        	VOID ScalosGfxBlitARGBAlphaTagList(struct RastPort *, const struct ARGBHeader *,
        		ULONG, ULONG, const struct IBox *, struct TagItem *)

        	VOID ScalosGfxBlitARGBAlphaTags(struct RastPort *, const struct ARGBHeader *,
        		ULONG, ULONG, const struct IBox *, ULONG, ...)

         

        FUNCTION

        INPUTS
            rp - Destination, this RastPort is been drawn to.
            srcH - Source gfxARGB array
            destLeft - Left offset in destination RastPort.
            destTop - Top offset in destination RastPort.
            srcSize - IBox defining both left/top offset in source gfxARGB
            array, and size of blit rectangle.
            tagList - pointer to list of Tags, or NULL.

        TAGS
            SCALOSGFX_BlitIconHilight - const struct ARGB *, ARGB value to use
            for highlighting.Its RGB values are added
            to the destination pixels, with clipping
            to 0..255 range.
            SCALOSGFX_BlitIconAlpha - const UBYTE *, specify alpha array for icon.
            SCALOSGFX_BlitIconTransparency - ULONG, specify alpha for icon, 0...255.
        RESULT
            nothing

        SEE ALSO
            ScalosGfxBlitARGBAlpha()


        NAME

            ScalosGfxBlitIcon -- Alpha blit from RastPort to RastPort

        SYNOPSIS

        	ScalosGfxBlitIcon(rpBackground, rpIcon, left, top, width, height, tagList)
        			  A0            A1      D0    D1   D2     D3      A2

        	VOID ScalosGfxBlitIcon(struct RastPort *, struct RastPort *,
        		ULONG, ULONG, ULONG, ULONG, struct TagItem *)

        	VOID ScalosGfxBlitIconTags(struct RastPort *, struct RastPort *,
        		ULONG, ULONG, ULONG, ULONG, ULONG, ...)

         

        FUNCTION
            Blit a rectangular area from rpIcon into rpBackground, with full
            alpha (transparency) support.
            This function supports RastPorts with Layers.

        INPUTS
            rpBackground - Target RastPort.
            rpIcon - Source RastPort. The BitMap of this RastPort is
            not modified.
            left - left start of blit in rpBackground
            top - top start of blit in rpBackground
            width - width of the blitting rectangle
            height - height of the blitting rectangle
            tagList - pointer to list of Tags, or NULL.

        TAGS
            SCALOSGFX_BlitIconHilight - const struct ARGB *, ARGB value to use
            for highlighting. Its RGB values are
            added to the destination pixels, with
            clipping to 0..255 range.
            SCALOSGFX_BlitIconAlpha - const UBYTE *, specify alpha array for icon.
            SCALOSGFX_BlitIconTransparency - ULONG, specify alpha for icon, 0...255.

        RESULT
            nothing

        SEE ALSO


...to the top


History

[edit | edit source]

...to the top

Additions/changes:

40.32 20040917	JL	- Bugfix: simple-refresh window redraw failed when 
				  issuing some menu commands, e.g. "open parent".
	20040908	JL	- Bugfix: renaming left-out icons sometimes caused random 
				  memory to be trashed. fixed.
				- Bugfix: renaming left-out icons caused Scalos processes to hang due to semaphore deadlocks.
				- Bugfix: cured semaphore deadlock that sometimes occured when automatic window update collided with some user 
				  action, e.g. opening a popup menu.
	20040828	JL	- Bugfix: with TrueType fonts, having one softlink in a 
				  text window caused all entries to be displayed underlined.
				- Added new internal commands "iconproperties" and 
				  "windowproperties" (Requires iconproperties.module 
				  and windowproperties.nodule).
				- Bugfix: drag&drop left garbage on screen if custom bob 
				  routines were used and "special" bob (e.g. "forbidden" 
				  or "copying") was visible and was larger than main bob.
	20040716	JL	- Added new qualifier during D&D to force moving of 
				  file system objects (instead of copying).
				- Implemented the long-planned "Create link" on D&D feature.
				- Bugfix: default icons were not shown transparent if 
				  D&D "real transparency" wasn't turned on.
	20040625	JL	- When copying icons, the "replace all", "skip all", 
				  and "abort" buttons of the overwrite request didn't work.
	20040612	JL	- Automatic update of windows caused enforcer hit and 
				  crashes if the modified files contains special 
				  pattern-matching characters in their names (e.g. "()[]#?|").
	20040602	JL	- Fixed long-standing bug that caused Scalos to lockup 
				  when an icon was selected while a new window was 
				  initially reading its icons.
				- About dialog sometimes opened with maximum screen width, 
				  but without any contents in the scrolling field. Fixed.
	20040527	JL	- Closing an icon window while it was initially reading 
				  its directory caused Enforcer hits and crashed 
				  Scalos. Fixed.
	20040523	JL	- Added TrueType font support. TT Fonts can be used for 
				  icons, text windows, tooltips, and the "About" window.
	20040519	JL	- Menu selection "leave out" (not from popup menu) 
				  caused enforcer hits when issued from "View all" 
				  text window. Fixed.
	20040425	JL	- Added CRC checks over prefs files. Now writing 
				  a prefs file only causes re-reading of prefs and 
				  reinitialization if file contents has actually changed.
	20040424	JL	- Disk Read-Only status display is now updated when 
				  disk is inserted.
	20040419	JL	- Icons without associated object were displayed 
				  incorrectly after window update. Fixed.
				- Bumped revision to 40.32.

 40.31	20040322	JL	- Default icons were not recognized on main window. This 
				  bug could show up after dragging default icons from 
				  some drawer window onto the desktop.
	20040221	JL	- Improved caching of filetype descriptors. With "env-handler", 
				  all filetypes were flushed from cache whenever a new 
				  filetype was loaded from ENVARC: to ENV:.
	20040216	JL	- Internal command "reset" didn't work correctly. Fixed.
	20040214	JL	- Icons were not updated correctly after change of file 
				  comment of rename with change of case 
				  only (e.g. "amiga" to "Amiga").
	20040211	JL	- Icon selection marks for popup menu could be drawn in 
				  incorrect window when "Apply to every selected icon" 
				  is enabled.
				- Fixed various problems with left-out icons (different 
				  icons with same name were not handled correctly, 
				  left-out icons were not updated as intended).
	20040210	JL	- "Mac-like selection" was broken. Fixed.
	20040206	JL	- "Snapshot window" didn't work if there was no 
				  icon present for window.
	20040126	JL	- Main window didn't allow multiple icons with same 
				  name (e.g. left-out icons from different paths). Fixed.
				- Bumped revision to 40.31.

 40.30	20040123	JL	- In "view all" text windows, "Leave out" icon "xxx" now 
				  removes both "xxx" and "xxx.info" from text window, and 
				  "Put away" causes both entries to reappear.
				- Now text window SCCM_IconWin_ReadIcon method correctly 
				  handles increase in column width.
				- All "cleanup**" menu commands are now disabled 
				  in text windows.
				- Fixed enable/disable state of "leave out" and "put away" 
				  menu commands for "view all" text windows.
				- "selectall" menu command is now disabled if 
				  all icons are selected.
				- "clearselection" menu command is now disabled if no 
				  icon is selected.
	20040122	JL	- Text windows now automatically update object associated 
				  entries if an icon is removed or added.
	20040118	JL	- Fixed internal locking during reading and parsing 
				  of Scalos filetypes descriptions.
				- AppIcons no longer can get "Default Icon" attribute.
	20040111	JL	- Default icons may be drawn with adjustable
				  degree of transparency.
				- Added support for MorphOS-style iconify gadgets. This 
				  fixed any visual distortion of iconify Gadgets under MorphOS.
	20040109	JL	- When loading default icons, Scalos now adds information 
				  about the original object (Path+Name) for usage by 
				  the iconobject datatypes.
	20040105	JL	- Made icon dd_Flags handling more flexible, so OS3.9 CD 
				  drawers open with correct viewmodes (WB handles 
				  invalid values of "3" like DDFLAGS_SHOWALL).
				- Scalos didn't handle default icons from icon drawer 
				  (e.g. def_drawer.info) correctly. Without separate 
				  DefIcons installed, only the icon.library built-in 
				  icons were used.
	20040104	JL	- Added "skip all" gadget to standard copy/move 
				  "replace" dialog.
				- Fixed enforcer hits/crashes when starting Scalos 
				  while Scalos is already running.
				- Added new ScalosControlA() tags 
				  SCALOSCTRLA_GetCopyBuffSize and 
				  SCALOSCTRLA_SetCopyBuffSize.
	20040101	JL	- Added preferences item to set default stack size.
				- FileTypes code assumed that popupmenu.library was open, 
				  leading to crashes on machines where that library was 
				  not installed.
				- Bumped revision to 40.30.
		
 40.29	20031230	JL	- Added full support for alpha channel icon drawing, 
				  including drag&drop ("Custom" bob routines only).
				- Memory for default action in filetype descriptions was 
				  freed while not in use. Fixed.
				- Filetype descriptions are now cached, in order to 
				  improve performance.
				- Starting WB programs left 2 locks dangling. Fixed.
	20031226	JL	- updated "%os" title function to recognize OS 3.5 
				  and OS 3.9.
				- Made localizable string for "BUSY" disks.
				- Popupmenu items now show default action (the action 
				  that is taken upon double-click) in bold text.
	20031222	JL	- Optimization of Drag-and-Drop bobs was broken, leading 
				  to very sluggish drawing of bobs when dragging 
				  multiple icons.
	20031208	JL	- Changed directory for Scalos filetype descriptors
				  from "Scalos:FileTypes/" to "ENV:Scalos/FileTypes/". For 
				  compatibility, Scalos still looks in the old place if the
				  new directory cannot be found.
	20031202	JL	- In Text window, icon update erroneously changed type 
				  from "WBGARBAGE" to "WBDRAWER".
	20031117	JL	- Fixed incorrect update of icons in text windows 
				  in "view all" mode.
	20030727	JL	- To provide a visual hint that popup menu commands only 
				  apply to the icon under the pointer, all other selected 
				  icons are temporarily deselected while the popup menu 
				  is open.
				- Added keyboard qualifier to apply popup menu commands to 
				  every selected icon, instead of only the icon under 
				  the mouse pointer.
	20030711	JL	- Fixed long delay upon startup when splash window was 
				  turned off.
				- Bugfix: selecting an icon in one window, then changing 
				  to another window, and hitting "enter" caused Scalos 
				  to crash with "invalid semaphore state" errors.
	20030628	JL	- Fixed several memory leaks associated with 
				  filetype-dependent popup menus and tooltips.
	20030618	JL	- In Window popup menus, "view by text/name" never 
				  displayed a checkmark.
	20030616	JL	- Drawers opened from text view windows did not correctly 
				  inherit the "view all" attribute.
				- Corrected minor typo in About window "100%" was lacking 
				  the percent sign.
	20030615	JL	- Bumped revision to 40.29.
		

 40.28	20030612	JL	- Major improvement in text view window update - now works 
				  the same way as icon window update, only the changed 
				  items are redrawn.
	20030531	JL	- Bugfix; In text view windows, it was erroneously 
				  possible to "snapshot" and "unsnapshot" icons. 
	20030529	JL	- Bugfix: In text view windows, no file comments 
				  were displayed.
	20030525	JL	- In text view windows, Scalos had problems recognizing 
				  default tool entries for project icons. Fixed.
	20030517	JL	- Text icon IDTA_Type returned wrong icon type 
				  for WBGARBAGE (Trashcan) icons.
	20030502	JL	- Major improvements to SCA_OpenIconWindow(). Now Scalos 
				  tries hard to find the appropriate icon for the window 
				  to be opened. If an icon is to be found, the window 
				  settings are taken from the icon.
	20030423	JL	- Text windows didn't recognize window resize events 
				  during reading of icons. Fixed.
	20030421	JL	- Rewrote context-sensitive disabling of menu items.
	20030420	JL	- Added requester to ask user what to do when a project 
				  icon without default tool is encountered.
				 - Added Polish catalog to developer archive, translation 
				   by Paweî Szczodry.
	20030418	JL	- Fixed file count routine in filetransclass. The bug 
				  caused incorrect calculation of total byte/item count 
				  and lead to display of more than 100% completion with 
				  nonsense values for "remaining time".
				- Removed display of every single item copied in 
				  filetrans copy/move requester. This optimization greatly 
				  improved copying speed.
	20030327	JL	- Added new method "SCCM_FileTrans_OverwriteRequest"
				  for FileTrans.sca class.
	20030301	JL	- Bugfix: Filetype wasn't set correctly for trashcan.
				- Bugfix: AsyncWB hook wasn't called correctly 
				  for "Empty Trashcan".
	20030218	JL	- Bugfix: Program name wasn't handed over to 
				  execute_command.module on icon double-click.
	20030216	JL	- Bugfix: Improved window clipping, now application-drawn 
				  AppIcons no longer draw across non-backdrop Workbench 
				  window border.
	20030211	JL	- Bugfix: When a drawer window was created in iconified 
				  state, it could not be uniconified by double-clicking 
				  its parent drawer.
	20030208	JL	- Bugfix: In 40.27, WBStartup execution of ARexx type 
				  icons was broken. Fixed.
				- Feature: Added display of estimated remaining 
				  time to file copy/move progress dialog.
				- Bumped revision to 40.28.
			
 40.27	20030130	JL	- Bugfix: Window backfill pattern re-layout didn't occur 
				  when "backdrop" was turned on and off.
	20030129	JL	- Bugfix: fixed enforcer hits/crashes during window 
				  zoom/resize when "always relayout" was enabled (code 
				  tried to use ptn_bitmap after FreeBitMap()).
	20030126	JL	- Bugfix: added locking mechanism for asynchronous 
				  backfill to avoid crashes when windows are closed while 
				  async backfill process hasn't finished.
	20030118	JL	- Bugfix: fixed enforcer hits when CLI project icon 
				  contained no default tool.
				- Improvement: Program list now contains full path for 
				  each program started instead of only program name.
				- New feature: Added SCA_ScalosControl() subcommand to 
				  get/free list of menu commands.
	20030111	JL	- Bugfix: Cut+Paste didn't work when AsyncWB was 
				  installed. Fixed.
				- New features: Added new FONT and VALIGN attributes 
				  to TOOLTIP STRING.
				- Bumped revision to 40.27.
		
 40.26	20030104	JL	- Bugfix: "about" produced 2 enforcer hits when no 
				  Scalos logo found.
				- Bugfix: Splash resizing / text positioning was broken 
				  when no Scalos logo was found.
				- Bugfix: window process hung when one of the standard 
				  modules could not be started.
	20030103	JL	- Bugfix: Snapshotting a window which had no icon created 
				  an ".info" instead of an icon with the drawer's name.
				- Bugfix: Windows with virtual width or height > 32768 
				  could produce problems from graphical screen 
				  corruption to system crash.
	20030102	JL	- New feature: Icon tooltips can now be user-defined in 
				  the file type description files. Scalos now supports 
				  file type information plugins, e.g. to display size 
				  information about image files.
	20021221	JL	- Bugfix: During file copy operations, icons could be 
				  overwritten without warning.
	20021209	JL	- Bugfix: TextInputHook wasn't used to run program 
				  without icon - instead always execute_command.module 
				  was called.
				- Bugfix: automatic disabling didn't work for some 
				  main menu items (e.g. "sizetofit" didn't get disabled 
				  in backdrop root window).
				- Bumped revision to 40.26.
			
			
 40.25	20021206	JL	- Added "viewbytype", "cleanupbyname", "cleanupbydate", 
				  "cleanupbysize", and "cleanupbytype" menu commands.
	20021205	JL	- Fixed Enforcer hits which occurred when an ARexx program 
				  ended that had been started from an icon window, and 
				  the icon window had been closed.
	20021130	JL	- Added support for cycling through icons in window 
				  via TAB key.
				- Rebuilt about window code to make use of the 
				  TT layout engine.
				- Fixed bug in SCA_SortNode() - lists with less than 
				  3 entries were not sorted.
	20021116	JL	- Fixed broken close-window abort recognition during 
				  GenerateIcons() icon drawing in window.
	20021019	JL	- The user-defined path for default icons was never 
				  used for iconified Scalos window icons. Now it is taken 
				  as fall-back if there are no theme-specific icons.
	20021018	JL	- Changed sizing method for splash window.
	20021014	JL	- Added new methods SCCM_AddToClipboard and 
				  SCCM_ClearClipboard to root class.
	20021013	JL	- Copy/paste didn't work for volumes/disks. Fixed.
				- Fixed another source for erroneous error messages 
				  during SCCM_FileTrans_Copy and SCCM_FileTrans_Move 
				  operations.
	20021009	JL	- Changes in icon font were not recognized in desktop 
				  window. Fixed.
				- The menu "copy" and "paste" commands trashed the 
				  destination file name. Fixed.
	20021008	JL	- Fixed some enforcer hits and crashed when selecting 
				  some device icons, and then pressing "enter" twice.
	20021006	JL	- Changed location of icons for iconified Scalos window 
				  from "ENV:Sys/def_iconify" to "THEME:window/def_iconify".
				- LoadWB.scalos now waits until Scalos opens its first
				  window on the Workbench screen before exiting.
				- Now Scalos first tries to load deficons from 
				  "THEME:DefIcons/". If that fails, the standard 
				  path "ENV:Sys/" is used.
	20021003	JL	- Now uses "titlebarimageclass" for iconify 
				  image if available.
				- changed all makefiles to work with GNU make.
				- Bumped revision to 40.25.
			
			
 40.24	20021003	JL	- Fixed broken ARexx menu command support.
	20021003	JL	- Major improvement of Tooltip layout engine.
				- Added tooltips for several Scalos gadgets, including 
				  the status bar images.
	20020929	JL	- Fixed menu bug where every menu item got a hotkey
				  mark. Now only the menu items which have got hotkeys
				  are shown with hotkey marks.
				- Icon positions were messed up during "cut", "copy" 
				  and "paste" operations. Fixed.
				- Changed file name for default device icons from 
				  ".info" to "def_.info" in 
				  order to match OS3.9 behaviour.
				- Changed file name for default volume icons from 
				  ".info" to "def_.info" in 
				  order to match OS3.9 behaviour.
				- Added missing SHADOWPEN vertical line to the left 
				  of the window iconify image.
				- The assign "THEME:" isn't touched any more if 
				  it exists prior to Scalos startup.
				- The assign "Scalos:" is created (pointing to PROGDIR:) 
				  on startup if it doesn't exist.
				- Tooltips are no longer displayed if ICandy == 0.
				- Bumped revision to 40.24.
			
			
 40.23	20020928	JL	- Improved handling of "cut" icons (shadowed display got 
				  corrupted). Needs iconobject.datatype 40.7 .
	20020926	JL	- Fixed bug that caused Scalos to crash when an icon
				  was removed during Drag&Drop (e.g. an AppIcon was 
				  removed by its application).
	20020923	JL	- Changed default setting for icon frame type from 
				  MF_FRAME_BUTTON to MF_FRAME_NONE.
	20020921	JL	- Moved special pointer icons ("forbidden", "copying", 
				  "makelink") from ENV:Scalos/ to THEME:PointerIcons/.
	20020915	JL	- Environment variable "scalos/icandy" is recognized
				  if set before Scalos startup. ATM, icandy < 2 turns
				  off splash screen and window status bars.
				  If not set, "Scalos/icandy" gets set with a default
				  value of "2".
	20020914	JL	- Changing "Fullbench" and "Poptitle" now works 
				  on-the-fly and doesn't require rebooting anymore.
				- Locale (language) preferences can now be changed 
				  on-the-fly, no reboot required anymore.
	20020913	JL	- Fixed erroneous message "This drawer cannot be opened"
				  when trying to open a drawer which is already open.
	20020831	JL	- Icon position now always is set to NO_ICON_POSITION
				  for default icons loaded via DefIcons.
	20020825	JL	- Changed default for Workbench "backdrop" to TRUE.
				- Changed tool tip placement - now tool tips are displayed
				  below mouse pointer if space allows.
	20020822	JL	- Added optional process priority field for filetype 
				  specific popup menu commands.
	20020817	JL	- Bugfix in FileCommands.c: since ExNext() result
				  ERROR_NO_MORE_ENTRIES was erroneously remembered as
				  error, an incorrect error reason could be displayed 
				  when a "real" error occurred.
				- Bumped revision to 40.23.
			
			
 40.22	20020812	JL	- Bugfix with "Show All" windows: icon list was read
				  before window was opened, leading to problems with
				  icon layout (invisible icons).
	20020803	JL	- Fixed problems with file type-specific popup menus 
				  and STACK parameter.
	20020801	JL	- Finished conversion of Scalos Pattern Prefs 
				  from ASM to C.
	20020720	JL	- First implementation of new filetype-specific popup 
				  menu system.
				- Removed obsoleted scalos.library 
				  function SCA_RemapBitmap().
	20020711	JL	- CheckMouseIcon() didn't take window borders into 
				  account, i.e. clicking on window border could cause
				  icon to be selected.
	20020703	JL	- Text icon font changes now take effect immediately,
				  Reboot is not required anymore.
	20020624	JL	- Fixed problem in wbl.c - spawned processes incorrectly
				  inherited the ConsoleTask pointer.
	20020623	JL	- Now SCCM_IconWin_Redraw also refreshes window frame
				  and status bar.
	20020622	JL	- Added image "THEME:Window/StatusBar/ShowAll" to status
				  bar, which visualises the "Show All Files" window 
				  setting.
	20020612	JL	- Fixed bug introduced by optimized pen allocation.
	20020601	JL	- Improved pen allocation in LockScalosPens() - pens 
				  which are members of dri_Pens are no longer allocated 
				  a second time.
				- Upon startup, Scalos should give a warning Requester 
				  if not all defined pens could be allocated.
	20020529	dm	- Finished converting cleanup code to C.
	20020526	JL	- Fixed bug in the scalos.library expunge code which was 
				  trying to FreeMem() an incorrect library base pointer 
				  when quitting Scalos.
				- When "quit Scalos" is requested, memory is flushed 
				  before checking scalos.library open count, so unused
				  libraries still resident in memory no longer prevent 
				  Scalos from closing.
				- Added optional background image for tooltips 
				  "THEME:TooltipBackground".
				- Added optional background image for window status bar
				  "THEME:Window/StatusBar/Background".
				- Added forgotten "PDTA_DestMode, PMODE_V43" in about.c
				  and GadgetBarImageClass.c. Now the entries for the 
				  Scalos processes in "PicTD" prefs are no longer required.
	20020525	JL	- Fixed a serious bug in the new C SCA_MoveNode() function 
				  which caused Scalos to crash when trying to "cleanup" a 
				  window which had already been cleaned up.
	20020513	JL	- Fixed an icon drag bug: When an icon was clicked with LMB 
				  and the mouse button held for several seconds without 
				  moving the icon, a DisplayBeep() was triggered when the
				  mouse button was released.
	20020504	JL	- Many minor changes to allow Scalos to cpiled with GCC.
				- Replaced handmade CLI startup detaching code by standard
				  cback.o and detach.o mdoules.
	20020414	JL	- Corrected error in scalos_lib.sfd - order of parameters 
				  for SCA_WBStartTags() was incorrect.
	20020412	JL	- When icons were selected purely via keyboard, the
				  "IconActive" variable was not updated and selected 
				  icons could not be opened by pressing "return".
				- When trying to open an disk/drawer icon via wb39/ARexx, 
				  under certain circumstances the Scalos main task could 
				  hang, waiting for a message reply. Fixed.
	20020405	JL	- When prefEnableSplash was turned off after splash window 
				  has opened, the splash window never closed. Fixed.
				- After removing an entry from the hidden device list,
				  that device used to appear multiple times on the Scalos
				  screen. Fixed.
	20020404	JL	- When AppIcon was replaced via AppChange, Scalos tried 
				  to free invalid memory while removing AppIcon. Fixed.
	20020403	JL	- ScalosMain() was called with seglist in d1 instead of 
				  d0, leading to enforcer hits or crash on exit when 
				  started from workbench via icon double-click.
				- Bumped revision to 40.22.
			
			
 40.21	20020402	JL	- Fixed lockup problem when a window opened or closed 
				  during drag/drop operations.
	20020329	JL	- Fixed problem in scalos library code - Expunge() never 
				  got called.
				- Fixed init problem with prefTextModeTextAttr.ta_Name, 
				  after unsuccessful startup, Scalos tried to 
				  FreeVecPooled() static string.
				- Added safeguard to AllocVecPooled() and FreeVecPooled() 
				  against being called with MemPool of NULL.
	20020309	JL	- SCCM_DeviceList_Generate now works fully asynchronous way, 
				  avoiding most sources of hangs connected to weird 
				  file systems.
	20020212	JL	- Finished converting Scalos startup and shutdown code to C.
	20020209	JL	- DefIcons support now integrated into Scalos, including 
				  automatic reload of DefIcons.prefs after 
				  external changes. Filetypes.plugin and Deficons.plugin 
				  are now obsolete.
	20020204	JL	- Programs started by Scalos were never removed from the 
				  internal program list. Fixed.
	20020203	JL	- Now displays message on screen title when user tries to 
				  double-click a drawer icon without associated directory.
	20020202	JL	- ToolTip sometimes didn't show used/total/percent 
				  correctly for disk icons. Fixed.
				- Bumped revision to 40.21.
			
			
 40.20	20020201	JL	- Dragged icons were corrupted on screens with 
				  interleaved bitmaps. Fixed.
				- Dragging icons with text didn't always work, depending 
				  on icon text colour settings. Fixed.
	20020127	JL	- UnSnapshot function was thoroughly broken - Should now 
				  again work as expected.
	20020126	JL	- Now supports adding submenus and new menus 
				  via SCA_NewAddAppMenuItem().
				- The Rename() patch now tries to update (i.e. remove) 
				  the old object's icon.
				- CopyCommand() now quietly returns OK if source of copy 
				  operation cannot be found, so copying of orphan icons 
				  (icons w/o associated objects) should work now.
	20020125	JL	- Plugged memory leak when reloading menu prefs.
				- Bumped revision to 40.20.
			
			
 40.19	20020121	JL	- Snapshot/Unsnapshot didn't free Lock on icons. Fixed.
				- Unsnapshot failed to move icon to wt_LateIconList. Fixed.
	20020119	JL	- ReLayoutIcons() forgot to update IDTA_TextPenShadow and 
				  IDTA_TextPenOutline pens. Fixed.
				- SCA_ScreenTitleMsg() was broken and couldn't display 
				  the last message. Fixed.
	20020115	JL	- Fixed problem in DragDropBobs.c : newiconobject.library 
				  didn't return image mask for special icons because 
				  IDTM_Layout was only called for normal image and 
				  IDTM_Mask_Selected was requested. Fixed.
	20020114	JL	- Fixed problem with MOS and SameLock() NULL Locks in 
				  Functions.c. Now it should be possible to open SYS: 
				  volume.
				- Bumped revision to 40.19.
			
		
 40.18	20020113	JL	- Undid most changes in DragDropBobs.c from 40.17. Now 
				  frames around icons work in a more compatible way, 
				  together with 40.2 icon datatypes.
	20020109	JL	- Commands "rename", "execute", "newdrawer" now support 
				  global TextInputHook.
	20020107	JL	- Built .sfd files for all Scalos components. All pragma 
				  and proto includes and .fd files are now created 
				  from those .sfd files.
	20020106	JL	- Several window backfill functions didn't check properly 
				  for non-existing background images (FileTransfer, 
				  Splash). Fixed.
				- INF_File was not set for text icons when file system 
				  returned non-standard fib_DirEntryType. Now INF_File is 
				  always set if fib_DirEntryType < 0.
				- The PenArray delivered by the workbench OpenScreen patch 
				  always contained -1 in the first entry, rendering it 
				  pretty useless. Fixed.
				- Adapted to now (NDK3.9) officially supported Workbench 
				  hooks (CopyHook, DeleteHook, SetupCleanupHook).
				- Now requires includes Release 45.1 to compile.
				- "Empty Trash" menu command now uses DeleteHook 
				  if available.
				- The PenArray delivered by the workbench OpenScreen patch 
				  always contained -1 in the first entry, rendering it 
				  pretty useless. Fixed.
	20020105	JL	- When changing icon attributes (e.g. border), AppIcons 
				  didn't get refreshed properly. Fixed.
	20020104	JL	- Automatic icon update on file system notification didn't 
				  work properly for left-out icons. Fixed.
				- Bumped revision to 40.18.
		
		
 40.17	20020101	JL	- Added separate pens for selected icon text, icon text 
				  outline, and icon text shadow.
	20011231	JL	- Several changes in DragDropBobs.c to enable frames 
				  around masked icons. Requires latest icon datatypes!!!
	20011229	JL	- Device icons got a name of "" (empty string) when tool
				  type SCALOS_NOTEXT was found, whereas other 
				  icons got NULL. Fixed.
	20011228	JL	- When Scalos tries to quit and there were still foreign 
				  windows on WB screen, a retry requester occurs. After 
				  clicking "Retry", Scalos tried to free PenShareMap more 
				  than once. Fixed.
	20011225	JL	- Non-DOS disk icons are now ghosted (just like WB3.9).
				- Many menu items (e.g. "Open", "Information") are now 
				  disabled for non-DOS disks.
				- Unreadable disks are now labeled as "DF0:Unreadable" 
				  instead of "DF0:????".
	20011221	JL	- OpenWorkBench() return ULONG instead of Workbench screen
				  address in case of success. Fixed.
				- Window status bar text now always uses text window font.
	20011215	JL	- Many changes and fixes in FileCommand.c (File 
				  moving/copying code). Moving objects to a different 
				  volume (copy-and-delete) now works.
	20011214	JL	- Added timeout (default=10s) to file transfer counting.
				- Added Win***s-like "Copy", "Cut", "Paste" menu commands 
				  to transfer files.
	20011213	JL	- Added workaround kludge for broken "delete.module" 
				  implementations that rely on wa_Name being empty 
				  for directories.
				- Fixed a memory trashing bug in CLIStart(). Only occurred 
				  when file name was longer than default tool name.
	20011212	JL	- LeaveOutIcon() trashed the CurrentDir of the Scalos 
				  window task. Fixed.
				- Scalos window tasks now have their directory namess 
				  appended to the task name, 
				  e.g. "Scalos_Window_Task ".
				- (old) SCA_RemoveAppObject() failed to remove icons in 
				  wt_LateIconList, leading to crashes with MUI 
				  applications on CloseWorkBench()/OpenWorkBench(). Fixed.
				- Added new pen for status bar text.
	20011208	JL	- Popup menus now can also be opened by keyboard
				  (Right Alt +Right Amiga).
				- SCCM_IconWin_CheckUpdate did not recognize changes 
				  between default icon and non-default icon (e.g. an icon
				  associated to an object was deleted - display didn't 
				  change). Fixed.
				- Added optional THEME:FileTransBackground background 
				  image to copy/move progress window.
				- Display of window drop marks is now settable into 3 
				  modes - none, non-backdrop windows only, always.
				- Added GBTDTA_SoftStyle to set text style 
				  for GadgetBarTextClass gadgets.
				- Bumped revision to 40.17.
		
		
 40.16	20011207	JL	- Scalos.c/RefreshTextWindow didn't check if window 
				  exists. Fixed.
				- Scalos.c/ReportError didn't propagate RESULT_UserAborted
				  if the user clicked the "Abort" button. Should 
				  be fixed now.
				- Major rewrite of FileTransfer class. Redesigned 
				  copy/move progress window with progress gauge and 
				  cancel button.
	20011205	JL	- Fixed another bug in window backfilling - filled area 
				  was exactly 1 pixel too small in x- and y-direction.
				- With window scrollbar arrows, the detection of shift 
				  key was reversed. Fixed.
				- Changed scrolling step for window scrollbar arrows 
				  to 10 pixel.
	20011204	JL	- Added SCCM_IconWin_AddToStatusBar, 
				  SCCM_IconWin_RemFromStatusBar, and 
				  SCCM_IconWin_UpdateStatusBar methods to make status bar
				  interfacing easier.
				- More changes in OpenWorkBench() / CloseWorkBench(). Now
				  also uses icon.library V44+ ICONCTRLA_SetGlobalScreen 
				  tag. Closing/reopening Scalos (e.g. via screen mode 
				  change) should now work.
	20011203	JL	- Rewrote OpenWorkBench() / CloseWorkBench() patches in C.
				  Problems with wrong colors after OpenWorkBench() should 
				  now be fixed.
	20011202	JL	- Added support for WB3.9-compatible (undocumented) 
				  CloseWB hook. Now e.g. AmiDock iconifies automagically 
				  on CloseWorkbench() and uniconifies afer OpenWorkBench().
				- With status bar enabled, Scalos window heights grew 
				  each time a window was iconified and re-opened. Fixed.
	20011201	JL	- Fixed broken FreePatternNode() - now reloading pattern 
				  prefs should work again.
				- Finally fixed long-standing bug in icon update code 
				  that sometimes lead to duplicate icons.
	20011130	JL	- Disk without icons now get default icon of type WBDISK 
				  instead of WBKICK.
				- Fixed problem with removed nodes in 
				  SCCM_DeviceList_Generate, leading to corrupted device 
				  icon list.
	20011129	JL	- Added file version information to tooltips.
	20011128	JL	- Implemented global copy and delete hooks for 
				  compatibility with AsyncWB.
				- Fixed inverted NoRemap checking in backfill functions.
	20011127	JL	- Finished converting all menu functions to C.
	20011124	JL	- Fixed wrong SCA_FreeNode() parameter 
				  in DevListClass_Generate().
				- LockScalosPens() produces lots of enforcer hits when 
				  no palette prefs could be found. Fixed.
	20011123	JL	- Finished converting all IDCMP handlers to C.
	20011120	JL	- Completed converting window background rendering 
				  code to C.
	20011117	JL	- Menu command "backdrop" didn't work. Fixed.
	20011116	JL	- Fixed missing Argument for WaitReply() in A5. This 
				  resulted in crashes when running modules with simple 
				  refresh windows.
				- Bumped revision to 40.16.
			
		
 40.15	20011113	JL	- INF_File was not set for backdrop icons. Fixed.
				- Devices are now counted and displayed separately 
				  during D&D.
	20011112	JL	- Changed screen pop-title algorithm so it should always 
				  get switched on if necessary.
				- Changed rendering of Logo in splash window back from 
				  DTM_DRAW to blitting functions.
				- Fixed error in DevListClass_Filter() - missing 
				  parentheses lead to wrong exception calculation.
				- Bumped revision to 40.15.
		
		
 40.15	20011112	JL	- Changed path for status bar images 
				  to "THEME:Window/StatusBar/".
	20011111	JL	- Added SCA_NoStatusBar attribute to SCA_OpenWindow() 
				  library function and SCALOS_NOSTATUSBAR tooltype to 
				  suppress status bar display on a single window.
	20011110	JL	- Fixed most serious error : failed to reserve memory for 
				  IconWindowClass instance data.
	20011108	JL	- Fixed wrong position for "iconify" gadget (overlapped 
				  zip gadget).
				- Horizontal scroller height was too small. Fixed.
				- Added special detection of Screen titlebar to circumvent 
				  problem with MagicMenu which lead to screen bar staying 
				  visible in spite of cleared SHOWTITLE flag.
	20011107	JL	- Added "Typing" symbol to status bar.
				- Icon selection by typing icon name didn't work for 
				  AppIcons and device icons. Fixed.
				- Removed LockIBase() in Window.c/QueryObjectUnderPointer(),
				  hopefully avoiding window lockups.
				- Converted automatic Screen bar switching code to C (see 
				  Scalos_Cx.c). Added additional checks for locked Layers 
				  to avoid deadlocks.
	20011106	DM		- Added two new preference variables, prefWindowHScroll and
				  prefWindowVScroll for the default distances of scrolling
				  icon windows by the keyboard (main_prefs.s, variables.h,
				  imports.i, exports.i).
				- Added parts of cleanup code converted to C to the source files
				  (cleanup.c, main_subroutines.s)
				- Added two missing includes to scalos_structures.h file
				  (graphics/gels.h and workbench/startup.h)
				- Can use shift+cursor keys in icon windows to scroll by a whole
				  page (well, inner height and width of icon window - IconWindowClass.c)
				- Can also use Return to open active icon in icon windows
				  (IconWindowClass.c)
				- Fixed problem with reading Workbench preferences and then showing
					  Scalos main window in wrong mode/sizes (WindowClass.c)
	20011104	JL	- Icon menu didn't get enabled when icon was selected via 
				  keyboard input (first letter(s) of icon name). Fixed.
	20011102	JL	- Replaced blitting function in Splash.c by DTM_DRAW.
				- Fixed old problems with pen allocations - ObtainPen() 
				  didn't check for success.
	20011101	JL	- Bumped revision to 40.14.
		
		
 40.13	20011020	JL	- During D&D, window dropmarks are no longer erased when 
				  mouse is over icon, but remain visible until mouse 
				  leaves window.
				- Added SCALOSCTRLA_GetEmulationMode tag 
				  for ScalosControl().
	20011013	JL	- Now MenuItems get disabled if they have SubItems and 
				  every SubItem is disabled.
				- Since redrawing of partially overlapped icons seems to 
				  work well, I disabled the strict icon overlap checking 
				  while D&D.
	20011012	JL	- Added support for AppIcons sending select/unselect 
				  notification messages and 
				  WBAPPICONA_NotifySelectState tag.
				- CLIStart() didn't work with WBPROJECT icons. Fixed.
	20011011	JL	- Icon window crashed after D&D when redrawing previously 
				  obscured icons - Fixed.
				- Sometimes IDCMP_INTUITICKS messages were not 
				  replied. Fixed.
				- Automatic change of default window patterns failed when 
				  switching between icon and text mode. Pattern numbers 
				  sometimes were treated as unsigned instead of signed 
				  numbers. Fixed.
	20011010	JL	- Added new Tags SCALOSCTRLA_GetTypeRestartTime and
				  SCALOSCTRLA_SetTypeRestartTime for ScalosControl().
	20011008	JL	- Menu commands "snapshotwindow" and "snapshotall" stayed 
				  disabled forever. Fixed name compare error 
				  in Prefs.c/CompareCommand().
				- Replaced remaining 64bit integer arithmetic code 
				  by C version.
	20011007	JL	- Finished converting "Title.sca" to C.
				- Updated SCA_Title" autodocs for "Title.sca" class.
	20011006	JL	- Finished converting "FileTransfer.sca" to C.
	20011005	JL	- Replaced fixed version/revision strings in about window 
				  by text macros "%v" and "%r".
				- Added feature: Icons may now be selected by typing the 
				  first character(s) of their names, just as in WB 3.9.
				- Added feature: Cursors key can be used to select icon 
				  right/left/below/above the currently selected one.
				- Finished converting "DeviceList.SCA" to C.
	20011005	JL	- Bumped revision to 40.13.
			
			
 40.12	20011004	JL	- When converting WindowClass to C, I somehow dropped one 
				  line of code and forgot to clear a window's UserPort 
				  before closing the window. So it could happen that 
				  IntuiMessages in the wt_IconPort already had got freed 
				  by Intuition on closing the corresponding window, 
				  leading to corrupted messages.
	20011001	JL	- SCA_WBStart() didn't work for icons with "CLI" or 
				  "REXX" tooltypes. Fixed.
	20010930	JL	- Wbstartup sometimes skiped icons with free 
				  positions (Unshapshot). Fixed.
	20010929	JL	- Finished converting Root class to C.
	20010928	JL	- Now all window, menu and wbl processes inherit the 
				  original workbench path.
	20010926	JL	- Added support for WBAPPMENUA_CommandKeyString (OS3.9) 
				  and separator bars to SCA_NewAddAppMenuItem().
	20010924	JL	- Finished converting TextWindow class to C.
	20010922	JL	- Finished converting IconWindow class to C.
	20010916	JL	- Finally fixed long-standing problems with simultaneous 
				  multiple window updates (Enforcer hits, icons 
				  appearing twice, etc.).
	20010910	JL	- Fixed problem reading large directories containing icons with 
				  both fixed and free positions. Icons with "free" 
				  positions were placed at the end of each block read, and 
				  could be overlapped by an icon read later with a fixed position.
	20010908	JL	- Bumped revision to 40.12.

 40.11	20010907	JL	- In Icon windows, icons without associated objects were not 
				  displayed with "Show all files" setting. Fixed.
	20010906	JL	- Text windows now show "Trashcan" in size column for 
				  trashcan drawers.
				- Icons of type WBDISK are hidden in text windows with 
				  "Show only icons".
	20010904	JL	- Major changes in text window directory scanning. Now 
				  icons without associated object are displayed in text 
				  windows with "Show only icons".
	20010903	JL	- Text windows now show "Drawer" in the size column for drawers.
	20010902	JL	- Changed number format for file sizes to "%lU", using localized
				  display format.
				- Finished converting window class to C.
				- Finished converting text icon class to C.
	20010901	JL	- Deleting left-out object now always updates ".backdrop" files.
				- Left-out icons got the "put away" menu item disabled when 
				  updated (e.g. by adding tooltypes). Fixed.
	20010831	JL	- Windows can now be scrolled with the arrow keys (only if no
				  icons are selected in window).
	20010830	JL	- Did some changes to the asm class macros to make the class
				  engine more "C-friendly".
	20010828	JL	- Moved Scalos .catalog files in archive from catalogs//
				  to catalogs//Scalos/.
				- Now .catalog files are ignored if their version is <40, avoiding
				  trouble with wrong messages.
	20010819	JL	- Added distinct pens for the dragging info text.
				- Additional checks on plugin initialization - Now erroneously 
				  added menu plugins should no longer cause Scalos to crash on startup.
				- CloseWorkBench() from VisualPrefs Task didn't work. Fixed.
				- CloseWorkBench() will not close Scalos while there are 
				  active "Scalos_Async_Backfill" processes.
				- Bumped revision to 40.11.

 40.10	20010817	JL	- Repaired bug in updateicon which sometimes caused icons to 
				  appear in incorrect windows.
	20010815	JL	- Duplicating/cloning items now pops up the file copying progress 
				  window.
				- Dragging multiple icons now shows one or two text lines under pointer 
				  telling how many files and drawers are being dragged.
				- Fixed severe bug in wbl.c : WBNode's were allocated with AllocVecPooled()
				  and freed with FreeVec().
	20010814	JL	- Added a varargs version of SCA_ScreenTitleMsg().
				- Added flag to switch between Flag: old dragging (all 
				  icons visible) and new "icon stack".
				- Added new SCA_ScalosControl() tags 
				  SCALOSCTRLA_GetOldDragIconMode
				  and SCALOSCTRLA_SetOldDragIconMode.
				- IconWinCheckUpdate() now correctly updates INF_DefaultIcon 
				  flag and INF_SupportsLeaveOut attribute.
	20010811	JL	- Missed a CurrentDir() when renaming objects, leading 
				  to a directory lock getting never UnLock()ed.
				- When D&D copying or moving icons, "Replace All" and 
				  "Abort" now should work correctly.
				- Message strings "xxx already exists" are now different
				  when moving and copying objects.
				- When moving icons inside window and new position overlaps 
				  other icon, the moved icons now jump back to their 
				  original positions.
				- Bumped revision to 40.10.

 40.9	20010811	JL	- THEME:SplashBackground was never freed, leaving a 
				  Lock on it. Fixed.
				- CLI and ARexx default tools icons didn't work 
				  in text windows. fixed.
	20010809	JL	- Enabled deadlock detection for lasso operations.
	20010808	JL	- Additional check for NULL wt_LateIconList in cleanup().
				- Text windows now again display "#?.info" files (icons).
				- Forbid drag-copying or -moving icon into own sibling 
				  window or on sibling icon to avoid move errors 
				  or endless recursion.
	20010807	JL	- Fixed multiple problems with text window updates.
	20010806	JL	- Added semaphore locking to protect from two or more Scalos 
				  tasks opening or closing windows at the same time.
				- Fixed broken "copy by dragging on drawer icon".
				- Added additional checking to prefs file notification.
				- Bumped revision to 40.9.

 40.8	20010804	JL	- Worked around semaphore deadlock in SetIconMenuOnOff(). This 
				  one occured when copying multiple directories between 
				  text windows.
	20010803	JL	- Copying/moving of (left-out) drawers, tools, or projects 
				  from main window to any drawer window didn't work. Fixed.
				- Dragging a device icon into an icon window (copying device 
				  into directory) no longer results in requester "DEVICE: 
				  already exists ....".
				- Bug #29 : Dragging a device icon into an icon window where 
				  a drawer with the name of the device (w/o ":") already 
				  existed: Nothing happened. Fixed.
				- left-out icons no longer show up in text icon windows.
				- "leave out" and "put away" now correctly update text windows.
				- Increased size of text window + tooltip date and time fields 
				  from 16 to 80 bytes.
				- Added date/time string length checking to ScaFormatDate().
	20010802	JL	- Fixed a race condition between DrawDrag() and DragEnter() that
				  could block window when trying to auto-remove icons.
				- Finally fixed icon masking problem with PAL Hires-Laced screen. When 
				  "Auto Remove Icons" was turned on, dragged icons left garbage at their
				  original position until finally dropped.
				  Problem finally solved without setting friend BitMap to NULL.
	20010731	JL	- Added preferences selectable pens for ToolTip text and background.
				- Due to an incompatibility in Palette.prefs, I renamed it to
				  "Palette13.prefs" . Scalos uses old "Palette.prefs" if 
				  no "Palette13.prefs" found. To create new prefs file, either 
				  copy old "Palette.prefs" to new "Palette13.prefs" or load 
				  Palette prefs editor and use "Save" button to generate 
				  new "Palette13.prefs".
	20010729	JL	- Added check for deleting files of an undefined DirEntryType.
				- For SoftLinks, ToolTips showed name of link target 
				  instead of link name. Fixed.
				- Bumped revision to 40.8.

 40.7	20010729	JL	- Dropped Popupmenu.library for icon ToolTip display and added
				  own layouting and rendering code.
	20010728	DM	+ Added check for copying files of a non-specific DirEntryType.
	    			  Copies files correctly across Samba network, deleting files
	    			  seems to work OK with the current code.
	20010728	JL	- Moved ToolTip display to separate task.
	20010727	DM	  + Fixed corrupt logo and text in about and splash windows by setting
				  all allocated bitmaps to have no friend bitmap
	20010726	JL	- Added AttempLockLayerRom() around icon ToolTip display routine in 
				  order to avoid deadlocks.
	20010724	JL	- Due to Mike's request, increased minimum window width by 20.
	20010723	JL	- Added "scalos/icandy" environment variable on startup and set contents to "2".
				- Changed every copyright string to "© 1999-2001 The Scalos Team".
				- Added "About" function to Menu and Palette preferences.
	20010722	JL	- Changing palette prefs now closes and reopens Scalos, no matter if
				  the "DisableCloseWorkbench" flag is set.
	20010721	JL	- "put away" command didn't work with icons without associated objects. Fixed.
				- "Scalos Menu" : added new menu commands "viewbysize" and "viewbydate".
				- "Disk.info" icons of type WBDISK will no longer appear inside drawer windows.
				- Switching window view mode while window is reading icons no 
				  longer causes window to close.
				- SCCM_IconWin_RemIcon now updates window's virtual size and adjusts sliders.
	20010720	JL	- Bumped revision to 40.7.

 40.6	20010718	JL	- Double-clicking tool icons in text windows didn't start execute command. 
				  Recognition of default icons in text windows didn't work when 
				  starting programs. Fixed.
	20010717	JL	- Found an icon masking problem with PAL Hires-Laced screen. When 
				  "auto remove icons" was turned on, dragged icons left garbage at their
				  original position until finally dropped.
				  Problem (mask BitMap and icon BitMap having different format, 
				  recognizable by different "BytesPerRow" values for equeal width) at 
				  least partially solved by setting friend BitMap to NULL if (Depth <= 8).
	20010716	JL	- Empty lines in ".backdrop" files should be ignored now.
				- CloseWorkBench() from IPrefs Task didn't work. Fixed.
	20010715	JL	- Text windows sometimes swallowed first character of file comment. Fixed.
	20010713	JL	- "Replace All" now works when drag-copying multiple objects.
	20010712	JL	- "select contents" now deselects all icons in non-selected windows.
				- "clear selection" now deselects all icons in all windows.
	20010711	JL	- Plugin libraries are now flushed on scalos exit.
				- Fixed possible problem with missing ScaWindowTask parameter on FreeIconList().
				- Bumped revision to 40.6.

 40.5	20010708	JL	- CheckMouseIcon() didn't work with negative coordinates. Fixed.
				- text windows initially opened with do_CurrentX < 0 in icon displayed
				  icon text at incorrect position. Fixed.
	20010707	JL	- When reading a directory, icons are no longer checked if they overlap each other.
				- converted SCA_OpenIconWindow() to C.
				- Bumped revision to 40.5.

 40.4	20010706	JL	- Enabled "snapshot window" and "snapshot all" for root window again.
	20010705	JL	- Changed locking in DrawDrag() - first call. When "Auto remove icons" was enabled,
				  Icons sometimes didn't get ghosted properly due to DRAGFLAGF_WindowLocked set.
				- Changed initial value for unused oldDir Locks from NULL to $ffffffff, to avoid
				  trouble with pr_CurrentDir = NULL (at the end of functions, CurrentDir() never 
				  got reset to initial value when that value was NULL).
				- AmigaDos menu commands failed to skip trailing '"' if command name is surrounded
				  by '"', e.g. "SYS:xyz" executed with '"' as first argument.
	20010704	JL	- AmigaDos menu commands now inherit the workbench path.
				- Bumped revision to 40.4.

 40.3	20010704	JL	- ReadIcon() didn't respect the "show only icons" setting for text windows, so
				  all files appeared after automatic window update.
	20010703	JL	- changed detection for WMFLAG_IsVirtualSize (sizetofit menu command enabling),
				  now also enabled if window is larger than necessary to hold icons.
	20010702	JL	- Screen menu items are now enabled/disabled each time 
				  SCCM_IconWin_SetVirtSize is applied (i.e. after any change in window size).
	20010630	JL	- Forgot to set  Flag in ReadTextWindowIconList(),
				  so all text icons were treated as if on a write-protected disk.
				- Bumped revision to 40.3.

 40.2	20010629	JL	- Fixed more problems run AmigaDOS menu commands without path.
	20010628	JL	- SnapshotWindow() sometimes wrote icon to wrong directory. Fixed.
				- Added wt_UpdateSemaphore locking for "update" command.
				- Bumped revision to 40.2.
		
 40.1	20010627	JL	- BltMaskBitMapRastPort() used incorrect MinTerm so Masking didn't work 
				  correctly. (e.g. logos in splash and about window on non-cybergraphics screen).
	20010626	JL	- CheckMouseIcon() didn't work when "Non-masked click area" was checked. Fixed.
				- Splash window didn't adjust logo when window was resized due to long message. Fixed.
				- ReadDatatypesImage() returned the original BitMap (PDTA_BitMap) instead of
				  the remapped one (PDTA_DestBitMap).
	20010624	JL	- Due to extended library functions, bumped version to 40.1.

39.234	20010623	JL	- Added SCA_ScalosControl() call to scalos.library. Only 3 tags supported
				  yet, documentation still missing.
	20010620	JL	- About and Splash window can may load different logo images 
				  "THEME:ScalosSplashLogo" and "THEME:ScalosAboutLogo". If those 
				  files are not found, both windows fall back to "THEME:ScalosLogo".
	20010617	JL	- Due to an incompatibility in menu.prefs, I renamed it to
				  "menu13.prefs" . Scalos uses old "menu.prefs" if no "menu13.prefs" found.
				  To create new prefs file, either copy old "menu.prefs" to new 
				  "menu13.prefs" or load old "menu.prefs" in menu prefs editor
				  and use "Save" button to generate new "menu13.prefs".
	20010616	JL	- Added new popup menu class for AppIcons.
				- "System Info" button in About window is disabled if sysinfo module cannot
				  be found.
				- Opening new icon windows in iconified state could lead to each icon 
				  appearing twice after uniconifying window - Fixed. Now wt_LateIconList is
				  cleared at the beginning of ReadIconList().
	20010615	JL	- Fixed enforcer hits in about window when no scalos logo could be loaded.
				- RunMenuCommand() didn't work with CLI (=AmigaDos) commands without
				  path, i.e. only filename specified. Fixed.
				- Icon tooltips no longer pop up when non-Scalos window is active.
				- Icon position for iconified Scalos windows can be specified in
				  window icon with SCALOS_ICONIFIED_XPOS and SCALOS_ICONIFIED_YPOS.
				- Bumped revision to 39.234.

39.233	20010614	JL	- AppIcon menu commands now support all WB3.5+ AMCLASSICON_... 
				  AppMessage class codes (e.g. Benchtrash information/snapshot/unsnapshot works).
	20010613	JL	- Due to common request, Bob functions now don't use chip memory 
				  if port "FBlit" is available.
	20010610	JL	- AppIcons always got IDTV_TextMode_Normal (no outline, no shadow). Fixed.
	20010609	JL	- ARexx menu commands now may have selected items as arguments.
				- Bumped revision to 39.233.

39.232	20010608	JL	- Enabling/disabling popup menus now works correctly with nested sub-menus.
	20010607	JL	- Scalos now does a "Update all" instead of "Redraw" when 
				  detecting changed main prefs.
	20010606	JL	- Softlink sometimes could not be copied due to incorrect parent directory - Fixed.
	20010605	JL	- Fixed nasty bug in AllocVecPooled()/FreeVecPooled() : a6 was overwritten.
				- In text windows with "Show only Icons", non-existing objects (i.e. icons 
				  without corresponding objects) are no longer displayed (e.g. "disk").
				- Disabled "Leave Out" for default icons.
				- Changed locking in TestPopup() to prevent deadlocks.
	20010603	JL	- Bug #4. Fixed crash when executing ARexx menu command.
	20010602	JL	- No tooltips are displayed for icon after clicking or double-clicking it.
				- Menu command "sizetofit" now also shrinks windows if appropriate.
				- Bumped revision to 39.232.

39.231	20010601	JL	- Text windows with "Show only Icons" displayed data for icons 
				  instead of objects. Fixed.
				- Bug #13. Drawers inside of text windows no longer open always 
				  in text mode, but use the drawer icon settings instead.
	20010530	JL	- checkmouseicon() and QueryObjectUnderPointer() now take 
				  "Non-masked click area" setting into account.
	20010529	JL	- Fixed possible race condition with QueryObjectUnderPointer() by 
				  extending window list and wt_IconSemaphore locking.
	20010526	JL	- AppIcons now have popup menus (currently the same as tool icons) 
				  if  is not 0.
				- Tooltips now recognize iconified scalos windows.
	20010525	JL	- Iconified window appIcons get the "WBAPPICONA_SupportsOpen, TRUE" Attribute.
				- Fixed error in SCA_NewAddAppIcon() - WBAPPICONA_Supports... tags didn't work.
				- Bumped revision to 39.231.

39.230	20010524	JL	- No icon tool tips are displayed if icon has tooltype "SCALOS_NOTOOLTIPS".
				- Added new menu commands "sizetofit" and "clearselection".
	20010523	JL	- Scalos now passes a copy of the window lock as wa_Lock and wa_Name=NULL
				  when no icons are selected (now OS3.9 Find work just as with Workbench).
				- Fixed a couple of problems with the new tooltip function.
	20010519	JL	- Bumped revision to 39.230.

39.229	20010519	JL	- Fixed bug in QueryObjectUnderPointer() - did not work correctly if Workbench
				  screen wasn't frontmost screen.
	20010517	JL	- Added check for ST_LINKFILE, ST_LINKDIR, ST_SOFTLINK before calling isLink().
				- (OLD) After updating left-out (backdrop) icon, updating the associated disk icon
				  created a new backdrop icon instead of refreshing the old one. Fixed.
	20010515	JL	- Replaced IDCMP_VANILLAKEY handling by IDCMP_RAWKEY in order to 
				  receive "key up" events.
				- Drag&Drag indicators (copy etc.) are now updated immediately when
				  pressing or releasing qualifier key.
	20010512	JL	- About window now supports optional background image "THEME:AboutBackground".
	20010510	JL	- Added support for wheel mouse (icon/text window scrolling).
	20010509	JL	- Text windows didn't get refreshed properly after deleting icons. Fixed.
	20010508	JL	- Icon tooltypes sometimes were not recognized correctly. Fixed.
				- Bumped revision to 39.229.

39.228	20010507	JL	- Changed method of soft link detection to a more system-friendly one.
				- Bumped revision to 39.228.

39.227	20010506	JL	- Scalos no longer tries to load appchange'd AppIcons when their 
				  name contains invalid characters, i.e. ":/".
				- Scalos now uses AddPart() to add the name of the AppIcon to the "Default icons"
				  path, to make sure there is always a "/" between path and file name.
				- Converted WBLtask to C. The "unable to load your tool ..." Request now offers
				  to select a different tool via ASL requester.
	20010504	JL	- "Leave Out" didn't work for icons without associated files or drawers. Fixed.
	20010501	JL	- Icon menu items weren't enabled correctly in text windows. Fixed.
				- "View All"  wasn't recognized when initially opening text windows. Fixed.
	20010430	JL	- Softlinks are now displayed with underlined names. This feature 
				  work only with iconobject.datatype 39.33 and later.
				  (I saw that feature at Workbench 3.9 (with BoingBag 1) and immediately liked it).
	20010429	JL	- Text windows now distinguish between "Show All Files" and "Show Only Icons".
				- Bumped revision to 39.227.

39.226	20010428	JL	- Splash window : added 10" timeout when waiting for update message reply.
	20010427	JL	- AppIcons now support the WBAPPICONA_Supports... tags.
				- Icon menu items are now enabled/disabled according to the icons properties,
				  e.g. for icons on read-only media "delete" and "rename" is disabled.
				- Splash window now supports optional background image "THEME:SplashBackground".
	20010424	JL	- Fixed Enforcer hit in file/directory copying code when 
				  FileTransClassInstance was NULL.
				- CopyCommand didn't work with DestName != NULL (to perform 
				  "Copy As" function). Fixed.
				- Objects can now get duplicated (cloned) via D&D into same window
				  with Control key held down.
	20010422	JL	- Window.c/QueryObjectUnderPointer() could crash if PtrLayer->Window was 
				  empty (NULL). Fixed.
				- Path Assign "THEME:" is set on program start to "Scalos:themes/default".
				- Bumped revision to 39.226.

39.225	20010421	JL	- Fixed enforcer hits/crash opening window popup menu with empty (NULL) ws_Name.
				- MoveCommand() no longer complains when trying to move non-existing object.
				- Bumped revision to 39.225.

39.224	20010420	JL	- Dropped drop zone rendering in separate layers and returned to complement
				  drawing due to lack of performance.
	20010417	JL	- Logo gets loaded by datatypes.library from THEME:ScalosLogo
				- Defined C names for all library bases.
	20010415	JL	- Region didn't get freed in class.c/SameWindow() if no icon was moved. Fixed.
				- Additional check for NULL window pointer in Scalos.c/LassoInit().
				- moving icons in same window with "AutoRemove Icons = Off" didn't work properly
				  because registers were trashed in main_subroutines.s/checkposition. Fixed.
				- Bumped revision to 39.224.

39.223	20010415	JL	- Due to Mike's request, bumped revision to 39.223.
			
222x26				- Removed locking with DragDropSemaphore due to deadlock problems.
				- Changed rendering of window/icon drop zones from complement drawing
				  to separate layers (in Requesters), hopefully eliminating all problems
				  with garbage left in windows.
	20010414	JL	- Changed to utilize CatComp and its automatically generated locale header files.
				  All localized string are now in "Scalos.cd". Tested with CatComp 44.6.
	20010413	JL	- Bumped version to 222x26.

222x25	20010413	JL	- Fixed crash when icon window was closed or iconified while reading icons
				  and drawer contained more than 20 icons.
	20010412	JL	- (OLD) Fixed another icon window cleanup bug - icons were incorrectly
				  positioned under certain conditions so that icon text could overlap
				  other icons.
	20010411	JL	- Lasso selection didn't respect window limits when selecting icons. Fixed.
	20010410	JL	- CLIStart() crashed with type WBTOOL icons. Fixed.
				- (OLD) SCA_OpenIconWindow() didn't work with SCA_Iconify tag. Fixed.
	20010409	JL	- Lasso didn't correctly calculate window left and top offsets. Fixed.
				- Popup menus now have two title lines, with the type of object in the
				  first line and the name of the object in the second one.
	20010407	JL	- File move and copy routiones rewritten from scratch. Extensive error checking
				  when moving/copying objects. Requester when trying to overwrite existing
				  objects while moving/copying.
				- Created locking mechanism (via DragDropSemaphore) to prevent window updates
				  during D&D.
	20010404	JL	- Renaming left-out icons will no longer lose their position.
	20010403	JL	- Changed window refresh after file system notify : icon update is held back until
				  2s after last update request. Fixes lengthy repeated icon window updates after
				  changing many items (e.g. "Select All", then "UnShapshot").
				- Implemented drag threshold, i.e. icons have to be moved more than 4 pixels until
				  drop zone indicator is drawn.
				  THE AMOUNT OF 4 PIXELS SHOULD BE MADE USER SELECTABLE IN PREFERENCES.
	20010402	JL	- When modifying icons, Icons used to disappear if no associated file existed. Fixed.
	20010401	JL	- Icon just left out did not disappear from desktop when volume (disk) was removed. Fixed.
				- Icons could be "left out" multiple times, leaving several lines in ".backdrop". Fixed.
	20010331	JL	- Fixed bug #25 - D&D didn't copy to drawer icon left out on the desktop.
	20010330	JL	- Bumped version to 222x25.

222x24	20010329	JL	- (OLD) ".backdrop" files are now updated when renaming objects. Fixed bug #22.
	20010328	JL	- Fixed OLD bug in root_handlemessages - stack could be corrupted if message without
				  handler routine was encountered. Possibly also fixes long-standing bug #21.
	20010327	JL	- Text mode windows used to show "#?.info" files when UseExAll was off. Fixed.
	20010325	JL	- (OLD) Fixed enforcer hits/Alerts with "leave out" and "put away".
				- (OLD) Leave out didn't work if .backdrop had a length of 0 bytes. Fixed.
	20010325	JL	- Bumped version to 222x24.

222x23	20010324	JL	- Rename.module, newdrawer.module and delete.module now trigger
				  window updates on completion.
				- On completion of rename.module, objects are checked if they have been renamed
				  and window names are adjusted if necessary (bug #16 finally wiped out).
	20010323	JL	- Lasso selection now only affects visible icons (same behaviour as Scalos 2.1d)
	20010321	JL	- Hopefully fixed multiple text window refresh problems.
				- Removed forced D&D source update.
	20010320	JL	- Window drop box was drawn incorrectly for text windows. Fixed.
				- Added new text window methods : SCCM_TextWin_BeginUpdate, SCCM_TextWin_EndUpdate.
				- Changed text window method SCCM_IconWin_RemIcon from no-op to working icon removal.
	20010319	JL	- Fixed serious bug in GetTextIcon_Fib() : Drop on text window icon caused
				  many enforcer hits.
				- D&D onto text icon drawers didn't work. Fixed.
				- IconWinCheckUpdate() now also works work text windows.
	20010318	JL	- Converted text window icon reading code to C.
				- Text windows displayed date+time incorrectly : last digit was shown twice. Fixed.
				- Text window columns now always are wide enough to show column title
				  (e.g. empty drawer in text mode only used to show the last column spanning all window width)
				- IconActive flag didn't get updated corrected when lasso-selecting icons. Fixed.
				- Left mousebutton click toggles icon selection state when shift pressed.
	20010317	JL	- Bumped version to 222x23.

222x22	20010317	JL	- Text mode windows used incorrect font. Inserted missing SetFont() in DrawTextGadgets().
				  Special indicator bobs were broken with system bob routines. Fixed.
	20010317	JL	- Bumped version to 222x22.
			
222x21	20010317	JL	- ReadIconList() failed when called from different WindowTask (e.g. activate
				  Window #1, RMB click Window #2, select "Update" via popup menu). Fixed.
				- Icons in backdrop windows could be dragged to overlap each other. Fixed.
				- At D&D operations, the first argument (file/drawer) didnþt get freed. Fixed.
	20010316	JL	- Prefs option "Hide hidden files" now hides files starting with "."
				  (only in functions converted to C yet).
				- Drag/Drop copy/move forces check for update on source.
				- Changed D&D special indicator handling:
				  * special bobs initially added to separate list instead of adding to srgh_boblist
				    and then moved to special bob list.
				  * drgh_boblist protected by semaphore to prevent DrawDrag() until InitDrag() finishes.
	20010315	JL	- Icon drop marks during menu popup didn't get erased properly
				  in simple-refresh windows. fixed.
	20010314	JL	- Fixed directory-reading bug with empty file names or files ".info".
				- special D&D indicators are now always drawn solid.
	20010313	JL	- Fixed (self-introduced) Bug in DragDropBobs.c : BlitTrans() 
				  handled masks incorrectly when width was a multiple of 16.
				- Bob functions now don't use chip memory if CyberGfxBase is available.
	20010312	JL	- Squished Bug #17 : Text window column headers no longer flicker
				  when MMB is held down and mouse is moved.
	20010310	JL	- Removed layout bug in iconwindow cleanup (icons did overlap).
	20010305	JL	- Lasso() now always uses Screen->MouseX/MouseY coordinates. 
				  No more offsets between mouse position and lasso corner !
222x20	20010303	JL	- PopupMenu now visually indicates selected icon.
				- Popup menus work without selecting window now (if any Scalos window is selected)
	20010227	JL	- finished converting main_dragdropbobs.s to C.
				- During D&D, special indicators show if icon may not be dropped
				  or icons are going to be copied.
				- During D&D, holding CTRL key forces copy (instead of move).
	20010221	JL	- During D&D, Icons leave a "shadow" at their original position if 
				  "Auto remove icons" is enabled. This Shadow is truly transparent 
				  if possible (CyberGfx + Screen depth > 8) and enabled
				  in preferences, else it is drawn "ghosted".
	20010220	JL	- Removed old bug in copyfiles - after a read error, Scalos didn't stop,
				  but tried to write 0xffffffff bytes to the destination.
222x17	20010217	JL	- ported all xxxDrop() stuff to C.
				  Changed ScaBob and ScaBob2 member names to avoid conflicts with Gels Bobs.
	20010216	JL	- Fixed old bug in execomprog, formatdiskprog, shutdownprog, renameprog,
				  newdrawerprog, deleteprog, emptytrashprog : TagList for SBA_WBStart() wasn't set,
				  a1 contained garbage.
	20010211	JL	- Bug #30: Removed GM_HITTEST from TextIconClass. Now TextIcons can be selected
				  Bug #19: Text window cleanup now works.
				- by clicking anywhere in the line, not only the name field.
	20010209	JL	- Fixed bug Scalos crashing on quit with drawer windows open
	20010207	JL	- Pulled nasty bug introduced by early plugin init in ReadDiskPlugin1
	20010129	JL	- Added new IconWindow methods SCCM_IconWin_DragEnter, SCCM_IconWin_DragLeave,
				  SCCM_IconWin_DragQuery. 
				- Added Qualifier to SCCM_IconWin_DragDrop.
				- Added global Variable "Default_StackSize". 
				- Added Support for ToolType "DONOTPROMPT" in conjunction with old ToolType "CLI". 
				- Moved all datat structure definitions to file "scalos_structures.i". 
				- Created C header file "scalos_structures.h".
				- Actual Plugin Data (e.g. instance size) is read before MakeClass()
				- Changed view of dragging selected icons to dragging a "stack" of max. 3 icons
				- When dragging, icons/windows indicate where things may be dropped.
				- Lasso activates icons on the fly now.
				- Popup menu titles reflect icon names.
	20010113	JL	- Ported to assemble with PhxAss. PhxAss doesn't like constructs like "iconnode\.node" 
				  so I put a prefix on all structure members e.g. "in_node".

39.220	20010111	DM	- Converted Juergen's fixes to values instead of constants, AsmOne seems to not like some of the included OS files - in various files
	20001231	MC0002	- Added includes for various lvo/#?.i
	20001230	MC0001	- Added exec/libraries.i for LIB_VERSION() macro
				  and OS3.5 asm includes for workbench.library, imageclass.i
	20001217	DM000A	- Removed include file main_about.s - all code now in C!
	20001212	DM0009	- Added some code for calling debug startup/shutdown C functions
	20001122	DM0007	- Removed about_pattern from main_tables.s and put into about.c (the only place that was using it)
				  All logo stuff moved from main_scalos.s to main_about.s (only place it is used)
	2000		DM0006
	2000		DM0005
	20001114	DM0004	- started converting the about requester and related code to C as a test of how painful this is going to be :)
	20001107	DM0003	- added the includes imports.i and exports.i. used for when combining with C code. Also added workaround for symbol export bug in AsmXXX
	20000903	DM0002	- Bumped version and date to 39.220 (1.2c) and 3/9/00
				- Fixed enforcer hit when there is no main menu prefs file on startup
				- Noticed that main menu prefs aren't read in with prefslib!

39.219	20000726	DM0001	- Altered some lines in readmainprefs routine so that scratch registers are reloaded before use
	19991130	CDH0001	- Added code for new "formatdisk" command from Menu Prefs
	19991204	CDH0002	- Added code for "SystemInfo.module" from About requester
	19991205	CDH0003	- Added code for new "shutdown" command from Menu Prefs



Scalos main Preferences


 40.13	20040827	+jl+	- Added passing of tooltypes on to prefs plugins.
 40.12	20040718	+jl+	- Added font preview for icon font, and text window font.
 				- In the "drag and drop" section, added new qualifier 
				  input field for "Create links" and "Force move".
				- On the "Miscellaneous" page, added a cycle gadget to 
				  select the type of links Scalos generates.
 40.11	20040516	+jl+	- Added new prefs page for TrueType font settings. TT Font 
				  selection is available for icons, text windows and 
				  tooltips and the "About" window ("Screen font").
 				- Added checking for custom MUI MCCs and MCC versions.
 				- Enabled "Multiple Lines" switch for icon text.
 40.10			+jl+	- Rearranged prefs pages - created new prefs
 				  group "Drag and Drop".
 40.9
 40.8	20040111	+jl+	- Added slider for degree of default icon 
				  drawing transparency.
 				- Transparency settings and "Custom" bob routines
 				  are now disabled when noo CyberGfx library found
 				  or when Workbench screen has no more than 256 colours.
 40.7	20040107	+jl+	- Several Datatypes images were no longer 
				  visible after iconify/uniconify. Fixed.
				- Added icon for iconified state.
 40.6	20040101 	+JL+	- Added gadget to adjust Scalos default stack size.
 40.5	20031227	+jl+	- Replaced MUI NFloattext class by Floattext.
 40.4   20031218	+jl+	- Updated Scalos URL to "scalos.noname.fr".
 40.3   20031216	+jl+	- Added missing load/save functions for 
				  Tooltip delay
 40.2	20031117	+jl+	- "Add plugin" command erroneously cleared 
				  internal plugin list.
 				- Changed module image display from 
				  TransferAnimObject to DataTypesMCCObject.
 40.1	20030104	+jl+	- Rewritten from scratch, based on code by Budda.
	20030710 	+JL+	- Initial release 40.1


Scalos FileTypes Preferences


 40.6	20041111	+jl+	- Replaced Assembler library startup code by C.
				  No functional changes.
 40.5	20040828	+jl+	- Added menu option and tooltype to hide all 
				  empty filetype entries.
 40.4	20040703	+jl+	- Added font preview to TTTFONT editing window.
 40.3	20040222	+jl+	- Changing the "create icons" menu item had no effect.
 				- Added TrueType font support for ToolTips (new TTFONT 
				  attribute for STRING).
 40.2	20040108	+jl+	- Added icon for iconified state.
				- Bugfix: Fixed handling of internal "modified" flag.
 				- Added lamp indicator for "modified" flags.
 40.1	20031211	+JL+	- Initial release 40.1


Scalos Menu Preferences


 40.12	20041111	+jl+	- Replaced Assembler library startup code by C.
				  No functional changes.
 40.10	20040424	+jl+	- Bugfix: Fixed handling of internal "modified" flag.
 				- Added lamp indicator for "modified" flags.
 				- Menu command "Merge" erroneously cleared the existing 
				  entries before importing the new ones. Fixed.
 40.9	20040222	+jl+	- Changing the "create icons" menu item had no effect.
 40.8	20040108	+jl+	- Added icon for iconified state.
 40.7	20030831	+JL+	- Moved core functionality to "MenuPrefs.prefsplugin".
 40.6	20030712 	JL	- Bugfix: Removed memory leak in CLI startup code.
 40.5	20030531 	JL	- Bugfix: Popup button for IconWindow command entries now 
				  only accepts directories.
				- Bugfix: Closing command popup ASL requester with "Ok" 
				  button failed to enter filename into Listview element.
				- Improvement: command popup ASL requester now defaults to 
				  "Scalos:Plugins/Menu/" directory for menu plugins.
 40.4	20030424 	JL	- Several bugfixes that affect renaming of menu items.
				- for Workbench commands, stack size and priority are taken
				  from icon, if available.
 40.2	20030223 	JL	- Added checking of menu level and number of menu items. It 
				  is no longer possible to add a new menu to a SubMenu, or 
				  to add more than 64 MenuItems to a menu, or to add more 
				  than 32 Entries to a sub menu.
 40.1	20021226 	JL	- Rewritten from scratch in C.


Scalos Palette Preferences


 40.7	20041111	+jl+	- Replaced Assembler library startup code by C.
				  No functional changes.
 40.6	20040424	+jl+	- Bugfix: Fixed handling of internal "modified" flag.
 				- Added lamp indicator for "modified" flags.
				- Changing the "create icons" menu item had no effect.
 40.5	20040121	+jl+	- Number of allocatable pens was too small by 1. Fixed.
 40.4	20040108	+jl+	- Added icon for iconified state.
 40.3	20030831 	JL	- Moved core functionality to "PalettePrefs.prefsplugin".
 40.2	20030712 	JL	- Bugfix: Removed memory leak in CLI startup code.
 40.1	20020601 	JL	- Added display for number of currently allocated and 
				  available pens.
	20011225 	JL	- Rewritten from scratch in C.
				- Added separate pens for selected icon text, icon text 
				  outline, and icon text shadow.


Scalos Pattern Preferences


 40.8	20041111	+jl+	- Replaced Assembler library startup code by C.
				  No functional changes.
 40.6	20040426	+jl+	- Bugfix: Fixed handling of internal "modified" flag.
 				- Added lamp indicator for "modified" flags.
				- Changing the "create icons" menu item had no effect.
 40.5	20040108	+jl+	- Added icon for iconified state.
 40.4	20030831	+JL+	- Moved core functionality to "PatternPrefs.prefsplugin".
 40.3	20030712	+JL+	- Bugfix: Removed memory leak in CLI startup code.
 40.2	20030129	+JL+	- Bugfix: Bubble for preview gadget was broken.
				- Bugfix: switching between "tiled" and "fit size" didn't work.
				- Rewritten from scratch in C.


Scalos LoadWB


  1.4	20040108	jl	- The functionality to wait until Scalos opens its first 
				  Window on the workbench screen can now be 
				  suppressed with NOWAIT.
  1.3	20021005 	JL	- LoadWB now waits until Scalos opened its first Window on 
				  the workbench screen. This is to avoid problems with 
				  Birdie.


picturedimensions.plugin


 40.3	20040117	+jl+	+Added localization for message strings.
 40.2	20030628	+jl+	+Fixed several memory leaks.
 40.1	20021231	+jl+	+Initial release


drawercontents.plugin


 40.3	20040117	+jl+	+Added localization for message strings.
 40.2	20030628	+jl+	+Fixed several memory leaks.
 40.1	20030104	+jl+	+Initial release


amigaiconobj35.datatype


 40.7	20031220	jl	+changed library from "struct Library" to "struct ClassLibrary"
 40.6	20030420	jl	+Added support for "borderless" flag.
 40.5	20021201	jl	+Enhanced cleanup - now does RemLibrary() on iconobject.datatype.
 40.4	20020815	jl	+Fixed possible enforcer hits in Expunge()
 40.3	20020131	jl	+Object pointer in A2 might have been set incorrectly under 
				 certain circumstances in OM_NEW/SetSuperImgBorders.
 40.2	20020112	jl	+Always sets IDTA_InnerLeft, IDTA_InnerTop, IDTA_InnerRight 
				 and IDTA_InnerBottom to 0 if icon has a RenderHook.
 40.1 	20020101	jl	+Removed IDTA_InnerLeft and IDTA_InnerTop checks to 
				 enable frames around masked icons
				+Added support for IDTA_SupportedIconTypes tag.
 39.31	20010627	jl	+Fixed wrong register for GetCyberMapAttr() Attribute parameter.
 39.30	20010508	jl	+some instance data is now longword aligned
 39.29	20010207	jl	+fixed 2 byte memory overwrite error in ClearMemory
 39.28	20010128	jl	+Added Semaphore protection for memory pools
 39.27	20010117	jl	+Begin revision history


amigaiconobject.datatype


 40.5 	20031220	+jl+	+changed library from "struct Library" to "struct ClassLibrary"
 40.4	20021201	+jl+	+Enhanced cleanup - now does RemLibrary() on iconobject.datatype.
 40.3	20020815	+jl+	+Fixed possible enforcer hits in Expunge()
 40.2	20020113	+jl+	+More changes for enhanced compatibility for icons with borders.
 40.1	20020101	+jl+	+Removed IDTA_InnerLeft and IDTA_InnerTop checks to 
				 enable frames around masked icons
 39.24	20010514	+jl+	+fixed mean bug in clLayout - somehow two lines had disappeared.
 39.23	20010511	+jl+	+fixed serious bug in clWrite.
 39.22	20010508	+jl+	+some instance data is now longword aligned
 39.21	20010128	+jl+	+Added Semaphore protection for memory pools
 39.20	20010117	+jl+	+All memory allocations are now being done via memory pools.


iconobject.datatype


 40.12	20040814	+jl+	+Added support for new IODRAWF_NoEraseBg flag.
 40.11	20040524	+jl+	+Added functionality to support TrueType fonts for icon text
 	20040611	+jl+	+Added support for splitting of icon text into multiple lines
 	20040611	+jl+	+Added support for transparent rendering of icon label shadow 
				 and outline (TrueType fonts only).
 40.10	20031220	+jl+	+changed library from "struct Library" to "struct ClassLibrary"
 40.9	20030420	+jl+	+Added support for per-icon "borderless" flag
 40.7	20020928	+jl+	+Added IDTA_UserFlags get/set tag.
 40.6	20020815	+jl+	+Fixed possible enforcer hits in Expunge()
 40.5	20020321	dm	+Fixed crash when GM_HITTEST was invoked with icon mask of NULL.
 40.4	20020320	+jl+	+GM_HITTEST was broken when icon borders were > 0.
 40.3	20020201	+jl+	+Added attribute tags IDTA_MaskBM_Normal and IDTA_MaskBM_Selected.
 40.2	20020113	+jl+	+More changes for enhanced compatibility for icons with borders.
 40.1	20020101	+jl+	+Added separate pens for selected icon text, icon text 
				 outline, and icon text shadow.
 39.38	20011230	+jl+	+Major changes to support borders around os3.5 icons and NewIcons.
 39.37	20010818	+jl+	+Added IDTA_Font attribute
 39.36	20010617	+jl+	+SetAttr(IDTA_ToolTypes) now stores a COPY of the
				 provided tooltype array. Copy gets freed on Dispose.
 39.35	20010613	+jl+	+checks for "FBlit" on OpenLibrary and doesn't use
				 any chip memory if found.
 39.34	20010508	+jl+	+longword-aligned structure IconObjectInst.
 39.33	20010429	+jl+	+Displays underlined text if IDTA_isLink is TRUE.
 39.32	20010311	+jl+	+Uses no chip mem if cybergraphics is found.
 39.31	20010209	+jl+	+Added missing "ret" in LibClose ... 
				 fixes crash on Scalos closing.
 39.30	20010128	+jl+	+Added Semaphore protection for memory pools
 39.29	20010117	+jl+	+All memory allocations are now being done via memory pools.
 39.28	20010114	+jl+	+fixed memory leak with iobj_name


newiconobject.datatype


 40.5 	20031220	+jl+	+changed library from "struct Library" to "struct ClassLibrary"
 40.4	20021201	+jl+	+Enhanced cleanup - now does RemLibrary() on iconobject.datatype.
 40.3	20020815	+jl+	+Fixed possible enforcer hits in Expunge()
 40.2	20020113	+jl+	+More changes for enhanced compatibility for icons with borders.
 40.1	20020101	+jl+	+Removed IDTA_InnerLeft and IDTA_InnerTop checks to 
				 enable frames around masked icons
 39.24	20011206	+jl+	+Fixed reversed check for IOFREELAYOUTB_ScreenAvailable 
				 in idtm_freelayout.
 39.23	20010714	+jl+	+Fixed bug in DTM_Write with IDTA_ToolTypes.
 39.22	20010627	+jl+	+Fixed wrong register for GetCyberMapAttr() Attribute parameter.
 39.21	20010508	+jl+	+some instance data is now longword aligned
 39.20	20010128	+jl+	+Added Semaphore protection for memory pools
 39.19	20010120	+jl+	+All memory allocations are now being done via memory pools.


pngiconobject.datatype


 40.12	20041111	+jl+	+Replaced Assembler library startup code by C.
				 No functional changes.
 40.11	20040915	+jl+	+Bugfix: icon mask generation clipped some pixels 
				 at right border. Fixed.
 40.10	20040801	+jl+	+Default icons were not saved to the correct path.
 40.9	20040523	+jl+	+Fixed severe memory trashing. Datatype used to overwrite 
				 random memory with some icons.
 40.8	20040429	+jl+	+Datatype now correctly recognizes and renders 
				 AppIcons generated by PowerIcons.
 40.7	20040226	+jl+	+Plugged several memory holes.
 40.6	20040111	+jl+	+Added support for default icons via IDTA_DefType tag.
 40.5	20040109	+jl+	+Now supports extra information about original 
				 object (Path+Name) for the determination 
				 of icon type.
 40.4	20040105	+jl+	+Iconobjects now use DrawerData defaults from 
				 icon.library default icon of the same type.
 40.3	20040104	+jl+	+Fixed severe bug that trashed random memory. 
				 Only occurred with icons without fixed position.
 40.2	20040102	+jl+	+Added optimization in alpha-blending routines.
 				+Fixed trashing of icon image data 
				 during IDTM_Write.
				+Disk icons (WBDISK) were not recognized properly.
 40.1	20011221	+jl+	+Initial version


iconobject.library


 40.4	20041110	+jl+	- Removed Assembler library startup code. 
				  No functional changes.
 40.3	20021201	+jl+	- Improved cleanup code: FreeClassList() now calls 
				  RemLibrary() for each datatype.
				- Added capability to copy/cut/paste attributes.
 40.2	20020815	+jl+	- Fixed possible Enforcer hit in Expunge()
 40.1	20020101	+jl+	- Added new library function Convert2IconObjectA()


wbrexx.plugin


 39.18	20041113	jl	+Replaced Assembler library startup functions 
				 by C code. No functional changes.
 39.17	20031222 	JL	+Changed "OpenDrawerByName()" to make use of the 
				 Scalos iconobject datatypes. 
 39.16	20030112	JL	+Removed some dependencies on undocumented internal 
				 Scalos data structures.
 39.15	20021206 	JL	+Added "MENU INVOKE WINDOW.CLEANUPBY.NAME/DATE"
				 "/SIZE/TYPE" functions.
				+Added "ICON MOVE IN/OUT" functions.
				+Added "MENU INVOKE WINDOW.RESIZETOFIT" function.
 39.14	20021130 	JL	+Added "ICON ACTIVATE UP/DOWN/LEFT/RIGHT" functions.
				+Fixed order of which icons get select with 
				 "ICON CYCLE NEXT/PREV" function.
 39.13	20020927 	JL	+Fixed bug in AddMenuItem() and AddKeyboardCommand()
				 which could lead to crashed when trying to add items
				 with already exiting names.
 39.12	20020131 	JL	+Now supports adding menu subitems and new menus. Using
				 this new features requires Scalos V40.20.
 39.11	20011030 	JL	+Fixed serious initialisation problem in Scalos 
				 preview mode, leading to crash on any keyboard input.
 39.10	20011020 	JL	+No longer initializes if Scalos is running in 
				 preview mode.
 39.9	20011008 	JL	+Changed priority to -79 in order to make it work 
				 for text windows.
				+"ICON MAKEVISIBLE" didn't always work correctly for 
				 text windows. Fixed.
 39.8	20010927 	JL	+Added missing MENU and KEYBOARD functions.
				+Fixed several bugs GETATTR function.
 39.7	20010719 	JL 	+Forgot to UnLock() lock in FindWindowByName(). Fixed.
 39.6	20010718 	JL 	+Changed matching algorithm in FindWindowByName(), 
				 important for all WINDOW commands.


wb39.plugin


 45.28	20041113	jl	+Replaced Assembler library startup functions 
				 by C code. No functional changes.
 45.27	20040612	JL	+Fixed enforcer hits when text window icons were 
				 renamed with AsyncWB (Added translation of text icon 
				 types in ChangeWorkbenchSelectionA() ).
 45.26	20040103 	JL	+Added several undocumented WorkbenchControl() tags, 
		    		 WBCtrl doesn't fail, however, not all values are used.
    				+MaxCopyMem can now be changed via 
				 WorkbenchControlA() calls.
 45.25	20031222 	JL	+Changed "OpenDrawerByName()" to make use of the 
				 Scalos iconobject datatypes. 
 45.24	20030112 	JL	+Removed some dependencies on undocumented internal 
				 Scalos data structures.
 45.23	20020914 	JL	+Added support for V45 WBOPENA_Show and WBOPENA_ViewBy
				 tags to OpenWorkbenchObjectA emulation.
 45.22	20020110 	JL	+The AMTYPE_APPWINDOW AppMessages generated in 
				 AppWindow.c had wrong mn_Replyport. Fixed.
 45.21	20011231 	JL	+Added support for "No Color Icons" and "No NewIcons" 
				 workbench prefs settings.
 45.20	20011223 	JL	+Avoid excessive Scalos root window updates 
				 with AddHiddenDevice/RemHiddenDevice.
 45.19	20011204 	JL	+Added support for (undocumented) CloseWB/OpenWB hook list.
				+Added Support for (undocumented) set/clear icon.library 
				 global screen.
 45.18	20011129 	JL	+Added support for getting and setting delete, copy, 
				 and text input hooks (undocumented).
 45.17	20011116 	JL	+fVolumeGauge was not longer checked. Fixed.
				+WB prefs are now checked each time a new device 
				 window is opened.
 45.16	20011020 	JL	+No longer installs patches if Scalos is running in 
				 preview mode.
 45.15	20011010 	JL	+Added proper handling for WorkbenchControl() tags 
				 WBCTRLA_SetTypeRestartTime and WBCTRLA_GetTypeRestartTime.
	20011008 	JL	+Changed priority to -89.
 45.14	20010714 	JL	After WBCTRLA_AddHiddenDeviceName and 
				WBCTRLA_RemoveHiddenDeviceName, now does 
				SCCM_IconWin_Update on root window.
 45.13	20010708 	JL	When opening drawer windows, DDVM_BYICON now gets 
				translated into IDTV_ViewModes_Icon.
	20010623 	JL	Added full Support for WBCTRLA_GetDefaultStackSize and
				WBCTRLA_GetProgramList, using new SCA_ScalosControl() call.
	20010524 	JL	HiddenDeviceList entries now get ln_Type=0x67 so
				Workbench prefs/IPrefs correctly removes old entries from list.
	20010523 	JL	Added additional argument checking to myWorkbenchControlA()
				Added Semaphore protection for HiddenDeviceList
	20010520 	DM	Some other small fixes
	20010518 	DM	Hidden device list completely supported (needs devicefilter.plugin
				to actually hide devices).
				Hidden devices read from workbench prefs file (scalos_helper.c)
	20010124 	JL	Fixed Malfunction of AddAppWindowDropZoneA() with WBDZA_Box


persist.plugin


 39.19	20041113	jl	+ Replaced Assembler library startup functions 
				  by C code. No functional changes.
 39.18	20031222	JL	- Changed "OpenDrawerByName()" to make use of the 
				  Scalos iconobject datatypes. 
 39.17	20020501	JL	- "Persistant_Windows" file no longer is deleted during 
				  initialization. The advantage is, if Scalos crashed before 
				  the first window gets re-opened, the Persistant_Windows 
				  file is untouched. As soon as the first window opens, 
				  the Persistant_Windows file is rewritten.
				- The re-opened windows won't get activated (works with 
				  Scalos V40.22+).
 39.16	20011228	JL	- Disabled some Printf() calls.
 39.15	20010803	JL	- Reversed order in which windows are reopened.
 39.14	20010730	JL	- Changed name of prefs file from "ENVARC:Scalos/Persist.config"
				  to "ENV:Scalos/Persist.prefs".
				- "Use_SCA_Iconify" now default to "1" if scalos.library 
				  version is at least 40.
 39.13			JL	- Name of persistant windows status file is now configurable 
				  in "ENVARC:Scalos/Persist.config".
 39.12			JL	- When re-opening drawer windows,
	    	      DDVM_BYICON now gets translated into IDTV_ViewModes_Icon.
 39.11	 		JL	- when re-opening window in iconified state, now immediately adds
				  entry in persist file (no SCCM_Window_Open will occur, so otherwise 
				  no entry would be generated at all).
 39.10	 		JL	- prefs file may contain comment lines beginning with "#".
				  empty lines in prefs file will be ignored.
				  iconified windows are remembered and re-iconified on startup.


volumegauge.plugin


 39.6	20041113	jl	+Replaced Assembler library startup functions 
				 by C code. No functional changes.
 39.5	20030112 	JL	+Removed some dependencies on undocumented internal 
				 Scalos data structures.
 39.4	20011110		- some changes for compatibility with Scalos 40.14.


deficons.plugin


 ./.	20031231	JL	- Depracated since functionality has been integrated 
				  into Scalos main program.
 45.6	20011230	JL	- OpenLibraries was called twice. Fixed.
				- Added support for individually enabled/disabled icon types.


xtwindows.plugin


 40.5	20040102	JL	- Adapted to changed OpenDrawerByName() function, now 
				  uses iconobject.library instead of icon.library.


ScalosCtrl


 40.16	20040104	JL	+ Added new CBS=COPYBUFFSIZE parameter.
	20040102		- Added "QUERY" command line switch.