summaryrefslogtreecommitdiff
path: root/packages/fv
diff options
context:
space:
mode:
authorpeter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-14 16:54:03 +0000
committerpeter <peter@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-14 16:54:03 +0000
commite5247b2cfbbc77f34dcf5a46d5f0066ea887e7b2 (patch)
tree035171903206a511a36bb5fe6bb79a231f95ce88 /packages/fv
parent1e8bbc586f27f8cff8d18e4dd94d18ddc8989b09 (diff)
downloadfpc-e5247b2cfbbc77f34dcf5a46d5f0066ea887e7b2.tar.gz
* moved freevision package
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@9752 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fv')
-rw-r--r--packages/fv/Makefile2790
-rw-r--r--packages/fv/Makefile.fpc33
-rw-r--r--packages/fv/examples/Makefile1928
-rw-r--r--packages/fv/examples/Makefile.fpc12
-rw-r--r--packages/fv/examples/platform.inc369
-rw-r--r--packages/fv/examples/testapp.lpi67
-rw-r--r--packages/fv/examples/testapp.pas468
-rw-r--r--packages/fv/src/app.pas1200
-rw-r--r--packages/fv/src/asciitab.pas322
-rw-r--r--packages/fv/src/buildfv.pas36
-rw-r--r--packages/fv/src/colortxt.pas126
-rw-r--r--packages/fv/src/dialogs.pas4186
-rw-r--r--packages/fv/src/drivers.pas1578
-rw-r--r--packages/fv/src/editors.pas3797
-rw-r--r--packages/fv/src/fvcommon.pas371
-rw-r--r--packages/fv/src/fvconsts.pas642
-rw-r--r--packages/fv/src/gadgets.pas306
-rw-r--r--packages/fv/src/go32smsg.inc93
-rw-r--r--packages/fv/src/histlist.pas416
-rw-r--r--packages/fv/src/inplong.pas305
-rw-r--r--packages/fv/src/memory.pas875
-rw-r--r--packages/fv/src/menus.pas1632
-rw-r--r--packages/fv/src/msgbox.pas321
-rw-r--r--packages/fv/src/outline.pas685
-rw-r--r--packages/fv/src/platform.inc415
-rw-r--r--packages/fv/src/resource.pas741
-rw-r--r--packages/fv/src/statuses.pas1404
-rw-r--r--packages/fv/src/stddlg.pas2770
-rw-r--r--packages/fv/src/str.inc190
-rw-r--r--packages/fv/src/strtxt.inc216
-rw-r--r--packages/fv/src/sysmsg.pas127
-rw-r--r--packages/fv/src/tabs.pas774
-rw-r--r--packages/fv/src/time.pas465
-rw-r--r--packages/fv/src/timeddlg.pas254
-rw-r--r--packages/fv/src/unixsmsg.inc126
-rw-r--r--packages/fv/src/validate.pas1048
-rw-r--r--packages/fv/src/views.pas4673
-rw-r--r--packages/fv/src/w32smsg.inc190
38 files changed, 35951 insertions, 0 deletions
diff --git a/packages/fv/Makefile b/packages/fv/Makefile
new file mode 100644
index 0000000000..61820c22fa
--- /dev/null
+++ b/packages/fv/Makefile
@@ -0,0 +1,2790 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2007/12/01]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+override PACKAGE_NAME=fv
+override PACKAGE_VERSION=2.0.0
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_UNITS+=buildfv
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_IMPLICITUNITS+=app colortxt dialogs drivers editors fvcommon fvconsts gadgets histlist inplong memory menus msgbox statuses stddlg tabs time validate views sysmsg asciitab timeddlg outline
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_RSTS+=app dialogs editors msgbox stddlg
+endif
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_EXAMPLEDIRS+=examples
+endif
+override INSTALL_BUILDUNIT=buildfv
+override INSTALL_FPCPACKAGE=y
+ifeq ($(FULL_TARGET),i386-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override COMPILER_SOURCEDIR+=src
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override COMPILER_SOURCEDIR+=src
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(CPU_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-Aas
+endif
+endif
+ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),linux)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_units
+ifneq ($(TARGET_UNITS),)
+override ALLTARGET+=fpc_units
+override UNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_UNITS))
+override IMPLICITUNITPPUFILES=$(addsuffix $(PPUEXT),$(TARGET_IMPLICITUNITS))
+override INSTALLPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+override CLEANPPUFILES+=$(UNITPPUFILES) $(IMPLICITUNITPPUFILES)
+endif
+fpc_units: $(COMPILER_UNITTARGETDIR) $(UNITPPUFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_examples
+ifneq ($(TARGET_EXAMPLES),)
+HASEXAMPLES=1
+override EXAMPLESOURCEFILES:=$(wildcard $(addsuffix .pp,$(TARGET_EXAMPLES)) $(addsuffix .pas,$(TARGET_EXAMPLES)) $(addsuffix .lpr,$(TARGET_EXAMPLES)) $(addsuffix .dpr,$(TARGET_EXAMPLES)))
+override EXAMPLEFILES:=$(addsuffix $(EXEEXT),$(TARGET_EXAMPLES))
+override EXAMPLEOFILES:=$(addsuffix $(OEXT),$(TARGET_EXAMPLES)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_EXAMPLES))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_EXAMPLES)))
+override CLEANEXEFILES+=$(EXAMPLEFILES) $(EXAMPLEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_EXAMPLES))
+endif
+endif
+ifneq ($(TARGET_EXAMPLEDIRS),)
+HASEXAMPLES=1
+endif
+fpc_examples: all $(EXAMPLEFILES) $(addsuffix _all,$(TARGET_EXAMPLEDIRS))
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+ $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+ $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+ @$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+ $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+ -$(UPXPROG) $(INSTALLEXEFILES)
+endif
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_distinstall
+fpc_distinstall: install exampleinstall
+.PHONY: fpc_zipinstall fpc_zipsourceinstall fpc_zipexampleinstall
+ifndef PACKDIR
+ifndef inUnix
+PACKDIR=$(BASEDIR)/../fpc-pack
+else
+PACKDIR=/tmp/fpc-pack
+endif
+endif
+ifndef ZIPNAME
+ifdef DIST_ZIPNAME
+ZIPNAME=$(DIST_ZIPNAME)
+else
+ZIPNAME=$(PACKAGE_NAME)
+endif
+endif
+ifndef FULLZIPNAME
+FULLZIPNAME=$(ZIPCROSSPREFIX)$(ZIPPREFIX)$(ZIPNAME)$(ZIPSUFFIX)
+endif
+ifndef ZIPTARGET
+ifdef DIST_ZIPTARGET
+ZIPTARGET=DIST_ZIPTARGET
+else
+ZIPTARGET=install
+endif
+endif
+ifndef USEZIP
+ifdef inUnix
+USETAR=1
+endif
+endif
+ifndef inUnix
+USEZIPWRAPPER=1
+endif
+ifdef USEZIPWRAPPER
+ZIPPATHSEP=$(PATHSEP)
+ZIPWRAPPER=$(subst /,$(PATHSEP),$(DIST_DESTDIR)/fpczip$(SRCBATCHEXT))
+else
+ZIPPATHSEP=/
+endif
+ZIPCMD_CDPACK:=cd $(subst /,$(ZIPPATHSEP),$(PACKDIR))
+ZIPCMD_CDBASE:=cd $(subst /,$(ZIPPATHSEP),$(BASEDIR))
+ifdef USETAR
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(TAREXT)
+ZIPCMD_ZIP:=$(TARPROG) cf$(TAROPT) $(ZIPDESTFILE) *
+else
+ZIPDESTFILE:=$(DIST_DESTDIR)/$(FULLZIPNAME)$(ZIPEXT)
+ZIPCMD_ZIP:=$(subst /,$(ZIPPATHSEP),$(ZIPPROG)) -Dr $(ZIPOPT) $(ZIPDESTFILE) *
+endif
+fpc_zipinstall:
+ $(MAKE) $(ZIPTARGET) INSTALL_PREFIX=$(PACKDIR) ZIPINSTALL=1
+ $(MKDIR) $(DIST_DESTDIR)
+ $(DEL) $(ZIPDESTFILE)
+ifdef USEZIPWRAPPER
+ifneq ($(ECHOREDIR),echo)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDPACK))" > $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_ZIP))" >> $(ZIPWRAPPER)
+ $(ECHOREDIR) -e "$(subst \,\\,$(ZIPCMD_CDBASE))" >> $(ZIPWRAPPER)
+else
+ echo $(ZIPCMD_CDPACK) > $(ZIPWRAPPER)
+ echo $(ZIPCMD_ZIP) >> $(ZIPWRAPPER)
+ echo $(ZIPCMD_CDBASE) >> $(ZIPWRAPPER)
+endif
+ifdef inUnix
+ /bin/sh $(ZIPWRAPPER)
+else
+ifdef RUNBATCH
+ $(RUNBATCH) (ZIPWRAPPER)
+else
+ $(ZIPWRAPPER)
+endif
+endif
+ $(DEL) $(ZIPWRAPPER)
+else
+ $(ZIPCMD_CDPACK) ; $(ZIPCMD_ZIP) ; $(ZIPCMD_CDBASE)
+endif
+ $(DELTREE) $(PACKDIR)
+fpc_zipsourceinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=sourceinstall ZIPSUFFIX=$(ZIPSOURCESUFFIX)
+fpc_zipexampleinstall:
+ifdef HASEXAMPLES
+ $(MAKE) fpc_zipinstall ZIPTARGET=exampleinstall ZIPSUFFIX=$(ZIPEXAMPLESUFFIX)
+endif
+fpc_zipdistinstall:
+ $(MAKE) fpc_zipinstall ZIPTARGET=distinstall
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+ -$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+ -$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+ -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ -$(DELTREE) units
+ -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+ -$(DEL) *.o *.ppu *.a
+endif
+ -$(DELTREE) *$(SMARTEXT)
+ -$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+ -$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+ -$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+ @$(ECHO)
+ @$(ECHO) == Package info ==
+ @$(ECHO) Package Name..... $(PACKAGE_NAME)
+ @$(ECHO) Package Version.. $(PACKAGE_VERSION)
+ @$(ECHO)
+ @$(ECHO) == Configuration info ==
+ @$(ECHO)
+ @$(ECHO) FPC.......... $(FPC)
+ @$(ECHO) FPC Version.. $(FPC_VERSION)
+ @$(ECHO) Source CPU... $(CPU_SOURCE)
+ @$(ECHO) Target CPU... $(CPU_TARGET)
+ @$(ECHO) Source OS.... $(OS_SOURCE)
+ @$(ECHO) Target OS.... $(OS_TARGET)
+ @$(ECHO) Full Source.. $(FULL_SOURCE)
+ @$(ECHO) Full Target.. $(FULL_TARGET)
+ @$(ECHO) SourceSuffix. $(SOURCESUFFIX)
+ @$(ECHO) TargetSuffix. $(TARGETSUFFIX)
+ @$(ECHO)
+ @$(ECHO) == Directory info ==
+ @$(ECHO)
+ @$(ECHO) Required pkgs... $(REQUIRE_PACKAGES)
+ @$(ECHO)
+ @$(ECHO) Basedir......... $(BASEDIR)
+ @$(ECHO) FPCDir.......... $(FPCDIR)
+ @$(ECHO) CrossBinDir..... $(CROSSBINDIR)
+ @$(ECHO) UnitsDir........ $(UNITSDIR)
+ @$(ECHO) PackagesDir..... $(PACKAGESDIR)
+ @$(ECHO)
+ @$(ECHO) GCC library..... $(GCCLIBDIR)
+ @$(ECHO) Other library... $(OTHERLIBDIR)
+ @$(ECHO)
+ @$(ECHO) == Tools info ==
+ @$(ECHO)
+ @$(ECHO) As........ $(AS)
+ @$(ECHO) Ld........ $(LD)
+ @$(ECHO) Ar........ $(AR)
+ @$(ECHO) Rc........ $(RC)
+ @$(ECHO)
+ @$(ECHO) Mv........ $(MVPROG)
+ @$(ECHO) Cp........ $(CPPROG)
+ @$(ECHO) Rm........ $(RMPROG)
+ @$(ECHO) GInstall.. $(GINSTALL)
+ @$(ECHO) Echo...... $(ECHO)
+ @$(ECHO) Shell..... $(SHELL)
+ @$(ECHO) Date...... $(DATE)
+ @$(ECHO) FPCMake... $(FPCMAKE)
+ @$(ECHO) PPUMove... $(PPUMOVE)
+ @$(ECHO) Upx....... $(UPXPROG)
+ @$(ECHO) Zip....... $(ZIPPROG)
+ @$(ECHO)
+ @$(ECHO) == Object info ==
+ @$(ECHO)
+ @$(ECHO) Target Loaders........ $(TARGET_LOADERS)
+ @$(ECHO) Target Units.......... $(TARGET_UNITS)
+ @$(ECHO) Target Implicit Units. $(TARGET_IMPLICITUNITS)
+ @$(ECHO) Target Programs....... $(TARGET_PROGRAMS)
+ @$(ECHO) Target Dirs........... $(TARGET_DIRS)
+ @$(ECHO) Target Examples....... $(TARGET_EXAMPLES)
+ @$(ECHO) Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+ @$(ECHO)
+ @$(ECHO) Clean Units......... $(CLEAN_UNITS)
+ @$(ECHO) Clean Files......... $(CLEAN_FILES)
+ @$(ECHO)
+ @$(ECHO) Install Units....... $(INSTALL_UNITS)
+ @$(ECHO) Install Files....... $(INSTALL_FILES)
+ @$(ECHO)
+ @$(ECHO) == Install info ==
+ @$(ECHO)
+ @$(ECHO) DateStr.............. $(DATESTR)
+ @$(ECHO) ZipName.............. $(ZIPNAME)
+ @$(ECHO) ZipPrefix............ $(ZIPPREFIX)
+ @$(ECHO) ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+ @$(ECHO) ZipSuffix............ $(ZIPSUFFIX)
+ @$(ECHO) FullZipName.......... $(FULLZIPNAME)
+ @$(ECHO) Install FPC Package.. $(INSTALL_FPCPACKAGE)
+ @$(ECHO)
+ @$(ECHO) Install base dir..... $(INSTALL_BASEDIR)
+ @$(ECHO) Install binary dir... $(INSTALL_BINDIR)
+ @$(ECHO) Install library dir.. $(INSTALL_LIBDIR)
+ @$(ECHO) Install units dir.... $(INSTALL_UNITDIR)
+ @$(ECHO) Install source dir... $(INSTALL_SOURCEDIR)
+ @$(ECHO) Install doc dir...... $(INSTALL_DOCDIR)
+ @$(ECHO) Install example dir.. $(INSTALL_EXAMPLEDIR)
+ @$(ECHO) Install data dir..... $(INSTALL_DATADIR)
+ @$(ECHO)
+ @$(ECHO) Dist destination dir. $(DIST_DESTDIR)
+ @$(ECHO) Dist zip name........ $(DIST_ZIPNAME)
+ @$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+ fpc_makefile_dirs
+fpc_makefile:
+ $(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+ifeq ($(FULL_TARGET),i386-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+TARGET_EXAMPLEDIRS_EXAMPLES=1
+endif
+ifdef TARGET_EXAMPLEDIRS_EXAMPLES
+examples_all:
+ $(MAKE) -C examples all
+examples_debug:
+ $(MAKE) -C examples debug
+examples_smart:
+ $(MAKE) -C examples smart
+examples_release:
+ $(MAKE) -C examples release
+examples_units:
+ $(MAKE) -C examples units
+examples_examples:
+ $(MAKE) -C examples examples
+examples_shared:
+ $(MAKE) -C examples shared
+examples_install:
+ $(MAKE) -C examples install
+examples_sourceinstall:
+ $(MAKE) -C examples sourceinstall
+examples_exampleinstall:
+ $(MAKE) -C examples exampleinstall
+examples_distinstall:
+ $(MAKE) -C examples distinstall
+examples_zipinstall:
+ $(MAKE) -C examples zipinstall
+examples_zipsourceinstall:
+ $(MAKE) -C examples zipsourceinstall
+examples_zipexampleinstall:
+ $(MAKE) -C examples zipexampleinstall
+examples_zipdistinstall:
+ $(MAKE) -C examples zipdistinstall
+examples_clean:
+ $(MAKE) -C examples clean
+examples_distclean:
+ $(MAKE) -C examples distclean
+examples_cleanall:
+ $(MAKE) -C examples cleanall
+examples_info:
+ $(MAKE) -C examples info
+examples_makefiles:
+ $(MAKE) -C examples makefiles
+examples:
+ $(MAKE) -C examples all
+.PHONY: examples_all examples_debug examples_smart examples_release examples_units examples_examples examples_shared examples_install examples_sourceinstall examples_exampleinstall examples_distinstall examples_zipinstall examples_zipsourceinstall examples_zipexampleinstall examples_zipdistinstall examples_clean examples_distclean examples_cleanall examples_info examples_makefiles examples
+endif
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples: fpc_examples
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall: fpc_distinstall
+zipinstall: fpc_zipinstall
+zipsourceinstall: fpc_zipsourceinstall
+zipexampleinstall: fpc_zipexampleinstall
+zipdistinstall: fpc_zipdistinstall
+clean: fpc_clean $(addsuffix _clean,$(TARGET_EXAMPLEDIRS))
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
+.NOTPARALLEL:
diff --git a/packages/fv/Makefile.fpc b/packages/fv/Makefile.fpc
new file mode 100644
index 0000000000..a71340c514
--- /dev/null
+++ b/packages/fv/Makefile.fpc
@@ -0,0 +1,33 @@
+#
+# Makefile.fpc for Free Vision for Free Pascal
+#
+
+[package]
+name=fv
+version=2.0.0
+
+[target]
+units=buildfv
+implicitunits=app colortxt dialogs drivers editors \
+ fvcommon fvconsts gadgets histlist inplong memory \
+ menus msgbox statuses stddlg tabs time validate \
+ views sysmsg asciitab timeddlg outline
+exampledirs=examples
+rsts=app dialogs editors msgbox stddlg
+
+[libs]
+libname=libfpfv.so
+libversion=2.0.0
+
+[compiler]
+sourcedir=src
+
+[install]
+buildunit=buildfv
+fpcpackage=y
+
+[default]
+fpcdir=../..
+
+[rules]
+.NOTPARALLEL:
diff --git a/packages/fv/examples/Makefile b/packages/fv/examples/Makefile
new file mode 100644
index 0000000000..c1b5642a6b
--- /dev/null
+++ b/packages/fv/examples/Makefile
@@ -0,0 +1,1928 @@
+#
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2007/12/01]
+#
+default: all
+MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
+BSDs = freebsd netbsd openbsd darwin
+UNIXs = linux $(BSDs) solaris qnx
+LIMIT83fs = go32v2 os2 emx watcom
+OSNeedsComspecToRunBatch = go32v2 watcom
+FORCE:
+.PHONY: FORCE
+override PATH:=$(patsubst %/,%,$(subst \,/,$(PATH)))
+ifneq ($(findstring darwin,$(OSTYPE)),)
+inUnix=1 #darwin
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+ifeq ($(findstring ;,$(PATH)),)
+inUnix=1
+SEARCHPATH:=$(filter-out .,$(subst :, ,$(PATH)))
+else
+SEARCHPATH:=$(subst ;, ,$(PATH))
+endif
+endif
+SEARCHPATH+=$(patsubst %/,%,$(subst \,/,$(dir $(MAKE))))
+PWD:=$(strip $(wildcard $(addsuffix /pwd.exe,$(SEARCHPATH))))
+ifeq ($(PWD),)
+PWD:=$(strip $(wildcard $(addsuffix /pwd,$(SEARCHPATH))))
+ifeq ($(PWD),)
+$(error You need the GNU utils package to use this Makefile)
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=
+endif
+else
+PWD:=$(firstword $(PWD))
+SRCEXEEXT=.exe
+endif
+ifndef inUnix
+ifeq ($(OS),Windows_NT)
+inWinNT=1
+else
+ifdef OS2_SHELL
+inOS2=1
+endif
+endif
+else
+ifneq ($(findstring cygdrive,$(PATH)),)
+inCygWin=1
+endif
+endif
+ifdef inUnix
+SRCBATCHEXT=.sh
+else
+ifdef inOS2
+SRCBATCHEXT=.cmd
+else
+SRCBATCHEXT=.bat
+endif
+endif
+ifdef COMSPEC
+ifneq ($(findstring $(OS_SOURCE),$(OSNeedsComspecToRunBatch)),)
+RUNBATCH=$(COMSPEC) /C
+endif
+endif
+ifdef inUnix
+PATHSEP=/
+else
+PATHSEP:=$(subst /,\,/)
+ifdef inCygWin
+PATHSEP=/
+endif
+endif
+ifdef PWD
+BASEDIR:=$(subst \,/,$(shell $(PWD)))
+ifdef inCygWin
+ifneq ($(findstring /cygdrive/,$(BASEDIR)),)
+BASENODIR:=$(patsubst /cygdrive%,%,$(BASEDIR))
+BASEDRIVE:=$(firstword $(subst /, ,$(BASENODIR)))
+BASEDIR:=$(subst /cygdrive/$(BASEDRIVE)/,$(BASEDRIVE):/,$(BASEDIR))
+endif
+endif
+else
+BASEDIR=.
+endif
+ifdef inOS2
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO=echo
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+endif
+override DEFAULT_FPCDIR=../../..
+ifndef FPC
+ifdef PP
+FPC=$(PP)
+endif
+endif
+ifndef FPC
+FPCPROG:=$(strip $(wildcard $(addsuffix /fpc$(SRCEXEEXT),$(SEARCHPATH))))
+ifneq ($(FPCPROG),)
+FPCPROG:=$(firstword $(FPCPROG))
+ifneq ($(CPU_TARGET),)
+FPC:=$(shell $(FPCPROG) -P$(CPU_TARGET) -PB)
+else
+FPC:=$(shell $(FPCPROG) -PB)
+endif
+ifneq ($(findstring Error,$(FPC)),)
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+else
+override FPC=$(firstword $(strip $(wildcard $(addsuffix /ppc386$(SRCEXEEXT),$(SEARCHPATH)))))
+endif
+endif
+override FPC:=$(subst $(SRCEXEEXT),,$(FPC))
+override FPC:=$(subst \,/,$(FPC))$(SRCEXEEXT)
+FOUNDFPC:=$(strip $(wildcard $(FPC)))
+ifeq ($(FOUNDFPC),)
+FOUNDFPC=$(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))
+ifeq ($(FOUNDFPC),)
+$(error Compiler $(FPC) not found)
+endif
+endif
+ifndef FPC_COMPILERINFO
+FPC_COMPILERINFO:=$(shell $(FPC) -iVSPTPSOTO)
+endif
+ifndef FPC_VERSION
+FPC_VERSION:=$(word 1,$(FPC_COMPILERINFO))
+endif
+export FPC FPC_VERSION FPC_COMPILERINFO
+unexport CHECKDEPEND ALLDEPENDENCIES
+ifndef CPU_TARGET
+ifdef CPU_TARGET_DEFAULT
+CPU_TARGET=$(CPU_TARGET_DEFAULT)
+endif
+endif
+ifndef OS_TARGET
+ifdef OS_TARGET_DEFAULT
+OS_TARGET=$(OS_TARGET_DEFAULT)
+endif
+endif
+ifneq ($(words $(FPC_COMPILERINFO)),5)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTP)
+FPC_COMPILERINFO+=$(shell $(FPC) -iSO)
+FPC_COMPILERINFO+=$(shell $(FPC) -iTO)
+endif
+ifndef CPU_SOURCE
+CPU_SOURCE:=$(word 2,$(FPC_COMPILERINFO))
+endif
+ifndef CPU_TARGET
+CPU_TARGET:=$(word 3,$(FPC_COMPILERINFO))
+endif
+ifndef OS_SOURCE
+OS_SOURCE:=$(word 4,$(FPC_COMPILERINFO))
+endif
+ifndef OS_TARGET
+OS_TARGET:=$(word 5,$(FPC_COMPILERINFO))
+endif
+FULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+FULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+TARGETSUFFIX=$(OS_TARGET)
+SOURCESUFFIX=$(OS_SOURCE)
+else
+TARGETSUFFIX=$(FULL_TARGET)
+SOURCESUFFIX=$(FULL_SOURCE)
+endif
+ifneq ($(FULL_TARGET),$(FULL_SOURCE))
+CROSSCOMPILE=1
+endif
+ifeq ($(findstring makefile,$(MAKECMDGOALS)),)
+ifeq ($(findstring $(FULL_TARGET),$(MAKEFILETARGETS)),)
+$(error The Makefile doesn't support target $(FULL_TARGET), please run fpcmake first)
+endif
+endif
+ifneq ($(findstring $(OS_TARGET),$(BSDs)),)
+BSDhier=1
+endif
+ifeq ($(OS_TARGET),linux)
+linuxHier=1
+endif
+export OS_TARGET OS_SOURCE CPU_TARGET CPU_SOURCE FULL_TARGET FULL_SOURCE TARGETSUFFIX SOURCESUFFIX CROSSCOMPILE
+ifdef FPCDIR
+override FPCDIR:=$(subst \,/,$(FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+else
+override FPCDIR=wrong
+endif
+ifdef DEFAULT_FPCDIR
+ifeq ($(FPCDIR),wrong)
+override FPCDIR:=$(subst \,/,$(DEFAULT_FPCDIR))
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=wrong
+endif
+endif
+endif
+ifeq ($(FPCDIR),wrong)
+ifdef inUnix
+override FPCDIR=/usr/local/lib/fpc/$(FPC_VERSION)
+ifeq ($(wildcard $(FPCDIR)/units),)
+override FPCDIR=/usr/lib/fpc/$(FPC_VERSION)
+endif
+else
+override FPCDIR:=$(subst /$(FPC),,$(firstword $(strip $(wildcard $(addsuffix /$(FPC),$(SEARCHPATH))))))
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(FPCDIR)/..
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR:=$(BASEDIR)
+ifeq ($(wildcard $(addprefix $(FPCDIR)/,rtl units)),)
+override FPCDIR=c:/pp
+endif
+endif
+endif
+endif
+endif
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(FPCDIR)/bin/$(TARGETSUFFIX))
+endif
+ifndef BINUTILSPREFIX
+ifndef CROSSBINDIR
+ifdef CROSSCOMPILE
+BINUTILSPREFIX=$(CPU_TARGET)-$(OS_TARGET)-
+endif
+endif
+endif
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(TARGETSUFFIX))
+ifeq ($(UNITSDIR),)
+UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
+endif
+PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
+ifeq ($(FULL_TARGET),i386-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+override TARGET_PROGRAMS+=testapp
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+override TARGET_PROGRAMS+=testapp
+endif
+ifdef REQUIRE_UNITSDIR
+override UNITSDIR+=$(REQUIRE_UNITSDIR)
+endif
+ifdef REQUIRE_PACKAGESDIR
+override PACKAGESDIR+=$(REQUIRE_PACKAGESDIR)
+endif
+ifdef ZIPINSTALL
+ifneq ($(findstring $(OS_TARGET),$(UNIXs)),)
+UNIXHier=1
+endif
+else
+ifneq ($(findstring $(OS_SOURCE),$(UNIXs)),)
+UNIXHier=1
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef PREFIX
+INSTALL_PREFIX=$(PREFIX)
+endif
+endif
+ifndef INSTALL_PREFIX
+ifdef UNIXHier
+INSTALL_PREFIX=/usr/local
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=/pp
+else
+INSTALL_BASEDIR:=/$(PACKAGE_NAME)
+endif
+endif
+endif
+export INSTALL_PREFIX
+ifdef INSTALL_FPCSUBDIR
+export INSTALL_FPCSUBDIR
+endif
+ifndef DIST_DESTDIR
+DIST_DESTDIR:=$(BASEDIR)
+endif
+export DIST_DESTDIR
+ifndef COMPILER_UNITTARGETDIR
+ifdef PACKAGEDIR_MAIN
+COMPILER_UNITTARGETDIR=$(PACKAGEDIR_MAIN)/units/$(TARGETSUFFIX)
+else
+COMPILER_UNITTARGETDIR=units/$(TARGETSUFFIX)
+endif
+endif
+ifndef COMPILER_TARGETDIR
+COMPILER_TARGETDIR=.
+endif
+ifndef INSTALL_BASEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/fpc/$(FPC_VERSION)
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)/lib/$(PACKAGE_NAME)
+endif
+else
+INSTALL_BASEDIR:=$(INSTALL_PREFIX)
+endif
+endif
+ifndef INSTALL_BINDIR
+ifdef UNIXHier
+INSTALL_BINDIR:=$(INSTALL_PREFIX)/bin
+else
+INSTALL_BINDIR:=$(INSTALL_BASEDIR)/bin
+ifdef INSTALL_FPCPACKAGE
+ifdef CROSSCOMPILE
+ifdef CROSSINSTALL
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(SOURCESUFFIX)
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+else
+INSTALL_BINDIR:=$(INSTALL_BINDIR)/$(TARGETSUFFIX)
+endif
+endif
+endif
+endif
+ifndef INSTALL_UNITDIR
+INSTALL_UNITDIR:=$(INSTALL_BASEDIR)/units/$(TARGETSUFFIX)
+ifdef INSTALL_FPCPACKAGE
+ifdef PACKAGE_NAME
+INSTALL_UNITDIR:=$(INSTALL_UNITDIR)/$(PACKAGE_NAME)
+endif
+endif
+endif
+ifndef INSTALL_LIBDIR
+ifdef UNIXHier
+INSTALL_LIBDIR:=$(INSTALL_PREFIX)/lib
+else
+INSTALL_LIBDIR:=$(INSTALL_UNITDIR)
+endif
+endif
+ifndef INSTALL_SOURCEDIR
+ifdef UNIXHier
+ifdef BSDhier
+SRCPREFIXDIR=share/src
+else
+ifdef linuxHier
+SRCPREFIXDIR=share/src
+else
+SRCPREFIXDIR=src
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_PREFIX)/$(SRCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+ifdef INSTALL_FPCSUBDIR
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(INSTALL_FPCSUBDIR)/$(PACKAGE_NAME)
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source/$(PACKAGE_NAME)
+endif
+else
+INSTALL_SOURCEDIR:=$(INSTALL_BASEDIR)/source
+endif
+endif
+endif
+ifndef INSTALL_DOCDIR
+ifdef UNIXHier
+ifdef BSDhier
+DOCPREFIXDIR=share/doc
+else
+ifdef linuxHier
+DOCPREFIXDIR=share/doc
+else
+DOCPREFIXDIR=doc
+endif
+endif
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_PREFIX)/$(DOCPREFIXDIR)/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc/$(PACKAGE_NAME)
+else
+INSTALL_DOCDIR:=$(INSTALL_BASEDIR)/doc
+endif
+endif
+endif
+ifndef INSTALL_EXAMPLEDIR
+ifdef UNIXHier
+ifdef INSTALL_FPCPACKAGE
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/fpc-$(FPC_VERSION)/$(PACKAGE_NAME)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/fpc-$(FPC_VERSION)/examples/$(PACKAGE_NAME)
+endif
+endif
+else
+ifdef BSDhier
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/share/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+ifdef linuxHier
+INSTALL_EXAMPLEDIR:=$(INSTALL_DOCDIR)/examples/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_PREFIX)/doc/$(PACKAGE_NAME)-$(PACKAGE_VERSION)
+endif
+endif
+endif
+else
+ifdef INSTALL_FPCPACKAGE
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples/$(PACKAGE_NAME)
+else
+INSTALL_EXAMPLEDIR:=$(INSTALL_BASEDIR)/examples
+endif
+endif
+endif
+ifndef INSTALL_DATADIR
+INSTALL_DATADIR=$(INSTALL_BASEDIR)
+endif
+ifndef INSTALL_SHAREDDIR
+INSTALL_SHAREDDIR=$(INSTALL_PREFIX)/lib
+endif
+ifdef CROSSCOMPILE
+ifndef CROSSBINDIR
+CROSSBINDIR:=$(wildcard $(CROSSTARGETDIR)/bin/$(SOURCESUFFIX))
+ifeq ($(CROSSBINDIR),)
+CROSSBINDIR:=$(wildcard $(INSTALL_BASEDIR)/cross/$(TARGETSUFFIX)/bin/$(FULL_SOURCE))
+endif
+endif
+else
+CROSSBINDIR=
+endif
+BATCHEXT=.bat
+LOADEREXT=.as
+EXEEXT=.exe
+PPLEXT=.ppl
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.so
+SHAREDLIBPREFIX=libfp
+STATICLIBPREFIX=libp
+IMPORTLIBPREFIX=libimp
+RSTEXT=.rst
+ifeq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),go32v1)
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+OEXT=.obj
+ASMEXT=.asm
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),emx)
+BATCHEXT=.cmd
+AOUTEXT=.out
+STATICLIBPREFIX=
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=emx
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),morphos)
+EXEEXT=
+SHAREDLIBEXT=.library
+SHORTSUFFIX=mos
+endif
+ifeq ($(OS_TARGET),atari)
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+EXEEXT=.nlm
+STATICLIBPREFIX=
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+ifeq ($(OS_TARGET),darwin)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=dwn
+endif
+ifeq ($(OS_TARGET),gba)
+EXEEXT=.gba
+SHAREDLIBEXT=.so
+SHORTSUFFIX=gba
+endif
+ifeq ($(OS_TARGET),symbian)
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=symbian
+endif
+else
+ifeq ($(OS_TARGET),go32v1)
+PPUEXT=.pp1
+OEXT=.o1
+ASMEXT=.s1
+SMARTEXT=.sl1
+STATICLIBEXT=.a1
+SHAREDLIBEXT=.so1
+STATICLIBPREFIX=
+SHORTSUFFIX=v1
+endif
+ifeq ($(OS_TARGET),go32v2)
+STATICLIBPREFIX=
+SHORTSUFFIX=dos
+endif
+ifeq ($(OS_TARGET),watcom)
+STATICLIBPREFIX=
+SHORTSUFFIX=wat
+endif
+ifeq ($(OS_TARGET),linux)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=lnx
+endif
+ifeq ($(OS_TARGET),freebsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=fbs
+endif
+ifeq ($(OS_TARGET),netbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=nbs
+endif
+ifeq ($(OS_TARGET),openbsd)
+BATCHEXT=.sh
+EXEEXT=
+HASSHAREDLIB=1
+SHORTSUFFIX=obs
+endif
+ifeq ($(OS_TARGET),win32)
+PPUEXT=.ppw
+OEXT=.ow
+ASMEXT=.sw
+SMARTEXT=.slw
+STATICLIBEXT=.aw
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=w32
+endif
+ifeq ($(OS_TARGET),os2)
+BATCHEXT=.cmd
+PPUEXT=.ppo
+ASMEXT=.so2
+OEXT=.oo2
+AOUTEXT=.out
+SMARTEXT=.sl2
+STATICLIBPREFIX=
+STATICLIBEXT=.ao2
+SHAREDLIBEXT=.dll
+SHORTSUFFIX=os2
+ECHO=echo
+endif
+ifeq ($(OS_TARGET),amiga)
+EXEEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.library
+SHORTSUFFIX=amg
+endif
+ifeq ($(OS_TARGET),atari)
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=.ttp
+SHORTSUFFIX=ata
+endif
+ifeq ($(OS_TARGET),beos)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=be
+endif
+ifeq ($(OS_TARGET),solaris)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=sun
+endif
+ifeq ($(OS_TARGET),qnx)
+BATCHEXT=.sh
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+SHORTSUFFIX=qnx
+endif
+ifeq ($(OS_TARGET),netware)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nw
+endif
+ifeq ($(OS_TARGET),netwlibc)
+STATICLIBPREFIX=
+PPUEXT=.ppu
+OEXT=.o
+ASMEXT=.s
+SMARTEXT=.sl
+STATICLIBEXT=.a
+SHAREDLIBEXT=.nlm
+EXEEXT=.nlm
+SHORTSUFFIX=nwl
+endif
+ifeq ($(OS_TARGET),macos)
+BATCHEXT=
+PPUEXT=.ppu
+ASMEXT=.s
+OEXT=.o
+SMARTEXT=.sl
+STATICLIBEXT=.a
+EXEEXT=
+DEBUGSYMEXT=.xcoff
+SHORTSUFFIX=mac
+endif
+endif
+ifneq ($(findstring $(OS_SOURCE),$(LIMIT83fs)),)
+FPCMADE=fpcmade.$(SHORTSUFFIX)
+ZIPSUFFIX=$(SHORTSUFFIX)
+ZIPCROSSPREFIX=
+ZIPSOURCESUFFIX=src
+ZIPEXAMPLESUFFIX=exm
+else
+FPCMADE=fpcmade.$(TARGETSUFFIX)
+ZIPSOURCESUFFIX=.source
+ZIPEXAMPLESUFFIX=.examples
+ifdef CROSSCOMPILE
+ZIPSUFFIX=.$(SOURCESUFFIX)
+ZIPCROSSPREFIX=$(TARGETSUFFIX)-
+else
+ZIPSUFFIX=.$(TARGETSUFFIX)
+ZIPCROSSPREFIX=
+endif
+endif
+ifndef ECHO
+ECHO:=$(strip $(wildcard $(addsuffix /gecho$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO:=$(strip $(wildcard $(addsuffix /echo$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ECHO),)
+ECHO= __missing_command_ECHO
+else
+ECHO:=$(firstword $(ECHO))
+endif
+else
+ECHO:=$(firstword $(ECHO))
+endif
+endif
+export ECHO
+ifndef DATE
+DATE:=$(strip $(wildcard $(addsuffix /gdate$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE:=$(strip $(wildcard $(addsuffix /date$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(DATE),)
+DATE= __missing_command_DATE
+else
+DATE:=$(firstword $(DATE))
+endif
+else
+DATE:=$(firstword $(DATE))
+endif
+endif
+export DATE
+ifndef GINSTALL
+GINSTALL:=$(strip $(wildcard $(addsuffix /ginstall$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL:=$(strip $(wildcard $(addsuffix /install$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(GINSTALL),)
+GINSTALL= __missing_command_GINSTALL
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+else
+GINSTALL:=$(firstword $(GINSTALL))
+endif
+endif
+export GINSTALL
+ifndef CPPROG
+CPPROG:=$(strip $(wildcard $(addsuffix /cp$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(CPPROG),)
+CPPROG= __missing_command_CPPROG
+else
+CPPROG:=$(firstword $(CPPROG))
+endif
+endif
+export CPPROG
+ifndef RMPROG
+RMPROG:=$(strip $(wildcard $(addsuffix /rm$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(RMPROG),)
+RMPROG= __missing_command_RMPROG
+else
+RMPROG:=$(firstword $(RMPROG))
+endif
+endif
+export RMPROG
+ifndef MVPROG
+MVPROG:=$(strip $(wildcard $(addsuffix /mv$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MVPROG),)
+MVPROG= __missing_command_MVPROG
+else
+MVPROG:=$(firstword $(MVPROG))
+endif
+endif
+export MVPROG
+ifndef MKDIRPROG
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /gmkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG:=$(strip $(wildcard $(addsuffix /mkdir$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(MKDIRPROG),)
+MKDIRPROG= __missing_command_MKDIRPROG
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+else
+MKDIRPROG:=$(firstword $(MKDIRPROG))
+endif
+endif
+export MKDIRPROG
+ifndef ECHOREDIR
+ifndef inUnix
+ECHOREDIR=echo
+else
+ECHOREDIR=$(ECHO)
+endif
+endif
+ifndef COPY
+COPY:=$(CPPROG) -fp
+endif
+ifndef COPYTREE
+COPYTREE:=$(CPPROG) -Rfp
+endif
+ifndef MKDIRTREE
+MKDIRTREE:=$(MKDIRPROG) -p
+endif
+ifndef MOVE
+MOVE:=$(MVPROG) -f
+endif
+ifndef DEL
+DEL:=$(RMPROG) -f
+endif
+ifndef DELTREE
+DELTREE:=$(RMPROG) -rf
+endif
+ifndef INSTALL
+ifdef inUnix
+INSTALL:=$(GINSTALL) -c -m 644
+else
+INSTALL:=$(COPY)
+endif
+endif
+ifndef INSTALLEXE
+ifdef inUnix
+INSTALLEXE:=$(GINSTALL) -c -m 755
+else
+INSTALLEXE:=$(COPY)
+endif
+endif
+ifndef MKDIR
+MKDIR:=$(GINSTALL) -m 755 -d
+endif
+export ECHOREDIR COPY COPYTREE MOVE DEL DELTREE INSTALL INSTALLEXE MKDIR
+ifndef PPUMOVE
+PPUMOVE:=$(strip $(wildcard $(addsuffix /ppumove$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(PPUMOVE),)
+PPUMOVE= __missing_command_PPUMOVE
+else
+PPUMOVE:=$(firstword $(PPUMOVE))
+endif
+endif
+export PPUMOVE
+ifndef FPCMAKE
+FPCMAKE:=$(strip $(wildcard $(addsuffix /fpcmake$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(FPCMAKE),)
+FPCMAKE= __missing_command_FPCMAKE
+else
+FPCMAKE:=$(firstword $(FPCMAKE))
+endif
+endif
+export FPCMAKE
+ifndef ZIPPROG
+ZIPPROG:=$(strip $(wildcard $(addsuffix /zip$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(ZIPPROG),)
+ZIPPROG= __missing_command_ZIPPROG
+else
+ZIPPROG:=$(firstword $(ZIPPROG))
+endif
+endif
+export ZIPPROG
+ifndef TARPROG
+TARPROG:=$(strip $(wildcard $(addsuffix /gtar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG:=$(strip $(wildcard $(addsuffix /tar$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(TARPROG),)
+TARPROG= __missing_command_TARPROG
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+else
+TARPROG:=$(firstword $(TARPROG))
+endif
+endif
+export TARPROG
+ASNAME=$(BINUTILSPREFIX)as
+LDNAME=$(BINUTILSPREFIX)ld
+ARNAME=$(BINUTILSPREFIX)ar
+RCNAME=$(BINUTILSPREFIX)rc
+ifneq ($(findstring 1.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),win32)
+ifeq ($(CROSSBINDIR),)
+ASNAME=asw
+LDNAME=ldw
+ARNAME=arw
+endif
+endif
+endif
+ifndef ASPROG
+ifdef CROSSBINDIR
+ASPROG=$(CROSSBINDIR)/$(ASNAME)$(SRCEXEEXT)
+else
+ASPROG=$(ASNAME)
+endif
+endif
+ifndef LDPROG
+ifdef CROSSBINDIR
+LDPROG=$(CROSSBINDIR)/$(LDNAME)$(SRCEXEEXT)
+else
+LDPROG=$(LDNAME)
+endif
+endif
+ifndef RCPROG
+ifdef CROSSBINDIR
+RCPROG=$(CROSSBINDIR)/$(RCNAME)$(SRCEXEEXT)
+else
+RCPROG=$(RCNAME)
+endif
+endif
+ifndef ARPROG
+ifdef CROSSBINDIR
+ARPROG=$(CROSSBINDIR)/$(ARNAME)$(SRCEXEEXT)
+else
+ARPROG=$(ARNAME)
+endif
+endif
+AS=$(ASPROG)
+LD=$(LDPROG)
+RC=$(RCPROG)
+AR=$(ARPROG)
+PPAS=ppas$(SRCBATCHEXT)
+ifdef inUnix
+LDCONFIG=ldconfig
+else
+LDCONFIG=
+endif
+ifdef DATE
+DATESTR:=$(shell $(DATE) +%Y%m%d)
+else
+DATESTR=
+endif
+ifndef UPXPROG
+ifeq ($(OS_TARGET),go32v2)
+UPXPROG:=1
+endif
+ifeq ($(OS_TARGET),win32)
+UPXPROG:=1
+endif
+ifdef UPXPROG
+UPXPROG:=$(strip $(wildcard $(addsuffix /upx$(SRCEXEEXT),$(SEARCHPATH))))
+ifeq ($(UPXPROG),)
+UPXPROG=
+else
+UPXPROG:=$(firstword $(UPXPROG))
+endif
+else
+UPXPROG=
+endif
+endif
+export UPXPROG
+ZIPOPT=-9
+ZIPEXT=.zip
+ifeq ($(USETAR),bz2)
+TAROPT=vj
+TAREXT=.tar.bz2
+else
+TAROPT=vz
+TAREXT=.tar.gz
+endif
+override REQUIRE_PACKAGES=rtl fv
+ifeq ($(FULL_TARGET),i386-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-go32v2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-win32)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-os2)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-beos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-qnx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-netware)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-wdosx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-emx)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-watcom)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-netwlibc)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),i386-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-atari)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-openbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),m68k-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-amiga)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-macos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-morphos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),sparc-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),sparc-netbsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),sparc-solaris)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),sparc-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),x86_64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),x86_64-freebsd)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),x86_64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),x86_64-win64)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),x86_64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-palmos)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-wince)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-gba)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-nds)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),arm-symbian)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-linux)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-darwin)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifeq ($(FULL_TARGET),powerpc64-embedded)
+REQUIRE_PACKAGES_RTL=1
+REQUIRE_PACKAGES_FV=1
+endif
+ifdef REQUIRE_PACKAGES_RTL
+PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_RTL),)
+ifneq ($(wildcard $(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)),)
+UNITDIR_RTL=$(PACKAGEDIR_RTL)/units/$(TARGETSUFFIX)
+else
+UNITDIR_RTL=$(PACKAGEDIR_RTL)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_RTL)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_RTL) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_RTL)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_RTL=
+UNITDIR_RTL:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /rtl/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_RTL),)
+UNITDIR_RTL:=$(firstword $(UNITDIR_RTL))
+else
+UNITDIR_RTL=
+endif
+endif
+ifdef UNITDIR_RTL
+override COMPILER_UNITDIR+=$(UNITDIR_RTL)
+endif
+endif
+ifdef REQUIRE_PACKAGES_FV
+PACKAGEDIR_FV:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /fv/Makefile.fpc,$(PACKAGESDIR))))))
+ifneq ($(PACKAGEDIR_FV),)
+ifneq ($(wildcard $(PACKAGEDIR_FV)/units/$(TARGETSUFFIX)),)
+UNITDIR_FV=$(PACKAGEDIR_FV)/units/$(TARGETSUFFIX)
+else
+UNITDIR_FV=$(PACKAGEDIR_FV)
+endif
+ifdef CHECKDEPEND
+$(PACKAGEDIR_FV)/$(FPCMADE):
+ $(MAKE) -C $(PACKAGEDIR_FV) $(FPCMADE)
+override ALLDEPENDENCIES+=$(PACKAGEDIR_FV)/$(FPCMADE)
+endif
+else
+PACKAGEDIR_FV=
+UNITDIR_FV:=$(subst /Package.fpc,,$(strip $(wildcard $(addsuffix /fv/Package.fpc,$(UNITSDIR)))))
+ifneq ($(UNITDIR_FV),)
+UNITDIR_FV:=$(firstword $(UNITDIR_FV))
+else
+UNITDIR_FV=
+endif
+endif
+ifdef UNITDIR_FV
+override COMPILER_UNITDIR+=$(UNITDIR_FV)
+endif
+endif
+ifndef NOCPUDEF
+override FPCOPTDEF=$(CPU_TARGET)
+endif
+ifneq ($(OS_TARGET),$(OS_SOURCE))
+override FPCOPT+=-T$(OS_TARGET)
+endif
+ifneq ($(CPU_TARGET),$(CPU_SOURCE))
+override FPCOPT+=-P$(CPU_TARGET)
+endif
+ifeq ($(OS_SOURCE),openbsd)
+override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
+endif
+ifndef CROSSBOOTSTRAP
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-XP$(BINUTILSPREFIX)
+endif
+ifneq ($(BINUTILSPREFIX),)
+override FPCOPT+=-Xr$(RLINKPATH)
+endif
+endif
+ifdef UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(UNITDIR))
+endif
+ifdef LIBDIR
+override FPCOPT+=$(addprefix -Fl,$(LIBDIR))
+endif
+ifdef OBJDIR
+override FPCOPT+=$(addprefix -Fo,$(OBJDIR))
+endif
+ifdef INCDIR
+override FPCOPT+=$(addprefix -Fi,$(INCDIR))
+endif
+ifdef LINKSMART
+override FPCOPT+=-XX
+endif
+ifdef CREATESMART
+override FPCOPT+=-CX
+endif
+ifdef DEBUG
+override FPCOPT+=-gl
+override FPCOPTDEF+=DEBUG
+endif
+ifdef RELEASE
+ifneq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(CPU_TARGET),i386)
+FPCCPUOPT:=-OG2p3
+endif
+ifeq ($(CPU_TARGET),powerpc)
+FPCCPUOPT:=-O1r
+endif
+else
+FPCCPUOPT:=-O2
+endif
+override FPCOPT+=-Ur -Xs $(FPCCPUOPT) -n
+override FPCOPTDEF+=RELEASE
+endif
+ifdef STRIP
+override FPCOPT+=-Xs
+endif
+ifdef OPTIMIZE
+override FPCOPT+=-O2
+endif
+ifdef VERBOSE
+override FPCOPT+=-vwni
+endif
+ifdef COMPILER_OPTIONS
+override FPCOPT+=$(COMPILER_OPTIONS)
+endif
+ifdef COMPILER_UNITDIR
+override FPCOPT+=$(addprefix -Fu,$(COMPILER_UNITDIR))
+endif
+ifdef COMPILER_LIBRARYDIR
+override FPCOPT+=$(addprefix -Fl,$(COMPILER_LIBRARYDIR))
+endif
+ifdef COMPILER_OBJECTDIR
+override FPCOPT+=$(addprefix -Fo,$(COMPILER_OBJECTDIR))
+endif
+ifdef COMPILER_INCLUDEDIR
+override FPCOPT+=$(addprefix -Fi,$(COMPILER_INCLUDEDIR))
+endif
+ifdef CROSSBINDIR
+override FPCOPT+=-FD$(CROSSBINDIR)
+endif
+ifdef COMPILER_TARGETDIR
+override FPCOPT+=-FE$(COMPILER_TARGETDIR)
+ifeq ($(COMPILER_TARGETDIR),.)
+override TARGETDIRPREFIX=
+else
+override TARGETDIRPREFIX=$(COMPILER_TARGETDIR)/
+endif
+endif
+ifdef COMPILER_UNITTARGETDIR
+override FPCOPT+=-FU$(COMPILER_UNITTARGETDIR)
+ifeq ($(COMPILER_UNITTARGETDIR),.)
+override UNITTARGETDIRPREFIX=
+else
+override UNITTARGETDIRPREFIX=$(COMPILER_UNITTARGETDIR)/
+endif
+else
+ifdef COMPILER_TARGETDIR
+override COMPILER_UNITTARGETDIR=$(COMPILER_TARGETDIR)
+override UNITTARGETDIRPREFIX=$(TARGETDIRPREFIX)
+endif
+endif
+ifdef CREATESHARED
+override FPCOPT+=-Cg
+ifeq ($(CPU_TARGET),i386)
+override FPCOPT+=-Aas
+endif
+endif
+ifeq ($(findstring 2.0.,$(FPC_VERSION)),)
+ifeq ($(OS_TARGET),linux)
+ifeq ($(CPU_TARGET),x86_64)
+override FPCOPT+=-Cg
+endif
+endif
+endif
+ifdef LINKSHARED
+endif
+ifdef OPT
+override FPCOPT+=$(OPT)
+endif
+ifdef FPCOPTDEF
+override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
+endif
+ifdef CFGFILE
+override FPCOPT+=@$(CFGFILE)
+endif
+ifdef USEENV
+override FPCEXTCMD:=$(FPCOPT)
+override FPCOPT:=!FPCEXTCMD
+export FPCEXTCMD
+endif
+override AFULL_TARGET=$(CPU_TARGET)-$(OS_TARGET)
+override AFULL_SOURCE=$(CPU_SOURCE)-$(OS_SOURCE)
+ifneq ($(AFULL_TARGET),$(AFULL_SOURCE))
+override ACROSSCOMPILE=1
+endif
+ifdef ACROSSCOMPILE
+override FPCOPT+=$(CROSSOPT)
+endif
+override COMPILER:=$(FPC) $(FPCOPT)
+ifeq (,$(findstring -s ,$(COMPILER)))
+EXECPPAS=
+else
+ifeq ($(FULL_SOURCE),$(FULL_TARGET))
+ifdef RUNBATCH
+EXECPPAS:=@$(RUNBATCH) $(PPAS)
+else
+EXECPPAS:=@$(PPAS)
+endif
+endif
+endif
+.PHONY: fpc_exes
+ifndef CROSSINSTALL
+ifneq ($(TARGET_PROGRAMS),)
+override EXEFILES=$(addsuffix $(EXEEXT),$(TARGET_PROGRAMS))
+override EXEOFILES:=$(addsuffix $(OEXT),$(TARGET_PROGRAMS)) $(addprefix $(STATICLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS))) $(addprefix $(IMPORTLIBPREFIX),$(addsuffix $(STATICLIBEXT),$(TARGET_PROGRAMS)))
+override ALLTARGET+=fpc_exes
+override INSTALLEXEFILES+=$(EXEFILES)
+override CLEANEXEFILES+=$(EXEFILES) $(EXEOFILES)
+ifeq ($(OS_TARGET),os2)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+ifeq ($(OS_TARGET),emx)
+override CLEANEXEFILES+=$(addsuffix $(AOUTEXT),$(TARGET_PROGRAMS))
+endif
+endif
+endif
+fpc_exes: $(COMPILER_TARGETDIR) $(COMPILER_UNITTARGETDIR) $(EXEFILES)
+ifdef TARGET_RSTS
+override RSTFILES=$(addsuffix $(RSTEXT),$(TARGET_RSTS))
+override CLEANRSTFILES+=$(RSTFILES)
+endif
+.PHONY: fpc_all fpc_smart fpc_debug fpc_release fpc_shared
+$(FPCMADE): $(ALLDEPENDENCIES) $(ALLTARGET)
+ @$(ECHOREDIR) Compiled > $(FPCMADE)
+fpc_all: $(FPCMADE)
+fpc_smart:
+ $(MAKE) all LINKSMART=1 CREATESMART=1
+fpc_debug:
+ $(MAKE) all DEBUG=1
+fpc_release:
+ $(MAKE) all RELEASE=1
+.SUFFIXES: $(EXEEXT) $(PPUEXT) $(OEXT) .pas .lpr .dpr .pp .rc .res
+$(COMPILER_UNITTARGETDIR):
+ $(MKDIRTREE) $(COMPILER_UNITTARGETDIR)
+$(COMPILER_TARGETDIR):
+ $(MKDIRTREE) $(COMPILER_TARGETDIR)
+%$(PPUEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(PPUEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pp
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.pas
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.lpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%$(EXEEXT): %.dpr
+ $(COMPILER) $<
+ $(EXECPPAS)
+%.res: %.rc
+ windres -i $< -o $@
+vpath %.pp $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.pas $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.lpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.dpr $(COMPILER_SOURCEDIR) $(COMPILER_INCLUDEDIR)
+vpath %.inc $(COMPILER_INCLUDEDIR)
+vpath %$(OEXT) $(COMPILER_UNITTARGETDIR)
+vpath %$(PPUEXT) $(COMPILER_UNITTARGETDIR)
+.PHONY: fpc_shared
+override INSTALLTARGET+=fpc_shared_install
+ifndef SHARED_LIBVERSION
+SHARED_LIBVERSION=$(FPC_VERSION)
+endif
+ifndef SHARED_LIBNAME
+SHARED_LIBNAME=$(PACKAGE_NAME)
+endif
+ifndef SHARED_FULLNAME
+SHARED_FULLNAME=$(SHAREDLIBPREFIX)$(SHARED_LIBNAME)-$(SHARED_LIBVERSION)$(SHAREDLIBEXT)
+endif
+ifndef SHARED_LIBUNITS
+SHARED_LIBUNITS:=$(TARGET_UNITS) $(TARGET_IMPLICITUNITS)
+override SHARED_LIBUNITS:=$(filter-out $(INSTALL_BUILDUNIT),$(SHARED_LIBUNITS))
+endif
+fpc_shared:
+ifdef HASSHAREDLIB
+ $(MAKE) all CREATESHARED=1 LINKSHARED=1 CREATESMART=1
+ifneq ($(SHARED_BUILD),n)
+ $(PPUMOVE) -q $(SHARED_LIBUNITS) -i$(COMPILER_UNITTARGETDIR) -o$(SHARED_FULLNAME) -d$(COMPILER_UNITTARGETDIR)
+endif
+else
+ @$(ECHO) Shared Libraries not supported
+endif
+fpc_shared_install:
+ifneq ($(SHARED_BUILD),n)
+ifneq ($(SHARED_LIBUNITS),)
+ifneq ($(wildcard $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME)),)
+ $(INSTALL) $(COMPILER_UNITTARGETDIR)/$(SHARED_FULLNAME) $(INSTALL_SHAREDDIR)
+endif
+endif
+endif
+.PHONY: fpc_install fpc_sourceinstall fpc_exampleinstall
+ifdef INSTALL_UNITS
+override INSTALLPPUFILES+=$(addsuffix $(PPUEXT),$(INSTALL_UNITS))
+endif
+ifdef INSTALL_BUILDUNIT
+override INSTALLPPUFILES:=$(filter-out $(INSTALL_BUILDUNIT)$(PPUEXT),$(INSTALLPPUFILES))
+endif
+ifdef INSTALLPPUFILES
+override INSTALLPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(INSTALLPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(INSTALLPPUFILES)))
+ifneq ($(UNITTARGETDIRPREFIX),)
+override INSTALLPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPUFILES)))
+override INSTALLPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(notdir $(INSTALLPPULINKFILES))))
+endif
+override INSTALL_CREATEPACKAGEFPC=1
+endif
+ifdef INSTALLEXEFILES
+ifneq ($(TARGETDIRPREFIX),)
+override INSTALLEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(notdir $(INSTALLEXEFILES)))
+endif
+endif
+fpc_install: all $(INSTALLTARGET)
+ifdef INSTALLEXEFILES
+ $(MKDIR) $(INSTALL_BINDIR)
+ifdef UPXPROG
+ -$(UPXPROG) $(INSTALLEXEFILES)
+endif
+ $(INSTALLEXE) $(INSTALLEXEFILES) $(INSTALL_BINDIR)
+endif
+ifdef INSTALL_CREATEPACKAGEFPC
+ifdef FPCMAKE
+ifdef PACKAGE_VERSION
+ifneq ($(wildcard Makefile.fpc),)
+ $(FPCMAKE) -p -T$(CPU_TARGET)-$(OS_TARGET) Makefile.fpc
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) Package.fpc $(INSTALL_UNITDIR)
+endif
+endif
+endif
+endif
+ifdef INSTALLPPUFILES
+ $(MKDIR) $(INSTALL_UNITDIR)
+ $(INSTALL) $(INSTALLPPUFILES) $(INSTALL_UNITDIR)
+ifneq ($(INSTALLPPULINKFILES),)
+ $(INSTALL) $(INSTALLPPULINKFILES) $(INSTALL_UNITDIR)
+endif
+ifneq ($(wildcard $(LIB_FULLNAME)),)
+ $(MKDIR) $(INSTALL_LIBDIR)
+ $(INSTALL) $(LIB_FULLNAME) $(INSTALL_LIBDIR)
+ifdef inUnix
+ ln -sf $(LIB_FULLNAME) $(INSTALL_LIBDIR)/$(LIB_NAME)
+endif
+endif
+endif
+ifdef INSTALL_FILES
+ $(MKDIR) $(INSTALL_DATADIR)
+ $(INSTALL) $(INSTALL_FILES) $(INSTALL_DATADIR)
+endif
+fpc_sourceinstall: distclean
+ $(MKDIR) $(INSTALL_SOURCEDIR)
+ $(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
+fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
+ifdef HASEXAMPLES
+ $(MKDIR) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef EXAMPLESOURCEFILES
+ $(COPY) $(EXAMPLESOURCEFILES) $(INSTALL_EXAMPLEDIR)
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(COPYTREE) $(addsuffix /*,$(TARGET_EXAMPLEDIRS)) $(INSTALL_EXAMPLEDIR)
+endif
+.PHONY: fpc_clean fpc_cleanall fpc_distclean
+ifdef EXEFILES
+override CLEANEXEFILES:=$(addprefix $(TARGETDIRPREFIX),$(CLEANEXEFILES))
+endif
+ifdef CLEAN_UNITS
+override CLEANPPUFILES+=$(addsuffix $(PPUEXT),$(CLEAN_UNITS))
+endif
+ifdef CLEANPPUFILES
+override CLEANPPULINKFILES:=$(subst $(PPUEXT),$(OEXT),$(CLEANPPUFILES)) $(addprefix $(STATICLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES))) $(addprefix $(IMPORTLIBPREFIX),$(subst $(PPUEXT),$(STATICLIBEXT),$(CLEANPPUFILES)))
+ifdef DEBUGSYMEXT
+override CLEANPPULINKFILES+=$(subst $(PPUEXT),$(DEBUGSYMEXT),$(CLEANPPUFILES))
+endif
+override CLEANPPUFILES:=$(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPUFILES))
+override CLEANPPULINKFILES:=$(wildcard $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANPPULINKFILES)))
+endif
+fpc_clean: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+ifdef CLEAN_FILES
+ -$(DEL) $(CLEAN_FILES)
+endif
+ifdef LIB_NAME
+ -$(DEL) $(LIB_NAME) $(LIB_FULLNAME)
+endif
+ -$(DEL) $(FPCMADE) Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *$(ASMEXT) *_ppas$(BATCHEXT)
+fpc_cleanall: $(CLEANTARGET)
+ifdef CLEANEXEFILES
+ -$(DEL) $(CLEANEXEFILES)
+endif
+ifdef COMPILER_UNITTARGETDIR
+ifdef CLEANPPUFILES
+ -$(DEL) $(CLEANPPUFILES)
+endif
+ifneq ($(CLEANPPULINKFILES),)
+ -$(DEL) $(CLEANPPULINKFILES)
+endif
+ifdef CLEANRSTFILES
+ -$(DEL) $(addprefix $(UNITTARGETDIRPREFIX),$(CLEANRSTFILES))
+endif
+endif
+ -$(DELTREE) units
+ -$(DEL) *$(OEXT) *$(PPUEXT) *$(RSTEXT) *$(ASMEXT) *$(STATICLIBEXT) *$(SHAREDLIBEXT) *$(PPLEXT)
+ifneq ($(PPUEXT),.ppu)
+ -$(DEL) *.o *.ppu *.a
+endif
+ -$(DELTREE) *$(SMARTEXT)
+ -$(DEL) fpcmade.* Package.fpc $(PPAS) script.res link.res $(FPCEXTFILE) $(REDIRFILE)
+ -$(DEL) *_ppas$(BATCHEXT)
+ifdef AOUTEXT
+ -$(DEL) *$(AOUTEXT)
+endif
+ifdef DEBUGSYMEXT
+ -$(DEL) *$(DEBUGSYMEXT)
+endif
+fpc_distclean: cleanall
+.PHONY: fpc_baseinfo
+override INFORULES+=fpc_baseinfo
+fpc_baseinfo:
+ @$(ECHO)
+ @$(ECHO) == Package info ==
+ @$(ECHO) Package Name..... $(PACKAGE_NAME)
+ @$(ECHO) Package Version.. $(PACKAGE_VERSION)
+ @$(ECHO)
+ @$(ECHO) == Configuration info ==
+ @$(ECHO)
+ @$(ECHO) FPC.......... $(FPC)
+ @$(ECHO) FPC Version.. $(FPC_VERSION)
+ @$(ECHO) Source CPU... $(CPU_SOURCE)
+ @$(ECHO) Target CPU... $(CPU_TARGET)
+ @$(ECHO) Source OS.... $(OS_SOURCE)
+ @$(ECHO) Target OS.... $(OS_TARGET)
+ @$(ECHO) Full Source.. $(FULL_SOURCE)
+ @$(ECHO) Full Target.. $(FULL_TARGET)
+ @$(ECHO) SourceSuffix. $(SOURCESUFFIX)
+ @$(ECHO) TargetSuffix. $(TARGETSUFFIX)
+ @$(ECHO)
+ @$(ECHO) == Directory info ==
+ @$(ECHO)
+ @$(ECHO) Required pkgs... $(REQUIRE_PACKAGES)
+ @$(ECHO)
+ @$(ECHO) Basedir......... $(BASEDIR)
+ @$(ECHO) FPCDir.......... $(FPCDIR)
+ @$(ECHO) CrossBinDir..... $(CROSSBINDIR)
+ @$(ECHO) UnitsDir........ $(UNITSDIR)
+ @$(ECHO) PackagesDir..... $(PACKAGESDIR)
+ @$(ECHO)
+ @$(ECHO) GCC library..... $(GCCLIBDIR)
+ @$(ECHO) Other library... $(OTHERLIBDIR)
+ @$(ECHO)
+ @$(ECHO) == Tools info ==
+ @$(ECHO)
+ @$(ECHO) As........ $(AS)
+ @$(ECHO) Ld........ $(LD)
+ @$(ECHO) Ar........ $(AR)
+ @$(ECHO) Rc........ $(RC)
+ @$(ECHO)
+ @$(ECHO) Mv........ $(MVPROG)
+ @$(ECHO) Cp........ $(CPPROG)
+ @$(ECHO) Rm........ $(RMPROG)
+ @$(ECHO) GInstall.. $(GINSTALL)
+ @$(ECHO) Echo...... $(ECHO)
+ @$(ECHO) Shell..... $(SHELL)
+ @$(ECHO) Date...... $(DATE)
+ @$(ECHO) FPCMake... $(FPCMAKE)
+ @$(ECHO) PPUMove... $(PPUMOVE)
+ @$(ECHO) Upx....... $(UPXPROG)
+ @$(ECHO) Zip....... $(ZIPPROG)
+ @$(ECHO)
+ @$(ECHO) == Object info ==
+ @$(ECHO)
+ @$(ECHO) Target Loaders........ $(TARGET_LOADERS)
+ @$(ECHO) Target Units.......... $(TARGET_UNITS)
+ @$(ECHO) Target Implicit Units. $(TARGET_IMPLICITUNITS)
+ @$(ECHO) Target Programs....... $(TARGET_PROGRAMS)
+ @$(ECHO) Target Dirs........... $(TARGET_DIRS)
+ @$(ECHO) Target Examples....... $(TARGET_EXAMPLES)
+ @$(ECHO) Target ExampleDirs.... $(TARGET_EXAMPLEDIRS)
+ @$(ECHO)
+ @$(ECHO) Clean Units......... $(CLEAN_UNITS)
+ @$(ECHO) Clean Files......... $(CLEAN_FILES)
+ @$(ECHO)
+ @$(ECHO) Install Units....... $(INSTALL_UNITS)
+ @$(ECHO) Install Files....... $(INSTALL_FILES)
+ @$(ECHO)
+ @$(ECHO) == Install info ==
+ @$(ECHO)
+ @$(ECHO) DateStr.............. $(DATESTR)
+ @$(ECHO) ZipName.............. $(ZIPNAME)
+ @$(ECHO) ZipPrefix............ $(ZIPPREFIX)
+ @$(ECHO) ZipCrossPrefix....... $(ZIPCROSSPREFIX)
+ @$(ECHO) ZipSuffix............ $(ZIPSUFFIX)
+ @$(ECHO) FullZipName.......... $(FULLZIPNAME)
+ @$(ECHO) Install FPC Package.. $(INSTALL_FPCPACKAGE)
+ @$(ECHO)
+ @$(ECHO) Install base dir..... $(INSTALL_BASEDIR)
+ @$(ECHO) Install binary dir... $(INSTALL_BINDIR)
+ @$(ECHO) Install library dir.. $(INSTALL_LIBDIR)
+ @$(ECHO) Install units dir.... $(INSTALL_UNITDIR)
+ @$(ECHO) Install source dir... $(INSTALL_SOURCEDIR)
+ @$(ECHO) Install doc dir...... $(INSTALL_DOCDIR)
+ @$(ECHO) Install example dir.. $(INSTALL_EXAMPLEDIR)
+ @$(ECHO) Install data dir..... $(INSTALL_DATADIR)
+ @$(ECHO)
+ @$(ECHO) Dist destination dir. $(DIST_DESTDIR)
+ @$(ECHO) Dist zip name........ $(DIST_ZIPNAME)
+ @$(ECHO)
+.PHONY: fpc_info
+fpc_info: $(INFORULES)
+.PHONY: fpc_makefile fpc_makefiles fpc_makefile_sub1 fpc_makefile_sub2 \
+ fpc_makefile_dirs
+fpc_makefile:
+ $(FPCMAKE) -w -T$(OS_TARGET) Makefile.fpc
+fpc_makefile_sub1:
+ifdef TARGET_DIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_DIRS))
+endif
+ifdef TARGET_EXAMPLEDIRS
+ $(FPCMAKE) -w -T$(OS_TARGET) $(addsuffix /Makefile.fpc,$(TARGET_EXAMPLEDIRS))
+endif
+fpc_makefile_sub2: $(addsuffix _makefile_dirs,$(TARGET_DIRS) $(TARGET_EXAMPLEDIRS))
+fpc_makefile_dirs: fpc_makefile_sub1 fpc_makefile_sub2
+fpc_makefiles: fpc_makefile fpc_makefile_dirs
+all: fpc_all
+debug: fpc_debug
+smart: fpc_smart
+release: fpc_release
+units: fpc_units
+examples:
+shared: fpc_shared
+install: fpc_install
+sourceinstall: fpc_sourceinstall
+exampleinstall: fpc_exampleinstall
+distinstall:
+zipinstall:
+zipsourceinstall:
+zipexampleinstall:
+zipdistinstall:
+clean: fpc_clean
+distclean: fpc_distclean
+cleanall: fpc_cleanall
+info: fpc_info
+makefiles: fpc_makefiles
+.PHONY: all debug smart release units examples shared install sourceinstall exampleinstall distinstall zipinstall zipsourceinstall zipexampleinstall zipdistinstall clean distclean cleanall info makefiles
+ifneq ($(wildcard fpcmake.loc),)
+include fpcmake.loc
+endif
diff --git a/packages/fv/examples/Makefile.fpc b/packages/fv/examples/Makefile.fpc
new file mode 100644
index 0000000000..08c7f85529
--- /dev/null
+++ b/packages/fv/examples/Makefile.fpc
@@ -0,0 +1,12 @@
+#
+# Makefile.fpc for Free Vision Test/Examples
+#
+
+[target]
+programs=testapp
+
+[require]
+packages=fv
+
+[default]
+fpcdir=../../..
diff --git a/packages/fv/examples/platform.inc b/packages/fv/examples/platform.inc
new file mode 100644
index 0000000000..00cc361ec3
--- /dev/null
+++ b/packages/fv/examples/platform.inc
@@ -0,0 +1,369 @@
+{***************[ PLATFORM INCLUDE UNIT ]******************}
+{ }
+{ System independent INCLUDE file to sort PLATFORMS }
+{ }
+{ Parts Copyright (c) 1997 by Balazs Scheidler }
+{ bazsi@tas.vein.hu }
+{ }
+{ Parts Copyright (c) 1999, 2000 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@projectent.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ - C'T patch to BP (16 Bit) }
+{ LINUX - FPC 0.9912+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Who Fix }
+{ ------- -------- --- ---------------------------- }
+{ 0.1 02 Jul 97 Bazsi Initial implementation }
+{ 0.2 28 Aug 97 LdB Fixed OS2 platform sort }
+{ 0.3 29 Aug 97 LdB Added assembler type changes }
+{ 0.4 29 Aug 97 LdB OS_DOS removed from WINDOWS }
+{ 0.5 23 Oct 97 LdB Delphi & speed compilers }
+{ 0.6 05 May 98 LdB Virtual Pascal 2.0 added }
+{ 0.7 19 May 98 LdB Delphi 2/3 definitions added }
+{ 0.8 06 Aug 98 CEC FPC only support fixed WIN32 }
+{ 0.9 10 Aug 98 LdB BP_VMTLink def/Undef added }
+{ 1.0 27 Aug 98 LdB Atari, Mac etc not undef dos }
+{ 1.1 25 Oct 98 PfV Delphi 4 definitions added }
+{ 1.2 06 Jun 99 LdB Sybil 2.0 support added }
+{ 1.3 13 Jun 99 LdB Sybil 2.0 undef BP_VMT link }
+{ 1.31 03 Nov 99 LdB FPC windows defines WIN32 }
+{ 1.32 04 Nov 99 LdB Delphi 5 definitions added }
+{ 1.33 16 Oct 00 LdB WIN32/WIN16 defines added }
+{**********************************************************}
+
+{ ****************************************************************************
+
+ This include file defines some conditional defines to allow us to select
+ the compiler/platform/target in a consequent way.
+
+ OS_XXXX The operating system used (XXXX may be one of:
+ DOS, OS2, Linux, Windows, Go32)
+ PPC_XXXX The compiler used: BP, FPK, Virtual, Speed
+ BIT_XX The number of bits of the target platform: 16 or 32
+ PROC_XXXX The mode of the target processor (Real or Protected)
+ This shouldn't be used, except for i386 specific parts.
+ ASM_XXXX This is the assembler type: BP, ISO-ANSI, FPK
+
+ ****************************************************************************
+
+ This is how the IFDEF and UNDEF statements below should translate.
+
+
+ PLATFORM SYSTEM COMPILER COMP ID CPU MODE BITS ASSEMBLER
+ -------- ------ -------- ------- -------- ---- ---------
+
+ DOS OS_DOS BP/TP7 PPC_BP PROC_Real BIT_16 ASM_BP
+
+ DPMI OS_DOS BP/TP7 PPC_BP PROC_Protected BIT_16 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+
+ LINUX OS_LINUX FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+
+ WINDOWS OS_WINDOWS BP/TP7 PPC_BP PROC_Protected BIT_16 ASM_BP
+ DELPHI PPC_DELPHI PROC_Protected BIT_16 ASM_BP
+ DELPHI2 PPC_DELPHI2 PROC_Protected BIT_16 ASM_BP
+
+ WIN95/NT OS_WINDOWS DELPHI2 PPC_DELPHI2 PROC_Protected BIT_32 ASM_BP
+ DELPHI3 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ DELPHI4 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ DELPHI5 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ VIRTUAL PPC_VIRTUAL PROC_Protected BIT 32 ASM_BP
+ SYBIL2 PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+
+ OS2 OS_OS2 BPOS2 PPC_BPOS2 PROC_Protected BIT_16 ASM_BP
+ VIRTUAL PPC_VIRTUAL PROC_Protected BIT_32 ASM_BP
+ SPEED PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ SYBIL2 PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+ ****************************************************************************}
+{****************************************************************************
+
+FOR ALL COMPILERS BP_VMTLink defined but FPC and Delphi3/Delphi4 undefine it
+
+ ****************************************************************************}
+{****************************************************************************
+
+FOR FPC THESE ARE THE TRANSLATIONS
+
+ PLATFORM SYSTEM COMPILER HANDLE SIZE ASM CPU
+ -------- ------ -------- ----------- ---- ---
+
+ DOS OS_DOS,OS_GO32 FPC 32-bit AT&T CPU86
+
+ WIN32 OS_WINDOWS FPC 32-bit AT&T ----
+
+ LINUX OS_LINUX FPC 32-bit AT&T ----
+
+ OS2 OS_OS2 FPC ????? AT&T CPU86
+
+ ATARI OS_ATARI FPC 32-bit Internal CPU68
+
+ MACOS OS_MAC FPC ????? Internal CPU68
+
+ AMIGA OS_AMIGA FPC 32-bit Internal CPU68
+
+ ****************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ Initial assume BORLAND 16 BIT DOS COMPILER - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$DEFINE OS_DOS}
+{$DEFINE PROC_Real}
+{$DEFINE BIT_16}
+{$DEFINE PPC_BP}
+{$DEFINE ASM_BP}
+{$DEFINE BP_VMTLink}
+{$DEFINE CPU86}
+
+{---------------------------------------------------------------------------}
+{ BORLAND 16 BIT DPMI changes protected mode - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF DPMI}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC 32 BIT COMPILER changes ASM, 32 bits etc - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF FPC}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_FPC}
+ {$UNDEF ASM_BP}
+ {$DEFINE ASM_FPC}
+ {$UNDEF BP_VMTLink}
+ {$DEFINE Use_API}
+ {$DEFINE NO_WINDOW}
+{$ENDIF}
+
+{$IFDEF NoAPI}
+{$UNDEF Use_API}
+{$UNDEF NO_WINDOW}
+{$ENDIF UseAPI}
+
+
+{---------------------------------------------------------------------------}
+{ FPC LINUX COMPILER changes operating system - Updated 27Aug98 LdB }
+{ Note: Other linux compilers would need to change other details }
+{---------------------------------------------------------------------------}
+{$IFDEF LINUX}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_LINUX}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC GO32V2 COMPILER changes operating system - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF GO32V2}
+ {$DEFINE OS_GO32}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ 32 BIT WINDOWS COMPILERS changes bit size - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF WIN32}
+ {$IFNDEF WINDOWS}
+ {$DEFINE WINDOWS}
+ {$ENDIF}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ WINDOWS COMPILERS change op system and proc mode - Updated 03Nov99 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF WINDOWS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_WINDOWS}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$IFDEF FPC}
+ {$DEFINE WIN32}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI1 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER80}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI2 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER90}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI2}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI3 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER100}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI4 COMPILER changes compiler type - Updated 25Oct98 pfv }
+{---------------------------------------------------------------------------}
+{$IFDEF VER120}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$DEFINE PPC_DELPHI4}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI5 COMPILER changes compiler type - Updated 04Nov99 pfv }
+{---------------------------------------------------------------------------}
+{$IFDEF VER130}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$DEFINE PPC_DELPHI4}
+ {$DEFINE PPC_DELPHI5}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ OS2 COMPILERS change compiler type and mode - Updated 27Aug98 LdB }
+{ Note: Assumes BPOS2 16BIT OS2 patch except for FPC which undefines this }
+{---------------------------------------------------------------------------}
+{$IFDEF OS2}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_OS2}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_BPOS2}
+ {$IFDEF FPC}
+ {$UNDEF PPC_BPOS2}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ VIRTUAL PASCAL changes compiler type/32 bit - Updated 27Aug98 LdB }
+{ Note: VP2 can compile win 32 code so changes op system as needed }
+{---------------------------------------------------------------------------}
+{$IFDEF VirtualPascal}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$IFDEF PPC_BPOS2}
+ {$UNDEF PPC_BPOS2}
+ {$ENDIF}
+ {$DEFINE PPC_VIRTUAL}
+ {$IFDEF WIN32}
+ {$UNDEF PPC_BP}
+ {$UNDEF OS_OS2}
+ {$DEFINE OS_WINDOWS}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ SPEED COMPILER changes compiler type/32 bit - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF Speed}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$UNDEF PPC_BPOS2}
+ {$DEFINE PPC_SPEED}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC AMIGA COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF AMIGA}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_AMIGA}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC ATARI COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF ATARI}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_ATARI}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC MAC COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF MACOS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_MAC}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF OS_DOS}
+ {$DEFINE NO_WINDOW}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ WIN16 AND WIN32 set if in windows - Updated 16Oct2000 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF OS_WINDOWS} { WINDOWS SYSTEM }
+ {$IFDEF BIT_16}
+ {$DEFINE WIN16} { 16 BIT WINDOWS }
+ {$ENDIF}
+ {$IFDEF BIT_32}
+ {$DEFINE WIN32} { 32 BIT WINDOWS }
+ {$ENDIF}
+{$ENDIF}
+
+
+
diff --git a/packages/fv/examples/testapp.lpi b/packages/fv/examples/testapp.lpi
new file mode 100644
index 0000000000..db391bbc2a
--- /dev/null
+++ b/packages/fv/examples/testapp.lpi
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<CONFIG>
+ <ProjectOptions>
+ <PathDelim Value="\"/>
+ <Version Value="5"/>
+ <General>
+ <Flags>
+ <MainUnitHasUsesSectionForAllUnits Value="False"/>
+ <MainUnitHasCreateFormStatements Value="False"/>
+ <MainUnitHasTitleStatement Value="False"/>
+ </Flags>
+ <MainUnit Value="0"/>
+ <IconPath Value="./"/>
+ <TargetFileExt Value=".exe"/>
+ <ActiveEditorIndexAtStart Value="0"/>
+ </General>
+ <LazDoc Paths=""/>
+ <PublishOptions>
+ <Version Value="2"/>
+ <IgnoreBinaries Value="False"/>
+ <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+ <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
+ </local>
+ </RunParams>
+ <Units Count="1">
+ <Unit0>
+ <Filename Value="testapp.pas"/>
+ <IsPartOfProject Value="True"/>
+ <UnitName Value="testapp"/>
+ <CursorPos X="1" Y="1"/>
+ <TopLine Value="1"/>
+ <EditorIndex Value="0"/>
+ <UsageCount Value="20"/>
+ <Loaded Value="True"/>
+ </Unit0>
+ </Units>
+ <JumpHistory Count="0" HistoryIndex="-1"/>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="5"/>
+ <PathDelim Value="\"/>
+ <SearchPaths>
+ <OtherUnitFiles Value="..\"/>
+ </SearchPaths>
+ <CodeGeneration>
+ <Generate Value="Faster"/>
+ </CodeGeneration>
+ <Other>
+ <CompilerPath Value="$(CompPath)"/>
+ </Other>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="2">
+ <Item1>
+ <Name Value="ECodetoolError"/>
+ </Item1>
+ <Item2>
+ <Name Value="EFOpenError"/>
+ </Item2>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
diff --git a/packages/fv/examples/testapp.pas b/packages/fv/examples/testapp.pas
new file mode 100644
index 0000000000..8d4546db38
--- /dev/null
+++ b/packages/fv/examples/testapp.pas
@@ -0,0 +1,468 @@
+PROGRAM testapp;
+
+{ $UNDEF OS2PM}
+
+{$IFDEF OS2PM}
+ {&PMTYPE PM} { FULL GUI MODE }
+{$ENDIF OS2PM}
+
+{ ******************************* REMARK ****************************** }
+{ This is a basic test program to test the app framework. In use will }
+{ be menus, statuslines, windows, dialogs, scrollbars, statictext, }
+{ radiobuttons, check boxes, list boxes and input lines. }
+{ }
+{ Working compilers: }
+{ WINDOWS BPW, VP2, Delphi1, FPC WIN (0.9912) }
+{ DOS has draw bugs but works for BP and FPC DOS (GO32V2) }
+{ OS2 dows not work still some PM bits to do }
+{ }
+{ Not working: }
+{ Delphi3, Delphi5 (sus 4) will compile but Tgroup.ForEach etc U/S. }
+{ Sybil2 Win32 should work but to big for demo mode so unsure! }
+{ }
+{ Special things to try out: }
+{ Check out the standard windows minimize etc icons. }
+{ }
+{ }
+{ Comments: }
+{ There is alot that may seem more complex than it needs to but }
+{ I have much more elaborate objects operating such as bitmaps, }
+{ bitmap buttons, percentage bars etc and they need these hooks. }
+{ Basically the intention is to be able to port existing TV apps }
+{ as a start point and then start to optimize and use the new }
+{ GUI specific objects. I will try to get some documentation }
+{ done on how everything works because some things are hard to }
+{ follow in windows. }
+{ ****************************** END REMARK *** Leon de Boer, 06Nov99 * }
+
+{$I Platform.inc}
+ USES
+{$IFDEF OS2PM}
+ {$IFDEF OS_OS2} Os2Def, os2PmApi, {$ENDIF}
+{$ENDIF OS2PM}
+ Objects, Drivers, Views, Editors, Menus, Dialogs, App, { Standard GFV units }
+ FVConsts,
+ {$ifdef TEST}
+ AsciiTab,
+ {$endif TEST}
+ {$ifdef DEBUG}
+ Gfvgraph,
+ {$endif DEBUG}
+ Gadgets, TimedDlg, MsgBox, StdDlg;
+
+
+CONST cmAppToolbar = 1000;
+ cmWindow1 = 1001;
+ cmWindow2 = 1002;
+ cmWindow3 = 1003;
+ cmTimedBox = 1004;
+ cmAscii = 1010;
+ cmCloseWindow1 = 1101;
+ cmCloseWindow2 = 1102;
+ cmCloseWindow3 = 1103;
+
+
+{---------------------------------------------------------------------------}
+{ TTestAppp OBJECT - STANDARD APPLICATION WITH MENU }
+{---------------------------------------------------------------------------}
+TYPE
+ PTVDemo = ^TTVDemo;
+
+ { TTVDemo }
+
+ TTVDemo = OBJECT (TApplication)
+ ClipboardWindow: PEditWindow;
+ Clock: PClockView;
+ Heap: PHeapView;
+ P1,P2,P3 : PGroup;
+ {$ifdef TEST}
+ ASCIIChart : PAsciiChart;
+ {$endif TEST}
+ CONSTRUCTOR Init;
+ PROCEDURE Idle; Virtual;
+ PROCEDURE HandleEvent(var Event : TEvent);virtual;
+ PROCEDURE InitMenuBar; Virtual;
+ PROCEDURE InitDeskTop; Virtual;
+ PROCEDURE InitStatusLine; Virtual;
+ PROCEDURE Window1;
+ PROCEDURE Window2;
+ PROCEDURE Window3;
+ PROCEDURE TimedBox;
+ PROCEDURE AsciiWindow;
+ PROCEDURE ShowAboutBox;
+ PROCEDURE NewEditWindow;
+ PROCEDURE OpenFile;
+ PROCEDURE CloseWindow(var P : PGroup);
+ End;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TTvDemo OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+CONSTRUCTOR TTvDemo.Init;
+VAR R: TRect;
+BEGIN
+ EditorDialog := @StdEditorDialog;
+ Inherited Init;
+ { Initialize demo gadgets }
+
+ GetExtent(R);
+ R.A.X := R.B.X - 9; R.B.Y := R.A.Y + 1;
+ Clock := New(PClockView, Init(R));
+ Insert(Clock);
+
+ GetExtent(R);
+ ClipboardWindow := New(PEditWindow, Init(R, '', wnNoNumber));
+ if ValidView(ClipboardWindow) <> nil then
+ begin
+ ClipboardWindow^.Hide;
+ ClipboardWindow^.Editor^.CanUndo := False;
+ InsertWindow(ClipboardWindow);
+ Clipboard := ClipboardWindow^.Editor;
+ end;
+END;
+
+procedure TTVDemo.Idle;
+
+function IsTileable(P: PView): Boolean; far;
+begin
+ IsTileable := (P^.Options and ofTileable <> 0) and
+ (P^.State and sfVisible <> 0);
+end;
+
+{$ifdef DEBUG}
+Var
+ WasSet : boolean;
+{$endif DEBUG}
+begin
+ inherited Idle;
+{$ifdef DEBUG}
+ if WriteDebugInfo then
+ begin
+ WasSet:=true;
+ WriteDebugInfo:=false;
+ end
+ else
+ WasSet:=false;
+ if WriteDebugInfo then
+{$endif DEBUG}
+ Clock^.Update;
+ Heap^.Update;
+{$ifdef DEBUG}
+ if WasSet then
+ WriteDebugInfo:=true;
+{$endif DEBUG}
+ if Desktop^.FirstThat(@IsTileable) <> nil then
+ EnableCommands([cmTile, cmCascade])
+ else
+ DisableCommands([cmTile, cmCascade]);
+end;
+
+PROCEDURE TTVDemo.HandleEvent(var Event : TEvent);
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evCommand) Then Begin
+ Case Event.Command Of
+ cmClipBoard:
+ begin
+ ClipboardWindow^.Select;
+ ClipboardWindow^.Show;
+ end;
+ cmNew : NewEditWindow;
+ cmOpen : OpenFile;
+ cmWindow1 : Window1;
+ cmWindow2 : Window2;
+ cmWindow3 : Window3;
+ cmTimedBox: TimedBox;
+ cmAscii : AsciiWindow;
+ cmCloseWindow1 : CloseWindow(P1);
+ cmCloseWindow2 : CloseWindow(P2);
+ cmCloseWindow3 : CloseWindow(P3);
+ cmAbout: ShowAboutBox;
+ Else Exit; { Unhandled exit }
+ End;
+ End;
+ ClearEvent(Event);
+END;
+
+{--TTvDemo------------------------------------------------------------------}
+{ InitMenuBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TTVDemo.InitMenuBar;
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get view extents }
+ R.B.Y := R.A.Y + 1; { One line high }
+ MenuBar := New(PMenuBar, Init(R, NewMenu(
+ NewSubMenu('~F~ile', 0, NewMenu(
+ StdFileMenuItems(Nil)), { Standard file menu }
+ NewSubMenu('~E~dit', 0, NewMenu(
+ StdEditMenuItems(
+ NewLine(
+ NewItem('~V~iew Clipboard', '', kbNoKey, cmClipboard, hcNoContext,
+ nil)))), { Standard edit menu plus view clipboard}
+ NewSubMenu('~T~est', 0, NewMenu(
+ NewItem('~A~scii Chart','',kbNoKey,cmAscii,hcNoContext,
+ NewItem('Window ~1~','',kbNoKey,cmWindow1,hcNoContext,
+ NewItem('Window ~2~','',kbNoKey,cmWindow2,hcNoContext,
+ NewItem('Window ~3~','',kbNoKey,cmWindow3,hcNoContext,
+ NewItem('~T~imed Box','',kbNoKey,cmTimedBox,hcNoContext,
+ NewItem('Close Window 1','',kbNoKey,cmCloseWindow1,hcNoContext,
+ NewItem('Close Window 2','',kbNoKey,cmCloseWindow2,hcNoContext,
+ NewItem('Close Window 3','',kbNoKey,cmCloseWindow3,hcNoContext,
+ Nil))))))))),
+ NewSubMenu('~W~indow', 0, NewMenu(
+ StdWindowMenuItems(Nil)), { Standard window menu }
+ NewSubMenu('~H~elp', hcNoContext, NewMenu(
+ NewItem('~A~bout...','',kbNoKey,cmAbout,hcNoContext,
+ nil)),
+ nil))))) //end NewSubMenus
+ ))); //end MenuBar
+END;
+
+{--TTvDemo------------------------------------------------------------------}
+{ InitDesktop -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TTvDemo.InitDesktop;
+VAR R: TRect; {ToolBar: PToolBar;}
+BEGIN
+ GetExtent(R); { Get app extents }
+ Inc(R.A.Y); { Adjust top down }
+ Dec(R.B.Y); { Adjust bottom up }
+(* ToolBar := New(PToolBar, Init(R.A.X*FontWidth,
+ R.A.Y*FontHeight, (R.B.X-R.A.X)*FontWidth, 20,
+ cmAppToolBar));
+ If (ToolBar <> Nil) Then Begin
+ R.A.X := R.A.X*FontWidth;
+ R.A.Y := R.A.Y*FontHeight + 25;
+ R.B.X := -R.B.X*FontWidth;
+ R.B.Y := -R.B.Y*Fontheight;
+ ToolBar^.AddTool(NewToolEntry(cmQuit, True,
+ '20X20EXIT', 'ToolBar.Res'));
+ ToolBar^.AddTool(NewToolEntry(cmNew, True,
+ '20X20NEW', 'ToolBar.Res'));
+ ToolBar^.AddTool(NewToolEntry(cmOpen, True,
+ '20X20LOAD', 'ToolBar.Res'));
+ Insert(ToolBar);
+ End;*)
+ Desktop := New(PDeskTop, Init(R));
+END;
+
+procedure TTVDemo.InitStatusLine;
+var
+ R: TRect;
+begin
+ GetExtent(R);
+ R.A.Y := R.B.Y - 1;
+ R.B.X := R.B.X - 12;
+ New(StatusLine,
+ Init(R,
+ NewStatusDef(0, $EFFF,
+ NewStatusKey('~F3~ Open', kbF3, cmOpen,
+ NewStatusKey('~F4~ New', kbF4, cmNew,
+ NewStatusKey('~Alt+F3~ Close', kbAltF3, cmClose,
+ StdStatusKeys(nil
+ )))),nil
+ )
+ )
+ );
+
+ GetExtent(R);
+ R.A.X := R.B.X - 12; R.A.Y := R.B.Y - 1;
+ Heap := New(PHeapView, Init(R));
+ Insert(Heap);
+end;
+
+PROCEDURE TTvDemo.Window1;
+VAR R: TRect; P: PGroup;
+BEGIN
+ { Create a basic window with static text and radio }
+ { buttons. The buttons should be orange and white }
+ R.Assign(5, 1, 35, 16); { Assign area }
+ P := New(PWindow, Init(R, 'TEST WINDOW 1', 1)); { Create a window }
+ If (P <> Nil) Then Begin { Window valid }
+ R.Assign(5, 5, 20, 6); { Assign area }
+ P^.Insert(New(PInputLine, Init(R, 30)));
+ R.Assign(5, 8, 20, 9); { Assign area }
+ P^.Insert(New(PRadioButtons, Init(R,
+ NewSItem('Test',
+ NewSITem('Item 2', Nil))))); { Red radio button }
+ R.Assign(5, 10, 28, 11); { Assign area }
+ P^.Insert(New(PStaticText, Init(R,
+ 'SOME STATIC TEXT'))); { Insert static text }
+ End;
+ Desktop^.Insert(P); { Insert into desktop }
+ P1:=P;
+END;
+
+PROCEDURE TTvDemo.AsciiWindow;
+begin
+{$ifdef TEST}
+ if ASCIIChart=nil then
+ begin
+ New(ASCIIChart, Init);
+ Desktop^.Insert(ASCIIChart);
+ end
+ else
+ ASCIIChart^.Focus;
+{$endif TEST}
+end;
+
+PROCEDURE TTVDemo.ShowAboutBox;
+begin
+ MessageBox(#3'Free Vision TUI Framework'#13 +
+ #3'Test/Demo Application'#13+
+ #3'(www.freepascal.org)',
+ nil, mfInformation or mfOKButton);
+end;
+
+PROCEDURE TTVDemo.NewEditWindow;
+var
+ R: TRect;
+begin
+ R.Assign(0, 0, 60, 20);
+ InsertWindow(New(PEditWindow, Init(R, '', wnNoNumber)));
+end;
+
+PROCEDURE TTVDemo.OpenFile;
+var
+ R: TRect;
+ FileDialog: PFileDialog;
+ FileName: FNameStr;
+const
+ FDOptions: Word = fdOKButton or fdOpenButton;
+begin
+ FileName := '*.*';
+ New(FileDialog, Init(FileName, 'Open file', '~F~ile name', FDOptions, 1));
+ if ExecuteDialog(FileDialog, @FileName) <> cmCancel then
+ begin
+ R.Assign(0, 0, 75, 20);
+ InsertWindow(New(PEditWindow, Init(R, FileName, wnNoNumber)));
+ end;
+end;
+
+PROCEDURE TTvDemo.TimedBox;
+var
+ X: longint;
+ S: string;
+begin
+ X := TimedMessageBox ('Everything OK?', nil, mfConfirmation or mfOKCancel, 10);
+ case X of
+ cmCancel: MessageBox ('cmCancel', nil, mfOKButton);
+ cmOK: MessageBox ('cmOK', nil, mfOKButton);
+ else
+ begin
+ Str (X, S);
+ MessageBox (S, nil, mfOKButton);
+ end;
+ end;
+end;
+
+PROCEDURE TTvDemo.CloseWindow(var P : PGroup);
+BEGIN
+ If Assigned(P) then
+ BEGIN
+ Desktop^.Delete(P);
+ Dispose(P,Done);
+ P:=Nil;
+ END;
+END;
+
+PROCEDURE TTvDemo.Window2;
+VAR R: TRect; P: PGroup;
+BEGIN
+ { Create a basic window with check boxes. The }
+ { check boxes should be orange and white }
+ R.Assign(15, 3, 45, 18); { Assign area }
+ P := New(PWindow, Init(R, 'TEST WINDOW 2', 2)); { Create window 2 }
+ If (P <> Nil) Then Begin { Window valid }
+ R.Assign(5, 5, 20, 7); { Assign area }
+ P^.Insert(New(PCheckBoxes, Init(R,
+ NewSItem('Test check',
+ NewSITem('Item 2', Nil))))); { Create check box }
+ End;
+ Desktop^.Insert(P); { Insert into desktop }
+ P2:=P;
+END;
+
+PROCEDURE TTvDemo.Window3;
+VAR R: TRect; P: PGroup; B: PScrollBar;
+ List: PStrCollection; Lb: PListBox;
+BEGIN
+ { Create a basic dialog box. In it are buttons, }
+ { list boxes, scrollbars, inputlines, checkboxes }
+ R.Assign(32, 2, 77, 18); { Assign screen area }
+ P := New(PDialog, Init(R, 'TEST DIALOG')); { Create dialog }
+ If (P <> Nil) Then Begin { Dialog valid }
+ R.Assign(5, 5, 20, 7); { Allocate area }
+ P^.Insert(New(PCheckBoxes, Init(R,
+ NewSItem('Test',
+ NewSITem('Item 2', Nil))))); { Insert check box }
+ R.Assign(5, 2, 20, 3); { Assign area }
+ B := New(PScrollBar, Init(R)); { Insert scroll bar }
+ If (B <> Nil) Then Begin { Scrollbar valid }
+ B^.SetRange(0, 100); { Set scrollbar range }
+ B^.SetValue(50); { Set position }
+ P^.Insert(B); { Insert scrollbar }
+ End;
+ R.Assign(5, 10, 20, 11); { Assign area }
+ P^.Insert(New(PInputLine, Init(R, 60))); { Create input line }
+ R.Assign(5, 13, 20, 14); { Assign area }
+ P^.Insert(New(PInputLine, Init(R, 60))); { Create input line }
+ R.Assign(40, 8, 41, 14); { Assign area }
+ B := New(PScrollBar, Init(R)); { Create scrollbar }
+ P^.Insert(B); { Insert scrollbar }
+ R.Assign(25, 8, 40, 14); { Assign area }
+ Lb := New(PListBox, Init(R, 1, B)); { Create listbox }
+ P^.Insert(Lb); { Insert listbox }
+ List := New(PStrCollection, Init(10, 5)); { Create string list }
+ List^.AtInsert(0, NewStr('Zebra')); { Insert text }
+ List^.AtInsert(1, NewStr('Apple')); { Insert text }
+ List^.AtInsert(2, NewStr('Third')); { Insert text }
+ List^.AtInsert(3, NewStr('Peach')); { Insert text }
+ List^.AtInsert(4, NewStr('Rabbit')); { Insert text }
+ List^.AtInsert(5, NewStr('Item six')); { Insert text }
+ List^.AtInsert(6, NewStr('Jaguar')); { Insert text }
+ List^.AtInsert(7, NewStr('Melon')); { Insert text }
+ List^.AtInsert(8, NewStr('Ninth')); { Insert text }
+ List^.AtInsert(9, NewStr('Last item')); { Insert text }
+ Lb^.Newlist(List); { Give list to listbox }
+ R.Assign(30, 2, 40, 4); { Assign area }
+ P^.Insert(New(PButton, Init(R, '~O~k', 100, bfGrabFocus)));{ Create okay button }
+ R.Assign(30, 15, 40, 17); { Assign area }
+ Desktop^.Insert(P); { Insert dialog }
+ P3:=P;
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MAIN PROGRAM START }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+VAR I: Integer; R: TRect; P: PGroup; MyApp: TTvDemo;
+{$IFDEF OS2PM}
+ {$IFDEF OS_OS2} Message: QMSg; Event: TEvent; {$ENDIF}
+{$ENDIF OS2PM}
+BEGIN
+ (*SystemPalette := CreateRGBPalette(256); { Create palette }
+ For I := 0 To 15 Do Begin
+ GetSystemRGBEntry(I, RGB); { Get palette entry }
+ AddToRGBPalette(RGB, SystemPalette); { Add entry to palette }
+ End;*)
+
+ MyApp.Init; { Initialize app }
+ MyApp.Run; { Run the app }
+{$IFDEF OS2PM}
+ {$IFDEF OS_OS2}
+ while (MyApp.EndState = 0)
+ AND WinGetMsg(Anchor, Message, 0, 0, 0) Do Begin
+ WinDispatchMsg(Anchor, Message);
+ NextQueuedEvent(Event);
+ If (event.What <> evNothing)
+ Then MyApp.handleEvent(Event);
+ End;
+ {$ENDIF}
+{$ENDIF OS2PM}
+ MyApp.Done; { Dispose of app }
+
+ {DisposeRGBPalette(SystemPalette);}
+END.
diff --git a/packages/fv/src/app.pas b/packages/fv/src/app.pas
new file mode 100644
index 0000000000..3b245025f5
--- /dev/null
+++ b/packages/fv/src/app.pas
@@ -0,0 +1,1200 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of APP.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@starwon.com.au - backup e-mail addr }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+
+UNIT App;
+
+{2.0 compatibility}
+{$ifdef VER2_0}
+ {$macro on}
+ {$define resourcestring := const}
+{$endif}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES
+ {$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ Windows, { Standard units }
+ {$ENDIF}
+
+ {$IFDEF OS_OS2} { OS2 CODE }
+ {$IFDEF PPC_FPC}
+ Os2Def, DosCalls, PmWin, { Standard units }
+ {$ELSE}
+ Os2Def, Os2Base, OS2PmApi, { Standard units }
+ {$ENDIF}
+ {$ENDIF}
+ Dos,
+ Video,
+ FVCommon, {Memory,} { GFV standard units }
+ Objects, Drivers, Views, Menus, HistList, Dialogs,
+ msgbox, fvconsts;
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ STANDARD APPLICATION COMMAND CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ cmNew = 30; { Open new file }
+ cmOpen = 31; { Open a file }
+ cmSave = 32; { Save current }
+ cmSaveAs = 33; { Save current as }
+ cmSaveAll = 34; { Save all files }
+ cmChangeDir = 35; { Change directories }
+ cmDosShell = 36; { Dos shell }
+ cmCloseAll = 37; { Close all windows }
+
+{---------------------------------------------------------------------------}
+{ TApplication PALETTE ENTRIES }
+{---------------------------------------------------------------------------}
+CONST
+ apColor = 0; { Coloured app }
+ apBlackWhite = 1; { B&W application }
+ apMonochrome = 2; { Monochrome app }
+
+{---------------------------------------------------------------------------}
+{ TBackGround PALETTES }
+{---------------------------------------------------------------------------}
+CONST
+ CBackground = #1; { Background colour }
+
+{---------------------------------------------------------------------------}
+{ TApplication PALETTES }
+{---------------------------------------------------------------------------}
+CONST
+ { Turbo Vision 1.0 Color Palettes }
+
+ CColor =
+ #$81#$70#$78#$74#$20#$28#$24#$17#$1F#$1A#$31#$31#$1E#$71#$1F +
+ #$37#$3F#$3A#$13#$13#$3E#$21#$3F#$70#$7F#$7A#$13#$13#$70#$7F#$7E +
+ #$70#$7F#$7A#$13#$13#$70#$70#$7F#$7E#$20#$2B#$2F#$78#$2E#$70#$30 +
+ #$3F#$3E#$1F#$2F#$1A#$20#$72#$31#$31#$30#$2F#$3E#$31#$13#$38#$00;
+
+ CBlackWhite =
+ #$70#$70#$78#$7F#$07#$07#$0F#$07#$0F#$07#$70#$70#$07#$70#$0F +
+ #$07#$0F#$07#$70#$70#$07#$70#$0F#$70#$7F#$7F#$70#$07#$70#$07#$0F +
+ #$70#$7F#$7F#$70#$07#$70#$70#$7F#$7F#$07#$0F#$0F#$78#$0F#$78#$07 +
+ #$0F#$0F#$0F#$70#$0F#$07#$70#$70#$70#$07#$70#$0F#$07#$07#$78#$00;
+
+ CMonochrome =
+ #$70#$07#$07#$0F#$70#$70#$70#$07#$0F#$07#$70#$70#$07#$70#$00 +
+ #$07#$0F#$07#$70#$70#$07#$70#$00#$70#$70#$70#$07#$07#$70#$07#$00 +
+ #$70#$70#$70#$07#$07#$70#$70#$70#$0F#$07#$07#$0F#$70#$0F#$70#$07 +
+ #$0F#$0F#$07#$70#$07#$07#$70#$07#$07#$07#$70#$0F#$07#$07#$70#$00;
+
+ { Turbo Vision 2.0 Color Palettes }
+
+ CAppColor =
+ #$71#$70#$78#$74#$20#$28#$24#$17#$1F#$1A#$31#$31#$1E#$71#$1F +
+ #$37#$3F#$3A#$13#$13#$3E#$21#$3F#$70#$7F#$7A#$13#$13#$70#$7F#$7E +
+ #$70#$7F#$7A#$13#$13#$70#$70#$7F#$7E#$20#$2B#$2F#$78#$2E#$70#$30 +
+ #$3F#$3E#$1F#$2F#$1A#$20#$72#$31#$31#$30#$2F#$3E#$31#$13#$38#$00 +
+ #$17#$1F#$1A#$71#$71#$1E#$17#$1F#$1E#$20#$2B#$2F#$78#$2E#$10#$30 +
+ #$3F#$3E#$70#$2F#$7A#$20#$12#$31#$31#$30#$2F#$3E#$31#$13#$38#$00 +
+ #$37#$3F#$3A#$13#$13#$3E#$30#$3F#$3E#$20#$2B#$2F#$78#$2E#$30#$70 +
+ #$7F#$7E#$1F#$2F#$1A#$20#$32#$31#$71#$70#$2F#$7E#$71#$13#$38#$00;
+
+ CAppBlackWhite =
+ #$70#$70#$78#$7F#$07#$07#$0F#$07#$0F#$07#$70#$70#$07#$70#$0F +
+ #$07#$0F#$07#$70#$70#$07#$70#$0F#$70#$7F#$7F#$70#$07#$70#$07#$0F +
+ #$70#$7F#$7F#$70#$07#$70#$70#$7F#$7F#$07#$0F#$0F#$78#$0F#$78#$07 +
+ #$0F#$0F#$0F#$70#$0F#$07#$70#$70#$70#$07#$70#$0F#$07#$07#$78#$00 +
+ #$07#$0F#$0F#$07#$70#$07#$07#$0F#$0F#$70#$78#$7F#$08#$7F#$08#$70 +
+ #$7F#$7F#$7F#$0F#$70#$70#$07#$70#$70#$70#$07#$7F#$70#$07#$78#$00 +
+ #$70#$7F#$7F#$70#$07#$70#$70#$7F#$7F#$07#$0F#$0F#$78#$0F#$78#$07 +
+ #$0F#$0F#$0F#$70#$0F#$07#$70#$70#$70#$07#$70#$0F#$07#$07#$78#$00;
+
+ CAppMonochrome =
+ #$70#$07#$07#$0F#$70#$70#$70#$07#$0F#$07#$70#$70#$07#$70#$00 +
+ #$07#$0F#$07#$70#$70#$07#$70#$00#$70#$70#$70#$07#$07#$70#$07#$00 +
+ #$70#$70#$70#$07#$07#$70#$70#$70#$0F#$07#$07#$0F#$70#$0F#$70#$07 +
+ #$0F#$0F#$07#$70#$07#$07#$70#$07#$07#$07#$70#$0F#$07#$07#$70#$00 +
+ #$70#$70#$70#$07#$07#$70#$70#$70#$0F#$07#$07#$0F#$70#$0F#$70#$07 +
+ #$0F#$0F#$07#$70#$07#$07#$70#$07#$07#$07#$70#$0F#$07#$07#$70#$00 +
+ #$70#$70#$70#$07#$07#$70#$70#$70#$0F#$07#$07#$0F#$70#$0F#$70#$07 +
+ #$0F#$0F#$07#$70#$07#$07#$70#$07#$07#$07#$70#$0F#$07#$07#$70#$00;
+
+{---------------------------------------------------------------------------}
+{ STANDRARD HELP CONTEXT CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+{ Note: range $FF00 - $FFFF of help contexts are reserved by Borland }
+ hcNew = $FF01; { New file help }
+ hcOpen = $FF02; { Open file help }
+ hcSave = $FF03; { Save file help }
+ hcSaveAs = $FF04; { Save file as help }
+ hcSaveAll = $FF05; { Save all files help }
+ hcChangeDir = $FF06; { Change dir help }
+ hcDosShell = $FF07; { Dos shell help }
+ hcExit = $FF08; { Exit program help }
+
+ hcUndo = $FF10; { Clipboard undo help }
+ hcCut = $FF11; { Clipboard cut help }
+ hcCopy = $FF12; { Clipboard copy help }
+ hcPaste = $FF13; { Clipboard paste help }
+ hcClear = $FF14; { Clipboard clear help }
+
+ hcTile = $FF20; { Desktop tile help }
+ hcCascade = $FF21; { Desktop cascade help }
+ hcCloseAll = $FF22; { Desktop close all }
+ hcResize = $FF23; { Window resize help }
+ hcZoom = $FF24; { Window zoom help }
+ hcNext = $FF25; { Window next help }
+ hcPrev = $FF26; { Window previous help }
+ hcClose = $FF27; { Window close help }
+
+{***************************************************************************}
+{ PUBLIC OBJECT DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TBackGround OBJECT - BACKGROUND OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TBackGround = OBJECT (TView)
+ Pattern: Char; { Background pattern }
+ CONSTRUCTOR Init (Var Bounds: TRect; APattern: Char);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PBackGround = ^TBackGround;
+
+{---------------------------------------------------------------------------}
+{ TDeskTop OBJECT - DESKTOP OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TDeskTop = OBJECT (TGroup)
+ Background : PBackground; { Background view }
+ TileColumnsFirst: Boolean; { Tile direction }
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ CONSTRUCTOR Load (Var S: TStream);
+ PROCEDURE TileError; Virtual;
+ PROCEDURE InitBackGround; Virtual;
+ PROCEDURE Tile (Var R: TRect);
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE Cascade (Var R: TRect);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PDeskTop = ^TDeskTop;
+
+{---------------------------------------------------------------------------}
+{ TProgram OBJECT - PROGRAM ANCESTOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TProgram = OBJECT (TGroup)
+ CONSTRUCTOR Init;
+ DESTRUCTOR Done; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION CanMoveFocus: Boolean;
+ FUNCTION ValidView (P: PView): PView;
+ FUNCTION InsertWindow (P: PWindow): PWindow;
+ FUNCTION ExecuteDialog (P: PDialog; Data: Pointer): Word;
+ PROCEDURE Run; Virtual;
+ PROCEDURE Idle; Virtual;
+ PROCEDURE InitScreen; Virtual;
+{ procedure DoneScreen; virtual;}
+ PROCEDURE InitDeskTop; Virtual;
+ PROCEDURE OutOfMemory; Virtual;
+ PROCEDURE InitMenuBar; Virtual;
+ PROCEDURE InitStatusLine; Virtual;
+ PROCEDURE SetScreenMode (Mode: Word);
+ PROCEDURE SetScreenVideoMode(const Mode: TVideoMode);
+ PROCEDURE PutEvent (Var Event: TEvent); Virtual;
+ PROCEDURE GetEvent (Var Event: TEvent); Virtual;
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PProgram = ^TProgram;
+
+{---------------------------------------------------------------------------}
+{ TApplication OBJECT - APPLICATION OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TApplication = OBJECT (TProgram)
+ CONSTRUCTOR Init;
+ DESTRUCTOR Done; Virtual;
+ PROCEDURE Tile;
+ PROCEDURE Cascade;
+ PROCEDURE DosShell;
+ PROCEDURE GetTileRect (Var R: TRect); Virtual;
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ procedure WriteShellMsg; virtual;
+ END;
+ PApplication = ^TApplication; { Application ptr }
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STANDARD MENU AND STATUS LINES ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-StdStatusKeys------------------------------------------------------
+Returns a pointer to a linked list of commonly used status line keys.
+The default status line for TApplication uses StdStatusKeys as its
+complete list of status keys.
+22Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION StdStatusKeys (Next: PStatusItem): PStatusItem;
+
+{-StdFileMenuItems---------------------------------------------------
+Returns a pointer to a list of menu items for a standard File menu.
+The standard File menu items are New, Open, Save, Save As, Save All,
+Change Dir, OS Shell, and Exit.
+22Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION StdFileMenuItems (Next: PMenuItem): PMenuItem;
+
+{-StdEditMenuItems---------------------------------------------------
+Returns a pointer to a list of menu items for a standard Edit menu.
+The standard Edit menu items are Undo, Cut, Copy, Paste, and Clear.
+22Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION StdEditMenuItems (Next: PMenuItem): PMenuItem;
+
+{-StdWindowMenuItems-------------------------------------------------
+Returns a pointer to a list of menu items for a standard Window menu.
+The standard Window menu items are Tile, Cascade, Close All,
+Size/Move, Zoom, Next, Previous, and Close.
+22Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION StdWindowMenuItems (Next: PMenuItem): PMenuItem;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{-RegisterApp--------------------------------------------------------
+Calls RegisterType for each of the object types defined in this unit.
+22oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE RegisterApp;
+
+{***************************************************************************}
+{ OBJECT REGISTRATION }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TBackGround STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RBackGround: TStreamRec = (
+ ObjType: idBackground; { Register id = 30 }
+ VmtLink: TypeOf(TBackGround);
+ Load: @TBackGround.Load; { Object load method }
+ Store: @TBackGround.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TDeskTop STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RDeskTop: TStreamRec = (
+ ObjType: idDesktop; { Register id = 31 }
+ VmtLink: TypeOf(TDeskTop);
+ Load: @TDeskTop.Load; { Object load method }
+ Store: @TDeskTop.Store { Object store method }
+ );
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED PUBLIC VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ AppPalette: Integer = apColor; { Application colour }
+ Desktop: PDeskTop = Nil; { Desktop object }
+ MenuBar: PMenuView = Nil; { Application menu }
+ StatusLine: PStatusLine = Nil; { App status line }
+ Application : PApplication = Nil; { Application object }
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+uses Mouse{,Resource};
+
+resourcestring sVideoFailed='Video initialization failed.';
+ sTypeExitOnReturn='Type EXIT to return...';
+
+
+{***************************************************************************}
+{ PRIVATE DEFINED CONSTANTS }
+{***************************************************************************}
+
+{***************************************************************************}
+{ PRIVATE INITIALIZED VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED PRIVATE VARIABLES }
+{---------------------------------------------------------------------------}
+CONST Pending: TEvent = (What: evNothing); { Pending event }
+
+{---------------------------------------------------------------------------}
+{ Tileable -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION Tileable (P: PView): Boolean;
+BEGIN
+ Tileable := (P^.Options AND ofTileable <> 0) AND { View is tileable }
+ (P^.State AND sfVisible <> 0); { View is visible }
+END;
+
+{---------------------------------------------------------------------------}
+{ ISqr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION ISqr (X: Sw_Integer): Sw_Integer;
+VAR I: Sw_Integer;
+BEGIN
+ I := 0; { Set value to zero }
+ Repeat
+ Inc(I); { Inc value }
+ Until (I * I > X); { Repeat till Sqr > X }
+ ISqr := I - 1; { Return result }
+END;
+
+{---------------------------------------------------------------------------}
+{ MostEqualDivisors -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MostEqualDivisors (N: Integer; Var X, Y: Integer; FavorY: Boolean);
+VAR I: Integer;
+BEGIN
+ I := ISqr(N); { Int square of N }
+ If ((N MOD I) <> 0) Then { Initial guess }
+ If ((N MOD (I+1)) = 0) Then Inc(I); { Add one row/column }
+ If (I < (N DIV I)) Then I := N DIV I; { In first page }
+ If FavorY Then Begin { Horz preferred }
+ X := N DIV I; { Calc x position }
+ Y := I; { Set y position }
+ End Else Begin { Vert preferred }
+ Y := N DIV I; { Calc y position }
+ X := I; { Set x position }
+ End;
+END;
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{--TBackGround--------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TBackGround.Init (Var Bounds: TRect; APattern: Char);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ GrowMode := gfGrowHiX + gfGrowHiY; { Set grow modes }
+ Pattern := APattern; { Hold pattern }
+END;
+
+{--TBackGround--------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TBackGround.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(Pattern, SizeOf(Pattern)); { Read pattern data }
+END;
+
+{--TBackGround--------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TBackGround.GetPalette: PPalette;
+CONST P: String[Length(CBackGround)] = CbackGround; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TBackGround--------------------------------------------------------------}
+{ DrawBackground -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TBackground.Draw;
+VAR B: TDrawBuffer;
+BEGIN
+ MoveChar(B, Pattern, GetColor($01), Size.X); { Fill draw buffer }
+ WriteLine(0, 0, Size.X, Size.Y, B); { Draw to area }
+END;
+
+{--TBackGround--------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TBackGround.Store (Var S: TStream);
+BEGIN
+ TView.Store(S); { TView store called }
+ S.Write(Pattern, SizeOf(Pattern)); { Write pattern data }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TDesktop OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TDesktop-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TDesktop.Init (Var Bounds: Objects.TRect);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ GrowMode := gfGrowHiX + gfGrowHiY; { Set growmode }
+ InitBackground; { Create background }
+ If (Background <> Nil) Then Insert(Background); { Insert background }
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TDesktop.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetSubViewPtr(S, Background); { Load background }
+ S.Read(TileColumnsFirst, SizeOf(TileColumnsFirst));{ Read data }
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ TileError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDeskTop.TileError;
+BEGIN { Abstract method }
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ InitBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDesktop.InitBackground;
+CONST Ch: Char = #176;
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get desktop extents }
+ BackGround := New(PBackground, Init(R, Ch)); { Insert a background }
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ Tile -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDeskTop.Tile (Var R: TRect);
+VAR NumCols, NumRows, NumTileable, LeftOver, TileNum: Integer;
+
+ FUNCTION DividerLoc (Lo, Hi, Num, Pos: Integer): Integer;
+ BEGIN
+ DividerLoc := LongInt( LongInt(Hi - Lo) * Pos)
+ DIV Num + Lo; { Calc position }
+ END;
+
+ PROCEDURE DoCountTileable (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+ BEGIN
+ If Tileable(P) Then Inc(NumTileable); { Count tileable views }
+ END;
+
+ PROCEDURE CalcTileRect (Pos: Integer; Var NR: TRect);
+ VAR X, Y, D: Integer;
+ BEGIN
+ D := (NumCols - LeftOver) * NumRows; { Calc d value }
+ If (Pos<D) Then Begin
+ X := Pos DIV NumRows; Y := Pos MOD NumRows; { Calc positions }
+ End Else Begin
+ X := (Pos - D) div (NumRows + 1) +
+ (NumCols - LeftOver); { Calc x position }
+ Y := (Pos - D) mod (NumRows + 1); { Calc y position }
+ End;
+ NR.A.X := DividerLoc(R.A.X, R.B.X, NumCols, X); { Top left x position }
+ NR.B.X := DividerLoc(R.A.X, R.B.X, NumCols, X+1);{ Right x position }
+ If (Pos >= D) Then Begin
+ NR.A.Y := DividerLoc(R.A.Y, R.B.Y,NumRows+1,Y);{ Top y position }
+ NR.B.Y := DividerLoc(R.A.Y, R.B.Y, NumRows+1,
+ Y+1); { Bottom y position }
+ End Else Begin
+ NR.A.Y := DividerLoc(R.A.Y, R.B.Y,NumRows,Y); { Top y position }
+ NR.B.Y := DividerLoc(R.A.Y, R.B.Y, NumRows,
+ Y+1); { Bottom y position }
+ End;
+ END;
+
+ PROCEDURE DoTile(P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+ VAR PState: Word; R: TRect;
+ BEGIN
+ If Tileable(P) Then Begin
+ CalcTileRect(TileNum, R); { Calc tileable area }
+ PState := P^.State; { Hold view state }
+ P^.State := P^.State AND NOT sfVisible; { Temp not visible }
+ P^.Locate(R); { Locate view }
+ P^.State := PState; { Restore view state }
+ Dec(TileNum); { One less to tile }
+ End;
+ END;
+
+BEGIN
+ NumTileable := 0; { Zero tileable count }
+ ForEach(@DoCountTileable); { Count tileable views }
+ If (NumTileable>0) Then Begin
+ MostEqualDivisors(NumTileable, NumCols, NumRows,
+ NOT TileColumnsFirst); { Do pre calcs }
+ If ((R.B.X - R.A.X) DIV NumCols = 0) OR
+ ((R.B.Y - R.A.Y) DIV NumRows = 0) Then TileError { Can't tile }
+ Else Begin
+ LeftOver := NumTileable MOD NumCols; { Left over count }
+ TileNum := NumTileable-1; { Tileable views }
+ ForEach(@DoTile); { Tile each view }
+ DrawView; { Now redraw }
+ End;
+ End;
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDesktop.Store (Var S: TStream);
+BEGIN
+ TGroup.Store(S); { Call group store }
+ PutSubViewPtr(S, Background); { Store background }
+ S.Write(TileColumnsFirst,SizeOf(TileColumnsFirst));{ Write data }
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ Cascade -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDeskTop.Cascade (Var R: TRect);
+VAR CascadeNum: Integer; LastView: PView; Min, Max: TPoint;
+
+ PROCEDURE DoCount (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+ BEGIN
+ If Tileable(P) Then Begin
+ Inc(CascadeNum); LastView := P; { Count cascadable }
+ End;
+ END;
+
+ PROCEDURE DoCascade (P: PView); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+ VAR PState: Word; NR: TRect;
+ BEGIN
+ If Tileable(P) AND (CascadeNum >= 0) Then Begin { View cascadable }
+ NR.Copy(R); { Copy rect area }
+ Inc(NR.A.X, CascadeNum); { Inc x position }
+ Inc(NR.A.Y, CascadeNum); { Inc y position }
+ PState := P^.State; { Hold view state }
+ P^.State := P^.State AND NOT sfVisible; { Temp stop draw }
+ P^.Locate(NR); { Locate the view }
+ P^.State := PState; { Now allow draws }
+ Dec(CascadeNum); { Dec count }
+ End;
+ END;
+
+BEGIN
+ CascadeNum := 0; { Zero cascade count }
+ ForEach(@DoCount); { Count cascadable }
+ If (CascadeNum>0) Then Begin
+ LastView^.SizeLimits(Min, Max); { Check size limits }
+ If (Min.X > R.B.X - R.A.X - CascadeNum) OR
+ (Min.Y > R.B.Y - R.A.Y - CascadeNum) Then
+ TileError Else Begin { Check for error }
+ Dec(CascadeNum); { One less view }
+ ForEach(@DoCascade); { Cascade view }
+ DrawView; { Redraw now }
+ End;
+ End;
+END;
+
+{--TDesktop-----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDesktop.HandleEvent (Var Event: TEvent);
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evCommand) Then Begin
+ Case Event.Command of { Command event }
+ cmNext: FocusNext(False); { Focus next view }
+ cmPrev: If (BackGround <> Nil) Then Begin
+ If Valid(cmReleasedFocus) Then
+ Current^.PutInFrontOf(Background); { Focus last view }
+ End Else FocusNext(True); { Focus prior view }
+ Else Exit;
+ End;
+ ClearEvent(Event); { Clear the event }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TProgram OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+
+{--TProgram-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TProgram.Init;
+VAR R: TRect;
+BEGIN
+ R.Assign(0, 0, ScreenWidth, ScreenHeight); { Full screen area }
+ Inherited Init(R); { Call ancestor }
+ Application := PApplication(@Self); { Set application ptr }
+ InitScreen; { Initialize screen }
+ State := sfVisible + sfSelected + sfFocused +
+ sfModal + sfExposed; { Deafult states }
+ Options := 0; { No options set }
+ Size.X := ScreenWidth; { Set x size value }
+ Size.Y := ScreenHeight; { Set y size value }
+ InitStatusLine; { Create status line }
+ InitMenuBar; { Create a bar menu }
+ InitDesktop; { Create desktop }
+ If (Desktop <> Nil) Then Insert(Desktop); { Insert desktop }
+ If (StatusLine <> Nil) Then Insert(StatusLine); { Insert status line }
+ If (MenuBar <> Nil) Then Insert(MenuBar); { Insert menu bar }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TProgram.Done;
+BEGIN
+ { Do not free the Buffer of Video Unit }
+ If Buffer = Views.PVideoBuf(VideoBuf) then
+ Buffer:=nil;
+ If (Desktop <> Nil) Then Dispose(Desktop, Done); { Destroy desktop }
+ If (MenuBar <> Nil) Then Dispose(MenuBar, Done); { Destroy menu bar }
+ If (StatusLine <> Nil) Then
+ Dispose(StatusLine, Done); { Destroy status line }
+ Application := Nil; { Clear application }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TProgram.GetPalette: PPalette;
+CONST P: Array[apColor..apMonochrome] Of String = (CAppColor, CAppBlackWhite,
+ CAppMonochrome);
+BEGIN
+ GetPalette := @P[AppPalette]; { Return palette }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ CanMoveFocus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TProgram.CanMoveFocus: Boolean;
+BEGIN
+ If (Desktop <> Nil) Then { Valid desktop view }
+ CanMovefocus := DeskTop^.Valid(cmReleasedFocus) { Check focus move }
+ Else CanMoveFocus := True; { No desktop who cares! }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ ValidView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TProgram.ValidView (P: PView): PView;
+BEGIN
+ ValidView := Nil; { Preset failure }
+ If (P <> Nil) Then Begin
+(*
+ If LowMemory Then Begin { Check memroy }
+ Dispose(P, Done); { Dispose view }
+ OutOfMemory; { Call out of memory }
+ Exit; { Now exit }
+ End;
+*)
+ If NOT P^.Valid(cmValid) Then Begin { Check view valid }
+ Dispose(P, Done); { Dipose view }
+ Exit; { Now exit }
+ End;
+ ValidView := P; { Return view }
+ End;
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ InsertWindow -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TProgram.InsertWindow (P: PWindow): PWindow;
+BEGIN
+ InsertWindow := Nil; { Preset failure }
+ If (ValidView(P) <> Nil) Then { Check view valid }
+ If (CanMoveFocus) AND (Desktop <> Nil) { Can we move focus }
+ Then Begin
+ Desktop^.Insert(P); { Insert window }
+ InsertWindow := P; { Return view ptr }
+ End Else Dispose(P, Done); { Dispose view }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ ExecuteDialog -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TProgram.ExecuteDialog (P: PDialog; Data: Pointer): Word;
+VAR ExecResult: Word;
+BEGIN
+ ExecuteDialog := cmCancel; { Preset cancel }
+ If (ValidView(P) <> Nil) Then Begin { Check view valid }
+ If (Data <> Nil) Then P^.SetData(Data^); { Set data }
+ If (P <> Nil) Then P^.SelectDefaultView; { Select default }
+ ExecResult := Desktop^.ExecView(P); { Execute view }
+ If (ExecResult <> cmCancel) AND (Data <> Nil)
+ Then P^.GetData(Data^); { Get data back }
+ Dispose(P, Done); { Dispose of dialog }
+ ExecuteDialog := ExecResult; { Return result }
+ End;
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ Run -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.Run;
+BEGIN
+ Execute; { Call execute }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ Idle -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.Idle;
+BEGIN
+ If (StatusLine <> Nil) Then StatusLine^.Update; { Update statusline }
+ If CommandSetChanged Then Begin { Check command change }
+ Message(@Self, evBroadcast, cmCommandSetChanged,
+ Nil); { Send message }
+ CommandSetChanged := False; { Clear flag }
+ End;
+ GiveUpTimeSlice;
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ InitScreen -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.InitScreen;
+
+{Initscreen is passive only, i.e. it detects the video size and capabilities
+ after initalization. Active video initalization is the task of Tapplication.}
+
+BEGIN
+ { the orginal code can't be used here because of the limited
+ video unit capabilities, the mono modus can't be handled
+ }
+{ Drivers.InitVideo;}
+ if (ScreenMode.Col div ScreenMode.Row<2) then
+ ShadowSize.X := 1
+ else
+ ShadowSize.X := 2;
+
+ ShadowSize.Y := 1;
+ ShowMarkers := False;
+ if ScreenMode.color then
+ AppPalette := apColor
+ else
+ AppPalette := apBlackWhite;
+ Buffer := Views.PVideoBuf(VideoBuf);
+END;
+
+
+{procedure TProgram.DoneScreen;
+begin
+ Drivers.DoneVideo;
+ Buffer:=nil;
+end;}
+
+
+{--TProgram-----------------------------------------------------------------}
+{ InitDeskTop -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.InitDesktop;
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get view extent }
+ If (MenuBar <> Nil) Then Inc(R.A.Y); { Adjust top down }
+ If (StatusLine <> Nil) Then Dec(R.B.Y); { Adjust bottom up }
+ DeskTop := New(PDesktop, Init(R)); { Create desktop }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ OutOfMemory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.OutOfMemory;
+BEGIN { Abstract method }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ InitMenuBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.InitMenuBar;
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get view extents }
+ R.B.Y := R.A.Y + 1; { One line high }
+ MenuBar := New(PMenuBar, Init(R, Nil)); { Create menu bar }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ InitStatusLine -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.InitStatusLine;
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get view extents }
+ R.A.Y := R.B.Y - 1; { One line high }
+ New(StatusLine, Init(R,
+ NewStatusDef(0, $FFFF,
+ NewStatusKey('~Alt-X~ Exit', kbAltX, cmQuit,
+ StdStatusKeys(Nil)), Nil))); { Default status line }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ SetScreenMode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.SetScreenMode (Mode: Word);
+var
+ R: TRect;
+begin
+ HideMouse;
+{ DoneMemory;}
+{ InitMemory;}
+ InitScreen;
+ Buffer := Views.PVideoBuf(VideoBuf);
+ R.Assign(0, 0, ScreenWidth, ScreenHeight);
+ ChangeBounds(R);
+ ShowMouse;
+end;
+
+procedure TProgram.SetScreenVideoMode(const Mode: TVideoMode);
+var
+ R: TRect;
+begin
+ hidemouse;
+{ DoneMouse;
+ DoneMemory;}
+ ScreenMode:=Mode;
+{ InitMouse;
+ InitMemory;}
+ InitScreen;
+ Video.SetVideoMode(Mode);
+ ScreenWidth:=Video.ScreenWidth;
+ ScreenHeight:=Video.ScreenHeight;
+ Buffer := Views.PVideoBuf(VideoBuf);
+ R.Assign(0, 0, ScreenWidth, ScreenHeight);
+ ChangeBounds(R);
+ ShowMouse;
+end;
+
+{--TProgram-----------------------------------------------------------------}
+{ PutEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.PutEvent (Var Event: TEvent);
+BEGIN
+ Pending := Event; { Set pending event }
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ GetEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.GetEvent (Var Event: TEvent);
+BEGIN
+ Event.What := evNothing;
+ If (Event.What = evNothing) Then Begin
+ If (Pending.What <> evNothing) Then Begin { Pending event }
+ Event := Pending; { Load pending event }
+ Pending.What := evNothing; { Clear pending event }
+ End Else Begin
+ NextQueuedEvent(Event); { Next queued event }
+ If (Event.What = evNothing) Then Begin
+ GetKeyEvent(Event); { Fetch key event }
+ If (Event.What = evKeyDown) then
+ Begin
+ if Event.keyCode = kbAltF12 then
+ ReDraw;
+ End;
+ If (Event.What = evNothing) Then Begin { No mouse event }
+ Drivers.GetMouseEvent(Event); { Load mouse event }
+ If (Event.What = evNothing) Then
+ begin
+ Drivers.GetSystemEvent(Event); { Load system event }
+ If (Event.What = evNothing) Then
+ Idle; { Idle if no event }
+ end;
+ End;
+ End;
+ End;
+ End;
+END;
+
+{--TProgram-----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TProgram.HandleEvent (Var Event: TEvent);
+VAR C: Char;
+BEGIN
+ If (Event.What = evKeyDown) Then Begin { Key press event }
+ C := GetAltChar(Event.KeyCode); { Get alt char code }
+ If (C >= '1') AND (C <= '9') Then
+ If (Message(Desktop, evBroadCast, cmSelectWindowNum,
+ Pointer(Byte(C) - $30)) <> Nil) { Select window }
+ Then ClearEvent(Event); { Clear event }
+ End;
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evCommand) AND { Command event }
+ (Event.Command = cmQuit) Then Begin { Quit command }
+ EndModal(cmQuit); { Endmodal operation }
+ ClearEvent(Event); { Clear event }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TApplication OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TApplication-------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TApplication.Init;
+
+BEGIN
+{ InitMemory;} { Start memory up }
+{ if not(InitResource) then
+ begin
+ writeln('Fatal: Can''t init resources');
+ halt(1);
+ end;}
+ initkeyboard;
+ if not Drivers.InitVideo then { Start video up }
+ begin
+ donekeyboard;
+ writeln(sVideoFailed);
+ halt(1);
+ end;
+ Drivers.InitEvents; { Start event drive }
+ Drivers.InitSysError; { Start system error }
+ InitHistory; { Start history up }
+ Inherited Init; { Call ancestor }
+ InitMsgBox;
+ { init mouse and cursor }
+ Video.SetCursorType(crHidden);
+ Mouse.SetMouseXY(1,1);
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TApplication.Done;
+BEGIN
+ Inherited Done; { Call ancestor }
+ DoneHistory; { Close history }
+ Drivers.DoneSysError; { Close system error }
+ Drivers.DoneEvents; { Close event drive }
+ drivers.donevideo;
+{ DoneMemory;} { Close memory }
+ donekeyboard;
+{ DoneResource;}
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ Tile -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TApplication.Tile;
+VAR R: TRect;
+BEGIN
+ GetTileRect(R); { Tileable area }
+ If (Desktop <> Nil) Then Desktop^.Tile(R); { Tile desktop }
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ Cascade -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TApplication.Cascade;
+VAR R: TRect;
+BEGIN
+ GetTileRect(R); { Cascade area }
+ If (Desktop <> Nil) Then Desktop^.Cascade(R); { Cascade desktop }
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ DosShell -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TApplication.DosShell;
+
+{$ifdef unix}
+var s:string;
+{$endif}
+
+BEGIN { Compatability only }
+ DoneSysError;
+ DoneEvents;
+ drivers.donevideo;
+ drivers.donekeyboard;
+{ DoneDosMem;}
+ WriteShellMsg;
+{$ifdef Unix}
+ s:=getenv('SHELL');
+ if s='' then
+ s:='/bin/sh';
+ exec(s,'');
+{$else}
+ SwapVectors;
+ Exec(GetEnv('COMSPEC'), '');
+ SwapVectors;
+{$endif}
+{ InitDosMem;}
+ drivers.initkeyboard;
+ drivers.initvideo;
+ InitScreen;
+ InitEvents;
+ InitSysError;
+ Redraw;
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ GetTileRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TApplication.GetTileRect (Var R: TRect);
+BEGIN
+ If (DeskTop <> Nil) Then Desktop^.GetExtent(R) { Desktop extents }
+ Else GetExtent(R); { Our extents }
+END;
+
+{--TApplication-------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TApplication.HandleEvent (Var Event: TEvent);
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evCommand) Then Begin
+ Case Event.Command Of
+ cmTile: Tile; { Tile request }
+ cmCascade: Cascade; { Cascade request }
+ cmDosShell: DosShell; { DOS shell request }
+ Else Exit; { Unhandled exit }
+ End;
+ ClearEvent(Event); { Clear the event }
+ End;
+END;
+
+procedure TApplication.WriteShellMsg;
+
+begin
+ writeln(sTypeExitOnReturn);
+end;
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STANDARD MENU AND STATUS LINES ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ StdStatusKeys -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION StdStatusKeys (Next: PStatusItem): PStatusItem;
+BEGIN
+ StdStatusKeys :=
+ NewStatusKey('', kbAltX, cmQuit,
+ NewStatusKey('', kbF10, cmMenu,
+ NewStatusKey('', kbAltF3, cmClose,
+ NewStatusKey('', kbF5, cmZoom,
+ NewStatusKey('', kbCtrlF5, cmResize,
+ NewStatusKey('', kbF6, cmNext,
+ NewStatusKey('', kbShiftF6, cmPrev,
+ Next)))))));
+END;
+
+{---------------------------------------------------------------------------}
+{ StdFileMenuItems -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION StdFileMenuItems (Next: PMenuItem): PMenuItem;
+BEGIN
+ StdFileMenuItems :=
+ NewItem('~N~ew', '', kbNoKey, cmNew, hcNew,
+ NewItem('~O~pen...', 'F3', kbF3, cmOpen, hcOpen,
+ NewItem('~S~ave', 'F2', kbF2, cmSave, hcSave,
+ NewItem('S~a~ve as...', '', kbNoKey, cmSaveAs, hcSaveAs,
+ NewItem('Save a~l~l', '', kbNoKey, cmSaveAll, hcSaveAll,
+ NewLine(
+ NewItem('~C~hange dir...', '', kbNoKey, cmChangeDir, hcChangeDir,
+ NewItem('OS shell', '', kbNoKey, cmDosShell, hcDosShell,
+ NewItem('E~x~it', 'Alt+X', kbAltX, cmQuit, hcExit,
+ Next)))))))));
+END;
+
+{---------------------------------------------------------------------------}
+{ StdEditMenuItems -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION StdEditMenuItems (Next: PMenuItem): PMenuItem;
+BEGIN
+ StdEditMenuItems :=
+ NewItem('~U~ndo', '', kbAltBack, cmUndo, hcUndo,
+ NewLine(
+ NewItem('Cu~t~', 'Shift+Del', kbShiftDel, cmCut, hcCut,
+ NewItem('~C~opy', 'Ctrl+Ins', kbCtrlIns, cmCopy, hcCopy,
+ NewItem('~P~aste', 'Shift+Ins', kbShiftIns, cmPaste, hcPaste,
+ NewItem('C~l~ear', 'Ctrl+Del', kbCtrlDel, cmClear, hcClear,
+ Next))))));
+END;
+
+{---------------------------------------------------------------------------}
+{ StdWindowMenuItems -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION StdWindowMenuItems (Next: PMenuItem): PMenuItem;
+BEGIN
+ StdWindowMenuItems :=
+ NewItem('~T~ile', '', kbNoKey, cmTile, hcTile,
+ NewItem('C~a~scade', '', kbNoKey, cmCascade, hcCascade,
+ NewItem('Cl~o~se all', '', kbNoKey, cmCloseAll, hcCloseAll,
+ NewLine(
+ NewItem('~S~ize/Move','Ctrl+F5', kbCtrlF5, cmResize, hcResize,
+ NewItem('~Z~oom', 'F5', kbF5, cmZoom, hcZoom,
+ NewItem('~N~ext', 'F6', kbF6, cmNext, hcNext,
+ NewItem('~P~revious', 'Shift+F6', kbShiftF6, cmPrev, hcPrev,
+ NewItem('~C~lose', 'Alt+F3', kbAltF3, cmClose, hcClose,
+ Next)))))))));
+END;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ RegisterApp -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE RegisterApp;
+BEGIN
+ RegisterType(RBackground); { Register background }
+ RegisterType(RDesktop); { Register desktop }
+END;
+
+END.
diff --git a/packages/fv/src/asciitab.pas b/packages/fv/src/asciitab.pas
new file mode 100644
index 0000000000..b3107be1a1
--- /dev/null
+++ b/packages/fv/src/asciitab.pas
@@ -0,0 +1,322 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of ASCIITAB.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 2002 by Pierre Muller }
+{ pierre@freepascal.org }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DPMI - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WIN95/NT - FPC 0.9912+ (32 Bit) }
+{ }
+
+UNIT AsciiTab;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES FVConsts, Objects, Drivers, Views, App; { Standard GFV units }
+
+{***************************************************************************}
+{ PUBLIC OBJECT DEFINITIONS }
+{***************************************************************************}
+
+
+{---------------------------------------------------------------------------}
+{ TTABLE OBJECT - 32x32 matrix of all chars }
+{---------------------------------------------------------------------------}
+
+type
+ PTable = ^TTable;
+ TTable = object(TView)
+ procedure Draw; virtual;
+ procedure HandleEvent(var Event:TEvent); virtual;
+ private
+ procedure DrawCurPos(enable : boolean);
+ end;
+
+{---------------------------------------------------------------------------}
+{ TREPORT OBJECT - View with details of current char }
+{---------------------------------------------------------------------------}
+ PReport = ^TReport;
+ TReport = object(TView)
+ ASCIIChar: LongInt;
+ constructor Load(var S: TStream);
+ procedure Draw; virtual;
+ procedure HandleEvent(var Event:TEvent); virtual;
+ procedure Store(var S: TStream);
+ end;
+
+{---------------------------------------------------------------------------}
+{ TASCIIChart OBJECT - the complete AsciiChar window }
+{---------------------------------------------------------------------------}
+
+ PASCIIChart = ^TASCIIChart;
+ TASCIIChart = object(TWindow)
+ Report: PReport;
+ Table: PTable;
+ constructor Init;
+ constructor Load(var S: TStream);
+ procedure Store(var S: TStream);
+ procedure HandleEvent(var Event:TEvent); virtual;
+ end;
+
+{---------------------------------------------------------------------------}
+{ AsciiTableCommandBase }
+{---------------------------------------------------------------------------}
+
+const
+ AsciiTableCommandBase: Word = 910;
+
+{---------------------------------------------------------------------------}
+{ Registrations records }
+{---------------------------------------------------------------------------}
+
+ RTable: TStreamRec = (
+ ObjType: idTable;
+ VmtLink: Ofs(TypeOf(TTable)^);
+ Load: @TTable.Load;
+ Store: @TTable.Store
+ );
+ RReport: TStreamRec = (
+ ObjType: idReport;
+ VmtLink: Ofs(TypeOf(TReport)^);
+ Load: @TReport.Load;
+ Store: @TReport.Store
+ );
+ RASCIIChart: TStreamRec = (
+ ObjType: idASCIIChart;
+ VmtLink: Ofs(TypeOf(TASCIIChart)^);
+ Load: @TASCIIChart.Load;
+ Store: @TASCIIChart.Store
+ );
+
+{---------------------------------------------------------------------------}
+{ Registration procedure }
+{---------------------------------------------------------------------------}
+procedure RegisterASCIITab;
+
+
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TTable OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+procedure TTable.Draw;
+var
+ NormColor : byte;
+ B : TDrawBuffer;
+ x,y : sw_integer;
+begin
+ NormColor:=GetColor(1);
+ For y:=0 to size.Y-1 do begin
+ For x:=0 to size.X-1 do
+ B[x]:=(NormColor shl 8) or ((y*Size.X+x) and $ff);
+ WriteLine(0,Y,Size.X,1,B);
+ end;
+ DrawCurPos(true);
+end;
+
+procedure TTable.DrawCurPos(enable : boolean);
+var
+ Color : byte;
+ B : word;
+begin
+ Color:=GetColor(1);
+ { add blinking if enable }
+ If Enable then
+ Color:=((Color and $F) shl 4) or (Color shr 4);
+ B:=(Color shl 8) or ((Cursor.Y*Size.X+Cursor.X) and $ff);
+ WriteLine(Cursor.X,Cursor.Y,1,1,B);
+end;
+
+procedure TTable.HandleEvent(var Event:TEvent);
+var
+ CurrentPos : TPoint;
+ Handled : boolean;
+
+ procedure SetTo(xpos, ypos : sw_integer);
+ var
+ newchar : ptrint;
+ begin
+ newchar:=(ypos*size.X+xpos) and $ff;
+ DrawCurPos(false);
+ SetCursor(xpos,ypos);
+ Message(Owner,evCommand,AsciiTableCommandBase,
+ pointer(newchar));
+ DrawCurPos(true);
+ ClearEvent(Event);
+ end;
+
+begin
+ case Event.What of
+ evMouseDown :
+ begin
+ If MouseInView(Event.Where) then
+ begin
+ MakeLocal(Event.Where, CurrentPos);
+ SetTo(CurrentPos.X, CurrentPos.Y);
+ exit;
+ end;
+ end;
+ evKeyDown :
+ begin
+ Handled:=true;
+ case Event.Keycode of
+ kbUp : if Cursor.Y>0 then
+ SetTo(Cursor.X,Cursor.Y-1);
+ kbDown : if Cursor.Y<Size.Y-1 then
+ SetTo(Cursor.X,Cursor.Y+1);
+ kbLeft : if Cursor.X>0 then
+ SetTo(Cursor.X-1,Cursor.Y);
+ kbRight: if Cursor.X<Size.X-1 then
+ SetTo(Cursor.X+1,Cursor.Y);
+ kbHome : SetTo(0,0);
+ kbEnd : SetTo(Size.X-1,Size.Y-1);
+ else
+ Handled:=false;
+ end;
+ if Handled then
+ exit;
+ end;
+ end;
+ inherited HandleEvent(Event);
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TReport OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+constructor TReport.Load(var S: TStream);
+begin
+ Inherited Load(S);
+ S.Read(AsciiChar,Sizeof(AsciiChar));
+end;
+
+procedure TReport.Draw;
+ var
+ stHex,stDec : string[3];
+ s : string;
+begin
+ Str(AsciiChar,StDec);
+ while length(stDec)<3 do
+ stDec:=' '+stDec;
+ stHex:=hexstr(AsciiChar,2);
+ s:='Char "'+chr(AsciiChar)+'" Decimal: '+
+ StDec+' Hex: $'+StHex+
+ ' '; // //{!ss:fill gap. FormatStr function using be better}
+ WriteStr(0,0,S,1);
+end;
+
+procedure TReport.HandleEvent(var Event:TEvent);
+begin
+ if (Event.what=evCommand) and
+ (Event.Command = AsciiTableCommandBase) then
+ begin
+ AsciiChar:=Event.InfoLong;
+ Draw;
+ ClearEvent(Event);
+ end
+ else inherited HandleEvent(Event);
+end;
+
+procedure TReport.Store(var S: TStream);
+begin
+ Inherited Store(S);
+ S.Write(AsciiChar,Sizeof(AsciiChar));
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TAsciiChart OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+constructor TASCIIChart.Init;
+var
+ R : Trect;
+begin
+ R.Assign(0,0,34,12);
+ Inherited Init(R,'Ascii table',wnNoNumber);
+ Flags:=Flags and not (wfGrow or wfZoom);
+ Palette:=wpGrayWindow;
+ R.Assign(1,10,33,11);
+ New(Report,Init(R));
+ Report^.Options:=Report^.Options or ofFramed;
+ Insert(Report);
+ R.Assign(1,1,33,9);
+ New(Table,Init(R));
+ Table^.Options:=Table^.Options or (ofSelectable+ofTopSelect);
+ Insert(Table);
+ Table^.Select;
+end;
+
+constructor TASCIIChart.Load(var S: TStream);
+begin
+ Inherited Load(S);
+ GetSubViewPtr(S,Table);
+ GetSubViewPtr(S,Report);
+end;
+
+procedure TASCIIChart.Store(var S: TStream);
+begin
+ Inherited Store(S);
+ PutSubViewPtr(S,Table);
+ PutSubViewPtr(S,Report);
+end;
+
+procedure TASCIIChart.HandleEvent(var Event:TEvent);
+begin
+ if (Event.what=evCommand) and
+ (Event.Command = AsciiTableCommandBase) then
+ begin
+ Report^.HandleEvent(Event);
+ end
+ else inherited HandleEvent(Event);
+end;
+{---------------------------------------------------------------------------}
+{ Registration procedure }
+{---------------------------------------------------------------------------}
+procedure RegisterASCIITab;
+begin
+ RegisterType(RTable);
+ RegisterType(RReport);
+ RegisterType(RAsciiChart);
+end;
+
+
+END.
diff --git a/packages/fv/src/buildfv.pas b/packages/fv/src/buildfv.pas
new file mode 100644
index 0000000000..de7fc74ac6
--- /dev/null
+++ b/packages/fv/src/buildfv.pas
@@ -0,0 +1,36 @@
+{
+
+ Unit to build all units of Free Vision
+}
+unit buildfv;
+interface
+uses
+ fvcommon,
+ objects,
+ drivers,
+{ memory,}
+ fvconsts,
+{ resource,}
+ views,
+ validate,
+ msgbox,
+ dialogs,
+ menus,
+ app,
+ stddlg,
+ asciitab,
+ tabs,
+ outline,
+ memory,
+ colortxt,
+ statuses,
+ histlist,
+ inplong,
+ editors,
+ gadgets,
+ timeddlg,
+ time;
+
+implementation
+
+end.
diff --git a/packages/fv/src/colortxt.pas b/packages/fv/src/colortxt.pas
new file mode 100644
index 0000000000..4bdb6b13a9
--- /dev/null
+++ b/packages/fv/src/colortxt.pas
@@ -0,0 +1,126 @@
+unit ColorTxt;
+
+{
+ TColoredText is a descendent of TStaticText designed to allow the writing
+ of colored text when color monitors are used. With a monochrome or BW
+ monitor, TColoredText acts the same as TStaticText.
+
+ TColoredText is used in exactly the same way as TStaticText except that
+ the constructor has an extra Byte parameter specifying the attribute
+ desired. (Do not use a 0 attribute, black on black).
+}
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+
+interface
+
+uses
+ objects, drivers, views, dialogs, app, fvconsts;
+
+type
+ PColoredText = ^TColoredText;
+ TColoredText = object(TStaticText)
+ Attr : Byte;
+ constructor Init(var Bounds: TRect; const AText: String; Attribute : Byte);
+ constructor Load(var S: TStream);
+ function GetTheColor : byte; virtual;
+ procedure Draw; virtual;
+ procedure Store(var S: TStream);
+ end;
+
+const
+ RColoredText: TStreamRec = (
+ ObjType: idColoredText;
+ VmtLink: Ofs(TypeOf(TColoredText)^);
+ Load: @TColoredText.Load;
+ Store: @TColoredText.Store
+ );
+
+implementation
+
+constructor TColoredText.Init(var Bounds: TRect; const AText: String;
+ Attribute : Byte);
+begin
+TStaticText.Init(Bounds, AText);
+Attr := Attribute;
+end;
+
+constructor TColoredText.Load(var S: TStream);
+begin
+TStaticText.Load(S);
+S.Read(Attr, Sizeof(Attr));
+end;
+
+procedure TColoredText.Store(var S: TStream);
+begin
+TStaticText.Store(S);
+S.Write(Attr, Sizeof(Attr));
+end;
+
+function TColoredText.GetTheColor : byte;
+begin
+if AppPalette = apColor then
+ GetTheColor := Attr
+else
+ GetTheColor := GetColor(1);
+end;
+
+procedure TColoredText.Draw;
+var
+ Color: Byte;
+ Center: Boolean;
+ I, J, L, P, Y: Sw_Integer;
+ B: TDrawBuffer;
+ S: String;
+begin
+ Color := GetTheColor;
+ GetText(S);
+ L := Length(S);
+ P := 1;
+ Y := 0;
+ Center := False;
+ while Y < Size.Y do
+ begin
+ MoveChar(B, ' ', Color, Size.X);
+ if P <= L then
+ begin
+ if S[P] = #3 then
+ begin
+ Center := True;
+ Inc(P);
+ end;
+ I := P;
+ repeat
+ J := P;
+ while (P <= L) and (S[P] = ' ') do Inc(P);
+ while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do Inc(P);
+ until (P > L) or (P >= I + Size.X) or (S[P] = #13);
+ if P > I + Size.X then
+ if J > I then P := J else P := I + Size.X;
+ if Center then J := (Size.X - P + I) div 2 else J := 0;
+ MoveBuf(B[J], S[I], Color, P - I);
+ while (P <= L) and (S[P] = ' ') do Inc(P);
+ if (P <= L) and (S[P] = #13) then
+ begin
+ Center := False;
+ Inc(P);
+ if (P <= L) and (S[P] = #10) then Inc(P);
+ end;
+ end;
+ WriteLine(0, Y, Size.X, 1, B);
+ Inc(Y);
+ end;
+end;
+
+
+end.
diff --git a/packages/fv/src/dialogs.pas b/packages/fv/src/dialogs.pas
new file mode 100644
index 0000000000..f91f9531c6
--- /dev/null
+++ b/packages/fv/src/dialogs.pas
@@ -0,0 +1,4186 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of DIALOGS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@starwon.com.au - backup e-mail addr }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+
+UNIT Dialogs;
+
+{$CODEPAGE cp437}
+
+{2.0 compatibility}
+{$ifdef VER2_0}
+ {$macro on}
+ {$define resourcestring := const}
+{$endif}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES
+ {$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ Windows, { Standard units }
+ {$ENDIF}
+
+ {$IFDEF OS_OS2} { OS2 CODE }
+ OS2Def, DosCalls, PMWIN, { Standard units }
+ {$ENDIF}
+
+ FVCommon, FVConsts, Objects, Drivers, Views, Validate; { Standard GFV units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ COLOUR PALETTE DEFINITIONS }
+{---------------------------------------------------------------------------}
+CONST
+ CGrayDialog = #32#33#34#35#36#37#38#39#40#41#42#43#44#45#46#47 +
+ #48#49#50#51#52#53#54#55#56#57#58#59#60#61#62#63;
+ CBlueDialog = #64#65#66#67#68#69#70#71#72#73#74#75#76#77#78#79 +
+ #80#81#82#83#84#85#86#87#88#89#90#91#92#92#94#95;
+ CCyanDialog = #96#97#98#99#100#101#102#103#104#105#106#107#108 +
+ #109#110#111#112#113#114#115#116#117#118#119#120 +
+ #121#122#123#124#125#126#127;
+ CStaticText = #6#7#8#9;
+ CLabel = #7#8#9#9;
+ CButton = #10#11#12#13#14#14#14#15;
+ CCluster = #16#17#18#18#31#6;
+ CInputLine = #19#19#20#21#14;
+ CHistory = #22#23;
+ CHistoryWindow = #19#19#21#24#25#19#20;
+ CHistoryViewer = #6#6#7#6#6;
+
+ CDialog = CGrayDialog; { Default palette }
+
+const
+ { ldXXXX constants }
+ ldNone = $0000;
+ ldNew = $0001;
+ ldEdit = $0002;
+ ldDelete = $0004;
+ ldNewEditDelete = ldNew or ldEdit or ldDelete;
+ ldHelp = $0008;
+ ldAllButtons = ldNew or ldEdit or ldDelete or ldHelp;
+ ldNewIcon = $0010;
+ ldEditIcon = $0020;
+ ldDeleteIcon = $0040;
+ ldAllIcons = ldNewIcon or ldEditIcon or ldDeleteIcon;
+ ldAll = ldAllIcons or ldAllButtons;
+ ldNoFrame = $0080;
+ ldNoScrollBar = $0100;
+
+ { ofXXXX constants }
+ ofNew = $0001;
+ ofDelete = $0002;
+ ofEdit = $0004;
+ ofNewEditDelete = ofNew or ofDelete or ofEdit;
+
+{---------------------------------------------------------------------------}
+{ TDialog PALETTE COLOUR CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ dpBlueDialog = 0; { Blue dialog colour }
+ dpCyanDialog = 1; { Cyan dialog colour }
+ dpGrayDialog = 2; { Gray dialog colour }
+
+{---------------------------------------------------------------------------}
+{ TButton FLAGS MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ bfNormal = $00; { Normal displayed }
+ bfDefault = $01; { Default command }
+ bfLeftJust = $02; { Left just text }
+ bfBroadcast = $04; { Broadcast command }
+ bfGrabFocus = $08; { Grab focus }
+
+{---------------------------------------------------------------------------}
+{ TMultiCheckBoxes FLAGS - (HiByte = Bits LoByte = Mask) }
+{---------------------------------------------------------------------------}
+CONST
+ cfOneBit = $0101; { One bit masks }
+ cfTwoBits = $0203; { Two bit masks }
+ cfFourBits = $040F; { Four bit masks }
+ cfEightBits = $08FF; { Eight bit masks }
+
+{---------------------------------------------------------------------------}
+{ DIALOG BROADCAST COMMANDS }
+{---------------------------------------------------------------------------}
+CONST
+ cmRecordHistory = 60; { Record history cmd }
+
+{***************************************************************************}
+{ RECORD DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ ITEM RECORD DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ PSItem = ^TSItem;
+ TSItem = RECORD
+ Value: PString; { Item string }
+ Next: PSItem; { Next item }
+ END;
+
+{***************************************************************************}
+{ OBJECT DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TInputLine OBJECT - INPUT LINE OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TInputLine = OBJECT (TView)
+ MaxLen: Sw_Integer; { Max input length }
+ CurPos: Sw_Integer; { Cursor position }
+ FirstPos: Sw_Integer; { First position }
+ SelStart: Sw_Integer; { Selected start }
+ SelEnd: Sw_Integer; { Selected end }
+ Data: PString; { Input line data }
+ Validator: PValidator; { Validator of view }
+ CONSTRUCTOR Init (Var Bounds: TRect; AMaxLen: Sw_Integer);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION Valid (Command: Word): Boolean; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE DrawCursor; Virtual;
+ PROCEDURE SelectAll (Enable: Boolean);
+ PROCEDURE SetValidator (AValid: PValidator);
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PRIVATE
+ FUNCTION CanScroll (Delta: Sw_Integer): Boolean;
+ END;
+ PInputLine = ^TInputLine;
+
+{---------------------------------------------------------------------------}
+{ TButton OBJECT - BUTTON ANCESTOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TButton = OBJECT (TView)
+ AmDefault: Boolean; { If default button }
+ Flags : Byte; { Button flags }
+ Command : Word; { Button command }
+ Title : PString; { Button title }
+ CONSTRUCTOR Init (Var Bounds: TRect; ATitle: TTitleStr; ACommand: Word;
+ AFlags: Word);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE Press; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE DrawState (Down: Boolean);
+ PROCEDURE MakeDefault (Enable: Boolean);
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PRIVATE
+ DownFlag: Boolean;
+ END;
+ PButton = ^TButton;
+
+{---------------------------------------------------------------------------}
+{ TCluster OBJECT - CLUSTER ANCESTOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ { Palette layout }
+ { 1 = Normal text }
+ { 2 = Selected text }
+ { 3 = Normal shortcut }
+ { 4 = Selected shortcut }
+ { 5 = Disabled text }
+
+ TCluster = OBJECT (TView)
+ Id : Sw_Integer; { New communicate id }
+ Sel : Sw_Integer; { Selected item }
+ Value : LongInt; { Bit value }
+ EnableMask: LongInt; { Mask enable bits }
+ Strings : TStringCollection; { String collection }
+ CONSTRUCTOR Init (Var Bounds: TRect; AStrings: PSItem);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION GetHelpCtx: Word; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION Mark (Item: Sw_Integer): Boolean; Virtual;
+ FUNCTION MultiMark (Item: Sw_Integer): Byte; Virtual;
+ FUNCTION ButtonState (Item: Sw_Integer): Boolean;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Press (Item: Sw_Integer); Virtual;
+ PROCEDURE MovedTo (Item: Sw_Integer); Virtual;
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE DrawMultiBox (Const Icon, Marker: String);
+ PROCEDURE DrawBox (Const Icon: String; Marker: Char);
+ PROCEDURE SetButtonState (AMask: Longint; Enable: Boolean);
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PRIVATE
+ FUNCTION FindSel (P: TPoint): Sw_Integer;
+ FUNCTION Row (Item: Sw_Integer): Sw_Integer;
+ FUNCTION Column (Item: Sw_Integer): Sw_Integer;
+ END;
+ PCluster = ^TCluster;
+
+{---------------------------------------------------------------------------}
+{ TRadioButtons OBJECT - RADIO BUTTON OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Normal text }
+ { 2 = Selected text }
+ { 3 = Normal shortcut }
+ { 4 = Selected shortcut }
+
+
+TYPE
+ TRadioButtons = OBJECT (TCluster)
+ FUNCTION Mark (Item: Sw_Integer): Boolean; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Press (Item: Sw_Integer); Virtual;
+ PROCEDURE MovedTo(Item: Sw_Integer); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ END;
+ PRadioButtons = ^TRadioButtons;
+
+{---------------------------------------------------------------------------}
+{ TCheckBoxes OBJECT - CHECK BOXES OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Normal text }
+ { 2 = Selected text }
+ { 3 = Normal shortcut }
+ { 4 = Selected shortcut }
+
+TYPE
+ TCheckBoxes = OBJECT (TCluster)
+ FUNCTION Mark (Item: Sw_Integer): Boolean; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Press (Item: Sw_Integer); Virtual;
+ END;
+ PCheckBoxes = ^TCheckBoxes;
+
+{---------------------------------------------------------------------------}
+{ TMultiCheckBoxes OBJECT - CHECK BOXES OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Normal text }
+ { 2 = Selected text }
+ { 3 = Normal shortcut }
+ { 4 = Selected shortcut }
+
+TYPE
+ TMultiCheckBoxes = OBJECT (TCluster)
+ SelRange: Byte; { Select item range }
+ Flags : Word; { Select flags }
+ States : PString; { Strings }
+ CONSTRUCTOR Init (Var Bounds: TRect; AStrings: PSItem;
+ ASelRange: Byte; AFlags: Word; Const AStates: String);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION MultiMark (Item: Sw_Integer): Byte; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Press (Item: Sw_Integer); Virtual;
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PMultiCheckBoxes = ^TMultiCheckBoxes;
+
+{---------------------------------------------------------------------------}
+{ TListBox OBJECT - LIST BOX OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Active }
+ { 2 = Inactive }
+ { 3 = Focused }
+ { 4 = Selected }
+ { 5 = Divider }
+
+TYPE
+ TListBox = OBJECT (TListViewer)
+ List: PCollection; { List of strings }
+ CONSTRUCTOR Init (Var Bounds: TRect; ANumCols: Sw_Word;
+ AScrollBar: PScrollBar);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
+ PROCEDURE NewList(AList: PCollection); Virtual;
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ procedure DeleteFocusedItem; virtual;
+ { DeleteFocusedItem deletes the focused item and redraws the view. }
+ {#X FreeFocusedItem }
+ procedure DeleteItem (Item : Sw_Integer); virtual;
+ { DeleteItem deletes Item from the associated collection. }
+ {#X FreeItem }
+ procedure FreeAll; virtual;
+ { FreeAll deletes and disposes of all items in the associated
+ collection. }
+ { FreeFocusedItem FreeItem }
+ procedure FreeFocusedItem; virtual;
+ { FreeFocusedItem deletes and disposes of the focused item then redraws
+ the listbox. }
+ {#X FreeAll FreeItem }
+ procedure FreeItem (Item : Sw_Integer); virtual;
+ { FreeItem deletes Item from the associated collection and disposes of
+ it, then redraws the listbox. }
+ {#X FreeFocusedItem FreeAll }
+ function GetFocusedItem : Pointer; virtual;
+ { GetFocusedItem is a more readable method of returning the focused
+ item from the listbox. It is however slightly slower than: }
+ {#M+}
+ {
+ Item := ListBox^.List^.At(ListBox^.Focused); }
+ {#M-}
+ procedure Insert (Item : Pointer); virtual;
+ { Insert inserts Item into the collection, adjusts the listbox's range,
+ then redraws the listbox. }
+ {#X FreeItem }
+ procedure SetFocusedItem (Item : Pointer); virtual;
+ { SetFocusedItem changes the focused item to Item then redraws the
+ listbox. }
+ {# FocusItemNum }
+ END;
+ PListBox = ^TListBox;
+
+{---------------------------------------------------------------------------}
+{ TStaticText OBJECT - STATIC TEXT OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TStaticText = OBJECT (TView)
+ Text: PString; { Text string ptr }
+ CONSTRUCTOR Init (Var Bounds: TRect; Const AText: String);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE GetText (Var S: String); Virtual;
+ END;
+ PStaticText = ^TStaticText;
+
+{---------------------------------------------------------------------------}
+{ TParamText OBJECT - PARMETER STATIC TEXT OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Text }
+
+TYPE
+ TParamText = OBJECT (TStaticText)
+ ParamCount: Sw_Integer; { Parameter count }
+ ParamList : Pointer; { Parameter list }
+ CONSTRUCTOR Init (Var Bounds: TRect; Const AText: String;
+ AParamCount: Sw_Integer);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION DataSize: Sw_Word; Virtual;
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE GetText (Var S: String); Virtual;
+ END;
+ PParamText = ^TParamText;
+
+{---------------------------------------------------------------------------}
+{ TLabel OBJECT - LABEL OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TLabel = OBJECT (TStaticText)
+ Light: Boolean;
+ Link: PView; { Linked view }
+ CONSTRUCTOR Init (Var Bounds: TRect; CONST AText: String; ALink: PView);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PLabel = ^TLabel;
+
+{---------------------------------------------------------------------------}
+{ THistoryViewer OBJECT - HISTORY VIEWER OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Active }
+ { 2 = Inactive }
+ { 3 = Focused }
+ { 4 = Selected }
+ { 5 = Divider }
+
+TYPE
+ THistoryViewer = OBJECT (TListViewer)
+ HistoryId: Word; { History id }
+ CONSTRUCTOR Init(Var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar;
+ AHistoryId: Word);
+ FUNCTION HistoryWidth: Sw_Integer;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PHistoryViewer = ^THistoryViewer;
+
+{---------------------------------------------------------------------------}
+{ THistoryWindow OBJECT - HISTORY WINDOW OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Frame passive }
+ { 2 = Frame active }
+ { 3 = Frame icon }
+ { 4 = ScrollBar page area }
+ { 5 = ScrollBar controls }
+ { 6 = HistoryViewer normal text }
+ { 7 = HistoryViewer selected text }
+
+TYPE
+ THistoryWindow = OBJECT (TWindow)
+ Viewer: PListViewer; { List viewer object }
+ CONSTRUCTOR Init (Var Bounds: TRect; HistoryId: Word);
+ FUNCTION GetSelection: String; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE InitViewer (HistoryId: Word); Virtual;
+ END;
+ PHistoryWindow = ^THistoryWindow;
+
+{---------------------------------------------------------------------------}
+{ THistory OBJECT - HISTORY OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Arrow }
+ { 2 = Sides }
+
+TYPE
+ THistory = OBJECT (TView)
+ HistoryId: Word;
+ Link: PInputLine;
+ CONSTRUCTOR Init (Var Bounds: TRect; ALink: PInputLine; AHistoryId: Word);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION InitHistoryWindow (Var Bounds: TRect): PHistoryWindow; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE RecordHistory (CONST S: String); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PHistory = ^THistory;
+
+ {#Z+}
+ PBrowseInputLine = ^TBrowseInputLine;
+ TBrowseInputLine = Object(TInputLine)
+ History: Sw_Word;
+ constructor Init(var Bounds: TRect; AMaxLen: Sw_Integer; AHistory: Sw_Word);
+ constructor Load(var S: TStream);
+ function DataSize: Sw_Word; virtual;
+ procedure GetData(var Rec); virtual;
+ procedure SetData(var Rec); virtual;
+ procedure Store(var S: TStream);
+ end; { of TBrowseInputLine }
+
+ TBrowseInputLineRec = record
+ Text: string;
+ History: Sw_Word;
+ end; { of TBrowseInputLineRec }
+ {#Z+}
+ PBrowseButton = ^TBrowseButton;
+ {#Z-}
+ TBrowseButton = Object(TButton)
+ Link: PBrowseInputLine;
+ constructor Init(var Bounds: TRect; ATitle: TTitleStr; ACommand: Word;
+ AFlags: Byte; ALink: PBrowseInputLine);
+ constructor Load(var S: TStream);
+ procedure Press; virtual;
+ procedure Store(var S: TStream);
+ end; { of TBrowseButton }
+
+
+ {#Z+}
+ PCommandIcon = ^TCommandIcon;
+ {#Z-}
+ TCommandIcon = Object(TStaticText)
+ { A TCommandIcon sends an evCommand message to its owner with
+ Event.Command set to #Command# when it is clicked with a mouse. }
+ constructor Init (var Bounds : TRect; AText : String; ACommand : Word);
+ { Creates an instance of a TCommandIcon and sets #Command# to
+ ACommand. AText is the text which is displayed as the icon. If an
+ error occurs Init fails. }
+ procedure HandleEvent (var Event : TEvent); virtual;
+ { Captures mouse events within its borders and sends an evCommand to
+ its owner in response to the mouse event. }
+ {#X Command }
+ private
+ Command : Word;
+ { Command is the command sent to the command icon's owner when it is
+ clicked. }
+ end; { of TCommandIcon }
+
+
+ {#Z+}
+ PCommandSItem = ^TCommandSItem;
+ {#Z-}
+ TCommandSItem = record
+ { A TCommandSItem is the data structure used to initialize command
+ clusters with #NewCommandSItem# rather than the standarad #NewSItem#.
+ It is used to associate a command with an individual cluster item. }
+ {#X TCommandCheckBoxes TCommandRadioButtons }
+ Value : String;
+ { Value is the text displayed for the cluster item. }
+ {#X Command Next }
+ Command : Word;
+ { Command is the command broadcast when the cluster item is pressed. }
+ {#X Value Next }
+ Next : PCommandSItem;
+ { Next is a pointer to the next item in the cluster. }
+ {#X Value Command }
+ end; { of TCommandSItem }
+
+
+ TCommandArray = array[0..15] of Word;
+ { TCommandArray holds a list of commands which are associated with a
+ cluster. }
+ {#X TCommandCheckBoxes TCommandRadioButtons }
+
+
+ {#Z+}
+ PCommandCheckBoxes = ^TCommandCheckBoxes;
+ {#Z-}
+ TCommandCheckBoxes = Object(TCheckBoxes)
+ { TCommandCheckBoxes function as normal TCheckBoxes, except that when a
+ cluster item is pressed it broadcasts a command associated with the
+ cluster item to the cluster's owner.
+
+ TCommandCheckBoxes are useful when other parts of a dialog should be
+ enabled or disabled in response to a check box's status. }
+ CommandList : TCommandArray;
+ { CommandList is the list of commands associated with each check box
+ item. }
+ {#X Init Load Store }
+ constructor Init (var Bounds : TRect; ACommandStrings : PCommandSItem);
+ { Init calls the inherited constructor, then sets up the #CommandList#
+ with the specified commands. If an error occurs Init fails. }
+ {#X NewCommandSItem }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor, then loads the #CommandList#
+ from the stream S. If an error occurs Load fails. }
+ {#X Store Init }
+ procedure Press (Item : Sw_Integer); virtual;
+ { Press calls the inherited Press then broadcasts the command
+ associated with the cluster item that was pressed to the check boxes'
+ owner. }
+ {#X CommandList }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes the #CommandList#
+ to the stream. }
+ {#X Load }
+ end; { of TCommandCheckBoxes }
+
+
+ {#Z+}
+ PCommandRadioButtons = ^TCommandRadioButtons;
+ {#Z-}
+ TCommandRadioButtons = Object(TRadioButtons)
+ { TCommandRadioButtons function as normal TRadioButtons, except that when
+ a cluster item is pressed it broadcasts a command associated with the
+ cluster item to the cluster's owner.
+
+ TCommandRadioButtons are useful when other parts of a dialog should be
+ enabled or disabled in response to a radiobutton's status. }
+ CommandList : TCommandArray; { commands for each possible value }
+ { The list of commands associated with each radio button item. }
+ {#X Init Load Store }
+ constructor Init (var Bounds : TRect; ACommandStrings : PCommandSItem);
+ { Init calls the inherited constructor and sets up the #CommandList#
+ with the specified commands. If an error occurs Init disposes of the
+ command strings then fails. }
+ {#X NewCommandSItem }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor then loads the #CommandList#
+ from the stream S. If an error occurs Load fails. }
+ {#X Store }
+ procedure MovedTo (Item : Sw_Integer); virtual;
+ { MovedTo calls the inherited MoveTo, then broadcasts the command of
+ the newly selected cluster item to the cluster's owner. }
+ {#X Press CommandList }
+ procedure Press (Item : Sw_Integer); virtual;
+ { Press calls the inherited Press then broadcasts the command
+ associated with the cluster item that was pressed to the check boxes
+ owner. }
+ {#X CommandList MovedTo }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes the #CommandList#
+ to the stream. }
+ {#X Load }
+ end; { of TCommandRadioButtons }
+
+ PEditListBox = ^TEditListBox;
+ TEditListBox = Object(TListBox)
+ CurrentField : Integer;
+ constructor Init (Bounds : TRect; ANumCols: Word;
+ AVScrollBar : PScrollBar);
+ constructor Load (var S : TStream);
+ function FieldValidator : PValidator; virtual;
+ function FieldWidth : Integer; virtual;
+ procedure GetField (InputLine : PInputLine); virtual;
+ function GetPalette : PPalette; virtual;
+ procedure HandleEvent (var Event : TEvent); virtual;
+ procedure SetField (InputLine : PInputLine); virtual;
+ function StartColumn : Integer; virtual;
+ PRIVATE
+ procedure EditField (var Event : TEvent);
+ end; { of TEditListBox }
+
+
+ PModalInputLine = ^TModalInputLine;
+ TModalInputLine = Object(TInputLine)
+ function Execute : Word; virtual;
+ procedure HandleEvent (var Event : TEvent); virtual;
+ procedure SetState (AState : Word; Enable : Boolean); virtual;
+ private
+ EndState : Word;
+ end; { of TModalInputLine }
+
+{---------------------------------------------------------------------------}
+{ TDialog OBJECT - DIALOG OBJECT }
+{---------------------------------------------------------------------------}
+
+ { Palette layout }
+ { 1 = Frame passive }
+ { 2 = Frame active }
+ { 3 = Frame icon }
+ { 4 = ScrollBar page area }
+ { 5 = ScrollBar controls }
+ { 6 = StaticText }
+ { 7 = Label normal }
+ { 8 = Label selected }
+ { 9 = Label shortcut }
+ { 10 = Button normal }
+ { 11 = Button default }
+ { 12 = Button selected }
+ { 13 = Button disabled }
+ { 14 = Button shortcut }
+ { 15 = Button shadow }
+ { 16 = Cluster normal }
+ { 17 = Cluster selected }
+ { 18 = Cluster shortcut }
+ { 19 = InputLine normal text }
+ { 20 = InputLine selected text }
+ { 21 = InputLine arrows }
+ { 22 = History arrow }
+ { 23 = History sides }
+ { 24 = HistoryWindow scrollbar page area }
+ { 25 = HistoryWindow scrollbar controls }
+ { 26 = ListViewer normal }
+ { 27 = ListViewer focused }
+ { 28 = ListViewer selected }
+ { 29 = ListViewer divider }
+ { 30 = InfoPane }
+ { 31 = Cluster disabled }
+ { 32 = Reserved }
+
+ PDialog = ^TDialog;
+ TDialog = object(TWindow)
+ constructor Init(var Bounds: TRect; ATitle: TTitleStr);
+ constructor Load(var S: TStream);
+ procedure Cancel (ACommand : Word); virtual;
+ { If the dialog is a modal dialog, Cancel calls EndModal(ACommand). If
+ the dialog is non-modal Cancel calls Close.
+
+ Cancel may be overridden to provide special processing prior to
+ destructing the dialog. }
+ procedure ChangeTitle (ANewTitle : TTitleStr); virtual;
+ { ChangeTitle disposes of the current title, assigns ANewTitle to Title,
+ then redraws the dialog. }
+ procedure FreeSubView (ASubView : PView); virtual;
+ { FreeSubView deletes and disposes ASubView from the dialog. }
+ {#X FreeAllSubViews IsSubView }
+ procedure FreeAllSubViews; virtual;
+ { Deletes then disposes all subviews in the dialog. }
+ {#X FreeSubView IsSubView }
+ function GetPalette: PPalette; virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ function IsSubView (AView : PView) : Boolean; virtual;
+ { IsSubView returns True if AView is non-nil and is a subview of the
+ dialog. }
+ {#X FreeSubView FreeAllSubViews }
+ function NewButton (X, Y, W, H : Sw_Integer; ATitle : TTitleStr;
+ ACommand, AHelpCtx : Word;
+ AFlags : Byte) : PButton;
+ { Creates and inserts into the dialog a new TButton with the
+ help context AHelpCtx.
+
+ A pointer to the new button is returned for checking validity of the
+ initialization. }
+ {#X NewInputLine NewLabel }
+ function NewLabel (X, Y : Sw_Integer; AText : String;
+ ALink : PView) : PLabel;
+ { NewLabel creates and inserts into the dialog a new TLabel and
+ associates it with ALink. }
+ {#X NewButton NewInputLine }
+ function NewInputLine (X, Y, W, AMaxLen : Sw_Integer; AHelpCtx : Word
+ ; AValidator : PValidator) : PInputLine;
+ { NewInputLine creates and inserts into the dialog a new TBSDInputLine
+ with the help context to AHelpCtx and the validator AValidator.
+
+ A pointer to the inputline is returned for checking validity of the
+ initialization. }
+ {#X NewButton NewLabel }
+ function Valid(Command: Word): Boolean; virtual;
+ end;
+
+ PListDlg = ^TListDlg;
+ TListDlg = object(TDialog)
+ { TListDlg displays a listbox of items, with optional New, Edit, and
+ Delete buttons displayed according to the options bit set in the
+ dialog. Use the ofXXXX flags declared in this unit OR'd with the
+ standard ofXXXX flags to set the appropriate bits in Options.
+
+ If enabled, when the New or Edit buttons are pressed, an evCommand
+ message is sent to the application with a Command value of NewCommand
+ or EditCommand, respectively. Using this mechanism in combination with
+ the declared Init parameters, a standard TListDlg can be used with any
+ type of list displayable in a TListBox or its descendant. }
+ NewCommand: Word;
+ EditCommand: Word;
+ ListBox: PListBox;
+ ldOptions: Word;
+ constructor Init (ATitle: TTitleStr; Items: string; AButtons: Word;
+ AListBox: PListBox; AEditCommand, ANewCommand: Word);
+ constructor Load(var S: TStream);
+ procedure HandleEvent(var Event: TEvent); virtual;
+ procedure Store(var S: TStream); { store should never be virtual;}
+ end; { of TListDlg }
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ ITEM STRING ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-NewSItem-----------------------------------------------------------
+Allocates memory for a new TSItem record and sets the text field
+and chains to the next TSItem. This allows easy construction of
+singly-linked lists of strings, to end a chain the next TSItem
+should be nil.
+28Apr98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewSItem (Const Str: String; ANext: PSItem): PSItem;
+
+{ NewCommandSItem allocates and returns a pointer to a new #TCommandSItem#
+ record. The Value and Next fields of the record are set to NewStr(Str)
+ and ANext, respectively. The NewSItem function and the TSItem record type
+ allow easy construction of singly-linked lists of command strings. }
+function NewCommandSItem (Str : String; ACommand : Word;
+ ANext : PCommandSItem) : PCommandSItem;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ DIALOG OBJECT REGISTRATION PROCEDURE }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-RegisterDialogs----------------------------------------------------
+This registers all the view type objects used in this unit.
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE RegisterDialogs;
+
+{***************************************************************************}
+{ STREAM REGISTRATION RECORDS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TDialog STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RDialog: TStreamRec = (
+ ObjType: idDialog; { Register id = 10 }
+ VmtLink: TypeOf(TDialog);
+ Load: @TDialog.Load; { Object load method }
+ Store: @TDialog.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TInputLine STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RInputLine: TStreamRec = (
+ ObjType: idInputLine; { Register id = 11 }
+ VmtLink: TypeOf(TInputLine);
+ Load: @TInputLine.Load; { Object load method }
+ Store: @TInputLine.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TButton STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RButton: TStreamRec = (
+ ObjType: idButton; { Register id = 12 }
+ VmtLink: TypeOf(TButton);
+ Load: @TButton.Load; { Object load method }
+ Store: @TButton.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TCluster STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RCluster: TStreamRec = (
+ ObjType: idCluster; { Register id = 13 }
+ VmtLink: TypeOf(TCluster);
+ Load: @TCluster.Load; { Object load method }
+ Store: @TCluster.Store { Objects store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TRadioButtons STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RRadioButtons: TStreamRec = (
+ ObjType: idRadioButtons; { Register id = 14 }
+ VmtLink: TypeOf(TRadioButtons);
+ Load: @TRadioButtons.Load; { Object load method }
+ Store: @TRadioButtons.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TCheckBoxes STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RCheckBoxes: TStreamRec = (
+ ObjType: idCheckBoxes; { Register id = 15 }
+ VmtLink: TypeOf(TCheckBoxes);
+ Load: @TCheckBoxes.Load; { Object load method }
+ Store: @TCheckBoxes.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TMultiCheckBoxes STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RMultiCheckBoxes: TStreamRec = (
+ ObjType: idMultiCheckBoxes; { Register id = 27 }
+ VmtLink: TypeOf(TMultiCheckBoxes);
+ Load: @TMultiCheckBoxes.Load; { Object load method }
+ Store: @TMultiCheckBoxes.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TListBox STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RListBox: TStreamRec = (
+ ObjType: idListBox; { Register id = 16 }
+ VmtLink: TypeOf(TListBox);
+ Load: @TListBox.Load; { Object load method }
+ Store: @TListBox.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TStaticText STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RStaticText: TStreamRec = (
+ ObjType: idStaticText; { Register id = 17 }
+ VmtLink: TypeOf(TStaticText);
+ Load: @TStaticText.Load; { Object load method }
+ Store: @TStaticText.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TLabel STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RLabel: TStreamRec = (
+ ObjType: idLabel; { Register id = 18 }
+ VmtLink: TypeOf(TLabel);
+ Load: @TLabel.Load; { Object load method }
+ Store: @TLabel.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ THistory STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RHistory: TStreamRec = (
+ ObjType: idHistory; { Register id = 19 }
+ VmtLink: TypeOf(THistory);
+ Load: @THistory.Load; { Object load method }
+ Store: @THistory.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TParamText STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RParamText: TStreamRec = (
+ ObjType: idParamText; { Register id = 20 }
+ VmtLink: TypeOf(TParamText);
+ Load: @TParamText.Load; { Object load method }
+ Store: @TParamText.Store { Object store method }
+ );
+
+ RCommandCheckBoxes : TStreamRec = (
+ ObjType : idCommandCheckBoxes;
+ VmtLink : Ofs(TypeOf(TCommandCheckBoxes)^);
+ Load : @TCommandCheckBoxes.Load;
+ Store : @TCommandCheckBoxes.Store);
+
+ RCommandRadioButtons : TStreamRec = (
+ ObjType : idCommandRadioButtons;
+ VmtLink : Ofs(TypeOf(TCommandRadioButtons)^);
+ Load : @TCommandRadioButtons.Load;
+ Store : @TCommandRadioButtons.Store);
+
+ RCommandIcon : TStreamRec = (
+ ObjType : idCommandIcon;
+ VmtLink : Ofs(Typeof(TCommandIcon)^);
+ Load : @TCommandIcon.Load;
+ Store : @TCommandIcon.Store);
+
+ RBrowseButton: TStreamRec = (
+ ObjType : idBrowseButton;
+ VmtLink : Ofs(TypeOf(TBrowseButton)^);
+ Load : @TBrowseButton.Load;
+ Store : @TBrowseButton.Store);
+
+ REditListBox : TStreamRec = (
+ ObjType : idEditListBox;
+ VmtLink : Ofs(TypeOf(TEditListBox)^);
+ Load : @TEditListBox.Load;
+ Store : @TEditListBox.Store);
+
+ RListDlg : TStreamRec = (
+ ObjType : idListDlg;
+ VmtLink : Ofs(TypeOf(TListDlg)^);
+ Load : @TListDlg.Load;
+ Store : @TListDlg.Store);
+
+ RModalInputLine : TStreamRec = (
+ ObjType : idModalInputLine;
+ VmtLink : Ofs(TypeOf(TModalInputLine)^);
+ Load : @TModalInputLine.Load;
+ Store : @TModalInputLine.Store);
+
+resourcestring slCancel='Cancel';
+ slOk='O~k~';
+ slYes='~Y~es';
+ slNo='~N~o';
+
+ slHelp='~H~elp';
+ slName='~N~ame';
+
+ slOpen='~O~pen';
+ slClose='~C~lose';
+ slCloseAll='Cl~o~se all';
+
+ slSave='~S~ave';
+ slSaveAll='Save a~l~l';
+ slSaveAs='S~a~ve as...';
+ slSaveFileAs='~S~ave file as';
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+USES App,HistList; { Standard GFV unit }
+
+{***************************************************************************}
+{ PRIVATE DEFINED CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ LEFT AND RIGHT ARROW CHARACTER CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST LeftArr = '<'; RightArr = '>';
+
+{---------------------------------------------------------------------------}
+{ TButton MESSAGES }
+{---------------------------------------------------------------------------}
+CONST
+ cmGrabDefault = 61; { Grab default }
+ cmReleaseDefault = 62; { Release default }
+
+{---------------------------------------------------------------------------}
+{ IsBlank -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION IsBlank (Ch: Char): Boolean;
+BEGIN
+ IsBlank := (Ch = ' ') OR (Ch = #13) OR (Ch = #10); { Check for characters }
+END;
+
+{---------------------------------------------------------------------------}
+{ HotKey -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION HotKey (Const S: String): Char;
+VAR I: Sw_Word;
+BEGIN
+ HotKey := #0; { Preset fail }
+ If (S <> '') Then Begin { Valid string }
+ I := Pos('~', S); { Search for tilde }
+ If (I <> 0) Then HotKey := UpCase(S[I+1]); { Return hotkey }
+ End;
+END;
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TDialog OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TDialog------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TDialog.Init (Var Bounds: TRect; ATitle: TTitleStr);
+BEGIN
+ Inherited Init(Bounds, ATitle, wnNoNumber); { Call ancestor }
+ Options := Options OR ofVersion20; { Version two dialog }
+ GrowMode := 0; { Clear grow mode }
+ Flags := wfMove + wfClose; { Close/moveable flags }
+ Palette := dpGrayDialog; { Default gray colours }
+END;
+
+{--TDialog------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TDialog.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ If (Options AND ofVersion = ofVersion10) Then Begin
+ Palette := dpGrayDialog; { Set gray palette }
+ Options := Options OR ofVersion20; { Update version flag }
+ End;
+END;
+
+{--TDialog------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TDialog.GetPalette: PPalette;
+CONST P: Array[dpBlueDialog..dpGrayDialog] Of String[Length(CBlueDialog)] =
+ (CBlueDialog, CCyanDialog, CGrayDialog); { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P[Palette]); { Return palette }
+END;
+
+{--TDialog------------------------------------------------------------------}
+{ Valid -> Platforms DOS/DPMI/WIN/NT/Os2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TDialog.Valid (Command: Word): Boolean;
+BEGIN
+ If (Command = cmCancel) Then Valid := True { Cancel returns true }
+ Else Valid := TGroup.Valid(Command); { Call group ancestor }
+END;
+
+{--TDialog------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TDialog.HandleEvent (Var Event: TEvent);
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evKeyDown: { Key down event }
+ Case Event.KeyCode Of
+ kbEsc, kbCtrlF4: Begin { Escape key press }
+ Event.What := evCommand; { Command event }
+ Event.Command := cmCancel; { cancel command }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ ClearEvent(Event); { Clear the event }
+ End;
+ kbCtrlF5: Begin { movement of modal dialogs }
+ If (State AND sfModal <> 0) Then
+ begin
+ Event.What := evCommand;
+ Event.Command := cmResize;
+ Event.InfoPtr := Nil;
+ PutEvent(Event);
+ ClearEvent(Event);
+ end;
+ End;
+ kbEnter: Begin { Enter key press }
+ Event.What := evBroadcast; { Broadcast event }
+ Event.Command := cmDefault; { Default command }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ evCommand: { Command event }
+ Case Event.Command Of
+ cmOk, cmCancel, cmYes, cmNo: { End dialog cmds }
+ If (State AND sfModal <> 0) Then Begin { View is modal }
+ EndModal(Event.Command); { End modal state }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ End;
+END;
+
+{****************************************************************************}
+{ TDialog.Cancel }
+{****************************************************************************}
+procedure TDialog.Cancel (ACommand : Word);
+begin
+ if State and sfModal = sfModal then
+ EndModal(ACommand)
+ else Close;
+end;
+
+{****************************************************************************}
+{ TDialog.ChangeTitle }
+{****************************************************************************}
+procedure TDialog.ChangeTitle (ANewTitle : TTitleStr);
+begin
+ if (Title <> nil) then
+ DisposeStr(Title);
+ Title := NewStr(ANewTitle);
+ Frame^.DrawView;
+end;
+
+{****************************************************************************}
+{ TDialog.FreeSubView }
+{****************************************************************************}
+procedure TDialog.FreeSubView (ASubView : PView);
+begin
+ if IsSubView(ASubView) then begin
+ Delete(ASubView);
+ Dispose(ASubView,Done);
+ DrawView;
+ end;
+end;
+
+{****************************************************************************}
+{ TDialog.FreeAllSubViews }
+{****************************************************************************}
+procedure TDialog.FreeAllSubViews;
+var
+ P : PView;
+begin
+ P := First;
+ repeat
+ P := First;
+ if (P <> nil) then begin
+ Delete(P);
+ Dispose(P,Done);
+ end;
+ until (P = nil);
+ DrawView;
+end;
+
+{****************************************************************************}
+{ TDialog.IsSubView }
+{****************************************************************************}
+function TDialog.IsSubView (AView : PView) : Boolean;
+var P : PView;
+begin
+ P := First;
+ while (P <> nil) and (P <> AView) do
+ P := P^.NextView;
+ IsSubView := ((P <> nil) and (P = AView));
+end;
+
+{****************************************************************************}
+{ TDialog.NewButton }
+{****************************************************************************}
+function TDialog.NewButton (X, Y, W, H : Sw_Integer; ATitle : TTitleStr;
+ ACommand, AHelpCtx : Word;
+ AFlags : Byte) : PButton;
+var
+ B : PButton;
+ R : TRect;
+begin
+ R.Assign(X,Y,X+W,Y+H);
+ B := New(PButton,Init(R,ATitle,ACommand,AFlags));
+ if (B <> nil) then begin
+ B^.HelpCtx := AHelpCtx;
+ Insert(B);
+ end;
+ NewButton := B;
+end;
+
+{****************************************************************************}
+{ TDialog.NewInputLine }
+{****************************************************************************}
+function TDialog.NewInputLine (X, Y, W, AMaxLen : Sw_Integer; AHelpCtx : Word
+ ; AValidator : PValidator) : PInputLine;
+var
+ P : PInputLine;
+ R : TRect;
+begin
+ R.Assign(X,Y,X+W,Y+1);
+ P := New(PInputLine,Init(R,AMaxLen));
+ if (P <> nil) then begin
+ P^.SetValidator(AValidator);
+ P^.HelpCtx := AHelpCtx;
+ Insert(P);
+ end;
+ NewInputLine := P;
+end;
+
+{****************************************************************************}
+{ TDialog.NewLabel }
+{****************************************************************************}
+function TDialog.NewLabel (X, Y : Sw_Integer; AText : String;
+ ALink : PView) : PLabel;
+var
+ P : PLabel;
+ R : TRect;
+begin
+ R.Assign(X,Y,X+CStrLen(AText)+1,Y+1);
+ P := New(PLabel,Init(R,AText,ALink));
+ if (P <> nil) then
+ Insert(P);
+ NewLabel := P;
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TInputLine OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TInputLine---------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TInputLine.Init (Var Bounds: TRect; AMaxLen: Sw_Integer);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ State := State OR sfCursorVis; { Cursor visible }
+ Options := Options OR (ofSelectable + ofFirstClick
+ + ofVersion20); { Set options }
+ If (MaxAvail > AMaxLen + 1) Then Begin { Check enough memory }
+ GetMem(Data, AMaxLen + 1); { Allocate memory }
+ Data^ := ''; { Data = empty string }
+ End;
+ MaxLen := AMaxLen; { Hold maximum length }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TInputLine.Load (Var S: TStream);
+VAR B: Byte;
+ W: Word;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(W, sizeof(w)); MaxLen:=W; { Read max length }
+ S.Read(W, sizeof(w)); CurPos:=w; { Read cursor position }
+ S.Read(W, sizeof(w)); FirstPos:=w; { Read first position }
+ S.Read(W, sizeof(w)); SelStart:=w; { Read selected start }
+ S.Read(W, sizeof(w)); SelEnd:=w; { Read selected end }
+ S.Read(B, SizeOf(B)); { Read string length }
+ GetMem(Data, B + 1); { Allocate memory }
+ S.Read(Data^[1], B); { Read string data }
+ SetLength(Data^, B); { Xfer string length }
+ If (Options AND ofVersion >= ofVersion20) Then { Version 2 or above }
+ Validator := PValidator(S.Get); { Get any validator }
+ Options := Options OR ofVersion20; { Set version 2 flag }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TInputLine.Done;
+BEGIN
+ If (Data <> Nil) Then FreeMem(Data, MaxLen + 1); { Release any memory }
+ SetValidator(Nil); { Clear any validator }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TInputLine.DataSize: Sw_Word;
+VAR DSize: Sw_Word;
+BEGIN
+ DSize := 0; { Preset zero datasize }
+ If (Validator <> Nil) AND (Data <> Nil) Then
+ DSize := Validator^.Transfer(Data^, Nil,
+ vtDataSize); { Add validator size }
+ If (DSize <> 0) Then DataSize := DSize { Use validtor size }
+ Else DataSize := MaxLen + 1; { No validator use size }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TInputLine.GetPalette: PPalette;
+CONST P: String[Length(CInputLine)] = CInputLine; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TInputLine.Valid (Command: Word): Boolean;
+
+ FUNCTION AppendError (AValidator: PValidator): Boolean;
+ BEGIN
+ AppendError := False; { Preset false }
+ If (Data <> Nil) Then
+ With AValidator^ Do
+ If (Options AND voOnAppend <> 0) AND { Check options }
+ (CurPos <> Length(Data^)) AND { Exceeds max length }
+ NOT IsValidInput(Data^, True) Then Begin { Check data valid }
+ Error; { Call error }
+ AppendError := True; { Return true }
+ End;
+ END;
+
+BEGIN
+ Valid := Inherited Valid(Command); { Call ancestor }
+ If (Validator <> Nil) AND (Data <> Nil) AND { Validator present }
+ (State AND sfDisabled = 0) Then { Not disabled }
+ If (Command = cmValid) Then { Valid command }
+ Valid := Validator^.Status = vsOk { Validator result }
+ Else If (Command <> cmCancel) Then { Not cancel command }
+ If AppendError(Validator) OR { Append any error }
+ NOT Validator^.Valid(Data^) Then Begin { Check validator }
+ Select; { Reselect view }
+ Valid := False; { Return false }
+ End;
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.Draw;
+VAR Color: Byte; L, R: Sw_Integer;
+ B : TDrawBuffer;
+BEGIN
+ if Options and ofSelectable = 0 then
+ Color := GetColor(5)
+ else
+ If (State AND sfFocused = 0) Then
+ Color := GetColor(1) { Not focused colour }
+ Else
+ Color := GetColor(2); { Focused colour }
+ MoveChar(B, ' ', Color, Size.X);
+ MoveStr(B[1], Copy(Data^, FirstPos + 1, Size.X - 2), Color);
+ if CanScroll(1) then
+ MoveChar(B[Size.X - 1], RightArr, GetColor(4), 1);
+ if (State and sfFocused <> 0) and
+ (Options and ofSelectable <> 0) then
+ begin
+ if CanScroll(-1) then
+ MoveChar(B[0], LeftArr, GetColor(4), 1);
+ { Highlighted part }
+ L := SelStart - FirstPos;
+ R := SelEnd - FirstPos;
+ if L < 0 then
+ L := 0;
+ if R > Size.X - 2 then
+ R := Size.X - 2;
+ if L < R then
+ MoveChar(B[L + 1], #0, GetColor(3), R - L);
+ SetCursor(CurPos - FirstPos + 1, 0);
+ end;
+ WriteLine(0, 0, Size.X, Size.Y, B);
+end;
+
+
+{--TInputLine---------------------------------------------------------------}
+{ DrawCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.DrawCursor;
+BEGIN
+ If (State AND sfFocused <> 0) Then
+ Begin { Focused window }
+ Cursor.Y:=0;
+ Cursor.X:=CurPos-FirstPos+1;
+ ResetCursor;
+ end;
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ SelectAll -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.SelectAll (Enable: Boolean);
+BEGIN
+ CurPos := 0; { Cursor to start }
+ FirstPos := 0; { First pos to start }
+ SelStart := 0; { Selected at start }
+ If Enable AND (Data <> Nil) Then
+ SelEnd := Length(Data^) Else SelEnd := 0; { Selected which end }
+ DrawView; { Now redraw the view }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ SetValidator -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.SetValidator (AValid: PValidator);
+BEGIN
+ If (Validator <> Nil) Then Validator^.Free; { Release validator }
+ Validator := AValid; { Set new validator }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.SetState (AState: Word; Enable: Boolean);
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState = sfSelected) OR ((AState = sfActive)
+ AND (State and sfSelected <> 0)) Then
+ SelectAll(Enable) Else { Call select all }
+ If (AState = sfFocused) Then DrawView; { Redraw for focus }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.GetData (Var Rec);
+BEGIN
+ If (Data <> Nil) Then Begin { Data ptr valid }
+ If (Validator = Nil) OR (Validator^.Transfer(Data^,
+ @Rec, vtGetData) = 0) Then Begin { No validator/data }
+ FillChar(Rec, DataSize, #0); { Clear the data area }
+ Move(Data^, Rec, Length(Data^) + 1); { Transfer our data }
+ End;
+ End Else FillChar(Rec, DataSize, #0); { Clear the data area }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.SetData (Var Rec);
+BEGIN
+ If (Data <> Nil) Then Begin { Data ptr valid }
+ If (Validator = Nil) OR (Validator^.Transfer(
+ Data^, @Rec, vtSetData) = 0) Then { No validator/data }
+ Move(Rec, Data^[0], DataSize); { Set our data }
+ End;
+ SelectAll(True); { Now select all }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.Store (Var S: TStream);
+VAR w: Word;
+BEGIN
+ TView.Store(S); { Implict TView.Store }
+ w:=MaxLen;S.Write(w, SizeOf(w)); { Read max length }
+ w:=CurPos;S.Write(w, SizeOf(w)); { Read cursor position }
+ w:=FirstPos;S.Write(w, SizeOf(w)); { Read first position }
+ w:=SelStart;S.Write(w, SizeOf(w)); { Read selected start }
+ w:=SelEnd;S.Write(w, SizeOf(w)); { Read selected end }
+ S.WriteStr(Data); { Write the data }
+ S.Put(Validator); { Write any validator }
+END;
+
+{--TInputLine---------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TInputLine.HandleEvent (Var Event: TEvent);
+CONST PadKeys = [$47, $4B, $4D, $4F, $73, $74];
+VAR WasAppending: Boolean; ExtendBlock: Boolean; OldData: String;
+Delta, Anchor, OldCurPos, OldFirstPos, OldSelStart, OldSelEnd: Sw_Integer;
+
+ FUNCTION MouseDelta: Sw_Integer;
+ VAR Mouse : TPOint;
+ BEGIN
+ MakeLocal(Event.Where, Mouse);
+ if Mouse.X <= 0 then
+ MouseDelta := -1
+ else if Mouse.X >= Size.X - 1 then
+ MouseDelta := 1
+ else
+ MouseDelta := 0;
+ END;
+
+ FUNCTION MousePos: Sw_Integer;
+ VAR Pos: Sw_Integer;
+ Mouse : TPoint;
+ BEGIN
+ MakeLocal(Event.Where, Mouse);
+ if Mouse.X < 1 then Mouse.X := 1;
+ Pos := Mouse.X + FirstPos - 1;
+ if Pos < 0 then Pos := 0;
+ if Pos > Length(Data^) then Pos := Length(Data^);
+ MousePos := Pos;
+ END;
+
+ PROCEDURE DeleteSelect;
+ BEGIN
+ If (SelStart <> SelEnd) Then Begin { An area selected }
+ If (Data <> Nil) Then
+ Delete(Data^, SelStart+1, SelEnd-SelStart); { Delete the text }
+ CurPos := SelStart; { Set cursor position }
+ End;
+ END;
+
+ PROCEDURE AdjustSelectBlock;
+ BEGIN
+ If (CurPos < Anchor) Then Begin { Selection backwards }
+ SelStart := CurPos; { Start of select }
+ SelEnd := Anchor; { End of select }
+ End Else Begin
+ SelStart := Anchor; { Start of select }
+ SelEnd := CurPos; { End of select }
+ End;
+ END;
+
+ PROCEDURE SaveState;
+ BEGIN
+ If (Validator <> Nil) Then Begin { Check for validator }
+ If (Data <> Nil) Then OldData := Data^; { Hold data }
+ OldCurPos := CurPos; { Hold cursor position }
+ OldFirstPos := FirstPos; { Hold first position }
+ OldSelStart := SelStart; { Hold select start }
+ OldSelEnd := SelEnd; { Hold select end }
+ If (Data = Nil) Then WasAppending := True { Invalid data ptr }
+ Else WasAppending := Length(Data^) = CurPos; { Hold appending state }
+ End;
+ END;
+
+ PROCEDURE RestoreState;
+ BEGIN
+ If (Validator <> Nil) Then Begin { Validator valid }
+ If (Data <> Nil) Then Data^ := OldData; { Restore data }
+ CurPos := OldCurPos; { Restore cursor pos }
+ FirstPos := OldFirstPos; { Restore first pos }
+ SelStart := OldSelStart; { Restore select start }
+ SelEnd := OldSelEnd; { Restore select end }
+ End;
+ END;
+
+ FUNCTION CheckValid (NoAutoFill: Boolean): Boolean;
+ VAR OldLen: Sw_Integer; NewData: String;
+ BEGIN
+ If (Validator <> Nil) Then Begin { Validator valid }
+ CheckValid := False; { Preset false return }
+ If (Data <> Nil) Then OldLen := Length(Data^); { Hold old length }
+ If (Validator^.Options AND voOnAppend = 0) OR
+ (WasAppending AND (CurPos = OldLen)) Then Begin
+ If (Data <> Nil) Then NewData := Data^ { Hold current data }
+ Else NewData := ''; { Set empty string }
+ If NOT Validator^.IsValidInput(NewData,
+ NoAutoFill) Then RestoreState Else Begin
+ If (Length(NewData) > MaxLen) Then { Exceeds maximum }
+ SetLength(NewData, MaxLen); { Set string length }
+ If (Data <> Nil) Then Data^ := NewData; { Set data value }
+ If (Data <> Nil) AND (CurPos >= OldLen) { Cursor beyond end }
+ AND (Length(Data^) > OldLen) Then { Cursor beyond string }
+ CurPos := Length(Data^); { Set cursor position }
+ CheckValid := True; { Return true result }
+ End;
+ End Else Begin
+ CheckValid := True; { Preset true return }
+ If (CurPos = OldLen) AND (Data <> Nil) Then { Lengths match }
+ If NOT Validator^.IsValidInput(Data^,
+ False) Then Begin { Check validator }
+ Validator^.Error; { Call error }
+ CheckValid := False; { Return false result }
+ End;
+ End;
+ End Else CheckValid := True; { No validator }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (State AND sfSelected <> 0) Then Begin { View is selected }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evMouseDown: Begin { Mouse down event }
+ Delta := MouseDelta; { Calc scroll value }
+ If CanScroll(Delta) Then Begin { Can scroll }
+ Repeat
+ If CanScroll(Delta) Then Begin { Still can scroll }
+ Inc(FirstPos, Delta); { Move start position }
+ DrawView; { Redraw the view }
+ End;
+ Until NOT MouseEvent(Event, evMouseAuto); { Until no mouse auto }
+ End Else If Event.Double Then { Double click }
+ SelectAll(True) Else Begin { Select whole text }
+ Anchor := MousePos; { Start of selection }
+ Repeat
+ If (Event.What = evMouseAuto) { Mouse auto event }
+ Then Begin
+ Delta := MouseDelta; { New position }
+ If CanScroll(Delta) Then { If can scroll }
+ Inc(FirstPos, Delta);
+ End;
+ CurPos := MousePos; { Set cursor position }
+ AdjustSelectBlock; { Adjust selected }
+ DrawView; { Redraw the view }
+ Until NOT MouseEvent(Event, evMouseMove
+ + evMouseAuto); { Until mouse released }
+ End;
+ ClearEvent(Event); { Clear the event }
+ End;
+ evKeyDown: Begin
+ SaveState; { Save state of view }
+ Event.KeyCode := CtrlToArrow(Event.KeyCode); { Convert keycode }
+ If (Event.ScanCode IN PadKeys) AND
+ (GetShiftState AND $03 <> 0) Then Begin { Mark selection active }
+ Event.CharCode := #0; { Clear char code }
+ If (CurPos = SelEnd) Then { Find if at end }
+ Anchor := SelStart Else { Anchor from start }
+ Anchor := SelEnd; { Anchor from end }
+ ExtendBlock := True; { Extended block true }
+ End Else ExtendBlock := False; { No extended block }
+ Case Event.KeyCode Of
+ kbLeft: If (CurPos > 0) Then Dec(CurPos); { Move cursor left }
+ kbRight: If (Data <> Nil) AND { Move right cursor }
+ (CurPos < Length(Data^)) Then Begin { Check not at end }
+ Inc(CurPos); { Move cursor }
+ CheckValid(True); { Check if valid }
+ End;
+ kbHome: CurPos := 0; { Move to line start }
+ kbEnd: Begin { Move to line end }
+ If (Data = Nil) Then CurPos := 0 { Invalid data ptr }
+ Else CurPos := Length(Data^); { Set cursor position }
+ CheckValid(True); { Check if valid }
+ End;
+ kbBack: If (Data <> Nil) AND (CurPos > 0) { Not at line start }
+ Then Begin
+ Delete(Data^, CurPos, 1); { Backspace over char }
+ Dec(CurPos); { Move cursor back one }
+ If (FirstPos > 0) Then Dec(FirstPos); { Move first position }
+ CheckValid(True); { Check if valid }
+ End;
+ kbDel: If (Data <> Nil) Then Begin { Delete character }
+ If (SelStart = SelEnd) Then { Select all on }
+ If (CurPos < Length(Data^)) Then Begin { Cursor not at end }
+ SelStart := CurPos; { Set select start }
+ SelEnd := CurPos + 1; { Set select end }
+ End;
+ DeleteSelect; { Deselect selection }
+ CheckValid(True); { Check if valid }
+ End;
+ kbIns: SetState(sfCursorIns, State AND
+ sfCursorIns = 0); { Flip insert state }
+ Else Case Event.CharCode Of
+ ' '..#255: If (Data <> Nil) Then Begin { Character key }
+ If (State AND sfCursorIns <> 0) Then
+ Delete(Data^, CurPos + 1, 1) Else { Overwrite character }
+ DeleteSelect; { Deselect selected }
+ If CheckValid(True) Then Begin { Check data valid }
+ If (Length(Data^) < MaxLen) Then { Must not exceed maxlen }
+ Begin
+ If (FirstPos > CurPos) Then
+ FirstPos := CurPos; { Advance first position }
+ Inc(CurPos); { Increment cursor }
+ Insert(Event.CharCode, Data^,
+ CurPos); { Insert the character }
+ End;
+ CheckValid(False); { Check data valid }
+ End;
+ End;
+ ^Y: If (Data <> Nil) Then Begin { Clear all data }
+ Data^ := ''; { Set empty string }
+ CurPos := 0; { Cursor to start }
+ End;
+ Else Exit; { Unused key }
+ End
+ End;
+ If ExtendBlock Then AdjustSelectBlock { Extended block }
+ Else Begin
+ SelStart := CurPos; { Set select start }
+ SelEnd := CurPos; { Set select end }
+ End;
+ If (FirstPos > CurPos) Then
+ FirstPos := CurPos; { Advance first pos }
+ If (Data <> Nil) Then OldData := Copy(Data^,
+ FirstPos+1, CurPos-FirstPos) { Text area string }
+ Else OldData := ''; { Empty string }
+ Delta := 1; { Safety = 1 char }
+ While (TextWidth(OldData) > (Size.X-Delta)
+ - TextWidth(LeftArr) - TextWidth(RightArr)) { Check text fits }
+ Do Begin
+ Inc(FirstPos); { Advance first pos }
+ OldData := Copy(Data^, FirstPos+1,
+ CurPos-FirstPos) { Text area string }
+ End;
+ DrawView; { Redraw the view }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ End;
+END;
+
+{***************************************************************************}
+{ TInputLine OBJECT PRIVATE METHODS }
+{***************************************************************************}
+{--TInputLine---------------------------------------------------------------}
+{ CanScroll -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TInputLine.CanScroll (Delta: Sw_Integer): Boolean;
+VAR S: String;
+BEGIN
+ If (Delta < 0) Then CanScroll := FirstPos > 0 { Check scroll left }
+ Else If (Delta > 0) Then Begin
+ If (Data = Nil) Then S := '' Else { Data ptr invalid }
+ S := Copy(Data^, FirstPos+1, Length(Data^)
+ - FirstPos); { Fetch max string }
+ CanScroll := (TextWidth(S)) > (Size.X -
+ TextWidth(LeftArr) - TextWidth(RightArr)); { Check scroll right }
+ End Else CanScroll := False; { Zero so no scroll }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TButton OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TButton------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TButton.Init (Var Bounds: TRect; ATitle: TTitleStr;
+ ACommand: Word; AFlags: Word);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ EventMask := EventMask OR evBroadcast; { Handle broadcasts }
+ Options := Options OR (ofSelectable + ofFirstClick
+ + ofPreProcess + ofPostProcess); { Set option flags }
+ If NOT CommandEnabled(ACommand) Then
+ State := State OR sfDisabled; { Check command state }
+ Flags := AFlags; { Hold flags }
+ If (AFlags AND bfDefault <> 0) Then AmDefault := True
+ Else AmDefault := False; { Check if default }
+ Title := NewStr(ATitle); { Hold title string }
+ Command := ACommand; { Hold button command }
+ TabMask := TabMask OR (tmLeft + tmRight +
+ tmTab + tmShiftTab + tmUp + tmDown); { Set tab masks }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TButton.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Title := S.ReadStr; { Read title }
+ S.Read(Command, SizeOf(Command)); { Read command }
+ S.Read(Flags, SizeOf(Flags)); { Read flags }
+ S.Read(AmDefault, SizeOf(AmDefault)); { Read if default }
+ If NOT CommandEnabled(Command) Then { Check command state }
+ State := State OR sfDisabled Else { Command disabled }
+ State := State AND NOT sfDisabled; { Command enabled }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TButton.Done;
+BEGIN
+ If (Title <> Nil) Then DisposeStr(Title); { Dispose title }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TButton.GetPalette: PPalette;
+CONST P: String[Length(CButton)] = CButton; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Get button palette }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ Press -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.Press;
+VAR E: TEvent;
+BEGIN
+ Message(Owner, evBroadcast, cmRecordHistory, Nil); { Message for history }
+ If (Flags AND bfBroadcast <> 0) Then { Broadcasting button }
+ Message(Owner, evBroadcast, Command, @Self) { Send message }
+ Else Begin
+ E.What := evCommand; { Command event }
+ E.Command := Command; { Set command value }
+ E.InfoPtr := @Self; { Pointer to self }
+ PutEvent(E); { Put event on queue }
+ End;
+END;
+
+{--TButton------------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.Draw;
+VAR I, J, Pos: Sw_Integer;
+ Bc: Word; Db: TDrawBuffer;
+ C : char;
+BEGIN
+ If (State AND sfDisabled <> 0) Then { Button disabled }
+ Bc := GetColor($0404) Else Begin { Disabled colour }
+ Bc := GetColor($0501); { Set normal colour }
+ If (State AND sfActive <> 0) Then { Button is active }
+ If (State AND sfSelected <> 0) Then
+ Bc := GetColor($0703) Else { Set selected colour }
+ If AmDefault Then Bc := GetColor($0602); { Set is default colour }
+ End;
+ if title=nil then
+ begin
+ MoveChar(Db[0],' ',GetColor(8),1);
+ {No title, draw an empty button.}
+ for j:=sw_integer(downflag) to size.x-2 do
+ MoveChar(Db[j],' ',Bc,1);
+ end
+ else
+ {We have a title.}
+ begin
+ If (Flags AND bfLeftJust = 0) Then Begin { Not left set title }
+ I := CTextWidth(Title^); { Fetch title width }
+ I := (Size.X - I) DIV 2; { Centre in button }
+ End
+ Else
+ I := 1; { Left edge of button }
+ If DownFlag then
+ begin
+ MoveChar(Db[0],' ',GetColor(8),1);
+ Pos:=1;
+ end
+ else
+ pos:=0;
+ For j:=0 to I-1 do
+ MoveChar(Db[pos+j],' ',Bc,1);
+ MoveCStr(Db[I+pos], Title^, Bc); { Move title to buffer }
+ For j:=pos+CStrLen(Title^)+I to size.X-2 do
+ MoveChar(Db[j],' ',Bc,1);
+ end;
+ If not DownFlag then
+ Bc:=GetColor(8);
+ MoveChar(Db[Size.X-1],' ',Bc,1);
+ WriteLine(0, 0, Size.X,1, Db); { Write the title }
+ If Size.Y>1 then Begin
+ Bc:=GetColor(8);
+ if not DownFlag then
+ begin
+ c:='Ü';
+ MoveChar(Db,c,Bc,1);
+ WriteLine(Size.X-1, 0, 1, 1, Db);
+ end;
+ MoveChar(Db,' ',Bc,1);
+ if DownFlag then c:=' '
+ else c:='ß';
+ MoveChar(Db[1],c,Bc,Size.X-1);
+ WriteLine(0, 1, Size.X, 1, Db);
+ End;
+END;
+
+{--TButton------------------------------------------------------------------}
+{ DrawState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.DrawState (Down: Boolean);
+BEGIN
+ DownFlag := Down; { Set down flag }
+ DrawView; { Redraw the view }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ MakeDefault -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.MakeDefault (Enable: Boolean);
+VAR C: Word;
+BEGIN
+ If (Flags AND bfDefault=0) Then Begin { Not default }
+ If Enable Then C := cmGrabDefault
+ Else C := cmReleaseDefault; { Change default }
+ Message(Owner, evBroadcast, C, @Self); { Message to owner }
+ AmDefault := Enable; { Set default flag }
+ DrawView; { Now redraw button }
+ End;
+END;
+
+{--TButton------------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.SetState (AState: Word; Enable: Boolean);
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState AND (sfSelected + sfActive) <> 0) { Changing select }
+ Then DrawView; { Redraw required }
+ If (AState AND sfFocused <> 0) Then
+ MakeDefault(Enable); { Check for default }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.Store (Var S: TStream);
+BEGIN
+ TView.Store(S); { Implict TView.Store }
+ S.WriteStr(Title); { Store title string }
+ S.Write(Command, SizeOf(Command)); { Store command }
+ S.Write(Flags, SizeOf(Flags)); { Store flags }
+ S.Write(AmDefault, SizeOf(AmDefault)); { Store default flag }
+END;
+
+{--TButton------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TButton.HandleEvent (Var Event: TEvent);
+VAR Down: Boolean; C: Char; ButRect: TRect;
+ Mouse : TPoint;
+BEGIN
+ ButRect.A.X := 0; { Get origin point }
+ ButRect.A.Y := 0; { Get origin point }
+ ButRect.B.X := Size.X + 2; { Calc right side }
+ ButRect.B.Y := Size.Y + 1; { Calc bottom }
+ If (Event.What = evMouseDown) Then Begin { Mouse down event }
+ MakeLocal(Event.Where, Mouse);
+ If NOT ButRect.Contains(Mouse) Then Begin { If point not in view }
+ ClearEvent(Event); { Clear the event }
+ Exit; { Speed up exit }
+ End;
+ End;
+ If (Flags AND bfGrabFocus <> 0) Then { Check focus grab }
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evMouseDown: Begin
+ If (State AND sfDisabled = 0) Then Begin { Button not disabled }
+ Down := False; { Clear down flag }
+ Repeat
+ MakeLocal(Event.Where, Mouse);
+ If (Down <> ButRect.Contains(Mouse)) { State has changed }
+ Then Begin
+ Down := NOT Down; { Invert down flag }
+ DrawState(Down); { Redraw button }
+ End;
+ Until NOT MouseEvent(Event, evMouseMove); { Wait for mouse move }
+ If Down Then Begin { Button is down }
+ Press; { Send out command }
+ DrawState(False); { Draw button up }
+ End;
+ End;
+ ClearEvent(Event); { Event was handled }
+ End;
+ evKeyDown: Begin
+ If (Title <> Nil) Then C := HotKey(Title^) { Key title hotkey }
+ Else C := #0; { Invalid title }
+ If (Event.KeyCode = GetAltCode(C)) OR { Alt char }
+ (Owner^.Phase = phPostProcess) AND (C <> #0)
+ AND (Upcase(Event.CharCode) = C) OR { Matches hotkey }
+ (State AND sfFocused <> 0) AND { View focused }
+ ((Event.CharCode = ' ') OR { Space bar }
+ (Event.KeyCode=kbEnter)) Then Begin { Enter key }
+ DrawState(True); { Draw button down }
+ Press; { Send out command }
+ ClearEvent(Event); { Clear the event }
+ DrawState(False); { Draw button up }
+ End;
+ End;
+ evBroadcast:
+ Case Event.Command of
+ cmDefault: If AmDefault AND { Default command }
+ (State AND sfDisabled = 0) Then Begin { Button enabled }
+ Press; { Send out command }
+ ClearEvent(Event); { Clear the event }
+ End;
+ cmGrabDefault, cmReleaseDefault: { Grab and release cmd }
+ If (Flags AND bfDefault <> 0) Then Begin { Change button state }
+ AmDefault := Event.Command = cmReleaseDefault;
+ DrawView; { Redraw the view }
+ End;
+ cmCommandSetChanged: Begin { Command set changed }
+ SetState(sfDisabled, NOT
+ CommandEnabled(Command)); { Set button state }
+ DrawView; { Redraw the view }
+ End;
+ End;
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TCluster OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+CONST TvClusterClassName = 'TVCLUSTER';
+
+{--TCluster-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TCluster.Init (Var Bounds: TRect; AStrings: PSItem);
+VAR I: Sw_Integer; P: PSItem;
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR (ofSelectable + ofFirstClick
+ + ofPreProcess + ofPostProcess + ofVersion20); { Set option masks }
+ I := 0; { Zero string count }
+ P := AStrings; { First item }
+ While (P <> Nil) Do Begin
+ Inc(I); { Count 1 item }
+ P := P^.Next; { Move to next item }
+ End;
+ Strings.Init(I, 0); { Create collection }
+ While (AStrings <> Nil) Do Begin
+ P := AStrings; { Transfer item ptr }
+ Strings.AtInsert(Strings.Count, AStrings^.Value);{ Insert string }
+ AStrings := AStrings^.Next; { Move to next item }
+ Dispose(P); { Dispose prior item }
+ End;
+ Sel := 0;
+ SetCursor(2,0);
+ ShowCursor;
+ EnableMask := Sw_Integer($FFFFFFFF); { Enable bit masks }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TCluster.Load (Var S: TStream);
+VAR w: word;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ If ((Options AND ofVersion) >= ofVersion20) Then { Version 2 TV view }
+ Begin
+ S.Read(Value, SizeOf(Value)); { Read value }
+ S.Read(Sel, Sizeof(Sel)); { Read select item }
+ S.Read(EnableMask, SizeOf(EnableMask)) { Read enable masks }
+ End
+ Else
+ Begin
+ w:=Value;
+ S.Read(w, SizeOf(w)); Value:=w; { Read value }
+ S.Read(Sel, SizeOf(Sel)); { Read select item }
+ EnableMask := Sw_integer($FFFFFFFF); { Enable all masks }
+ Options := Options OR ofVersion20; { Set version 2 mask }
+ End;
+ Strings.Load(S); { Load string data }
+ SetButtonState(0, True); { Set button state }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TCluster.Done;
+BEGIN
+ Strings.Done; { Dispose of strings }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.DataSize: Sw_Word;
+BEGIN
+ DataSize := SizeOf(Sw_Word); { Exchanges a word }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.GetHelpCtx: Word;
+BEGIN
+ If (HelpCtx = hcNoContext) Then { View has no help }
+ GetHelpCtx := hcNoContext Else { No help context }
+ GetHelpCtx := HelpCtx + Sel; { Help of selected }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.GetPalette: PPalette;
+CONST P: String[Length(CCluster)] = CCluster; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Cluster palette }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Mark -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.Mark (Item: Sw_Integer): Boolean;
+BEGIN
+ Mark := False; { Default false }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ MultiMark -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.MultiMark (Item: Sw_Integer): Byte;
+BEGIN
+ MultiMark := Byte(Mark(Item) = True); { Return multi mark }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ ButtonState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.ButtonState (Item: Sw_Integer): Boolean;
+BEGIN
+ If (Item > 31) Then ButtonState := False Else { Impossible item }
+ ButtonState := ((1 SHL Item) AND EnableMask)<>0; { Return true/false }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.Draw;
+BEGIN
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Press -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.Press (Item: Sw_Integer);
+VAR P: PView;
+BEGIN
+ P := TopView;
+ If (Id <> 0) AND (P <> Nil) Then NewMessage(P,
+ evCommand, cmIdCommunicate, Id, Value, @Self); { Send new message }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ MovedTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.MovedTo (Item: Sw_Integer);
+BEGIN { Abstract method }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.SetState (AState: Word; Enable: Boolean);
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState AND sfFocused <> 0) Then Begin
+ DrawView; { Redraw masked areas }
+ End;
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ DrawMultiBox -> Platforms DOS/DPMI/WIN/NT - Updated 05Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.DrawMultiBox (Const Icon, Marker: String);
+VAR I, J, Cur, Col: Sw_Integer; CNorm, CSel, CDis, Color: Word; B: TDrawBuffer;
+BEGIN
+ CNorm := GetColor($0301); { Normal colour }
+ CSel := GetColor($0402); { Selected colour }
+ CDis := GetColor($0505); { Disabled colour }
+ For I := 0 To Size.Y-1 Do Begin { For each line }
+ MoveChar(B, ' ', Byte(CNorm), Size.X); { Fill buffer }
+ For J := 0 To (Strings.Count - 1) DIV Size.Y + 1
+ Do Begin
+ Cur := J*Size.Y + I; { Current line }
+ If (Cur < Strings.Count) Then Begin
+ Col := Column(Cur); { Calc column }
+ If (Col + CStrLen(PString(Strings.At(Cur))^)+
+ 5 < Sizeof(TDrawBuffer) DIV SizeOf(Word))
+ AND (Col < Size.X) Then Begin { Text fits in column }
+ If NOT ButtonState(Cur) Then
+ Color := CDis Else If (Cur = Sel) AND { Disabled colour }
+ (State and sfFocused <> 0) Then
+ Color := CSel Else { Selected colour }
+ Color := CNorm; { Normal colour }
+ MoveChar(B[Col], ' ', Byte(Color),
+ Size.X-Col); { Set this colour }
+ MoveStr(B[Col], Icon, Byte(Color)); { Transfer icon string }
+ WordRec(B[Col+2]).Lo := Byte(Marker[
+ MultiMark(Cur) + 1]); { Transfer marker }
+ MoveCStr(B[Col+5], PString(Strings.At(
+ Cur))^, Color); { Transfer item string }
+ If ShowMarkers AND (State AND sfFocused <> 0)
+ AND (Cur = Sel) Then Begin { Current is selected }
+ WordRec(B[Col]).Lo := Byte(SpecialChars[0]);
+ WordRec(B[Column(Cur+Size.Y)-1]).Lo
+ := Byte(SpecialChars[1]); { Set special character }
+ End;
+ End;
+ End;
+ End;
+ WriteBuf(0, I, Size.X, 1, B); { Write buffer }
+ End;
+ SetCursor(Column(Sel)+2,Row(Sel));
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ DrawBox -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.DrawBox (Const Icon: String; Marker: Char);
+BEGIN
+ DrawMultiBox(Icon, ' '+Marker); { Call draw routine }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ SetButtonState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.SetButtonState (AMask: Longint; Enable: Boolean);
+VAR I: Sw_Integer; M: Longint;
+BEGIN
+ If Enable Then EnableMask := EnableMask OR AMask { Set enable bit mask }
+ Else EnableMask := EnableMask AND NOT AMask; { Disable bit mask }
+ If (Strings.Count <= 32) Then Begin { Valid string number }
+ M := 1; { Preset bit masks }
+ For I := 1 To Strings.Count Do Begin { For each item string }
+ If ((M AND EnableMask) <> 0) Then Begin { Bit enabled }
+ Options := Options OR ofSelectable; { Set selectable option }
+ Exit; { Now exit }
+ End;
+ M := M SHL 1; { Create newbit mask }
+ End;
+ Options := Options AND NOT ofSelectable; { Make not selectable }
+ End;
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.GetData (Var Rec);
+BEGIN
+ sw_Word(Rec) := Value; { Return current value }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.SetData (Var Rec);
+BEGIN
+ Value :=sw_Word(Rec); { Set current value }
+ DrawView; { Redraw masked areas }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.Store (Var S: TStream);
+var
+ w : word;
+BEGIN
+ TView.Store(S); { TView.Store called }
+ If ((Options AND ofVersion) >= ofVersion20) { Version 2 TV view }
+ Then Begin
+ S.Write(Value, SizeOf(Value)); { Write value }
+ S.Write(Sel, SizeOf(Sel)); { Write select item }
+ S.Write(EnableMask, SizeOf(EnableMask)); { Write enable masks }
+ End Else Begin
+ w:=Value;
+ S.Write(w, SizeOf(Word)); { Write value }
+ S.Write(Sel, SizeOf(Sel)); { Write select item }
+ End;
+ Strings.Store(S); { Store strings }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCluster.HandleEvent (Var Event: TEvent);
+VAR C: Char; I, S, Vh: Sw_Integer; Key: Word; Mouse: TPoint; Ts: PString;
+
+ PROCEDURE MoveSel;
+ BEGIN
+ If (I <= Strings.Count) Then Begin
+ Sel := S; { Set selected item }
+ MovedTo(Sel); { Move to selected }
+ DrawView; { Now draw changes }
+ End;
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If ((Options AND ofSelectable) = 0) Then Exit; { Check selectable }
+ If (Event.What = evMouseDown) Then Begin { MOUSE EVENT }
+ MakeLocal(Event.Where, Mouse); { Make point local }
+ I := FindSel(Mouse); { Find selected item }
+ If (I <> -1) Then { Check in view }
+ If ButtonState(I) Then Sel := I; { If enabled select }
+ DrawView; { Now draw changes }
+ Repeat
+ MakeLocal(Event.Where, Mouse); { Make point local }
+ Until NOT MouseEvent(Event, evMouseMove); { Wait for mouse up }
+ MakeLocal(Event.Where, Mouse); { Make point local }
+ If (FindSel(Mouse) = Sel) AND ButtonState(Sel) { If valid/selected }
+ Then Begin
+ Press(Sel); { Call pressed }
+ DrawView; { Now draw changes }
+ End;
+ ClearEvent(Event); { Event was handled }
+ End Else If (Event.What = evKeyDown) Then Begin { KEY EVENT }
+ Vh := Size.Y; { View height }
+ S := Sel; { Hold current item }
+ Key := CtrlToArrow(Event.KeyCode); { Convert keystroke }
+ Case Key Of
+ kbUp, kbDown, kbRight, kbLeft:
+ If (State AND sfFocused <> 0) Then Begin { Focused key event }
+ I := 0; { Zero process count }
+ Repeat
+ Inc(I); { Inc process count }
+ Case Key Of
+ kbUp: Dec(S); { Next item up }
+ kbDown: Inc(S); { Next item down }
+ kbRight: Begin { Next column across }
+ Inc(S, Vh); { Move to next column }
+ If (S >= Strings.Count) Then { No next column check }
+ S := (S+1) MOD Vh; { Move to last column }
+ End;
+ kbLeft: Begin { Prior column across }
+ Dec(S, Vh); { Move to prior column }
+ If (S < 0) Then S := ((Strings.Count +
+ Vh - 1) DIV Vh) * Vh + S - 1; { No prior column check }
+ End;
+ End;
+ If (S >= Strings.Count) Then S := 0; { Roll up to top }
+ If (S < 0) Then S := Strings.Count - 1; { Roll down to bottom }
+ Until ButtonState(S) OR (I > Strings.Count); { Repeat until select }
+ MoveSel; { Move to selected }
+ ClearEvent(Event); { Event was handled }
+ End;
+ Else Begin { Not an arrow key }
+ For I := 0 To Strings.Count-1 Do Begin { Scan each item }
+ Ts := Strings.At(I); { Fetch string pointer }
+ If (Ts <> Nil) Then C := HotKey(Ts^) { Check for hotkey }
+ Else C := #0; { No valid string }
+ If (GetAltCode(C) = Event.KeyCode) OR { Hot key for item }
+ (((Owner^.Phase = phPostProcess) OR { Owner in post process }
+ (State AND sfFocused <> 0)) AND (C <> #0) { Non zero hotkey }
+ AND (UpCase(Event.CharCode) = C)) { Matches current key }
+ Then Begin
+ If ButtonState(I) Then Begin { Check mask enabled }
+ If Focus Then Begin { Check view focus }
+ Sel := I; { Set selected }
+ MovedTo(Sel); { Move to selected }
+ Press(Sel); { Call pressed }
+ DrawView; { Now draw changes }
+ End;
+ ClearEvent(Event); { Event was handled }
+ End;
+ Exit; { Now exit }
+ End;
+ End;
+ If (Event.CharCode = ' ') AND { Spacebar key }
+ (State AND sfFocused <> 0) AND { Check focused view }
+ ButtonState(Sel) Then Begin { Check item enabled }
+ Press(Sel); { Call pressed }
+ DrawView; { Now draw changes }
+ ClearEvent(Event); { Event was handled }
+ End;
+ End;
+ End;
+ End;
+END;
+
+{***************************************************************************}
+{ TCluster OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{--TCluster-----------------------------------------------------------------}
+{ FindSel -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.FindSel (P: TPoint): Sw_Integer;
+VAR I, S, Vh: Sw_Integer; R: TRect;
+BEGIN
+ GetExtent(R); { Get view extents }
+ If R.Contains(P) Then Begin { Point in view }
+ Vh := Size.Y; { View height }
+ I := 0; { Preset zero value }
+ While (P.X >= Column(I+Vh)) Do Inc(I, Vh); { Inc view size }
+ S := I + P.Y; { Line to select }
+ If ((S >= 0) AND (S < Strings.Count)) { Valid selection }
+ Then FindSel := S Else FindSel := -1; { Return selected item }
+ End Else FindSel := -1; { Point outside view }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Row -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.Row (Item: Sw_Integer): Sw_Integer;
+BEGIN
+ Row := Item MOD Size.Y; { Normal mod value }
+END;
+
+{--TCluster-----------------------------------------------------------------}
+{ Column -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 03Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCluster.Column (Item: Sw_Integer): Sw_Integer;
+VAR I, Col, Width, L, Vh: Sw_Integer; Ts: PString;
+BEGIN
+ Vh := Size.Y; { Vertical size }
+ If (Item >= Vh) Then Begin { Valid selection }
+ Width := 0; { Zero width }
+ Col := -6; { Start column at -6 }
+ For I := 0 To Item Do Begin { For each item }
+ If (I MOD Vh = 0) Then Begin { Start next column }
+ Inc(Col, Width + 6); { Add column width }
+ Width := 0; { Zero width }
+ End;
+ If (I < Strings.Count) Then Begin { Valid string }
+ Ts := Strings.At(I); { Transfer string }
+ If (Ts <> Nil) Then L := CStrLen(Ts^) { Length of string }
+ Else L := 0; { No string }
+ End;
+ If (L > Width) Then Width := L; { Hold longest string }
+ End;
+ Column := Col; { Return column }
+ End Else Column := 0; { Outside select area }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TRadioButtons OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TRadioButtons------------------------------------------------------------}
+{ Mark -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TRadioButtons.Mark (Item: Sw_Integer): Boolean;
+BEGIN
+ Mark := Item = Value; { True if item = value }
+END;
+
+{--TRadioButtons------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRadioButtons.Draw;
+CONST Button = ' ( ) ';
+BEGIN
+ Inherited Draw;
+ DrawMultiBox(Button, ' *'); { Redraw the text }
+END;
+
+{--TRadioButtons------------------------------------------------------------}
+{ Press -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRadioButtons.Press (Item: Sw_Integer);
+BEGIN
+ Value := Item; { Set value field }
+ Inherited Press(Item); { Call ancestor }
+END;
+
+{--TRadioButtons------------------------------------------------------------}
+{ MovedTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRadioButtons.MovedTo (Item: Sw_Integer);
+BEGIN
+ Value := Item; { Set value to item }
+ If (Id <> 0) Then NewMessage(Owner, evCommand,
+ cmIdCommunicate, Id, Value, @Self); { Send new message }
+END;
+
+{--TRadioButtons------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRadioButtons.SetData (Var Rec);
+BEGIN
+ Sel := Sw_word(Rec); { Set selection }
+ Inherited SetData(Rec); { Call ancestor }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TCheckBoxes OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TCheckBoxes--------------------------------------------------------------}
+{ Mark -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TCheckBoxes.Mark(Item: Sw_Integer): Boolean;
+BEGIN
+ If (Value AND (1 SHL Item) <> 0) Then { Check if item ticked }
+ Mark := True Else Mark := False; { Return result }
+END;
+
+{--TCheckBoxes--------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCheckBoxes.Draw;
+CONST Button = ' [ ] ';
+BEGIN
+ Inherited Draw;
+ DrawMultiBox(Button, ' X'); { Redraw the text }
+END;
+
+{--TCheckBoxes--------------------------------------------------------------}
+{ Press -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TCheckBoxes.Press (Item: Sw_Integer);
+BEGIN
+ Value := Value XOR (1 SHL Item); { Flip the item mask }
+ Inherited Press(Item); { Call ancestor }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TMultiCheckBoxes OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Jun98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMultiCheckBoxes.Init (Var Bounds: TRect; AStrings: PSItem;
+ASelRange: Byte; AFlags: Word; Const AStates: String);
+BEGIN
+ Inherited Init(Bounds, AStrings); { Call ancestor }
+ SelRange := ASelRange; { Hold select range }
+ Flags := AFlags; { Hold flags }
+ States := NewStr(AStates); { Hold string }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMultiCheckBoxes.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(SelRange, SizeOf(SelRange)); { Read select range }
+ S.Read(Flags, SizeOf(Flags)); { Read flags }
+ States := S.ReadStr; { Read strings }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TMultiCheckBoxes.Done;
+BEGIN
+ If (States <> Nil) Then DisposeStr(States); { Dispose strings }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMultiCheckBoxes.DataSize: Sw_Word;
+BEGIN
+ DataSize := SizeOf(LongInt); { Size to exchange }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ MultiMark -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMultiCheckBoxes.MultiMark (Item: Sw_Integer): Byte;
+BEGIN
+ MultiMark := (Value SHR (Word(Item) *
+ WordRec(Flags).Hi)) AND WordRec(Flags).Lo; { Return mark state }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMultiCheckBoxes.Draw;
+CONST Button = ' [ ] ';
+BEGIN
+ Inherited Draw;
+ DrawMultiBox(Button, States^); { Draw the items }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Press -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMultiCheckBoxes.Press (Item: Sw_Integer);
+VAR CurState: ShortInt;
+BEGIN
+ CurState := (Value SHR (Word(Item) *
+ WordRec(Flags).Hi)) AND WordRec(Flags).Lo; { Hold current state }
+ Dec(CurState); { One down }
+ If (CurState >= SelRange) OR (CurState < 0) Then
+ CurState := SelRange - 1; { Roll if needed }
+ Value := (Value AND NOT (LongInt(WordRec(Flags).Lo)
+ SHL (Word(Item) * WordRec(Flags).Hi))) OR
+ (LongInt(CurState) SHL (Word(Item) *
+ WordRec(Flags).Hi)); { Calculate value }
+ Inherited Press(Item); { Call ancestor }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMultiCheckBoxes.GetData (Var Rec);
+BEGIN
+ Longint(Rec) := Value; { Return value }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMultiCheckBoxes.SetData (Var Rec);
+BEGIN
+ Value := Longint(Rec); { Set value }
+ DrawView; { Redraw masked areas }
+END;
+
+{--TMultiCheckBoxes---------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMultiCheckBoxes.Store (Var S: TStream);
+BEGIN
+ TCluster.Store(S); { TCluster store called }
+ S.Write(SelRange, SizeOf(SelRange)); { Write select range }
+ S.Write(Flags, SizeOf(Flags)); { Write select flags }
+ S.WriteStr(States); { Write strings }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TListBox OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+TYPE
+ TListBoxRec = PACKED RECORD
+ List: PCollection; { List collection ptr }
+ Selection: sw_integer; { Selected item }
+ END;
+
+{--TListBox-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TListBox.Init (Var Bounds: TRect; ANumCols: Sw_Word;
+ AScrollBar: PScrollBar);
+BEGIN
+ Inherited Init(Bounds, ANumCols, Nil, AScrollBar); { Call ancestor }
+ SetRange(0); { Set range to zero }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TListBox.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ List := PCollection(S.Get); { Fetch collection }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/Os2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TListBox.DataSize: Sw_Word;
+BEGIN
+ DataSize := SizeOf(TListBoxRec); { Xchg data size }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TListBox.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
+VAR P: PString;
+BEGIN
+ GetText := ''; { Preset return }
+ If (List <> Nil) Then Begin { A list exists }
+ P := PString(List^.At(Item)); { Get string ptr }
+ If (P <> Nil) Then GetText := P^; { Return string }
+ End;
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ NewList -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListBox.NewList (AList: PCollection);
+BEGIN
+ If (List <> Nil) Then Dispose(List, Done); { Dispose old list }
+ List := AList; { Hold new list }
+ If (AList <> Nil) Then SetRange(AList^.Count) { Set new item range }
+ Else SetRange(0); { Set zero range }
+ If (Range > 0) Then FocusItem(0); { Focus first item }
+ DrawView; { Redraw all view }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListBox.GetData (Var Rec);
+BEGIN
+ TListBoxRec(Rec).List := List; { Return current list }
+ TListBoxRec(Rec).Selection := Focused; { Return focused item }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListBox.SetData (Var Rec);
+BEGIN
+ NewList(TListBoxRec(Rec).List); { Hold new list }
+ FocusItem(TListBoxRec(Rec).Selection); { Focus selected item }
+ DrawView; { Redraw all view }
+END;
+
+{--TListBox-----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListBox.Store (Var S: TStream);
+BEGIN
+ TListViewer.Store(S); { TListViewer store }
+ S.Put(List); { Store list to stream }
+END;
+
+{****************************************************************************}
+{ TListBox.DeleteFocusedItem }
+{****************************************************************************}
+procedure TListBox.DeleteFocusedItem;
+begin
+ DeleteItem(Focused);
+end;
+
+{****************************************************************************}
+{ TListBox.DeleteItem }
+{****************************************************************************}
+procedure TListBox.DeleteItem (Item : Sw_Integer);
+begin
+ if (List <> nil) and (List^.Count > 0) and
+ ((Item < List^.Count) and (Item > -1)) then begin
+ if IsSelected(Item) and (Item > 0) then
+ FocusItem(Item - 1);
+ List^.AtDelete(Item);
+ SetRange(List^.Count);
+ end;
+end;
+
+{****************************************************************************}
+{ TListBox.FreeAll }
+{****************************************************************************}
+procedure TListBox.FreeAll;
+begin
+ if (List <> nil) then
+ begin
+ List^.FreeAll;
+ SetRange(List^.Count);
+ end;
+end;
+
+{****************************************************************************}
+{ TListBox.FreeFocusedItem }
+{****************************************************************************}
+procedure TListBox.FreeFocusedItem;
+begin
+ FreeItem(Focused);
+end;
+
+{****************************************************************************}
+{ TListBox.FreeItem }
+{****************************************************************************}
+procedure TListBox.FreeItem (Item : Sw_Integer);
+begin
+ if (Item > -1) and (Item < Range) then
+ begin
+ List^.AtFree(Item);
+ if (Range > 1) and (Focused >= List^.Count) then
+ Dec(Focused);
+ SetRange(List^.Count);
+ end;
+end;
+
+{****************************************************************************}
+{ TListBox.SetFocusedItem }
+{****************************************************************************}
+procedure TListBox.SetFocusedItem (Item : Pointer);
+begin
+ FocusItem(List^.IndexOf(Item));
+end;
+
+{****************************************************************************}
+{ TListBox.GetFocusedItem }
+{****************************************************************************}
+function TListBox.GetFocusedItem : Pointer;
+begin
+ if (List = nil) or (List^.Count = 0) then
+ GetFocusedItem := nil
+ else GetFocusedItem := List^.At(Focused);
+end;
+
+{****************************************************************************}
+{ TListBox.Insert }
+{****************************************************************************}
+procedure TListBox.Insert (Item : Pointer);
+begin
+ if (List <> nil) then
+ begin
+ List^.Insert(Item);
+ SetRange(List^.Count);
+ end;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TStaticText OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TStaticText--------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStaticText.Init (Var Bounds: TRect; Const AText: String);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Text := NewStr(AText); { Create string ptr }
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStaticText.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Text := S.ReadStr; { Read text string }
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TStaticText.Done;
+BEGIN
+ If (Text <> Nil) Then DisposeStr(Text); { Dispose string }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TStaticText.GetPalette: PPalette;
+CONST P: String[Length(CStaticText)] = CStaticText; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStaticText.Draw;
+VAR Just: Byte; I, J, P, Y, L: Sw_Integer; S: String;
+ B : TDrawBuffer;
+ Color : Byte;
+BEGIN
+ GetText(S); { Fetch text to write }
+ Color := GetColor(1);
+ P := 1; { X start position }
+ Y := 0; { Y start position }
+ L := Length(S); { Length of text }
+ While (Y < Size.Y) Do Begin
+ MoveChar(B, ' ', Color, Size.X);
+ if P <= L then
+ begin
+ Just := 0; { Default left justify }
+ If (S[P] = #2) Then Begin { Right justify char }
+ Just := 2; { Set right justify }
+ Inc(P); { Next character }
+ End;
+ If (S[P] = #3) Then Begin { Centre justify char }
+ Just := 1; { Set centre justify }
+ Inc(P); { Next character }
+ End;
+ I := P; { Start position }
+ repeat
+ J := P;
+ while (P <= L) and (S[P] = ' ') do
+ Inc(P);
+ while (P <= L) and (S[P] <> ' ') and (S[P] <> #13) do
+ Inc(P);
+ until (P > L) or (P >= I + Size.X) or (S[P] = #13);
+ If P > I + Size.X Then { Text to long }
+ If J > I Then
+ P := J
+ Else
+ P := I + Size.X;
+ Case Just Of
+ 0: J := 0; { Left justify }
+ 1: J := (Size.X - (P-I)) DIV 2; { Centre justify }
+ 2: J := Size.X - (P-I); { Right justify }
+ End;
+ MoveBuf(B[J], S[I], Color, P - I);
+ While (P <= L) AND (P-I <= Size.X) AND ((S[P] = #13) OR (S[P] = #10))
+ Do Inc(P); { Remove CR/LF }
+ End;
+ WriteLine(0, Y, Size.X, 1, B);
+ Inc(Y); { Next line }
+ End;
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStaticText.Store (Var S: TStream);
+BEGIN
+ TView.Store(S); { Call TView store }
+ S.WriteStr(Text); { Write text string }
+END;
+
+{--TStaticText--------------------------------------------------------------}
+{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStaticText.GetText (Var S: String);
+BEGIN
+ If (Text <> Nil) Then S := Text^ { Copy text string }
+ Else S := ''; { Return empty string }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TParamText OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TParamText---------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TParamText.Init (Var Bounds: TRect; Const AText: String;
+ AParamCount: Sw_Integer);
+BEGIN
+ Inherited Init(Bounds, AText); { Call ancestor }
+ ParamCount := AParamCount; { Hold param count }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TParamText.Load (Var S: TStream);
+VAR w: Word;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(w, SizeOf(w)); ParamCount:=w; { Read parameter count }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TParamText.DataSize: Sw_Word;
+BEGIN
+ DataSize := ParamCount * SizeOf(Pointer); { Return data size }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TParamText.GetData (Var Rec);
+BEGIN
+ Pointer(Rec) := @ParamList; { Return parm ptr }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TParamText.SetData (Var Rec);
+BEGIN
+ ParamList := @Rec; { Fetch parameter list }
+ DrawView; { Redraw all the view }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TParamText.Store (Var S: TStream);
+VAR w: Word;
+BEGIN
+ TStaticText.Store(S); { Statictext store }
+ w:=ParamCount;S.Write(w, SizeOf(w)); { Store param count }
+END;
+
+{--TParamText---------------------------------------------------------------}
+{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TParamText.GetText (Var S: String);
+BEGIN
+ If (Text = Nil) Then S := '' Else { Return empty string }
+ FormatStr(S, Text^, ParamList^); { Return text string }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TLabel OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TLabel-------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TLabel.Init (Var Bounds: TRect; CONST AText: String; ALink: PView);
+BEGIN
+ Inherited Init(Bounds, AText); { Call ancestor }
+ Link := ALink; { Hold link }
+ Options := Options OR (ofPreProcess+ofPostProcess);{ Set pre/post process }
+ EventMask := EventMask OR evBroadcast; { Sees broadcast events }
+END;
+
+{--TLabel-------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TLabel.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetPeerViewPtr(S, Link); { Load link view }
+END;
+
+{--TLabel-------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TLabel.GetPalette: PPalette;
+CONST P: String[Length(CLabel)] = CLabel; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TLabel-------------------------------------------------------------------}
+{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TLabel.Draw;
+VAR SCOff: Byte; Color: Word; B: TDrawBuffer;
+BEGIN
+ If Light Then Begin { Light colour select }
+ Color := GetColor($0402); { Choose light colour }
+ SCOff := 0; { Zero offset }
+ End Else Begin
+ Color := GetColor($0301); { Darker colour }
+ SCOff := 4; { Set offset }
+ End;
+ MoveChar(B[0], ' ', Byte(Color), Size.X); { Clear the buffer }
+ If (Text <> Nil) Then MoveCStr(B[1], Text^, Color);{ Transfer label text }
+ If ShowMarkers Then WordRec(B[0]).Lo := Byte(
+ SpecialChars[SCOff]); { Show marker if req }
+ WriteLine(0, 0, Size.X, 1, B); { Write the text }
+END;
+
+{--TLabel-------------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TLabel.Store (Var S: TStream);
+BEGIN
+ TStaticText.Store(S); { TStaticText.Store }
+ PutPeerViewPtr(S, Link); { Store link view }
+END;
+
+{--TLabel-------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TLabel.HandleEvent (Var Event: TEvent);
+VAR C: Char;
+
+ PROCEDURE FocusLink;
+ BEGIN
+ If (Link <> Nil) AND (Link^.Options AND
+ ofSelectable <> 0) Then Link^.Focus; { Focus link view }
+ ClearEvent(Event); { Clear the event }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evMouseDown: FocusLink; { Focus link view }
+ evKeyDown:
+ Begin
+ if assigned(text) then
+ begin
+ C := HotKey(Text^); { Check for hotkey }
+ If (GetAltCode(C) = Event.KeyCode) OR { Alt plus char }
+ ((C <> #0) AND (Owner^.Phase = phPostProcess) { Post process phase }
+ AND (UpCase(Event.CharCode) = C)) Then { Upper case match }
+ FocusLink; { Focus link view }
+ end;
+ end;
+ evBroadcast: If ((Event.Command = cmReceivedFocus)
+ OR (Event.Command = cmReleasedFocus)) AND { Focus state change }
+ (Link <> Nil) Then Begin
+ Light := Link^.State AND sfFocused <> 0; { Change light state }
+ DrawView; { Now redraw change }
+ End;
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ THistoryViewer OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--THistoryViewer-----------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR THistoryViewer.Init (Var Bounds: TRect; AHScrollBar,
+AVScrollBar: PScrollBar; AHistoryId: Word);
+BEGIN
+ Inherited Init(Bounds, 1, AHScrollBar,
+ AVScrollBar); { Call ancestor }
+ HistoryId := AHistoryId; { Hold history id }
+ SetRange(HistoryCount(AHistoryId)); { Set history range }
+ If (Range > 1) Then FocusItem(1); { Set to item 1 }
+ If (HScrollBar <> Nil) Then
+ HScrollBar^.SetRange(1, HistoryWidth-Size.X + 3);{ Set scrollbar range }
+END;
+
+{--THistoryViewer-----------------------------------------------------------}
+{ HistoryWidth -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistoryViewer.HistoryWidth: Sw_Integer;
+VAR Width, T, Count, I: Sw_Integer;
+BEGIN
+ Width := 0; { Zero width variable }
+ Count := HistoryCount(HistoryId); { Hold count value }
+ For I := 0 To Count-1 Do Begin { For each item }
+ T := Length(HistoryStr(HistoryId, I)); { Get width of item }
+ If (T > Width) Then Width := T; { Set width to max }
+ End;
+ HistoryWidth := Width; { Return max item width }
+END;
+
+{--THistoryViewer-----------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistoryViewer.GetPalette: PPalette;
+CONST P: String[Length(CHistoryViewer)] = CHistoryViewer;{ Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--THistoryViewer-----------------------------------------------------------}
+{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistoryViewer.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
+BEGIN
+ GetText := HistoryStr(HistoryId, Item); { Return history string }
+END;
+
+{--THistoryViewer-----------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THistoryViewer.HandleEvent (Var Event: TEvent);
+BEGIN
+ If ((Event.What = evMouseDown) AND (Event.Double)) { Double click mouse }
+ OR ((Event.What = evKeyDown) AND
+ (Event.KeyCode = kbEnter)) Then Begin { Enter key press }
+ EndModal(cmOk); { End with cmOk }
+ ClearEvent(Event); { Event was handled }
+ End Else If ((Event.What = evKeyDown) AND
+ (Event.KeyCode = kbEsc)) OR { Esc key press }
+ ((Event.What = evCommand) AND
+ (Event.Command = cmCancel)) Then Begin { Cancel command }
+ EndModal(cmCancel); { End with cmCancel }
+ ClearEvent(Event); { Event was handled }
+ End Else Inherited HandleEvent(Event); { Call ancestor }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ THistoryWindow OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--THistoryWindow-----------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR THistoryWindow.Init (Var Bounds: TRect; HistoryId: Word);
+BEGIN
+ Inherited Init(Bounds, '', wnNoNumber); { Call ancestor }
+ Flags := wfClose; { Close flag only }
+ InitViewer(HistoryId); { Create list view }
+END;
+
+{--THistoryWindow-----------------------------------------------------------}
+{ GetSelection -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistoryWindow.GetSelection: String;
+BEGIN
+ If (Viewer = Nil) Then GetSelection := '' Else { Return empty string }
+ GetSelection := Viewer^.GetText(Viewer^.Focused,
+ 255); { Get focused string }
+END;
+
+{--THistoryWindow-----------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistoryWindow.GetPalette: PPalette;
+CONST P: String[Length(CHistoryWindow)] = CHistoryWindow;{ Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return the palette }
+END;
+
+{--THistoryWindow-----------------------------------------------------------}
+{ InitViewer -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THistoryWindow.InitViewer(HistoryId: Word);
+VAR R: TRect;
+BEGIN
+ GetExtent(R); { Get extents }
+ R.Grow(-1,-1); { Grow inside }
+ Viewer := New(PHistoryViewer, Init(R,
+ StandardScrollBar(sbHorizontal + sbHandleKeyboard),
+ StandardScrollBar(sbVertical + sbHandleKeyboard),
+ HistoryId)); { Create the viewer }
+ If (Viewer <> Nil) Then Insert(Viewer); { Insert viewer }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ THistory OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--THistory-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR THistory.Init (Var Bounds: TRect; ALink: PInputLine;
+AHistoryId: Word);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR ofPostProcess; { Set post process }
+ EventMask := EventMask OR evBroadcast; { See broadcast events }
+ Link := ALink; { Hold link view }
+ HistoryId := AHistoryId; { Hold history id }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR THistory.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetPeerViewPtr(S, Link); { Load link view }
+ S.Read(HistoryId, SizeOf(HistoryId)); { Read history id }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistory.GetPalette: PPalette;
+CONST P: String[Length(CHistory)] = CHistory; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return the palette }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ InitHistoryWindow -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION THistory.InitHistoryWindow (Var Bounds: TRect): PHistoryWindow;
+VAR P: PHistoryWindow;
+BEGIN
+ P := New(PHistoryWindow, Init(Bounds, HistoryId)); { Create history window }
+ If (Link <> Nil) Then
+ P^.HelpCtx := Link^.HelpCtx; { Set help context }
+ InitHistoryWindow := P; { Return history window }
+END;
+
+PROCEDURE THistory.Draw;
+VAR B: TDrawBuffer;
+BEGIN
+ MoveCStr(B,#222'~v~'#221, GetColor($0102)); { Set buffer data }
+ WriteLine(0, 0, Size.X, Size.Y, B); { Write buffer }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ RecordHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THistory.RecordHistory (CONST S: String);
+BEGIN
+ HistoryAdd(HistoryId, S); { Add to history }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THistory.Store (Var S: TStream);
+BEGIN
+ TView.Store(S); { TView.Store called }
+ PutPeerViewPtr(S, Link); { Store link view }
+ S.Write(HistoryId, SizeOf(HistoryId)); { Store history id }
+END;
+
+{--THistory-----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THistory.HandleEvent (Var Event: TEvent);
+VAR C: Word; Rslt: String; R, P: TRect; HistoryWindow: PHistoryWindow;
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Link = Nil) Then Exit; { No link view exits }
+ If (Event.What = evMouseDown) OR { Mouse down event }
+ ((Event.What = evKeyDown) AND
+ (CtrlToArrow(Event.KeyCode) = kbDown) AND { Down arrow key }
+ (Link^.State AND sfFocused <> 0)) Then Begin { Link view selected }
+ If NOT Link^.Focus Then Begin
+ ClearEvent(Event); { Event was handled }
+ Exit; { Now exit }
+ End;
+ RecordHistory(Link^.Data^); { Record current data }
+ Link^.GetBounds(R); { Get view bounds }
+ Dec(R.A.X); { One char in from us }
+ Inc(R.B.X); { One char short of us }
+ Inc(R.B.Y, 7); { Seven lines down }
+ Dec(R.A.Y,1); { One line below us }
+ Owner^.GetExtent(P); { Get owner extents }
+ R.Intersect(P); { Intersect views }
+ Dec(R.B.Y,1); { Shorten length by one }
+ HistoryWindow := InitHistoryWindow(R); { Create history window }
+ If (HistoryWindow <> Nil) Then Begin { Window crested okay }
+ C := Owner^.ExecView(HistoryWindow); { Execute this window }
+ If (C = cmOk) Then Begin { Result was okay }
+ Rslt := HistoryWindow^.GetSelection; { Get history selection }
+ If Length(Rslt) > Link^.MaxLen Then
+ SetLength(Rslt, Link^.MaxLen); { Hold new length }
+ Link^.Data^ := Rslt; { Hold new selection }
+ Link^.SelectAll(True); { Select all string }
+ Link^.DrawView; { Redraw link view }
+ End;
+ Dispose(HistoryWindow, Done); { Dispose of window }
+ End;
+ ClearEvent(Event); { Event was handled }
+ End Else If (Event.What = evBroadcast) Then { Broadcast event }
+ If ((Event.Command = cmReleasedFocus) AND
+ (Event.InfoPtr = Link)) OR
+ (Event.Command = cmRecordHistory) Then { Record command }
+ RecordHistory(Link^.Data^); { Record the history }
+END;
+
+{****************************************************************************}
+{ TBrowseButton Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TBrowseButton.Init }
+{****************************************************************************}
+constructor TBrowseButton.Init(var Bounds: TRect; ATitle: TTitleStr;
+ ACommand: Word; AFlags: Byte; ALink: PBrowseInputLine);
+begin
+ if not inherited Init(Bounds,ATitle,ACommand,AFlags) then
+ Fail;
+ Link := ALink;
+end;
+
+{****************************************************************************}
+{ TBrowseButton.Load }
+{****************************************************************************}
+constructor TBrowseButton.Load(var S: TStream);
+begin
+ if not inherited Load(S) then
+ Fail;
+ GetPeerViewPtr(S,Link);
+end;
+
+{****************************************************************************}
+{ TBrowseButton.Press }
+{****************************************************************************}
+procedure TBrowseButton.Press;
+var
+ E: TEvent;
+begin
+ Message(Owner, evBroadcast, cmRecordHistory, nil);
+ if Flags and bfBroadcast <> 0 then
+ Message(Owner, evBroadcast, Command, Link) else
+ begin
+ E.What := evCommand;
+ E.Command := Command;
+ E.InfoPtr := Link;
+ PutEvent(E);
+ end;
+end;
+
+{****************************************************************************}
+{ TBrowseButton.Store }
+{****************************************************************************}
+procedure TBrowseButton.Store(var S: TStream);
+begin
+ inherited Store(S);
+ PutPeerViewPtr(S,Link);
+end;
+
+
+{****************************************************************************}
+{ TBrowseInputLine Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TBrowseInputLine.Init }
+{****************************************************************************}
+constructor TBrowseInputLine.Init(var Bounds: TRect; AMaxLen: Sw_Integer; AHistory: Sw_Word);
+begin
+ if not inherited Init(Bounds,AMaxLen) then
+ Fail;
+ History := AHistory;
+end;
+
+{****************************************************************************}
+{ TBrowseInputLine.Load }
+{****************************************************************************}
+constructor TBrowseInputLine.Load(var S: TStream);
+begin
+ if not inherited Load(S) then
+ Fail;
+ S.Read(History,SizeOf(History));
+ if (S.Status <> stOk) then
+ Fail;
+end;
+
+{****************************************************************************}
+{ TBrowseInputLine.DataSize }
+{****************************************************************************}
+function TBrowseInputLine.DataSize: Sw_Word;
+begin
+ DataSize := SizeOf(TBrowseInputLineRec);
+end;
+
+{****************************************************************************}
+{ TBrowseInputLine.GetData }
+{****************************************************************************}
+procedure TBrowseInputLine.GetData(var Rec);
+var
+ LocalRec: TBrowseInputLineRec absolute Rec;
+begin
+ if (Validator = nil) or
+ (Validator^.Transfer(Data^,@LocalRec.Text, vtGetData) = 0) then
+ begin
+ FillChar(LocalRec.Text, DataSize, #0);
+ Move(Data^, LocalRec.Text, Length(Data^) + 1);
+ end;
+ LocalRec.History := History;
+end;
+
+{****************************************************************************}
+{ TBrowseInputLine.SetData }
+{****************************************************************************}
+procedure TBrowseInputLine.SetData(var Rec);
+var
+ LocalRec: TBrowseInputLineRec absolute Rec;
+begin
+ if (Validator = nil) or
+ (Validator^.Transfer(Data^, @LocalRec.Text, vtSetData) = 0) then
+ Move(LocalRec.Text, Data^[0], MaxLen + 1);
+ History := LocalRec.History;
+ SelectAll(True);
+end;
+
+{****************************************************************************}
+{ TBrowseInputLine.Store }
+{****************************************************************************}
+procedure TBrowseInputLine.Store(var S: TStream);
+begin
+ inherited Store(S);
+ S.Write(History,SizeOf(History));
+end;
+
+
+{****************************************************************************}
+{ TCommandCheckBoxes Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TCommandCheckBoxes.Init }
+{****************************************************************************}
+constructor TCommandCheckBoxes.Init (var Bounds : TRect;
+ ACommandStrings : PCommandSItem);
+var StartSItem, S : PSItem;
+ CItems : PCommandSItem;
+ i : Sw_Integer;
+begin
+ if ACommandStrings = nil then
+ Fail;
+ { set up string list }
+ StartSItem := NewSItem(ACommandStrings^.Value,nil);
+ S := StartSItem;
+ CItems := ACommandStrings^.Next;
+ while (CItems <> nil) do begin
+ S^.Next := NewSItem(CItems^.Value,nil);
+ S := S^.Next;
+ CItems := CItems^.Next;
+ end;
+ { construct check boxes }
+ if not TCheckBoxes.Init(Bounds,StartSItem) then begin
+ while (StartSItem <> nil) do begin
+ S := StartSItem;
+ StartSItem := StartSItem^.Next;
+ if (S^.Value <> nil) then
+ DisposeStr(S^.Value);
+ Dispose(S);
+ end;
+ Fail;
+ end;
+ { set up CommandList and dispose of memory used by ACommandList }
+ i := 0;
+ while (ACommandStrings <> nil) do begin
+ CommandList[i] := ACommandStrings^.Command;
+ CItems := ACommandStrings;
+ ACommandStrings := ACommandStrings^.Next;
+ Dispose(CItems);
+ Inc(i);
+ end;
+end;
+
+{****************************************************************************}
+{ TCommandCheckBoxes.Load }
+{****************************************************************************}
+constructor TCommandCheckBoxes.Load (var S : TStream);
+begin
+ if not TCheckBoxes.Load(S) then
+ Fail;
+ S.Read(CommandList,SizeOf(CommandList));
+ if (S.Status <> stOk) then begin
+ TCheckBoxes.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TCommandCheckBoxes.Press }
+{****************************************************************************}
+procedure TCommandCheckBoxes.Press (Item : Sw_Integer);
+var Temp : Sw_Integer;
+begin
+ Temp := Value;
+ TCheckBoxes.Press(Item);
+ if (Value <> Temp) then { value changed - notify peers }
+ Message(Owner,evCommand,CommandList[Item],@Value);
+end;
+
+{****************************************************************************}
+{ TCommandCheckBoxes.Store }
+{****************************************************************************}
+procedure TCommandCheckBoxes.Store (var S : TStream);
+begin
+ TCheckBoxes.Store(S);
+ S.Write(CommandList,SizeOf(CommandList));
+end;
+
+{****************************************************************************}
+{ TCommandIcon Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TCommandIcon.Init }
+{****************************************************************************}
+constructor TCommandIcon.Init (var Bounds : TRect; AText : String;
+ ACommand : Word);
+begin
+ if not TStaticText.Init(Bounds,AText) then
+ Fail;
+ Options := Options or ofPostProcess;
+ Command := ACommand;
+end;
+
+{****************************************************************************}
+{ TCommandIcon.HandleEvent }
+{****************************************************************************}
+procedure TCommandIcon.HandleEvent (var Event : TEvent);
+begin
+ if ((Event.What = evMouseDown) and MouseInView(MouseWhere)) then begin
+ ClearEvent(Event);
+ Message(Owner,evCommand,Command,nil);
+ end;
+ TStaticText.HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TCommandInputLine Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TCommandInputLine.Changed }
+{****************************************************************************}
+{procedure TCommandInputLine.Changed;
+begin
+ Message(Owner,evBroadcast,cmInputLineChanged,@Self);
+end; }
+
+{****************************************************************************}
+{ TCommandInputLine.HandleEvent }
+{****************************************************************************}
+{procedure TCommandInputLine.HandleEvent (var Event : TEvent);
+var E : TEvent;
+begin
+ E := Event;
+ TBSDInputLine.HandleEvent(Event);
+ if ((E.What and evKeyBoard = evKeyBoard) and (Event.KeyCode = kbEnter))
+ then Changed;
+end; }
+
+{****************************************************************************}
+{ TCommandRadioButtons Object }
+{****************************************************************************}
+
+{****************************************************************************}
+{ TCommandRadioButtons.Init }
+{****************************************************************************}
+constructor TCommandRadioButtons.Init (var Bounds : TRect;
+ ACommandStrings : PCommandSItem);
+var
+ StartSItem, S : PSItem;
+ CItems : PCommandSItem;
+ i : Sw_Integer;
+begin
+ if ACommandStrings = nil
+ then Fail;
+ { set up string list }
+ StartSItem := NewSItem(ACommandStrings^.Value,nil);
+ S := StartSItem;
+ CItems := ACommandStrings^.Next;
+ while (CItems <> nil) do begin
+ S^.Next := NewSItem(CItems^.Value,nil);
+ S := S^.Next;
+ CItems := CItems^.Next;
+ end;
+ { construct check boxes }
+ if not TRadioButtons.Init(Bounds,StartSItem) then begin
+ while (StartSItem <> nil) do begin
+ S := StartSItem;
+ StartSItem := StartSItem^.Next;
+ if (S^.Value <> nil) then
+ DisposeStr(S^.Value);
+ Dispose(S);
+ end;
+ Fail;
+ end;
+ { set up command list }
+ i := 0;
+ while (ACommandStrings <> nil) do begin
+ CommandList[i] := ACommandStrings^.Command;
+ CItems := ACommandStrings;
+ ACommandStrings := ACommandStrings^.Next;
+ Dispose(CItems);
+ Inc(i);
+ end;
+end;
+
+{****************************************************************************}
+{ TCommandRadioButtons.Load }
+{****************************************************************************}
+constructor TCommandRadioButtons.Load (var S : TStream);
+begin
+ if not TRadioButtons.Load(S) then
+ Fail;
+ S.Read(CommandList,SizeOf(CommandList));
+ if (S.Status <> stOk) then begin
+ TRadioButtons.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TCommandRadioButtons.MoveTo }
+{****************************************************************************}
+procedure TCommandRadioButtons.MovedTo (Item : Sw_Integer);
+var Temp : Sw_Integer;
+begin
+ Temp := Value;
+ TRadioButtons.MovedTo(Item);
+ if (Value <> Temp) then { value changed - notify peers }
+ Message(Owner,evCommand,CommandList[Item],@Value);
+end;
+
+{****************************************************************************}
+{ TCommandRadioButtons.Press }
+{****************************************************************************}
+procedure TCommandRadioButtons.Press (Item : Sw_Integer);
+var Temp : Sw_Integer;
+begin
+ Temp := Value;
+ TRadioButtons.Press(Item);
+ if (Value <> Temp) then { value changed - notify peers }
+ Message(Owner,evCommand,CommandList[Item],@Value);
+end;
+
+{****************************************************************************}
+{ TCommandRadioButtons.Store }
+{****************************************************************************}
+procedure TCommandRadioButtons.Store (var S : TStream);
+begin
+ TRadioButtons.Store(S);
+ S.Write(CommandList,SizeOf(CommandList));
+end;
+
+{****************************************************************************}
+{ TEditListBox Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TEditListBox.Init }
+{****************************************************************************}
+constructor TEditListBox.Init (Bounds : TRect; ANumCols: Word;
+ AVScrollBar : PScrollBar);
+
+begin
+ if not inherited Init(Bounds,ANumCols,AVScrollBar)
+ then Fail;
+ CurrentField := 1;
+end;
+
+{****************************************************************************}
+{ TEditListBox.Load }
+{****************************************************************************}
+constructor TEditListBox.Load (var S : TStream);
+begin
+ if not inherited Load(S)
+ then Fail;
+ CurrentField := 1;
+end;
+
+{****************************************************************************}
+{ TEditListBox.EditField }
+{****************************************************************************}
+procedure TEditListBox.EditField (var Event : TEvent);
+var R : TRect;
+ InputLine : PModalInputLine;
+begin
+ R.Assign(StartColumn,(Origin.Y + Focused - TopItem),
+ (StartColumn + FieldWidth + 2),(Origin.Y + Focused - TopItem + 1));
+ Owner^.MakeGlobal(R.A,R.A);
+ Owner^.MakeGlobal(R.B,R.B);
+ InputLine := New(PModalInputLine,Init(R,FieldWidth));
+ InputLine^.SetValidator(FieldValidator);
+ if InputLine <> nil
+ then begin
+ { Use TInputLine^.SetData so that data validation occurs }
+ { because TInputLine.Data is allocated memory large enough }
+ { to hold a string of MaxLen. It is also faster. }
+ GetField(InputLine);
+ if (Application^.ExecView(InputLine) = cmOk)
+ then SetField(InputLine);
+ Dispose(InputLine,done);
+ end;
+end;
+
+{****************************************************************************}
+{ TEditListBox.FieldValidator }
+{****************************************************************************}
+function TEditListBox.FieldValidator : PValidator;
+ { In a multiple field listbox FieldWidth should return the width }
+ { appropriate for Field. The default is an inputline for editing }
+ { a string of length large enough to fill the listbox field. }
+begin
+ FieldValidator := nil;
+end;
+
+{****************************************************************************}
+{ TEditListBox.FieldWidth }
+{****************************************************************************}
+function TEditListBox.FieldWidth : Integer;
+ { In a multiple field listbox FieldWidth should return the width }
+ { appropriate for CurrentField. }
+begin
+ FieldWidth := Size.X - 2;
+end;
+
+{****************************************************************************}
+{ TEditListBox.GetField }
+{****************************************************************************}
+procedure TEditListBox.GetField (InputLine : PInputLine);
+ { Places a string appropriate to Field and Focused into InputLine that }
+ { will be edited. Override this method for complex data types. }
+begin
+ InputLine^.SetData(PString(List^.At(Focused))^);
+end;
+
+{****************************************************************************}
+{ TEditListBox.GetPalette }
+{****************************************************************************}
+function TEditListBox.GetPalette : PPalette;
+begin
+ GetPalette := inherited GetPalette;
+end;
+
+{****************************************************************************}
+{ TEditListBox.HandleEvent }
+{****************************************************************************}
+procedure TEditListBox.HandleEvent (var Event : TEvent);
+begin
+ if (Event.What = evKeyboard) and (Event.KeyCode = kbAltE)
+ then begin { edit field }
+ EditField(Event);
+ DrawView;
+ ClearEvent(Event);
+ end;
+ inherited HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TEditListBox.SetField }
+{****************************************************************************}
+procedure TEditListBox.SetField (InputLine : PInputLine);
+ { Override this method for field types other than PStrings. }
+var Item : PString;
+begin
+ Item := NewStr(InputLine^.Data^);
+ if Item <> nil
+ then begin
+ List^.AtFree(Focused);
+ List^.Insert(Item);
+ SetFocusedItem(Item);
+ end;
+end;
+
+{****************************************************************************}
+{ TEditListBox.StartColumn }
+{****************************************************************************}
+function TEditListBox.StartColumn : Integer;
+begin
+ StartColumn := Origin.X;
+end;
+
+{****************************************************************************}
+{ TListDlg Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TListDlg.Init }
+{****************************************************************************}
+constructor TListDlg.Init (ATitle : TTitleStr; Items:
+ String; AButtons: Word; AListBox: PListBox; AEditCommand, ANewCommand :
+ Word);
+var
+ Bounds: TRect;
+ b: Byte;
+ ButtonCount: Byte;
+ i, j, Gap, Line: Integer;
+ Scrollbar: PScrollbar;
+ HasFrame: Boolean;
+ HasButtons: Boolean;
+ HasScrollBar: Boolean;
+ HasItems: Boolean;
+begin
+ if AListBox = nil then
+ Fail
+ else
+ ListBox := AListBox;
+ HasFrame := ((AButtons and ldNoFrame) = 0);
+ HasButtons := ((AButtons and ldAllButtons) <> 0);
+ HasScrollBar := ((AButtons and ldNoScrollBar) = 0);
+ HasItems := (Items <> '');
+ ButtonCount := 2;
+ for b := 0 to 3 do
+ if (AButtons and ($0001 shl 1)) <> 0 then
+ Inc(ButtonCount);
+ { Make sure dialog is large enough for buttons }
+ ListBox^.GetExtent(Bounds);
+ Bounds.Move(ListBox^.Origin.X,ListBox^.Origin.Y);
+ if HasFrame then
+ begin
+ Inc(Bounds.B.X,2);
+ Inc(Bounds.B.Y,2);
+ end;
+ if HasButtons then
+ begin
+ Inc(Bounds.B.X,14);
+ if Bounds.B.Y < (ButtonCount * 2) + 4 then
+ Bounds.B.Y := (ButtonCount * 2) + 5;
+ end;
+ if HasItems then
+ Inc(Bounds.B.Y,1);
+ if not TDialog.Init(Bounds,ATitle) then
+ Fail;
+ NewCommand := ANewCommand;
+ EditCommand := AEditCommand;
+ Options := Options or ofNewEditDelete;
+ if (not HasFrame) and (Frame <> nil) then
+ begin
+ Delete(Frame);
+ Dispose(Frame,Done);
+ Frame := nil;
+ Options := Options and not ofFramed;
+ end;
+ HelpCtx := hcListDlg;
+ { position and insert ListBox }
+ ListBox := AListBox;
+ Insert(ListBox);
+ if HasItems then
+ if HasFrame then
+ ListBox^.MoveTo(2,2)
+ else ListBox^.MoveTo(0,2)
+ else
+ if HasFrame then
+ ListBox^.MoveTo(1,1)
+ else ListBox^.MoveTo(0,0);
+ if HasButtons then
+ if ListBox^.Size.Y < (ButtonCount * 2) then
+ ListBox^.GrowTo(ListBox^.Size.X,ButtonCount * 2);
+ { do Items }
+ if HasItems then
+ begin
+ Bounds.Assign(1,1,CStrLen(Items)+2,2);
+ Insert(New(PLabel,Init(Bounds,Items,ListBox)));
+ end;
+ { do scrollbar }
+ if HasScrollBar then
+ begin
+ Bounds.Assign(ListBox^.Size.X+ListBox^.Origin.X,ListBox^.Origin.Y,
+ ListBox^.Size.X + ListBox^.Origin.X + 1,
+ ListBox^.Size.Y + ListBox^.Origin.Y { origin });
+ ScrollBar := New(PScrollBar,Init(Bounds));
+ Bounds.Assign(Origin.X,Origin.Y,Origin.X + Size.X + 1, Origin.Y + Size.Y);
+ ChangeBounds(Bounds);
+ Insert(Scrollbar);
+ end;
+ if HasButtons then
+ begin { do buttons }
+ j := $0001;
+ Gap := 0;
+ for i := 0 to 3 do
+ if ((j shl i) and AButtons) <> 0 then
+ Inc(Gap);
+ Gap := ((Size.Y - 2) div (Gap + 2));
+ if Gap < 2 then
+ Gap := 2;
+ { Insert Buttons }
+ Line := 2;
+ if (AButtons and ldNew) = ldNew then
+ begin
+ Insert(NewButton(Size.X - 12,Line,10,2,'~N~ew',cmNew,hcInsert,bfNormal));
+ Inc(Line,Gap);
+ end;
+ if (AButtons and ldEdit) = ldEdit then
+ begin
+ Insert(NewButton(Size.X - 12,Line,10,2,'~E~dit',cmEdit,hcEdit,
+ bfNormal));
+ Inc(Line,Gap);
+ end;
+ if (AButtons and ldDelete) = ldDelete then
+ begin
+ Insert(NewButton(Size.X - 12,Line,10,2,'~D~elete',cmDelete,hcDelete,
+ bfNormal));
+ Inc(Line,Gap);
+ end;
+ Insert(NewButton(Size.X - 12,Line,10,2,'O~k~',cmOK,hcOk,bfDefault or
+ bfNormal));
+ Inc(Line,Gap);
+ Insert(NewButton(Size.X - 12,Line,10,2,'Cancel',cmCancel,hcCancel,
+ bfNormal));
+ if (AButtons and ldHelp) = ldHelp then
+ begin
+ Inc(Line,Gap);
+ Insert(NewButton(Size.X - 12,Line,10,2,'~H~elp',cmHelp,hcNoContext,
+ bfNormal));
+ end;
+ end;
+ if HasFrame and ((AButtons and ldAllIcons) <> 0) then
+ begin
+ Line := 2;
+ if (AButtons and ldNewIcon) = ldNewIcon then
+ begin
+ Bounds.Assign(Line,Size.Y-1,Line+5,Size.Y);
+ Insert(New(PCommandIcon,Init(Bounds,' Ins ',cmNew)));
+ Inc(Line,5);
+ if (AButtons and (ldEditIcon or ldDeleteIcon)) <> 0 then
+ begin
+ Bounds.Assign(Line,Size.Y-1,Line+1,Size.Y);
+ Insert(New(PStaticText,Init(Bounds,'/')));
+ Inc(Line,1);
+ end;
+ end;
+ if (AButtons and ldEditIcon) = ldEditIcon then
+ begin
+ Bounds.Assign(Line,Size.Y-1,Line+6,Size.Y);
+ Insert(New(PCommandIcon,Init(Bounds,' Edit ',cmEdit)));
+ Inc(Line,6);
+ if (AButtons and ldDeleteIcon) <> 0 then
+ begin
+ Bounds.Assign(Line,Size.Y-1,Line+1,Size.Y);
+ Insert(New(PStaticText,Init(Bounds,'/')));
+ Inc(Line,1);
+ end;
+ end;
+ if (AButtons and ldNewIcon) = ldNewIcon then
+ begin
+ Bounds.Assign(Line,Size.Y-1,Line+5,Size.Y);
+ Insert(New(PCommandIcon,Init(Bounds,' Del ',cmDelete)));
+ end;
+ end;
+ { Set focus to list boLine when dialog opens }
+ SelectNext(False);
+end;
+
+{****************************************************************************}
+{ TListDlg.Load }
+{****************************************************************************}
+constructor TListDlg.Load (var S : TStream);
+begin
+ if not TDialog.Load(S) then
+ Fail;
+ S.Read(NewCommand,SizeOf(NewCommand));
+ S.Read(EditCommand,SizeOf(EditCommand));
+ GetSubViewPtr(S,ListBox);
+end;
+
+{****************************************************************************}
+{ TListDlg.HandleEvent }
+{****************************************************************************}
+procedure TListDlg.HandleEvent (var Event : TEvent);
+const
+ TargetCommands: TCommandSet = [cmNew, cmEdit, cmDelete];
+begin
+ if ((Event.What and evCommand) <> 0) and
+ (Event.Command in TargetCommands) then
+ case Event.Command of
+ cmDelete:
+ if Options and ofDelete = ofDelete then
+ begin
+ ListBox^.FreeFocusedItem;
+ ListBox^.DrawView;
+ ClearEvent(Event);
+ end;
+ cmNew:
+ if Options and ofNew = ofNew then
+ begin
+ Message(Application,evCommand,NewCommand,nil);
+ ListBox^.SetRange(ListBox^.List^.Count);
+ ListBox^.DrawView;
+ ClearEvent(Event);
+ end;
+ cmEdit:
+ if Options and ofEdit = ofEdit then
+ begin
+ Message(Application,evCommand,EditCommand,ListBox^.GetFocusedItem);
+ ListBox^.DrawView;
+ ClearEvent(Event);
+ end;
+ end;
+ if (Event.What and evBroadcast > 0) and
+ (Event.Command = cmListItemSelected) then
+ begin { use PutEvent instead of Message so that a window list box works }
+ Event.What := evCommand;
+ Event.Command := cmOk;
+ Event.InfoPtr := nil;
+ PutEvent(Event);
+ end;
+ TDialog.HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TListDlg.Store }
+{****************************************************************************}
+procedure TListDlg.Store (var S : TStream);
+begin
+ TDialog.Store(S);
+ S.Write(NewCommand,SizeOf(NewCommand));
+ S.Write(EditCommand,SizeOf(EditCommand));
+ PutSubViewPtr(S,ListBox);
+end;
+
+{****************************************************************************}
+{ TModalInputLine Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TModalInputLine.Execute }
+{****************************************************************************}
+function TModalInputLine.Execute : Word;
+var Event : TEvent;
+begin
+ repeat
+ EndState := 0;
+ repeat
+ GetEvent(Event);
+ HandleEvent(Event);
+ if Event.What <> evNothing
+ then Owner^.EventError(Event); { may change this to ClearEvent }
+ until (EndState <> 0);
+ until Valid(EndState);
+ Execute := EndState;
+end;
+
+{****************************************************************************}
+{ TModalInputLine.HandleEvent }
+{****************************************************************************}
+procedure TModalInputLine.HandleEvent (var Event : TEvent);
+begin
+ case Event.What of
+ evKeyboard : case Event.KeyCode of
+ kbUp, kbDown : EndModal(cmCancel);
+ kbEnter : EndModal(cmOk);
+ else inherited HandleEvent(Event);
+ end;
+ evMouse : if MouseInView(Event.Where)
+ then inherited HandleEvent(Event)
+ else EndModal(cmCancel);
+ else inherited HandleEvent(Event);
+ end;
+end;
+
+{****************************************************************************}
+{ TModalInputLine.SetState }
+{****************************************************************************}
+procedure TModalInputLine.SetState (AState : Word; Enable : Boolean);
+var Pos : Integer;
+begin
+ if (AState = sfSelected)
+ then begin
+ Pos := CurPos;
+ inherited SetState(AState,Enable);
+ CurPos := Pos;
+ SelStart := CurPos;
+ SelEnd := CurPos;
+ BlockCursor;
+ DrawView;
+ end
+ else inherited SetState(AState,Enable);
+end;
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ ITEM STRING ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ NewSItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28Apr98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewSItem (Const Str: String; ANext: PSItem): PSItem;
+VAR Item: PSItem;
+BEGIN
+ New(Item); { Allocate item }
+ Item^.Value := NewStr(Str); { Hold item string }
+ Item^.Next := ANext; { Chain the ptr }
+ NewSItem := Item; { Return item }
+END;
+
+{****************************************************************************}
+{ NewCommandSItem }
+{****************************************************************************}
+function NewCommandSItem (Str : String; ACommand : Word;
+ ANext : PCommandSItem) : PCommandSItem;
+var Temp : PCommandSItem;
+begin
+ New(Temp);
+ if (Temp <> nil) then
+ begin
+ Temp^.Value := Str;
+ Temp^.Command := ACommand;
+ Temp^.Next := ANext;
+ end;
+ NewCommandSItem := Temp;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ DIALOG OBJECT REGISTRATION ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ RegisterDialogs -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE RegisterDialogs;
+BEGIN
+ RegisterType(RDialog); { Register dialog }
+ RegisterType(RInputLine); { Register inputline }
+ RegisterType(RButton); { Register button }
+ RegisterType(RCluster); { Register cluster }
+ RegisterType(RRadioButtons); { Register radiobutton }
+ RegisterType(RCheckBoxes); { Register check boxes }
+ RegisterType(RMultiCheckBoxes); { Register multi boxes }
+ RegisterType(RListBox); { Register list box }
+ RegisterType(RStaticText); { Register static text }
+ RegisterType(RLabel); { Register label }
+ RegisterType(RHistory); { Register history }
+ RegisterType(RParamText); { Register parm text }
+ RegisterType(RCommandCheckBoxes);
+ RegisterType(RCommandIcon);
+ RegisterType(RCommandRadioButtons);
+ RegisterType(REditListBox);
+ RegisterType(RModalInputLine);
+ RegisterType(RListDlg);
+END;
+
+END.
diff --git a/packages/fv/src/drivers.pas b/packages/fv/src/drivers.pas
new file mode 100644
index 0000000000..a3426e6f0b
--- /dev/null
+++ b/packages/fv/src/drivers.pas
@@ -0,0 +1,1578 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent clone of DRIVERS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999, 2000 }
+{ by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@projectent.com.au - backup e-mail addr }
+{ }
+{ Original FormatStr kindly donated by Marco Schmidt }
+{ }
+{ Mouse callback hook under FPC with kind assistance of }
+{ Pierre Muller, Gertjan Schouten & Florian Klaempfl. }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+
+UNIT Drivers;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$IFNDEF OS_UNIX}
+{$S-} { Disable Stack Checking }
+{$ENDIF}
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+{$ifdef CPU68K}
+ {$DEFINE ENDIAN_BIG}
+{$endif CPU68K}
+
+{$ifdef FPC}
+ {$INLINE ON}
+{$endif}
+
+USES
+ {$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ Windows, { Standard unit }
+ {$ENDIF}
+
+ {$ifdef OS_DOS}
+ Dos,
+ {$endif OS_DOS}
+
+ {$IFDEF OS_OS2} { OS2 CODE }
+ {$IFDEF PPC_Virtual} { VIRTUAL PASCAL UNITS }
+ OS2Def, OS2Base, OS2PMAPI, { Standard units }
+ {$ENDIF}
+ {$IFDEF PPC_Speed} { SPEED PASCAL UNITS }
+ BseDos, Os2Def, { Standard units }
+ {$ENDIF}
+ {$IFDEF PPC_FPC} { FPC UNITS }
+ DosCalls, Os2Def, { Standard units }
+ {$ENDIF}
+ {$ENDIF}
+
+ {$IFDEF OS_UNIX}
+ {$ifdef VER1_0}
+ linux,
+ {$else}
+ baseunix,unix,
+ {$endif}
+ {$ENDIF}
+
+ {$IFDEF OS_NETWARE_LIBC}
+ libc,
+ {$ENDIF}
+ {$IFDEF OS_NETWARE_CLIB}
+ nwserv,
+ {$ENDIF}
+
+ video,
+ SysMsg,
+ FVCommon, Objects; { GFV standard units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ EVENT TYPE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ evMouseDown = $0001; { Mouse down event }
+ evMouseUp = $0002; { Mouse up event }
+ evMouseMove = $0004; { Mouse move event }
+ evMouseAuto = $0008; { Mouse auto event }
+ evKeyDown = $0010; { Key down event }
+ evCommand = $0100; { Command event }
+ evBroadcast = $0200; { Broadcast event }
+
+{---------------------------------------------------------------------------}
+{ EVENT CODE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ evNothing = $0000; { Empty event }
+ evMouse = $000F; { Mouse event }
+ evKeyboard = $0010; { Keyboard event }
+ evMessage = $FF00; { Message event }
+
+{---------------------------------------------------------------------------}
+{ EXTENDED KEY CODES }
+{---------------------------------------------------------------------------}
+CONST
+ kbNoKey = $0000; kbAltEsc = $0100; kbEsc = $011B;
+ kbAltSpace = $0200; kbCtrlIns = $0400; kbShiftIns = $0500;
+ kbCtrlDel = $0600; kbShiftDel = $0700; kbAltBack = $0800;
+ kbAltShiftBack= $0900; kbBack = $0E08; kbCtrlBack = $0E7F;
+ kbShiftTab = $0F00; kbTab = $0F09; kbAltQ = $1000;
+ kbCtrlQ = $1011; kbAltW = $1100; kbCtrlW = $1117;
+ kbAltE = $1200; kbCtrlE = $1205; kbAltR = $1300;
+ kbCtrlR = $1312; kbAltT = $1400; kbCtrlT = $1414;
+ kbAltY = $1500; kbCtrlY = $1519; kbAltU = $1600;
+ kbCtrlU = $1615; kbAltI = $1700; kbCtrlI = $1709;
+ kbAltO = $1800; kbCtrlO = $180F; kbAltP = $1900;
+ kbCtrlP = $1910; kbAltLftBrack = $1A00; kbAltRgtBrack = $1B00;
+ kbCtrlEnter = $1C0A; kbEnter = $1C0D; kbAltA = $1E00;
+ kbCtrlA = $1E01; kbAltS = $1F00; kbCtrlS = $1F13;
+ kbAltD = $2000; kbCtrlD = $2004; kbAltF = $2100;
+ kbCtrlF = $2106; kbAltG = $2200; kbCtrlG = $2207;
+ kbAltH = $2300; kbCtrlH = $2308; kbAltJ = $2400;
+ kbCtrlJ = $240A; kbAltK = $2500; kbCtrlK = $250B;
+ kbAltL = $2600; kbCtrlL = $260C; kbAltSemiCol = $2700;
+ kbAltQuote = $2800; kbAltOpQuote = $2900; kbAltBkSlash = $2B00;
+ kbAltZ = $2C00; kbCtrlZ = $2C1A; kbAltX = $2D00;
+ kbCtrlX = $2D18; kbAltC = $2E00; kbCtrlC = $2E03;
+ kbAltV = $2F00; kbCtrlV = $2F16; kbAltB = $3000;
+ kbCtrlB = $3002; kbAltN = $3100; kbCtrlN = $310E;
+ kbAltM = $3200; kbCtrlM = $320D; kbAltComma = $3300;
+ kbAltPeriod = $3400; kbAltSlash = $3500; kbAltGreyAst = $3700;
+ kbSpaceBar = $3920; kbF1 = $3B00; kbF2 = $3C00;
+ kbF3 = $3D00; kbF4 = $3E00; kbF5 = $3F00;
+ kbF6 = $4000; kbF7 = $4100; kbF8 = $4200;
+ kbF9 = $4300; kbF10 = $4400; kbHome = $4700;
+ kbUp = $4800; kbPgUp = $4900; kbGrayMinus = $4A2D;
+ kbLeft = $4B00; kbCenter = $4C00; kbRight = $4D00;
+ kbAltGrayPlus = $4E00; kbGrayPlus = $4E2B; kbEnd = $4F00;
+ kbDown = $5000; kbPgDn = $5100; kbIns = $5200;
+ kbDel = $5300; kbShiftF1 = $5400; kbShiftF2 = $5500;
+ kbShiftF3 = $5600; kbShiftF4 = $5700; kbShiftF5 = $5800;
+ kbShiftF6 = $5900; kbShiftF7 = $5A00; kbShiftF8 = $5B00;
+ kbShiftF9 = $5C00; kbShiftF10 = $5D00; kbCtrlF1 = $5E00;
+ kbCtrlF2 = $5F00; kbCtrlF3 = $6000; kbCtrlF4 = $6100;
+ kbCtrlF5 = $6200; kbCtrlF6 = $6300; kbCtrlF7 = $6400;
+ kbCtrlF8 = $6500; kbCtrlF9 = $6600; kbCtrlF10 = $6700;
+ kbAltF1 = $6800; kbAltF2 = $6900; kbAltF3 = $6A00;
+ kbAltF4 = $6B00; kbAltF5 = $6C00; kbAltF6 = $6D00;
+ kbAltF7 = $6E00; kbAltF8 = $6F00; kbAltF9 = $7000;
+ kbAltF10 = $7100; kbCtrlPrtSc = $7200; kbCtrlLeft = $7300;
+ kbCtrlRight = $7400; kbCtrlEnd = $7500; kbCtrlPgDn = $7600;
+ kbCtrlHome = $7700; kbAlt1 = $7800; kbAlt2 = $7900;
+ kbAlt3 = $7A00; kbAlt4 = $7B00; kbAlt5 = $7C00;
+ kbAlt6 = $7D00; kbAlt7 = $7E00; kbAlt8 = $7F00;
+ kbAlt9 = $8000; kbAlt0 = $8100; kbAltMinus = $8200;
+ kbAltEqual = $8300; kbCtrlPgUp = $8400; kbF11 = $8500;
+ kbF12 = $8600; kbShiftF11 = $8700; kbShiftF12 = $8800;
+ kbCtrlF11 = $8900; kbCtrlF12 = $8A00; kbAltF11 = $8B00;
+ kbAltF12 = $8C00; kbCtrlUp = $8D00; kbCtrlMinus = $8E00;
+ kbCtrlCenter = $8F00; kbCtrlGreyPlus= $9000; kbCtrlDown = $9100;
+ kbCtrlTab = $9400; kbAltHome = $9700; kbAltUp = $9800;
+ kbAltPgUp = $9900; kbAltLeft = $9B00; kbAltRight = $9D00;
+ kbAltEnd = $9F00; kbAltDown = $A000; kbAltPgDn = $A100;
+ kbAltIns = $A200; kbAltDel = $A300; kbAltTab = $A500;
+
+{ ------------------------------- REMARK ------------------------------ }
+{ New keys not initially defined by Borland in their unit interface. }
+{ ------------------------------ END REMARK --- Leon de Boer, 15May96 - }
+ kbFullStop = $342E; kbComma = $332C; kbBackSlash = $352F;
+ kbApostrophe = $2827; kbSemiColon = $273B; kbEqual = $0D3D;
+ kbGreaterThan = $343E; kbLessThan = $333C; kbQuestion = $353F;
+ kbQuote = $2822; kbColon = $273A; kbPlus = $0D2B;
+ kbPipe = $2B7C; kbSlash = $2B5C; kbExclaim = $0221;
+ kbAt = $0340; kbNumber = $0423; kbPercent = $0625;
+ kbCaret = $075E; kbAmpersand = $0826; kbAsterix = $092A;
+ kbLeftBracket = $0A28; kbRightBracket= $0B29; kbApprox = $2960;
+ kbTilde = $297E; kbDollar = $0524; kbMinus = $0C2D;
+ kbUnderline = $0C5F; kbLeftSqBr = $1A5B; kbRightSqBr = $1B5D;
+ kbLeftCurlyBr = $1A7B; kbRightCurlyBr= $1B7D;
+
+{---------------------------------------------------------------------------}
+{ KEYBOARD STATE AND SHIFT MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ kbRightShift = $0001; { Right shift key }
+ kbLeftShift = $0002; { Left shift key }
+ kbCtrlShift = $0004; { Control key down }
+ kbAltShift = $0008; { Alt key down }
+ kbScrollState = $0010; { Scroll lock on }
+ kbNumState = $0020; { Number lock on }
+ kbCapsState = $0040; { Caps lock on }
+ kbInsState = $0080; { Insert mode on }
+
+ kbBothShifts = kbRightShift + kbLeftShift; { Right & Left shifts }
+
+{---------------------------------------------------------------------------}
+{ MOUSE BUTTON STATE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ mbLeftButton = $01; { Left mouse button }
+ mbRightButton = $02; { Right mouse button }
+ mbMiddleButton = $04; { Middle mouse button }
+
+{---------------------------------------------------------------------------}
+{ SCREEN CRT MODE CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ smBW80 = $0002; { Black and white }
+ smCO80 = $0003; { Colour mode }
+ smMono = $0007; { Monochrome mode }
+ smFont8x8 = $0100; { 8x8 font mode }
+
+{***************************************************************************}
+{ PUBLIC TYPE DEFINITIONS }
+{***************************************************************************}
+
+{ ******************************* REMARK ****************************** }
+{ The TEvent definition is completely compatable with all existing }
+{ code but adds two new fields ID and Data into the message record }
+{ which helps with WIN/NT and OS2 message processing. }
+{ ****************************** END REMARK *** Leon de Boer, 11Sep97 * }
+
+{---------------------------------------------------------------------------}
+{ EVENT RECORD DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ TEvent =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ What: Sw_Word; { Event type }
+ Case Sw_Word Of
+ evNothing: (); { ** NO EVENT ** }
+ evMouse: (
+ Buttons: Byte; { Mouse buttons }
+ Double: Boolean; { Double click state }
+ Where: TPoint); { Mouse position }
+ evKeyDown: (
+ { ** KEY EVENT ** }
+ Case Sw_Integer Of
+ 0: (KeyCode: Word); { Full key code }
+ 1: (
+{$ifdef ENDIAN_BIG}
+ ScanCode: Byte;
+ CharCode: Char;
+{$else not ENDIAN_BIG}
+ CharCode: Char; { Char code }
+ ScanCode: Byte; { Scan code }
+{$endif not ENDIAN_BIG}
+ KeyShift: byte)); { Shift states }
+ evMessage: ( { ** MESSAGE EVENT ** }
+ Command: Sw_Word; { Message command }
+ Id : Sw_Word; { Message id }
+ Data : Real; { Message data }
+ Case Sw_Word Of
+ 0: (InfoPtr: Pointer); { Message pointer }
+ 1: (InfoLong: Longint); { Message longint }
+ 2: (InfoWord: Word); { Message Sw_Word }
+ 3: (InfoInt: Integer); { Message Sw_Integer }
+ 4: (InfoByte: Byte); { Message byte }
+ 5: (InfoChar: Char)); { Message character }
+ END;
+ PEvent = ^TEvent;
+
+ TVideoMode = Video.TVideoMode; { Screen mode }
+
+{---------------------------------------------------------------------------}
+{ ERROR HANDLER FUNCTION DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ TSysErrorFunc = FUNCTION (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{ Get Dos counter ticks }
+Function GetDosTicks:longint; { returns ticks at 18.2 Hz, just like DOS }
+
+
+procedure GiveUpTimeSlice;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ BUFFER MOVE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-CStrLen------------------------------------------------------------
+Returns the length of string S, where S is a control string using tilde
+characters ('~') to designate shortcut characters. The tildes are
+excluded from the length of the string, as they will not appear on
+the screen. For example, given the string '~B~roccoli' as its
+parameter, CStrLen returns 8.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION CStrLen (Const S: String): Sw_Integer;
+
+{-MoveStr------------------------------------------------------------
+Moves a string into a buffer for use with a view's WriteBuf or WriteLine.
+Dest must be a TDrawBuffer (or an equivalent array of Sw_Words). The
+characters in Str are moved into the low bytes of corresponding Sw_Words
+in Dest. The high bytes of the Sw_Words are set to Attr, or remain
+unchanged if Attr is zero.
+25May96 LdB
+---------------------------------------------------------------------}
+PROCEDURE MoveStr (Var Dest; Const Str: String; Attr: Byte);
+
+{-MoveCStr-----------------------------------------------------------
+The characters in Str are moved into the low bytes of corresponding
+Sw_Words in Dest. The high bytes of the Sw_Words are set to Lo(Attr) or
+Hi(Attr). Tilde characters (~) in the string toggle between the two
+attribute bytes passed in the Attr Sw_Word.
+25May96 LdB
+---------------------------------------------------------------------}
+PROCEDURE MoveCStr (Var Dest; Const Str: String; Attrs: Word);
+
+{-MoveBuf------------------------------------------------------------
+Count bytes are moved from Source into the low bytes of corresponding
+Sw_Words in Dest. The high bytes of the Sw_Words in Dest are set to Attr,
+or remain unchanged if Attr is zero.
+25May96 LdB
+---------------------------------------------------------------------}
+PROCEDURE MoveBuf (Var Dest, Source; Attr: Byte; Count: Sw_Word);
+
+{-MoveChar------------------------------------------------------------
+Moves characters into a buffer for use with a view's WriteBuf or
+WriteLine. Dest must be a TDrawBuffer (or an equivalent array of Sw_Words).
+The low bytes of the first Count Sw_Words of Dest are set to C, or
+remain unchanged if Ord(C) is zero. The high bytes of the Sw_Words are
+set to Attr, or remain unchanged if Attr is zero.
+25May96 LdB
+---------------------------------------------------------------------}
+PROCEDURE MoveChar (Var Dest; C: Char; Attr: Byte; Count: Sw_Word);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ KEYBOARD SUPPORT ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-GetAltCode---------------------------------------------------------
+Returns the scancode corresponding to Alt+Ch key that is given.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION GetAltCode (Ch: Char): Word;
+
+{-GetCtrlCode--------------------------------------------------------
+Returns the scancode corresponding to Alt+Ch key that is given.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION GetCtrlCode (Ch: Char): Word;
+
+{-GetAltChar---------------------------------------------------------
+Returns the ascii character for the Alt+Key scancode that was given.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION GetAltChar (KeyCode: Word): Char;
+
+{-GetCtrlChar--------------------------------------------------------
+Returns the ascii character for the Ctrl+Key scancode that was given.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION GetCtrlChar (KeyCode: Word): Char;
+
+{-CtrlToArrow--------------------------------------------------------
+Converts a WordStar-compatible control key code to the corresponding
+cursor key code.
+25May96 LdB
+---------------------------------------------------------------------}
+FUNCTION CtrlToArrow (KeyCode: Word): Word;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ KEYBOARD CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-GetShiftState------------------------------------------------------
+Returns a byte containing the current Shift key state. The return
+value contains a combination of the kbXXXX constants for shift states.
+08Jul96 LdB
+---------------------------------------------------------------------}
+FUNCTION GetShiftState: Byte;
+
+{-GetKeyEvent--------------------------------------------------------
+Checks whether a keyboard event is available. If a key has been pressed,
+Event.What is set to evKeyDown and Event.KeyCode is set to the scan
+code of the key. Otherwise, Event.What is set to evNothing.
+19May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE GetKeyEvent (Var Event: TEvent);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MOUSE CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-ShowMouse----------------------------------------------------------
+Decrements the hide counter and if zero the mouse is shown on screen.
+30Jun98 LdB
+---------------------------------------------------------------------}
+PROCEDURE ShowMouse;
+
+{-HideMouse----------------------------------------------------------
+If mouse hide counter is zero it removes the cursor from the screen.
+The hide counter is then incremented by one count.
+30Jun98 LdB
+---------------------------------------------------------------------}
+PROCEDURE HideMouse;
+
+{-GetMouseEvent------------------------------------------------------
+Checks whether a mouse event is available. If a mouse event has occurred,
+Event.What is set to evMouseDown, evMouseUp, evMouseMove, or evMouseAuto
+and the button and double click variables are set appropriately.
+06Jan97 LdB
+---------------------------------------------------------------------}
+PROCEDURE GetMouseEvent (Var Event: TEvent);
+
+{-GetSystemEvent------------------------------------------------------
+Checks whether a system event is available. If a system event has occurred,
+Event.What is set to evCommand appropriately
+10Oct2000 PM
+---------------------------------------------------------------------}
+procedure GetSystemEvent (Var Event: TEvent);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ EVENT HANDLER CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-InitEvents---------------------------------------------------------
+Initializes the event manager, enabling the mouse handler routine and
+under DOS/DPMI shows the mouse on screen. It is called automatically
+by TApplication.Init.
+02May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE InitEvents;
+
+{-DoneEvents---------------------------------------------------------
+Terminates event manager and disables the mouse and under DOS hides
+the mouse. It is called automatically by TApplication.Done.
+02May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneEvents;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ VIDEO CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-Initkeyboard-------------------------------------------------------
+Initializes the keyboard. Before it is called read(ln)/write(ln)
+are functional, after it is called FV's keyboard routines are
+functional.
+---------------------------------------------------------------------}
+
+procedure initkeyboard;
+
+{-Donekeyboard-------------------------------------------------------
+Restores keyboard to original state. FV's keyboard routines may not
+be used after a call to this. Read(ln)/write(ln) can be used again.
+---------------------------------------------------------------------}
+
+procedure donekeyboard;
+
+{-InitVideo---------------------------------------------------------
+Initializes the video manager, Saves the current screen mode in
+StartupMode, and switches to the mode indicated by ScreenMode.
+19May98 LdB
+---------------------------------------------------------------------}
+function InitVideo:boolean;
+
+{-DoneVideo---------------------------------------------------------
+Terminates the video manager by restoring the initial screen mode
+(given by StartupMode), clearing the screen, and restoring the cursor.
+Called automatically by TApplication.Done.
+03Jan97 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneVideo;
+
+{-ClearScreen--------------------------------------------------------
+Does nothing provided for compatability purposes only.
+04Jan97 LdB
+---------------------------------------------------------------------}
+PROCEDURE ClearScreen;
+
+{-SetVideoMode-------------------------------------------------------
+Does nothing provided for compatability purposes only.
+04Jan97 LdB
+---------------------------------------------------------------------}
+PROCEDURE SetVideoMode (Mode: Sw_Word);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ ERROR CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-InitSysError-------------------------------------------------------
+Error handling is not yet implemented so this simply sets
+SysErrActive=True (ie it lies) and exits.
+20May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE InitSysError;
+
+{-DoneSysError-------------------------------------------------------
+Error handling is not yet implemented so this simply sets
+SysErrActive=False and exits.
+20May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneSysError;
+
+{-SystemError---------------------------------------------------------
+Error handling is not yet implemented so this simply drops through.
+20May98 LdB
+---------------------------------------------------------------------}
+FUNCTION SystemError (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STRING FORMAT ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-PrintStr-----------------------------------------------------------
+Does nothing provided for compatability purposes only.
+30Jun98 LdB
+---------------------------------------------------------------------}
+PROCEDURE PrintStr (CONST S: String);
+
+{-FormatStr----------------------------------------------------------
+A string formatting routine that given a string that includes format
+specifiers and a list of parameters in Params, FormatStr produces a
+formatted output string in Result.
+18Feb99 LdB
+---------------------------------------------------------------------}
+PROCEDURE FormatStr (Var Result: String; CONST Format: String; Var Params);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ >> NEW QUEUED EVENT HANDLER ROUTINES << }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-PutEventInQueue-----------------------------------------------------
+If there is room in the queue the event is placed in the next vacant
+position in the queue manager.
+17Mar98 LdB
+---------------------------------------------------------------------}
+FUNCTION PutEventInQueue (Var Event: TEvent): Boolean;
+
+{-NextQueuedEvent----------------------------------------------------
+If there are queued events the next event is loaded into event else
+evNothing is returned.
+17Mar98 LdB
+---------------------------------------------------------------------}
+PROCEDURE NextQueuedEvent(Var Event: TEvent);
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+PROCEDURE HideMouseCursor;
+PROCEDURE ShowMouseCursor;
+
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ CheckSnow : Boolean = False; { Compatability only }
+ MouseEvents : Boolean = False; { Mouse event state }
+ MouseReverse : Boolean = False; { Mouse reversed }
+ HiResScreen : Boolean = False; { Compatability only }
+ CtrlBreakHit : Boolean = False; { Compatability only }
+ SaveCtrlBreak: Boolean = False; { Compatability only }
+ SysErrActive : Boolean = False; { Compatability only }
+ FailSysErrors: Boolean = False; { Compatability only }
+ ButtonCount : Byte = 0; { Mouse button count }
+ DoubleDelay : Sw_Word = 8; { Double click delay }
+ RepeatDelay : Sw_Word = 8; { Auto mouse delay }
+ SysColorAttr : Sw_Word = $4E4F; { System colour attr }
+ SysMonoAttr : Sw_Word = $7070; { System mono attr }
+ StartupMode : Sw_Word = $FFFF; { Compatability only }
+ CursorLines : Sw_Word = $FFFF; { Compatability only }
+ ScreenBuffer : Pointer = Nil; { Compatability only }
+ SaveInt09 : Pointer = Nil; { Compatability only }
+ SysErrorFunc : TSysErrorFunc = {$ifdef FPC}@{$endif}SystemError; { System error ptr }
+
+
+{***************************************************************************}
+{ UNINITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ UNINITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+VAR
+ MouseIntFlag: Byte; { Mouse in int flag }
+ MouseButtons: Byte; { Mouse button state }
+ ScreenWidth : Byte; { Screen text width }
+ ScreenHeight: Byte; { Screen text height }
+ ScreenMode : TVideoMode; { Screen mode }
+ MouseWhere : TPoint; { Mouse position }
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+{ API Units }
+ USES
+ FVConsts,
+ Keyboard,Mouse;
+
+{***************************************************************************}
+{ PRIVATE INTERNAL CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ DOS/DPMI MOUSE INTERRUPT EVENT QUEUE SIZE }
+{---------------------------------------------------------------------------}
+CONST EventQSize = 16; { Default int bufsize }
+
+{---------------------------------------------------------------------------}
+{ DOS/DPMI/WIN/NT/OS2 NEW EVENT QUEUE MAX SIZE }
+{---------------------------------------------------------------------------}
+CONST QueueMax = 64; { Max new queue size }
+
+{---------------------------------------------------------------------------}
+{ MAX WIEW WIDTH to avoid TDrawBuffer overrun in views unit }
+{---------------------------------------------------------------------------}
+CONST MaxViewWidth = 255; { Max view width }
+
+{***************************************************************************}
+{ PRIVATE INTERNAL TYPES }
+{***************************************************************************}
+
+{***************************************************************************}
+{ PRIVATE INTERNAL INITIALIZED VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ DOS/DPMI/WIN/NT/OS2 ALT KEY SCANCODES FROM KEYS (0-127) }
+{---------------------------------------------------------------------------}
+CONST AltCodes: Array [0..127] Of Byte = (
+ $00, $00, $00, $00, $00, $00, $00, $00, { $00 - $07 }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $08 - $0F }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $10 - $17 }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $18 - $1F }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $20 - $27 }
+ $00, $00, $00, $00, $00, $82, $00, $00, { $28 - $2F }
+ $81, $78, $79, $7A, $7B, $7C, $7D, $7E, { $30 - $37 }
+ $7F, $80, $00, $00, $00, $83, $00, $00, { $38 - $3F }
+ $00, $1E, $30, $2E, $20, $12, $21, $22, { $40 - $47 }
+ $23, $17, $24, $25, $26, $32, $31, $18, { $48 - $4F }
+ $19, $10, $13, $1F, $14, $16, $2F, $11, { $50 - $57 }
+ $2D, $15, $2C, $00, $00, $00, $00, $00, { $58 - $5F }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $60 - $67 }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $68 - $6F }
+ $00, $00, $00, $00, $00, $00, $00, $00, { $70 - $77 }
+ $00, $00, $00, $00, $00, $00, $00, $00); { $78 - $7F }
+
+{***************************************************************************}
+{ PRIVATE INTERNAL INITIALIZED VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ NEW CONTROL VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ HideCount : Sw_Integer = 0; { Cursor hide count }
+ QueueCount: Sw_Word = 0; { Queued message count }
+ QueueHead : Sw_Word = 0; { Queue head pointer }
+ QueueTail : Sw_Word = 0; { Queue tail pointer }
+
+{***************************************************************************}
+{ PRIVATE INTERNAL UNINITIALIZED VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ UNINITIALIZED DOS/DPMI/API VARIABLES }
+{---------------------------------------------------------------------------}
+VAR
+ LastDouble : Boolean; { Last double buttons }
+ LastButtons: Byte; { Last button state }
+ DownButtons: Byte; { Last down buttons }
+ EventCount : Sw_Word; { Events in queue }
+ AutoDelay : Sw_Word; { Delay time count }
+ DownTicks : Sw_Word; { Down key tick count }
+ AutoTicks : Sw_Word; { Held key tick count }
+ LastWhereX : Sw_Word; { Last x position }
+ LastWhereY : Sw_Word; { Last y position }
+ DownWhereX : Sw_Word; { Last x position }
+ DownWhereY : Sw_Word; { Last y position }
+ LastWhere : TPoint; { Last mouse position }
+ DownWhere : TPoint; { Last down position }
+ EventQHead : Pointer; { Head of queue }
+ EventQTail : Pointer; { Tail of queue }
+ EventQueue : Array [0..EventQSize - 1] Of TEvent; { Event queue }
+ EventQLast : RECORD END; { Simple end marker }
+ StartupScreenMode : TVideoMode;
+
+{---------------------------------------------------------------------------}
+{ GetDosTicks (18.2 Hz) }
+{---------------------------------------------------------------------------}
+
+Function GetDosTicks:longint; { returns ticks at 18.2 Hz, just like DOS }
+{$IFDEF OS_OS2}
+ const
+ QSV_MS_COUNT = 14;
+ var
+ L: longint;
+ begin
+ DosQuerySysInfo (QSV_MS_COUNT, QSV_MS_COUNT, L, 4);
+ GetDosTicks := L div 55;
+ end;
+{$ENDIF}
+{$IFDEF OS_UNIX}
+ var
+ tv : TimeVal;
+ { tz : TimeZone;}
+ begin
+ {$ifdef ver1_0}
+ GetTimeOfDay(tv{,tz});
+ GetDosTicks:=((tv.Sec mod 86400) div 60)*1092+((tv.Sec mod 60)*1000000+tv.USec) div 54945;
+ {$else}
+ FPGetTimeOfDay(@tv,nil{,tz});
+ GetDosTicks:=((tv.tv_Sec mod 86400) div 60)*1092+((tv.tv_Sec mod 60)*1000000+tv.tv_USec) div 54945;
+
+ {$endif}
+ end;
+{$ENDIF OS_UNIX}
+{$IFDEF OS_WINDOWS}
+ begin
+ GetDosTicks:=GetTickCount div 55;
+ end;
+{$ENDIF OS_WINDOWS}
+{$IFDEF OS_DOS}
+ begin
+ GetDosTicks:=MemL[$40:$6c];
+ end;
+{$ENDIF OS_DOS}
+{$IFDEF OS_NETWARE_LIBC}
+var
+ tv : TTimeVal;
+ tz : TTimeZone;
+ begin
+ fpGetTimeOfDay(tv,tz);
+ GetDosTicks:=((tv.tv_sec mod 86400) div 60)*1092+((tv.tv_Sec mod 60)*1000000+tv.tv_USec) div 549
+ end;
+{$ENDIF}
+{$IFDEF OS_NETWARE_CLIB}
+ begin
+ GetDosTicks := Nwserv.GetCurrentTicks;
+ end;
+{$ENDIF}
+
+
+procedure GiveUpTimeSlice;
+{$IFDEF OS_DOS}
+var r: registers;
+begin
+ Intr ($28, R); (* This is supported everywhere. *)
+ r.ax:=$1680;
+ intr($2f,r);
+end;
+{$ENDIF}
+{$IFDEF OS_UNIX}
+ var
+ req,rem : timespec;
+begin
+ req.tv_sec:=0;
+ req.tv_nsec:=10000000;{ 10 ms }
+ {$ifdef ver1_0}nanosleep(req,rem){$else}fpnanosleep(@req,@rem){$endif};
+end;
+{$ENDIF}
+{$IFDEF OS_OS2}
+begin
+ DosSleep (5);
+end;
+{$ENDIF}
+{$IFDEF OS_WINDOWS}
+begin
+ { if the return value of this call is non zero then
+ it means that a ReadFileEx or WriteFileEx have completed
+ unused for now ! }
+ { wait for 10 ms }
+ if SleepEx(10,true)=WAIT_IO_COMPLETION then
+ begin
+ { here we should handle the completion of the routines
+ if we use them }
+ end;
+end;
+{$ENDIF}
+{$IFDEF OS_NETWARE_LIBC}
+ begin
+ Delay (10);
+ end;
+{$ENDIF}
+{$IFDEF OS_NETWARE_CLIB}
+ begin
+ Delay (10);
+ end;
+{$ENDIF}
+
+
+{---------------------------------------------------------------------------}
+{ UNINITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+VAR
+ SaveExit: Pointer; { Saved exit pointer }
+ Queue : Array [0..QueueMax-1] Of TEvent; { New message queue }
+
+{***************************************************************************}
+{ PRIVATE INTERNAL ROUTINES }
+{***************************************************************************}
+
+PROCEDURE ShowMouseCursor;inline;
+BEGIN
+ ShowMouse;
+END;
+
+PROCEDURE HideMouseCursor;inline;
+BEGIN
+ HideMouse;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ DOS/DPMI/WIN/NT/OS2 PRIVATE INTERNAL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ ExitDrivers -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jun98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE ExitDrivers; {$IFNDEF PPC_FPC}{$IFNDEF OS_UNIX} FAR; {$ENDIF}{$ENDIF}
+BEGIN
+ DoneSysError; { Relase error trap }
+ DoneEvents; { Close event driver }
+{ DoneKeyboard;}
+ DoneVideo;
+ ExitProc := SaveExit; { Restore old exit }
+END;
+
+{---------------------------------------------------------------------------}
+{ DetectVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+
+procedure DetectVideo;
+VAR
+ CurrMode : TVideoMode;
+begin
+ { Video.InitVideo; Incompatible with BP
+ and forces a screen clear which is often a bad thing PM }
+ GetVideoMode(CurrMode);
+ ScreenMode:=CurrMode;
+end;
+
+{---------------------------------------------------------------------------}
+{ DetectMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+FUNCTION DetectMouse: Byte;inline;
+begin
+ DetectMouse:=Mouse.DetectMouse;
+end;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ BUFFER MOVE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ CStrLen -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION CStrLen (Const S: String): Sw_Integer;
+VAR I, J: Sw_Integer;
+BEGIN
+ J := 0; { Set result to zero }
+ For I := 1 To Length(S) Do
+ If (S[I] <> '~') Then Inc(J); { Inc count if not ~ }
+ CStrLen := J; { Return length }
+END;
+
+{---------------------------------------------------------------------------}
+{ MoveStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MoveStr (Var Dest; Const Str: String; Attr: Byte);
+VAR I: Word; P: PWord;
+BEGIN
+ For I := 1 To Length(Str) Do Begin { For each character }
+ P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
+ If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
+ WordRec(P^).Lo := Byte(Str[I]); { Copy string char }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ MoveCStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MoveCStr (Var Dest; Const Str: String; Attrs: Word);
+VAR B: Byte; I, J: Sw_Word; P: PWord;
+BEGIN
+ J := 0; { Start position }
+ For I := 1 To Length(Str) Do Begin { For each character }
+ If (Str[I] <> '~') Then Begin { Not tilde character }
+ P := @TWordArray(Dest)[J]; { Pointer to Sw_Word }
+ If (Lo(Attrs) <> 0) Then
+ WordRec(P^).Hi := Lo(Attrs); { Copy attribute }
+ WordRec(P^).Lo := Byte(Str[I]); { Copy string char }
+ Inc(J); { Next position }
+ End Else Begin
+ B := Hi(Attrs); { Hold attribute }
+ WordRec(Attrs).Hi := Lo(Attrs); { Copy low to high }
+ WordRec(Attrs).Lo := B; { Complete exchange }
+ End;
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ MoveBuf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MoveBuf (Var Dest, Source; Attr: Byte; Count: Sw_Word);
+VAR I: Word; P: PWord;
+BEGIN
+ For I := 1 To Count Do Begin
+ P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
+ If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
+ WordRec(P^).Lo := TByteArray(Source)[I-1]; { Copy source data }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ MoveChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MoveChar (Var Dest; C: Char; Attr: Byte; Count: Sw_Word);
+VAR I: Word; P: PWord;
+BEGIN
+ For I := 1 To Count Do Begin
+ P := @TWordArray(Dest)[I-1]; { Pointer to Sw_Word }
+ If (Attr <> 0) Then WordRec(P^).Hi := Attr; { Copy attribute }
+ If (Ord(C) <> 0) Then WordRec(P^).Lo := Byte(C); { Copy character }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ KEYBOARD SUPPORT ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ GetAltCode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetAltCode (Ch: Char): Word;
+BEGIN
+ GetAltCode := 0; { Preset zero return }
+ Ch := UpCase(Ch); { Convert upper case }
+ If (Ch < #128) Then
+ GetAltCode := AltCodes[Ord(Ch)] SHL 8 { Return code }
+ Else If (Ch = #240) Then GetAltCode := $0200 { Return code }
+ Else GetAltCode := 0; { Return zero }
+END;
+
+{---------------------------------------------------------------------------}
+{ GetCtrlCode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetCtrlCode (Ch: Char): Word;
+BEGIN
+ GetCtrlCode := GetAltCode(Ch) OR (Ord(Ch) - $40); { Ctrl+key code }
+END;
+
+{---------------------------------------------------------------------------}
+{ GetAltChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetAltChar (KeyCode: Word): Char;
+VAR I: Sw_Integer;
+BEGIN
+ GetAltChar := #0; { Preset fail return }
+ If (Lo(KeyCode) = 0) Then Begin { Extended key }
+ If (Hi(KeyCode) <= $83) Then Begin { Highest value in list }
+ I := 0; { Start at first }
+ While (I < 128) AND (Hi(KeyCode) <> AltCodes[I])
+ Do Inc(I); { Search for match }
+ If (I < 128) Then GetAltChar := Chr(I); { Return character }
+ End Else
+ If (Hi(KeyCode)=$02) Then GetAltChar := #240; { Return char }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ GetCtrlChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetCtrlChar (KeyCode: Word): Char;
+VAR C: Char;
+BEGIN
+ C := #0; { Preset #0 return }
+ If (Lo(KeyCode) > 0) AND (Lo(KeyCode) <= 26) Then { Between 1-26 }
+ C := Chr(Lo(KeyCode) + $40); { Return char A-Z }
+ GetCtrlChar := C; { Return result }
+END;
+
+{---------------------------------------------------------------------------}
+{ CtrlToArrow -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25May96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION CtrlToArrow (KeyCode: Word): Word;
+CONST NumCodes = 11;
+ CtrlCodes : Array [0..NumCodes-1] Of Char =
+ (#19, #4, #5, #24, #1, #6, #7, #22, #18, #3, #8);
+ ArrowCodes: Array [0..NumCodes-1] Of Sw_Word =
+ (kbLeft, kbRight, kbUp, kbDown, kbHome, kbEnd, kbDel, kbIns,
+ kbPgUp, kbPgDn, kbBack);
+VAR I: Sw_Integer;
+BEGIN
+ CtrlToArrow := KeyCode; { Preset key return }
+ For I := 0 To NumCodes - 1 Do
+ If WordRec(KeyCode).Lo = Byte(CtrlCodes[I]) { Matches a code }
+ Then Begin
+ CtrlToArrow := ArrowCodes[I]; { Return key stroke }
+ Exit; { Now exit }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ KEYBOARD CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ GetShiftState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08Jul96 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetShiftState: Byte;
+begin
+ GetShiftState:=Keyboard.GetKeyEventShiftState(Keyboard.PollShiftStateEvent);
+end;
+
+{---------------------------------------------------------------------------}
+{ GetKeyEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+procedure GetKeyEvent (Var Event: TEvent);
+var
+ key : TKeyEvent;
+ keycode : Word;
+ keyshift : byte;
+begin
+ if Keyboard.PollKeyEvent<>0 then
+ begin
+ key:=Keyboard.GetKeyEvent;
+ keycode:=Keyboard.GetKeyEventCode(key);
+ keyshift:=KeyBoard.GetKeyEventShiftState(key);
+ { fixup shift-keys }
+ if keyshift and kbShift<>0 then
+ begin
+ case keycode of
+ $5200 : keycode:=kbShiftIns;
+ $5300 : keycode:=kbShiftDel;
+ $8500 : keycode:=kbShiftF1;
+ $8600 : keycode:=kbShiftF2;
+ end;
+ end
+ { fixup ctrl-keys }
+ else if keyshift and kbCtrl<>0 then
+ begin
+ case keycode of
+ $5200,
+ $9200 : keycode:=kbCtrlIns;
+ $5300,
+ $9300 : keycode:=kbCtrlDel;
+ end;
+ end
+ { fixup alt-keys }
+ else if keyshift and kbAlt<>0 then
+ begin
+ case keycode of
+ $0e08,
+ $0e00 : keycode:=kbAltBack;
+ end;
+ end
+ { fixup normal keys }
+ else
+ begin
+ case keycode of
+ $e00d : keycode:=kbEnter;
+ end;
+ end;
+ Event.What:=evKeyDown;
+ Event.KeyCode:=keycode;
+{$ifdef ENDIAN_LITTLE}
+ Event.CharCode:=chr(keycode and $ff);
+ Event.ScanCode:=keycode shr 8;
+{$endif ENDIAN_LITTLE}
+ Event.KeyShift:=keyshift;
+ end
+ else
+ Event.What:=evNothing;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MOUSE CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ HideMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun98 LdB }
+{---------------------------------------------------------------------------}
+procedure HideMouse;
+begin
+{ Is mouse hidden yet?
+ If (HideCount = 0) Then}
+ Mouse.HideMouse;
+{ Inc(HideCount);}
+end;
+
+{---------------------------------------------------------------------------}
+{ ShowMouse -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jun98 LdB }
+{---------------------------------------------------------------------------}
+procedure ShowMouse;
+begin
+{ if HideCount>0 then
+ dec(HideCount);
+ if (HideCount=0) then}
+ Mouse.ShowMouse;
+end;
+
+{---------------------------------------------------------------------------}
+{ GetMouseEvent -> Platforms DOS/DPMI/WINDOWS/OS2 - Updated 30Jun98 LdB }
+{---------------------------------------------------------------------------}
+procedure GetMouseEvent (Var Event: TEvent);
+var
+ e : Mouse.TMouseEvent;
+begin
+ if Mouse.PollMouseEvent(e) then
+ begin
+ Mouse.GetMouseEvent(e);
+ MouseWhere.X:=e.x;
+ MouseWhere.Y:=e.y;
+ Event.Double:=false;
+ case e.Action of
+ MouseActionMove :
+ Event.What:=evMouseMove;
+ MouseActionDown :
+ begin
+ Event.What:=evMouseDown;
+ if (DownButtons=e.Buttons) and (LastWhere.X=MouseWhere.X) and (LastWhere.Y=MouseWhere.Y) and
+ (GetDosTicks-DownTicks<=DoubleDelay) then
+ Event.Double:=true;
+ DownButtons:=e.Buttons;
+ DownWhere.X:=MouseWhere.x;
+ DownWhere.Y:=MouseWhere.y;
+ DownTicks:=GetDosTicks;
+ AutoTicks:=GetDosTicks;
+ if AutoTicks=0 then
+ AutoTicks:=1;
+ AutoDelay:=RepeatDelay;
+ end;
+ MouseActionUp :
+ begin
+ AutoTicks:=0;
+ Event.What:=evMouseUp;
+ AutoTicks:=0;
+ end;
+ end;
+ Event.Buttons:=e.Buttons;
+ Event.Where.X:=MouseWhere.x;
+ Event.Where.Y:=MouseWhere.y;
+ LastButtons:=Event.Buttons;
+ LastWhere.x:=Event.Where.x;
+ LastWhere.y:=Event.Where.y;
+ end
+ else if (AutoTicks <> 0) and (GetDosTicks >= AutoTicks + AutoDelay) then
+ begin
+ Event.What:=evMouseAuto;
+ Event.Buttons:=LastButtons;
+ Event.Where.X:=LastWhere.x;
+ Event.Where.Y:=LastWhere.y;
+ AutoTicks:=GetDosTicks;
+ AutoDelay:=1;
+ end
+ else
+ FillChar(Event,sizeof(TEvent),0);
+ if MouseReverse and ((Event.Buttons and 3) in [1,2]) then
+ Event.Buttons := Event.Buttons xor 3;
+end;
+
+{---------------------------------------------------------------------------}
+{ GetSystemEvent }
+{---------------------------------------------------------------------------}
+procedure GetSystemEvent (Var Event: TEvent);
+var
+ SysEvent : TsystemEvent;
+begin
+ if PollSystemEvent(SysEvent) then
+ begin
+ SysMsg.GetSystemEvent(SysEvent);
+ case SysEvent.typ of
+ SysNothing :
+ Event.What:=evNothing;
+ SysSetFocus :
+ begin
+ Event.What:=evBroadcast;
+ Event.Command:=cmReceivedFocus;
+ end;
+ SysReleaseFocus :
+ begin
+ Event.What:=evBroadcast;
+ Event.Command:=cmReleasedFocus;
+ end;
+ SysClose :
+ begin
+ Event.What:=evCommand;
+ Event.Command:=cmQuitApp;
+ end;
+ SysResize :
+ begin
+ Event.What:=evCommand;
+ Event.Command:=cmResizeApp;
+ Event.Id:=SysEvent.x;
+ Event.InfoWord:=SysEvent.y;
+ end;
+ else
+ Event.What:=evNothing;
+ end;
+ end
+ else
+ Event.What:=evNothing;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ EVENT HANDLER CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ InitEvents -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 07Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InitEvents;
+BEGIN
+ If (ButtonCount <> 0) Then
+ begin { Mouse is available }
+ Mouse.InitMouse; { Hook the mouse }
+ { this is required by the use of HideCount variable }
+ Mouse.ShowMouse; { visible by default }
+ { HideCount:=0; }
+ LastButtons := 0; { Clear last buttons }
+ DownButtons := 0; { Clear down buttons }
+ MouseWhere.X:=Mouse.GetMouseX;
+ MouseWhere.Y:=Mouse.GetMouseY; { Get mouse position }
+ LastWhere.x:=MouseWhere.x;
+ LastWhereX:=MouseWhere.x;
+ LastWhere.y:=MouseWhere.y;
+ LastWhereY:=MouseWhere.y;
+ MouseEvents := True; { Set initialized flag }
+ end;
+ InitSystemMsg;
+END;
+
+{---------------------------------------------------------------------------}
+{ DoneEvents -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneEvents;
+BEGIN
+ DoneSystemMsg;
+ Mouse.DoneMouse;
+ MouseEvents:=false;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ VIDEO CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+const
+ VideoInitialized : boolean = false;
+
+{---------------------------------------------------------------------------}
+{ InitKeyboard -> Platforms ALL - 07May06 DM }
+{---------------------------------------------------------------------------}
+
+procedure initkeyboard;inline;
+
+begin
+ keyboard.initkeyboard;
+end;
+
+{---------------------------------------------------------------------------}
+{ DoneKeyboard -> Platforms ALL - 07May06 DM }
+{---------------------------------------------------------------------------}
+
+procedure donekeyboard;inline;
+
+begin
+ keyboard.donekeyboard;
+end;
+
+{---------------------------------------------------------------------------}
+{ InitVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Nov99 LdB }
+{---------------------------------------------------------------------------}
+function InitVideo:boolean;
+
+var StoreScreenMode : TVideoMode;
+
+begin
+ initvideo:=false;
+ if VideoInitialized then
+ begin
+ StoreScreenMode:=ScreenMode;
+ DoneVideo;
+ end
+ else
+ StoreScreenMode.Col:=0;
+
+ Video.InitVideo;
+ if video.errorcode<>viook then
+ exit;
+ GetVideoMode(StartupScreenMode);
+ GetVideoMode(ScreenMode);
+{$ifdef win32}
+ { Force the console to the current screen mode }
+ Video.SetVideoMode(ScreenMode);
+{$endif win32}
+
+ If (StoreScreenMode.Col<>0) and
+ ((StoreScreenMode.color<>ScreenMode.color) or
+ (StoreScreenMode.row<>ScreenMode.row) or
+ (StoreScreenMode.col<>ScreenMode.col)) then
+ begin
+ Video.SetVideoMode(StoreScreenMode);
+ GetVideoMode(ScreenMode);
+ end;
+
+ if ScreenWidth > MaxViewWidth then
+ ScreenWidth := MaxViewWidth;
+ ScreenWidth:=Video.ScreenWidth;
+ ScreenHeight:=Video.ScreenHeight;
+ VideoInitialized:=true;
+ initvideo:=true;
+end;
+
+{---------------------------------------------------------------------------}
+{ DoneVideo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneVideo;
+BEGIN
+ if not VideoInitialized then
+ exit;
+ Video.SetVideoMode(StartupScreenMode);
+ Video.ClearScreen;
+ Video.SetCursorPos(0,0);
+ Video.DoneVideo;
+ VideoInitialized:=false;
+END;
+
+{---------------------------------------------------------------------------}
+{ ClearScreen -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Jan97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE ClearScreen;
+BEGIN
+ Video.ClearScreen;
+END;
+
+{---------------------------------------------------------------------------}
+{ SetVideoMode -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 10Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SetVideoMode (Mode: Sw_Word);
+BEGIN
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ ERROR CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ InitSysError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InitSysError;
+BEGIN
+ SysErrActive := True; { Set active flag }
+END;
+
+{---------------------------------------------------------------------------}
+{ DoneSysError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneSysError;
+BEGIN
+ SysErrActive := False; { Clear active flag }
+END;
+
+{---------------------------------------------------------------------------}
+{ SystemError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION SystemError (ErrorCode: Sw_Integer; Drive: Byte): Sw_Integer;
+BEGIN
+ If (FailSysErrors = False) Then Begin { Check error ignore }
+
+ End Else SystemError := 1; { Return 1 for ignored }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STRING FORMAT ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ PrintStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18Feb99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE PrintStr (CONST S: String);
+BEGIN
+ Write(S); { Write to screen }
+END;
+
+{---------------------------------------------------------------------------}
+{ FormatStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 13Jul99 LdB }
+{---------------------------------------------------------------------------}
+procedure FormatStr (Var Result: String; CONST Format: String; Var Params);
+TYPE TLongArray = Array[0..0] Of PtrInt;
+VAR W, ResultLength : integer;
+ FormatIndex, Justify, Wth: Byte;
+ Fill: Char; S: String;
+
+ FUNCTION LongToStr (L: Longint; Radix: Byte): String;
+ CONST HexChars: Array[0..15] Of Char =
+ ('0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
+ VAR I: LongInt; S: String; Sign: String[1];
+ begin
+ LongToStr := ''; { Preset empty return }
+ If (L < 0) Then begin { If L is negative }
+ Sign := '-'; { Sign is negative }
+ L := Abs(L); { Convert to positive }
+ end Else Sign := ''; { Sign is empty }
+ S := ''; { Preset empty string }
+ Repeat
+ I := L MOD Radix; { Radix mod of value }
+ S := HexChars[I] + S; { Add char to string }
+ L := L DIV Radix; { Divid by radix }
+ Until (L = 0); { Until no remainder }
+ LongToStr := Sign + S; { Return result }
+ end;
+
+ procedure HandleParameter (I : LongInt);
+ begin
+ While (FormatIndex <= Length(Format)) Do begin { While length valid }
+ if ResultLength>=High(Result) then
+ exit;
+ While (FormatIndex <= Length(Format)) and
+ (Format[FormatIndex] <> '%') { Param char not found }
+ Do begin
+ Result[ResultLength+1] := Format[FormatIndex]; { Transfer character }
+ Inc(ResultLength); { One character added }
+ Inc(FormatIndex); { Next param char }
+ end;
+ If (FormatIndex < Length(Format)) and { Not last char and }
+ (Format[FormatIndex] = '%') Then begin { '%' char found }
+ Fill := ' '; { Default fill char }
+ Justify := 0; { Default justify }
+ Wth := 0; { Default 0=no width }
+ Inc(FormatIndex); { Next character }
+ If (Format[FormatIndex] = '0') Then
+ Fill := '0'; { Fill char to zero }
+ If (Format[FormatIndex] = '-') Then begin { Optional just char }
+ Justify := 1; { Right justify }
+ Inc(FormatIndex); { Next character }
+ end;
+ While ((FormatIndex <= Length(Format)) and { Length still valid }
+ (Format[FormatIndex] >= '0') and
+ (Format[FormatIndex] <= '9')) Do begin { Numeric character }
+ Wth := Wth * 10; { Multiply x10 }
+ Wth := Wth + Ord(Format[FormatIndex])-$30; { Add numeric value }
+ Inc(FormatIndex); { Next character }
+ end;
+ If ((FormatIndex <= Length(Format)) and { Length still valid }
+ (Format[FormatIndex] = '#')) Then begin { Parameter marker }
+ Inc(FormatIndex); { Next character }
+ HandleParameter(Wth); { Width is param idx }
+ end;
+ If (FormatIndex <= Length(Format)) Then begin{ Length still valid }
+ Case Format[FormatIndex] Of
+ '%': begin { Literal % }
+ S := '%';
+ Inc(FormatIndex);
+ Move(S[1], Result[ResultLength+1], 1);
+ Inc(ResultLength,Length(S));
+ Continue;
+ end;
+ 'c': S := Char(TLongArray(Params)[I]); { Character parameter }
+ 'd': S := LongToStr(TLongArray(Params)[I],
+ 10); { Decimal parameter }
+ 's': S := PString(TLongArray(Params)[I])^;{ String parameter }
+ 'x': S := LongToStr(TLongArray(Params)[I],
+ 16); { Hex parameter }
+ end;
+ Inc(FormatIndex); { Next character }
+ If (Wth > 0) Then begin { Width control active }
+ If (Length(S) > Wth) Then begin { We must shorten S }
+ If (Justify=1) Then { Check right justify }
+ S := Copy(S, Length(S)-Wth+1, Wth) { Take right side data }
+ Else S := Copy(S, 1, Wth); { Take left side data }
+ end Else begin { We must pad out S }
+ If (Justify=1) Then { Right justify }
+ While (Length(S) < Wth) Do
+ S := S+Fill Else { Right justify fill }
+ While (Length(S) < Wth) Do
+ S := Fill + S; { Left justify fill }
+ end;
+ end;
+ W:=Length(S);
+ if W+ResultLength+1>High(Result) then
+ W:=High(Result)-ResultLength;
+ Move(S[1], Result[ResultLength+1],
+ W); { Move data to result }
+ Inc(ResultLength,W); { Adj result length }
+ Inc(I);
+ end;
+ end;
+ end;
+ end;
+
+begin
+ ResultLength := 0; { Zero result length }
+ FormatIndex := 1; { Format index to 1 }
+ HandleParameter(0); { Handle parameter }
+ Result[0] := Chr(ResultLength); { Set string length }
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ NEW QUEUED EVENT HANDLER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ PutEventInQueue -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Mar98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION PutEventInQueue (Var Event: TEvent): Boolean;
+BEGIN
+ If (QueueCount < QueueMax) Then Begin { Check room in queue }
+ Queue[QueueHead] := Event; { Store event }
+ Inc(QueueHead); { Inc head position }
+ If (QueueHead = QueueMax) Then QueueHead := 0; { Roll to start check }
+ Inc(QueueCount); { Inc queue count }
+ PutEventInQueue := True; { Return successful }
+ End Else PutEventInQueue := False; { Return failure }
+END;
+
+{---------------------------------------------------------------------------}
+{ NextQueuedEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Mar98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE NextQueuedEvent(Var Event: TEvent);
+BEGIN
+ If (QueueCount > 0) Then Begin { Check queued event }
+ Event := Queue[QueueTail]; { Fetch next event }
+ Inc(QueueTail); { Inc tail position }
+ If (QueueTail = QueueMax) Then QueueTail := 0; { Roll to start check }
+ Dec(QueueCount); { Dec queue count }
+ End Else Event.What := evNothing; { Return empty event }
+END;
+
+{***************************************************************************}
+{ UNIT INITIALIZATION ROUTINE }
+{***************************************************************************}
+BEGIN
+ ButtonCount := DetectMouse; { Detect mouse }
+ DetectVideo; { Detect video }
+{ InitKeyboard;}
+ InitSystemMsg;
+{$ifdef win32}
+ SetFileApisToOEM;
+{$endif}
+
+ SaveExit := ExitProc; { Save old exit }
+ ExitProc := @ExitDrivers; { Set new exit }
+END.
diff --git a/packages/fv/src/editors.pas b/packages/fv/src/editors.pas
new file mode 100644
index 0000000000..4503b8359c
--- /dev/null
+++ b/packages/fv/src/editors.pas
@@ -0,0 +1,3797 @@
+unit Editors;
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+
+
+{$define UNIXLF}
+
+{2.0 compatibility}
+{$ifdef VER2_0}
+ {$macro on}
+ {$define resourcestring := const}
+{$endif}
+
+interface
+
+uses
+ Objects, Drivers,Views,Dialogs,FVCommon,FVConsts;
+
+const
+ { Length constants. }
+ Tab_Stop_Length = 74;
+
+{$ifdef PPC_BP}
+ MaxLineLength = 1024;
+ MinBufLength = $1000;
+ MaxBufLength = $ff00;
+ NotFoundValue = $ffff;
+ LineInfoGrow = 256;
+ MaxLines = 16000;
+{$else}
+ MaxLineLength = 4096;
+ MinBufLength = $1000;
+ MaxBufLength = $7fffff00;
+ NotFoundValue = $ffffffff;
+ LineInfoGrow = 1024;
+ MaxLines = $7ffffff;
+{$endif}
+
+
+ { Editor constants for dialog boxes. }
+ edOutOfMemory = 0;
+ edReadError = 1;
+ edWriteError = 2;
+ edCreateError = 3;
+ edSaveModify = 4;
+ edSaveUntitled = 5;
+ edSaveAs = 6;
+ edFind = 7;
+ edSearchFailed = 8;
+ edReplace = 9;
+ edReplacePrompt = 10;
+
+ edJumpToLine = 11;
+ edPasteNotPossible = 12;
+ edReformatDocument = 13;
+ edReformatNotAllowed = 14;
+ edReformNotPossible = 15;
+ edReplaceNotPossible = 16;
+ edRightMargin = 17;
+ edSetTabStops = 18;
+ edWrapNotPossible = 19;
+
+ { Editor flag constants for dialog options. }
+ efCaseSensitive = $0001;
+ efWholeWordsOnly = $0002;
+ efPromptOnReplace = $0004;
+ efReplaceAll = $0008;
+ efDoReplace = $0010;
+ efBackupFiles = $0100;
+
+ { Constants for object palettes. }
+ CIndicator = #2#3;
+ CEditor = #6#7;
+ CMemo = #26#27;
+
+type
+ TEditorDialog = function (Dialog : Integer; Info : Pointer) : Word;
+
+ PIndicator = ^TIndicator;
+ TIndicator = object (TView)
+ Location : Objects.TPoint;
+ Modified : Boolean;
+ AutoIndent : Boolean; { Added boolean for AutoIndent mode. }
+ WordWrap : Boolean; { Added boolean for WordWrap mode. }
+ constructor Init (var Bounds : TRect);
+ procedure Draw; virtual;
+ function GetPalette : PPalette; virtual;
+ procedure SetState (AState : Word; Enable : Boolean); virtual;
+ procedure SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
+ IsModified : Boolean;
+ IsWordWrap : Boolean);
+ end;
+
+ TLineInfoRec = record
+ Len,Attr : Sw_word;
+ end;
+ TLineInfoArr = array[0..MaxLines] of TLineInfoRec;
+ PLineInfoArr = ^TLineInfoArr;
+
+ PLineInfo = ^TLineInfo;
+ TLineInfo = object
+ Info : PLineInfoArr;
+ MaxPos : Sw_Word;
+ constructor Init;
+ destructor Done;
+ procedure Grow(pos:Sw_word);
+ procedure SetLen(pos,val:Sw_Word);
+ procedure SetAttr(pos,val:Sw_Word);
+ function GetLen(pos:Sw_Word):Sw_Word;
+ function GetAttr(pos:Sw_Word):Sw_Word;
+ end;
+
+
+ PEditBuffer = ^TEditBuffer;
+ TEditBuffer = array[0..MaxBufLength] of Char;
+
+ PEditor = ^TEditor;
+ TEditor = object (TView)
+ HScrollBar : PScrollBar;
+ VScrollBar : PScrollBar;
+ Indicator : PIndicator;
+ Buffer : PEditBuffer;
+ BufSize : Sw_Word;
+ BufLen : Sw_Word;
+ GapLen : Sw_Word;
+ SelStart : Sw_Word;
+ SelEnd : Sw_Word;
+ CurPtr : Sw_Word;
+ CurPos : Objects.TPoint;
+ Delta : Objects.TPoint;
+ Limit : Objects.TPoint;
+ DrawLine : Sw_Integer;
+ DrawPtr : Sw_Word;
+ DelCount : Sw_Word;
+ InsCount : Sw_Word;
+ Flags : Longint;
+ IsReadOnly : Boolean;
+ IsValid : Boolean;
+ CanUndo : Boolean;
+ Modified : Boolean;
+ Selecting : Boolean;
+ Overwrite : Boolean;
+ AutoIndent : Boolean;
+ NoSelect : Boolean;
+ TabSize : Sw_Word; { tabsize for displaying }
+ BlankLine : Sw_Word; { First blank line after a paragraph. }
+ Word_Wrap : Boolean; { Added boolean to toggle wordwrap on/off. }
+ Line_Number : string[8]; { Holds line number to jump to. }
+ Right_Margin : Sw_Integer; { Added integer to set right margin. }
+ Tab_Settings : String[Tab_Stop_Length]; { Added string to hold tab stops. }
+
+ constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
+ AIndicator : PIndicator; ABufSize : Sw_Word);
+ constructor Load (var S : Objects.TStream);
+ destructor Done; virtual;
+ function BufChar (P : Sw_Word) : Char;
+ function BufPtr (P : Sw_Word) : Sw_Word;
+ procedure ChangeBounds (var Bounds : TRect); virtual;
+ procedure ConvertEvent (var Event : Drivers.TEvent); virtual;
+ function CursorVisible : Boolean;
+ procedure DeleteSelect;
+ procedure DoneBuffer; virtual;
+ procedure Draw; virtual;
+ procedure FormatLine (var DrawBuf; LinePtr : Sw_Word; Width : Sw_Integer; Colors : Word);virtual;
+ function GetPalette : PPalette; virtual;
+ procedure HandleEvent (var Event : Drivers.TEvent); virtual;
+ procedure InitBuffer; virtual;
+ function InsertBuffer (var P : PEditBuffer; Offset, Length : Sw_Word;AllowUndo, SelectText : Boolean) : Boolean;
+ function InsertFrom (Editor : PEditor) : Boolean; virtual;
+ function InsertText (Text : Pointer; Length : Sw_Word; SelectText : Boolean) : Boolean;
+ procedure ScrollTo (X, Y : Sw_Integer);
+ function Search (const FindStr : String; Opts : Word) : Boolean;
+ function SetBufSize (NewSize : Sw_Word) : Boolean; virtual;
+ procedure SetCmdState (Command : Word; Enable : Boolean);
+ procedure SetSelect (NewStart, NewEnd : Sw_Word; CurStart : Boolean);
+ procedure SetCurPtr (P : Sw_Word; SelectMode : Byte);
+ procedure SetState (AState : Word; Enable : Boolean); virtual;
+ procedure Store (var S : Objects.TStream);
+ procedure TrackCursor (Center : Boolean);
+ procedure Undo;
+ procedure UpdateCommands; virtual;
+ function Valid (Command : Word) : Boolean; virtual;
+
+ private
+ KeyState : Integer;
+ LockCount : Byte;
+ UpdateFlags : Byte;
+ Place_Marker : Array [1..10] of Sw_Word; { Inserted array to hold place markers. }
+ Search_Replace : Boolean; { Added boolean to test for Search and Replace insertions. }
+
+ procedure Center_Text (Select_Mode : Byte);
+ function CharPos (P, Target : Sw_Word) : Sw_Integer;
+ function CharPtr (P : Sw_Word; Target : Sw_Integer) : Sw_Word;
+ procedure Check_For_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean);
+ function ClipCopy : Boolean;
+ procedure ClipCut;
+ procedure ClipPaste;
+ procedure DeleteRange (StartPtr, EndPtr : Sw_Word; DelSelect : Boolean);
+ procedure DoSearchReplace;
+ procedure DoUpdate;
+ function Do_Word_Wrap (Select_Mode : Byte; Center_Cursor : Boolean) : Boolean;
+ procedure DrawLines (Y, Count : Sw_Integer; LinePtr : Sw_Word);
+ procedure Find;
+ function GetMousePtr (Mouse : Objects.TPoint) : Sw_Word;
+ function HasSelection : Boolean;
+ procedure HideSelect;
+ procedure Insert_Line (Select_Mode : Byte);
+ function IsClipboard : Boolean;
+ procedure Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
+ procedure Jump_To_Line (Select_Mode : Byte);
+ function LineEnd (P : Sw_Word) : Sw_Word;
+ function LineMove (P : Sw_Word; Count : Sw_Integer) : Sw_Word;
+ function LineStart (P : Sw_Word) : Sw_Word;
+ function LineNr (P : Sw_Word) : Sw_Word;
+ procedure Lock;
+ function NewLine (Select_Mode : Byte) : Boolean;
+ function NextChar (P : Sw_Word) : Sw_Word;
+ function NextLine (P : Sw_Word) : Sw_Word;
+ function NextWord (P : Sw_Word) : Sw_Word;
+ function PrevChar (P : Sw_Word) : Sw_Word;
+ function PrevLine (P : Sw_Word) : Sw_Word;
+ function PrevWord (P : Sw_Word) : Sw_Word;
+ procedure Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
+ function Reformat_Paragraph (Select_Mode : Byte; Center_Cursor : Boolean) : Boolean;
+ procedure Remove_EOL_Spaces (Select_Mode : Byte);
+ procedure Replace;
+ procedure Scroll_Down;
+ procedure Scroll_Up;
+ procedure Select_Word;
+ procedure SetBufLen (Length : Sw_Word);
+ procedure Set_Place_Marker (Element : Byte);
+ procedure Set_Right_Margin;
+ procedure Set_Tabs;
+ procedure StartSelect;
+ procedure Tab_Key (Select_Mode : Byte);
+ procedure ToggleInsMode;
+ procedure Unlock;
+ procedure Update (AFlags : Byte);
+ procedure Update_Place_Markers (AddCount : Word; KillCount : Word; StartPtr,EndPtr : Sw_Word);
+ end;
+
+ TMemoData = record
+ Length : Sw_Word;
+ Buffer : TEditBuffer;
+ end;
+
+ PMemo = ^TMemo;
+ TMemo = object (TEditor)
+ constructor Load (var S : Objects.TStream);
+ function DataSize : Sw_Word; virtual;
+ procedure GetData (var Rec); virtual;
+ function GetPalette : PPalette; virtual;
+ procedure HandleEvent (var Event : Drivers.TEvent); virtual;
+ procedure SetData (var Rec); virtual;
+ procedure Store (var S : Objects.TStream);
+ end;
+
+ PFileEditor = ^TFileEditor;
+ TFileEditor = object (TEditor)
+ FileName : FNameStr;
+ constructor Init (var Bounds : TRect; AHScrollBar, AVScrollBar : PScrollBar;
+ AIndicator : PIndicator; AFileName : FNameStr);
+ constructor Load (var S : Objects.TStream);
+ procedure DoneBuffer; virtual;
+ procedure HandleEvent (var Event : Drivers.TEvent); virtual;
+ procedure InitBuffer; virtual;
+ function LoadFile : Boolean;
+ function Save : Boolean;
+ function SaveAs : Boolean;
+ function SaveFile : Boolean;
+ function SetBufSize (NewSize : Sw_Word) : Boolean; virtual;
+ procedure Store (var S : Objects.TStream);
+ procedure UpdateCommands; virtual;
+ function Valid (Command : Word) : Boolean; virtual;
+ end;
+
+ PEditWindow = ^TEditWindow;
+ TEditWindow = object (TWindow)
+ Editor : PFileEditor;
+ constructor Init (var Bounds : TRect; FileName : FNameStr; ANumber : Integer);
+ constructor Load (var S : Objects.TStream);
+ procedure Close; virtual;
+ function GetTitle (MaxSize : Sw_Integer) : TTitleStr; virtual;
+ procedure HandleEvent (var Event : Drivers.TEvent); virtual;
+ procedure SizeLimits(var Min, Max: TPoint); virtual;
+ procedure Store (var S : Objects.TStream);
+ end;
+
+
+function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
+function CreateFindDialog: PDialog;
+function CreateReplaceDialog: PDialog;
+function JumpLineDialog : PDialog;
+function ReformDocDialog : PDialog;
+function RightMarginDialog : PDialog;
+function TabStopDialog : Dialogs.PDialog;
+function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
+
+const
+ WordChars : set of Char = ['!'..#255];
+
+ LineBreak : string[2]=
+{$ifdef UNIXLF}
+ #10;
+{$else}
+ #13#10;
+{$endif}
+
+
+ { The Allow_Reformat boolean is a programmer hook. }
+ { I've placed this here to allow programmers to }
+ { determine whether or not paragraph and document }
+ { reformatting are allowed if Word_Wrap is not }
+ { active. Some people say don't allow, and others }
+ { say allow it. I've left it up to the programmer. }
+ { Set to FALSE if not allowed, or TRUE if allowed. }
+ Allow_Reformat : Boolean = True;
+
+ EditorDialog : TEditorDialog = {$ifdef fpc}@{$endif}DefEditorDialog;
+ EditorFlags : Word = efBackupFiles + efPromptOnReplace;
+ FindStr : String[80] = '';
+ ReplaceStr : String[80] = '';
+ Clipboard : PEditor = nil;
+
+ ToClipCmds : TCommandSet = ([cmCut,cmCopy,cmClear]);
+ FromClipCmds : TCommandSet = ([cmPaste]);
+ UndoCmds : TCommandSet = ([cmUndo,cmRedo]);
+
+TYPE
+ TFindDialogRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ record
+ Find : String[80];
+ Options : Word;
+ end;
+
+ TReplaceDialogRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ record
+ Find : String[80];
+ Replace : String[80];
+ Options : Word;
+ end;
+
+ TRightMarginRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ record
+ Margin_Position : String[3];
+ end;
+
+ TTabStopRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ record
+ Tab_String : String [Tab_Stop_Length];
+ end;
+
+CONST
+ { VMT constants. }
+ REditor : TStreamRec = (ObjType : 70;
+ VmtLink : Ofs (TypeOf (TEditor)^);
+ Load : @TEditor.Load;
+ Store : @TEditor.Store);
+
+ RMemo : TStreamRec = (ObjType : 71;
+ VmtLink : Ofs (TypeOf (TMemo)^);
+ Load : @TMemo.Load;
+ Store : @TMemo.Store);
+
+ RFileEditor : TStreamRec = (ObjType : 72;
+ VmtLink : Ofs (TypeOf (TFileEditor)^);
+ Load : @TFileEditor.Load;
+ Store : @TFileEditor.Store);
+
+ RIndicator : TStreamRec = (ObjType : 73;
+ VmtLink : Ofs (TypeOf (TIndicator)^);
+ Load : @TIndicator.Load;
+ Store : @TIndicator.Store);
+
+ REditWindow : TStreamRec = (ObjType : 74;
+ VmtLink : Ofs (TypeOf (TEditWindow)^);
+ Load : @TEditWindow.Load;
+ Store : @TEditWindow.Store);
+
+procedure RegisterEditors;
+
+
+{****************************************************************************
+ Implementation
+****************************************************************************}
+
+implementation
+
+uses
+ Dos, App, StdDlg, MsgBox{, Resource};
+
+type
+ pword = ^word;
+
+resourcestring sClipboard='Clipboard';
+ sFileCreateError='Error creating file %s';
+ sFileReadError='Error reading file %s';
+ sFileUntitled='Save untitled file?';
+ sFileWriteError='Error writing to file %s';
+ sFind='Find';
+ sJumpTo='Jump To';
+ sModified=''#3'%s'#13#10#13#3'has been modified. Save?';
+ sOutOfMemory='Not enough memory for this operation.';
+ sPasteNotPossible='Wordwrap on: Paste not possible in current margins when at end of line.';
+ sReformatDocument='Reformat Document';
+ sReformatNotPossible='Paragraph reformat not possible while trying to wrap current line with current margins.';
+ sReformattingTheDocument='Reformatting the document:';
+ sReplaceNotPossible='Wordwrap on: Replace not possible in current margins when at end of line.';
+ sReplaceThisOccurence='Replace this occurence?';
+ sRightMargin='Right Margin';
+ sSearchStringNotFound='Search string not found.';
+ sSelectWhereToBegin='Please select where to begin.';
+ sSetting='Setting:';
+ sTabSettings='Tab Settings';
+ sUnknownDialog='Unknown dialog requested!';
+ sUntitled='Untitled';
+ sWordWrapNotPossible='Wordwrap on: Wordwrap not possible in current margins with continuous line.';
+ sWordWrapOff='You must turn on wordwrap before you can reformat.';
+
+ slCaseSensitive='~C~ase sensitive';
+ slCurrentLine='~C~urrent line';
+ slEntireDocument='~E~ntire document';
+ slLineNumber='~L~ine number';
+ slNewText='~N~ew text';
+ slPromptOnReplace='~P~rompt on replace';
+ slReplace='~R~eplace';
+ slReplaceAll='~R~eplace all';
+ slTextToFind='~T~ext to find';
+ slWholeWordsOnly='~W~hole words only';
+
+
+CONST
+ { Update flag constants. }
+ ufUpdate = $01;
+ ufLine = $02;
+ ufView = $04;
+ ufStats = $05;
+
+ { SelectMode constants. }
+ smExtend = $01;
+ smDouble = $02;
+
+ sfSearchFailed = NotFoundValue;
+
+ { Arrays that hold all the command keys and options. }
+ FirstKeys : array[0..46 * 2] of Word = (46, Ord (^A), cmWordLeft,
+ Ord (^B), cmReformPara,
+ Ord (^C), cmPageDown,
+ Ord (^D), cmCharRight,
+ Ord (^E), cmLineUp,
+ Ord (^F), cmWordRight,
+ Ord (^G), cmDelChar,
+ Ord (^H), cmBackSpace,
+ Ord (^I), cmTabKey,
+ Ord (^J), $FF04,
+ Ord (^K), $FF02,
+ Ord (^L), cmSearchAgain,
+ Ord (^M), cmNewLine,
+ Ord (^N), cmInsertLine,
+ Ord (^O), $FF03,
+ Ord (^Q), $FF01,
+ Ord (^R), cmPageUp,
+ Ord (^S), cmCharLeft,
+ Ord (^T), cmDelWord,
+ Ord (^U), cmUndo,
+ Ord (^V), cmInsMode,
+ Ord (^W), cmScrollUp,
+ Ord (^X), cmLineDown,
+ Ord (^Y), cmDelLine,
+ Ord (^Z), cmScrollDown,
+ kbLeft, cmCharLeft,
+ kbRight, cmCharRight,
+ kbCtrlLeft, cmWordLeft,
+ kbCtrlRight, cmWordRight,
+ kbHome, cmLineStart,
+ kbEnd, cmLineEnd,
+ kbCtrlHome, cmHomePage,
+ kbCtrlEnd, cmEndPage,
+ kbUp, cmLineUp,
+ kbDown, cmLineDown,
+ kbPgUp, cmPageUp,
+ kbPgDn, cmPageDown,
+ kbCtrlPgUp, cmTextStart,
+ kbCtrlPgDn, cmTextEnd,
+ kbIns, cmInsMode,
+ kbDel, cmDelChar,
+ kbCtrlBack, cmDelStart,
+ kbShiftIns, cmPaste,
+ kbShiftDel, cmCut,
+ kbCtrlIns, cmCopy,
+ kbCtrlDel, cmClear);
+
+ { SCRLUP - Stop. } { Added ^W to scroll screen up. }
+ { SCRLDN - Stop. } { Added ^Z to scroll screen down. }
+ { REFORM - Stop. } { Added ^B for paragraph reformatting. }
+ { PRETAB - Stop. } { Added ^I for preset tabbing. }
+ { JLINE - Stop. } { Added ^J to jump to a line number. }
+ { INSLIN - Stop. } { Added ^N to insert line at cursor. }
+ { INDENT - Stop. } { Removed ^O and put it into ^QI. }
+ { HOMEND - Stop. } { Added kbCtrlHome and kbCtrlEnd pages. }
+ { CTRLBK - Stop. } { Added kbCtrlBack same as ^QH. }
+
+ QuickKeys : array[0..21 * 2] of Word = (21, Ord ('0'), cmJumpMark0,
+ Ord ('1'), cmJumpMark1,
+ Ord ('2'), cmJumpMark2,
+ Ord ('3'), cmJumpMark3,
+ Ord ('4'), cmJumpMark4,
+ Ord ('5'), cmJumpMark5,
+ Ord ('6'), cmJumpMark6,
+ Ord ('7'), cmJumpMark7,
+ Ord ('8'), cmJumpMark8,
+ Ord ('9'), cmJumpMark9,
+ Ord ('A'), cmReplace,
+ Ord ('C'), cmTextEnd,
+ Ord ('D'), cmLineEnd,
+ Ord ('F'), cmFind,
+ Ord ('H'), cmDelStart,
+ Ord ('I'), cmIndentMode,
+ Ord ('L'), cmUndo,
+ Ord ('R'), cmTextStart,
+ Ord ('S'), cmLineStart,
+ Ord ('U'), cmReformDoc,
+ Ord ('Y'), cmDelEnd);
+
+ { UNDO - Stop. } { Added IDE undo feature of ^QL. }
+ { REFDOC - Stop. } { Added document reformat feature if ^QU pressed. }
+ { MARK - Stop. } { Added cmJumpMark# to allow place marking. }
+ { INDENT - Stop. } { Moved IndentMode here from Firstkeys. }
+
+ BlockKeys : array[0..20 * 2] of Word = (20, Ord ('0'), cmSetMark0,
+ Ord ('1'), cmSetMark1,
+ Ord ('2'), cmSetMark2,
+ Ord ('3'), cmSetMark3,
+ Ord ('4'), cmSetMark4,
+ Ord ('5'), cmSetMark5,
+ Ord ('6'), cmSetMark6,
+ Ord ('7'), cmSetMark7,
+ Ord ('8'), cmSetMark8,
+ Ord ('9'), cmSetMark9,
+ Ord ('B'), cmStartSelect,
+ Ord ('C'), cmPaste,
+ Ord ('D'), cmSave,
+ Ord ('F'), cmSaveAs,
+ Ord ('H'), cmHideSelect,
+ Ord ('K'), cmCopy,
+ Ord ('S'), cmSave,
+ Ord ('T'), cmSelectWord,
+ Ord ('Y'), cmCut,
+ Ord ('X'), cmSaveDone);
+
+ { SELWRD - Stop. } { Added ^KT to select word only. }
+ { SAVE - Stop. } { Added ^KD, ^KF, ^KS, ^KX key commands. }
+ { MARK - Stop. } { Added cmSetMark# to allow place marking. }
+
+ FormatKeys : array[0..5 * 2] of Word = (5, Ord ('C'), cmCenterText,
+ Ord ('T'), cmCenterText,
+ Ord ('I'), cmSetTabs,
+ Ord ('R'), cmRightMargin,
+ Ord ('W'), cmWordWrap);
+
+ { WRAP - Stop. } { Added Wordwrap feature if ^OW pressed. }
+ { RMSET - Stop. } { Added set right margin feature if ^OR pressed. }
+ { PRETAB - Stop. } { Added preset tab feature if ^OI pressed. }
+ { CENTER - Stop. } { Added center text option ^OC for a line. }
+
+ JumpKeys : array[0..1 * 2] of Word = (1, Ord ('L'), cmJumpLine);
+
+ { JLINE - Stop. } { Added jump to line number feature if ^JL pressed. }
+
+ KeyMap : array[0..4] of Pointer = (@FirstKeys,
+ @QuickKeys,
+ @BlockKeys,
+ @FormatKeys,
+ @JumpKeys);
+
+ { WRAP - Stop. } { Added @FormatKeys for new ^O? keys. }
+ { PRETAB - Stop. } { Added @FormatKeys for new ^O? keys. }
+ { JLINE - Stop. } { Added @JumpKeys for new ^J? keys. }
+ { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
+
+
+{****************************************************************************
+ Dialogs
+****************************************************************************}
+
+function DefEditorDialog (Dialog : Integer; Info : Pointer) : Word;
+begin
+ DefEditorDialog := cmCancel;
+end; { DefEditorDialog }
+
+
+function CreateFindDialog: PDialog;
+var
+ D: PDialog;
+ Control: PView;
+ R: TRect;
+begin
+ R.Assign(0, 0, 38, 12);
+ D := New(PDialog, Init(R,sFind));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign(3, 3, 32, 4);
+ Control := New(PInputLine, Init(R, 80));
+ Control^.HelpCtx := hcDFindText;
+ Insert(Control);
+ R.Assign(2, 2, 15, 3);
+ Insert(New(PLabel, Init(R, slTextToFind, Control)));
+ R.Assign(32, 3, 35, 4);
+ Insert(New(PHistory, Init(R, PInputLine(Control), 10)));
+
+ R.Assign(3, 5, 35, 7);
+ Control := New(PCheckBoxes, Init(R,
+ NewSItem (slCaseSensitive,
+ NewSItem (slWholeWordsOnly,nil))));
+ Control^.HelpCtx := hcCCaseSensitive;
+ Insert(Control);
+
+ R.Assign(14, 9, 24, 11);
+ Control := New (PButton, Init(R,slOK,cmOk,bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ Inc(R.A.X, 12); Inc(R.B.X, 12);
+ Control := New (PButton, Init(R,slCancel,cmCancel, bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+
+ SelectNext(False);
+ end;
+ CreateFindDialog := D;
+end;
+
+
+function CreateReplaceDialog: PDialog;
+var
+ D: PDialog;
+ Control: PView;
+ R: TRect;
+begin
+ R.Assign(0, 0, 40, 16);
+ D := New(PDialog, Init(R,slReplace));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign(3, 3, 34, 4);
+ Control := New(PInputLine, Init(R, 80));
+ Control^.HelpCtx := hcDFindText;
+ Insert(Control);
+ R.Assign(2, 2, 15, 3);
+ Insert(New(PLabel, Init(R,slTextToFind, Control)));
+ R.Assign(34, 3, 37, 4);
+ Insert(New(PHistory, Init(R, PInputLine(Control), 10)));
+
+ R.Assign(3, 6, 34, 7);
+ Control := New(PInputLine, Init(R, 80));
+ Control^.HelpCtx := hcDReplaceText;
+ Insert(Control);
+ R.Assign(2, 5, 12, 6);
+ Insert(New(PLabel, Init(R,slNewText, Control)));
+ R.Assign(34, 6, 37, 7);
+ Insert(New(PHistory, Init(R, PInputLine(Control), 11)));
+
+ R.Assign(3, 8, 37, 12);
+ Control := New (Dialogs.PCheckBoxes, Init (R,
+ NewSItem (slCasesensitive,
+ NewSItem (slWholewordsonly,
+ NewSItem (slPromptonreplace,
+ NewSItem (slReplaceall, nil))))));
+ Control^.HelpCtx := hcCCaseSensitive;
+ Insert (Control);
+
+ R.Assign (8, 13, 18, 15);
+ Control := New (PButton, Init (R,slOK, cmOk, bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ R.Assign (22, 13, 32, 15);
+ Control := New (PButton, Init (R,slCancel, cmCancel, bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+
+ SelectNext(False);
+ end;
+ CreateReplaceDialog := D;
+end;
+
+
+function JumpLineDialog : PDialog;
+VAR
+ D : PDialog;
+ R : TRect;
+ Control: PView;
+Begin
+ R.Assign (0, 0, 26, 8);
+ D := New(PDialog, Init(R,sJumpTo));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign (3, 2, 15, 3);
+ Control := New (Dialogs.PStaticText, Init (R,slLineNumber));
+ Insert (Control);
+
+ R.Assign (15, 2, 21, 3);
+ Control := New (Dialogs.PInputLine, Init (R, 4));
+ Control^.HelpCtx := hcDLineNumber;
+ Insert (Control);
+
+ R.Assign (21, 2, 24, 3);
+ Insert (New (Dialogs.PHistory, Init (R, Dialogs.PInputLine (Control), 12)));
+
+ R.Assign (2, 5, 12, 7);
+ Control := New (Dialogs.PButton, Init (R, slOK, cmOK, Dialogs.bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ R.Assign (14, 5, 24, 7);
+ Control := New (Dialogs.PButton, Init (R, slCancel, cmCancel, Dialogs.bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+
+ SelectNext (False);
+ end;
+ JumpLineDialog := D;
+end; { JumpLineDialog }
+
+
+function ReformDocDialog : Dialogs.PDialog;
+ { This is a local function that brings up a dialog box }
+ { that asks where to start reformatting the document. }
+VAR
+ R : TRect;
+ D : Dialogs.PDialog;
+ Control : PView;
+Begin
+ R.Assign (0, 0, 32, 11);
+ D := New (Dialogs.PDialog, Init (R, sReformatDocument));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign (2, 2, 30, 3);
+ Control := New (Dialogs.PStaticText, Init (R, sSelectWhereToBegin));
+ Insert (Control);
+
+ R.Assign (3, 3, 29, 4);
+ Control := New (Dialogs.PStaticText, Init (R, sReformattingTheDocument));
+ Insert (Control);
+
+ R.Assign (50, 5, 68, 6);
+ Control := New (Dialogs.PLabel, Init (R, sReformatDocument, Control));
+ Insert (Control);
+
+ R.Assign (5, 5, 26, 7);
+ Control := New (Dialogs.PRadioButtons, Init (R,
+ NewSItem (slCurrentLine,
+ NewSItem (slEntireDocument, Nil))));
+ Control^.HelpCtx := hcDReformDoc;
+ Insert (Control);
+
+ R.Assign (4, 8, 14, 10);
+ Control := New (Dialogs.PButton, Init (R, slOK, cmOK, Dialogs.bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ R.Assign (17, 8, 27, 10);
+ Control := New (Dialogs.PButton, Init (R, slCancel, cmCancel, Dialogs.bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+
+ SelectNext (False);
+ end;
+ ReformDocDialog := D;
+end; { ReformDocDialog }
+
+
+function RightMarginDialog : Dialogs.PDialog;
+ { This is a local function that brings up a dialog box }
+ { that allows the user to change the Right_Margin. }
+VAR
+ R : TRect;
+ D : PDialog;
+ Control : PView;
+Begin
+ R.Assign (0, 0, 26, 8);
+ D := New (Dialogs.PDialog, Init (R, sRightMargin));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign (5, 2, 13, 3);
+ Control := New (Dialogs.PStaticText, Init (R, sSetting));
+ Insert (Control);
+
+ R.Assign (13, 2, 18, 3);
+ Control := New (Dialogs.PInputLine, Init (R, 3));
+ Control^.HelpCtx := hcDRightMargin;
+ Insert (Control);
+
+ R.Assign (18, 2, 21, 3);
+ Insert (New (Dialogs.PHistory, Init (R, Dialogs.PInputLine (Control), 13)));
+
+ R.Assign (2, 5, 12, 7);
+ Control := New (Dialogs.PButton, Init (R, slOK, cmOK, Dialogs.bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ R.Assign (14, 5, 24, 7);
+ Control := New (Dialogs.PButton, Init (R, slCancel, cmCancel, Dialogs.bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+
+ SelectNext (False);
+ end;
+ RightMarginDialog := D;
+end; { RightMarginDialog; }
+
+
+function TabStopDialog : Dialogs.PDialog;
+ { This is a local function that brings up a dialog box }
+ { that allows the user to set their own tab stops. }
+VAR
+ Index : Sw_Integer; { Local Indexing variable. }
+ R : TRect;
+ D : PDialog;
+ Control : PView;
+ Tab_Stop : String[2]; { Local string to print tab column number. }
+Begin
+ R.Assign (0, 0, 80, 8);
+ D := New (Dialogs.PDialog, Init (R, sTabSettings));
+ with D^ do
+ begin
+ Options := Options or ofCentered;
+
+ R.Assign (2, 2, 77, 3);
+ Control := New (Dialogs.PStaticText, Init (R,
+ ' ....|....|....|....|....|....|....|....|....|....|....|....|....|....|....'));
+ Insert (Control);
+
+ for Index := 1 to 7 do
+ begin
+ R.Assign (Index * 10 + 1, 1, Index * 10 + 3, 2);
+ Str (Index * 10, Tab_Stop);
+ Control := New (Dialogs.PStaticText, Init (R, Tab_Stop));
+ Insert (Control);
+ end;
+
+ R.Assign (2, 3, 78, 4);
+ Control := New (Dialogs.PInputLine, Init (R, 74));
+ Control^.HelpCtx := hcDTabStops;
+ Insert (Control);
+
+ R.Assign (38, 5, 41, 6);
+ Insert (New (Dialogs.PHistory, Init (R, Dialogs.PInputLine (Control), 14)));
+
+ R.Assign (27, 5, 37, 7);
+ Control := New (Dialogs.PButton, Init (R, slOK, cmOK, Dialogs.bfDefault));
+ Control^.HelpCtx := hcDOk;
+ Insert (Control);
+
+ R.Assign (42, 5, 52, 7);
+ Control := New (Dialogs.PButton, Init (R, slCancel, cmCancel, Dialogs.bfNormal));
+ Control^.HelpCtx := hcDCancel;
+ Insert (Control);
+ SelectNext (False);
+ end;
+ TabStopDialog := D;
+end { TabStopDialog };
+
+
+function StdEditorDialog(Dialog: Integer; Info: Pointer): Word;
+var
+ R: TRect;
+ T: TPoint;
+begin
+ case Dialog of
+ edOutOfMemory:
+ StdEditorDialog := MessageBox(sOutOfMemory, nil, mfError + mfOkButton);
+ edReadError:
+ StdEditorDialog := MessageBox(sFileReadError, @Info, mfError + mfOkButton);
+ edWriteError:
+ StdEditorDialog := MessageBox(sFileWriteError, @Info, mfError + mfOkButton);
+ edCreateError:
+ StdEditorDialog := MessageBox(sFileCreateError, @Info, mfError + mfOkButton);
+ edSaveModify:
+ StdEditorDialog := MessageBox(sModified, @Info, mfInformation + mfYesNoCancel);
+ edSaveUntitled:
+ StdEditorDialog := MessageBox(sFileUntitled, nil, mfInformation + mfYesNoCancel);
+ edSaveAs:
+ StdEditorDialog := Application^.ExecuteDialog(New(PFileDialog, Init('*.*',
+ slSaveFileAs, slName, fdOkButton, 101)), Info);
+ edFind:
+ StdEditorDialog := Application^.ExecuteDialog(CreateFindDialog, Info);
+ edSearchFailed:
+ StdEditorDialog := MessageBox(sSearchStringNotFound, nil, mfError + mfOkButton);
+ edReplace:
+ StdEditorDialog := Application^.ExecuteDialog(CreateReplaceDialog, Info);
+ edReplacePrompt:
+ begin
+ { Avoid placing the dialog on the same line as the cursor }
+ R.Assign(0, 1, 40, 8);
+ R.Move((Desktop^.Size.X - R.B.X) div 2, 0);
+ Desktop^.MakeGlobal(R.B, T);
+ Inc(T.Y);
+ if PPoint(Info)^.Y <= T.Y then
+ R.Move(0, Desktop^.Size.Y - R.B.Y - 2);
+ StdEditorDialog := MessageBoxRect(R, sReplaceThisOccurence,
+ nil, mfYesNoCancel + mfInformation);
+ end;
+ edJumpToLine:
+ StdEditorDialog := Application^.ExecuteDialog(JumpLineDialog, Info);
+ edSetTabStops:
+ StdEditorDialog := Application^.ExecuteDialog(TabStopDialog, Info);
+ edPasteNotPossible:
+ StdEditorDialog := MessageBox (sPasteNotPossible, nil, mfError + mfOkButton);
+ edReformatDocument:
+ StdEditorDialog := Application^.ExecuteDialog(ReformDocDialog, Info);
+ edReformatNotAllowed:
+ StdEditorDialog := MessageBox (sWordWrapOff, nil, mfError + mfOkButton);
+ edReformNotPossible:
+ StdEditorDialog := MessageBox (sReformatNotPossible, nil, mfError + mfOkButton);
+ edReplaceNotPossible:
+ StdEditorDialog := MessageBox (sReplaceNotPossible, nil, mfError + mfOkButton);
+ edRightMargin:
+ StdEditorDialog := Application^.ExecuteDialog(RightMarginDialog, Info);
+ edWrapNotPossible:
+ StdEditorDialog := MessageBox (sWordWrapNotPossible, nil, mfError + mfOKButton);
+ else
+ StdEditorDialog := MessageBox (sUnknownDialog, nil, mfError + mfOkButton);
+ end;
+end;
+
+
+{****************************************************************************
+ Helpers
+****************************************************************************}
+
+function CountLines(var Buf; Count: sw_Word): sw_Integer;
+var
+ p : pchar;
+ lines : sw_word;
+begin
+ p:=pchar(@buf);
+ lines:=0;
+ while (count>0) do
+ begin
+ if p^ in [#10,#13] then
+ begin
+ inc(lines);
+ if ord((p+1)^)+ord(p^)=23 then
+ begin
+ inc(p);
+ dec(count);
+ if count=0 then
+ break;
+ end;
+ end;
+ inc(p);
+ dec(count);
+ end;
+ CountLines:=Lines;
+end;
+
+
+procedure GetLimits(var Buf; Count: sw_Word;var lim:objects.TPoint);
+{ Get the limits needed for Buf, its an extended version of countlines (lim.y),
+ which also gets the maximum line length in lim.x }
+var
+ p : pchar;
+ len : sw_word;
+begin
+ lim.x:=0;
+ lim.y:=0;
+ len:=0;
+ p:=pchar(@buf);
+ while (count>0) do
+ begin
+ if p^ in [#10,#13] then
+ begin
+ if len>lim.x then
+ lim.x:=len;
+ inc(lim.y);
+ if ord((p+1)^)+ord(p^)=23 then
+ begin
+ inc(p);
+ dec(count);
+ end;
+ len:=0;
+ end
+ else
+ inc(len);
+ inc(p);
+ dec(count);
+ end;
+end;
+
+
+function ScanKeyMap(KeyMap: Pointer; KeyCode: Word): Word;
+var
+ p : pword;
+ count : sw_word;
+begin
+ p:=keymap;
+ count:=p^;
+ inc(p);
+ while (count>0) do
+ begin
+ if (lo(p^)=lo(keycode)) and
+ ((hi(p^)=0) or (hi(p^)=hi(keycode))) then
+ begin
+ inc(p);
+ scankeymap:=p^;
+ exit;
+ end;
+ inc(p,2);
+ dec(count);
+ end;
+ scankeymap:=0;
+end;
+
+
+Type
+ Btable = Array[0..255] of Byte;
+Procedure BMMakeTable(const s:string; Var t : Btable);
+{ Makes a Boyer-Moore search table. s = the search String t = the table }
+Var
+ x : sw_integer;
+begin
+ FillChar(t,sizeof(t),length(s));
+ For x := length(s) downto 1 do
+ if (t[ord(s[x])] = length(s)) then
+ t[ord(s[x])] := length(s) - x;
+end;
+
+
+function Scan(var Block; Size: Sw_Word;const Str: String): Sw_Word;
+Var
+ buffer : Array[0..MaxBufLength-1] of Byte Absolute block;
+ s2 : String;
+ len,
+ numb : Sw_Word;
+ found : Boolean;
+ bt : Btable;
+begin
+ BMMakeTable(str,bt);
+ len:=length(str);
+ s2[0]:=chr(len); { sets the length to that of the search String }
+ found:=False;
+ numb:=pred(len);
+ While (not found) and (numb<(size-len)) do
+ begin
+ { partial match }
+ if buffer[numb] = ord(str[len]) then
+ begin
+ { less partial! }
+ if buffer[numb-pred(len)] = ord(str[1]) then
+ begin
+ move(buffer[numb-pred(len)],s2[1],len);
+ if (str=s2) then
+ begin
+ found:=true;
+ break;
+ end;
+ end;
+ inc(numb);
+ end
+ else
+ inc(numb,Bt[buffer[numb]]);
+ end;
+ if not found then
+ Scan := NotFoundValue
+ else
+ Scan := numb - pred(len);
+end;
+
+
+function IScan(var Block; Size: Sw_Word;const Str: String): Sw_Word;
+Var
+ buffer : Array[0..MaxBufLength-1] of Char Absolute block;
+ s : String;
+ len,
+ numb,
+ x : Sw_Word;
+ found : Boolean;
+ bt : Btable;
+ p : pchar;
+ c : char;
+begin
+ len:=length(str);
+ if (len=0) or (len>size) then
+ begin
+ IScan := NotFoundValue;
+ exit;
+ end;
+ { create uppercased string }
+ s[0]:=chr(len);
+ for x:=1 to len do
+ begin
+ if str[x] in ['a'..'z'] then
+ s[x]:=chr(ord(str[x])-32)
+ else
+ s[x]:=str[x];
+ end;
+ BMMakeTable(s,bt);
+ found:=False;
+ numb:=pred(len);
+ While (not found) and (numb<(size-len)) do
+ begin
+ { partial match }
+ c:=buffer[numb];
+ if c in ['a'..'z'] then
+ c:=chr(ord(c)-32);
+ if (c=s[len]) then
+ begin
+ { less partial! }
+ p:=@buffer[numb-pred(len)];
+ x:=1;
+ while (x<=len) do
+ begin
+ if not(((p^ in ['a'..'z']) and (chr(ord(p^)-32)=s[x])) or
+ (p^=s[x])) then
+ break;
+ inc(p);
+ inc(x);
+ end;
+ if (x>len) then
+ begin
+ found:=true;
+ break;
+ end;
+ inc(numb);
+ end
+ else
+ inc(numb,Bt[ord(c)]);
+ end;
+ if not found then
+ IScan := NotFoundValue
+ else
+ IScan := numb - pred(len);
+end;
+
+
+{****************************************************************************
+ TIndicator
+****************************************************************************}
+
+constructor TIndicator.Init (var Bounds : TRect);
+begin
+ Inherited Init (Bounds);
+ GrowMode := gfGrowLoY + gfGrowHiY;
+end; { TIndicator.Init }
+
+
+procedure TIndicator.Draw;
+VAR
+ Color : Byte;
+ Frame : Char;
+ L : array[0..1] of Longint;
+ S : String[15];
+ B : TDrawBuffer;
+begin
+ if State and sfDragging = 0 then
+ begin
+ Color := GetColor (1);
+ Frame := #205;
+ end
+ else
+ begin
+ Color := GetColor (2);
+ Frame := #196;
+ end;
+ MoveChar (B, Frame, Color, Size.X);
+ { If the text has been modified, put an 'M' in the TIndicator display. }
+ if Modified then
+ WordRec (B[1]).Lo := 77;
+ { If WordWrap is active put a 'W' in the TIndicator display. }
+ if WordWrap then
+ WordRec (B[2]).Lo := 87
+ else
+ WordRec (B[2]).Lo := Byte (Frame);
+ { If AutoIndent is active put an 'I' in TIndicator display. }
+ if AutoIndent then
+ WordRec (B[0]).Lo := 73
+ else
+ WordRec (B[0]).Lo := Byte (Frame);
+ L[0] := Location.Y + 1;
+ L[1] := Location.X + 1;
+ FormatStr (S, ' %d:%d ', L);
+ MoveStr (B[9 - Pos (':', S)], S, Color); { Changed original 8 to 9. }
+ WriteBuf (0, 0, Size.X, 1, B);
+end; { TIndicator.Draw }
+
+
+function TIndicator.GetPalette : PPalette;
+const
+ P : string[Length (CIndicator)] = CIndicator;
+begin
+ GetPalette := PPalette(@P);
+end; { TIndicator.GetPalette }
+
+
+procedure TIndicator.SetState (AState : Word; Enable : Boolean);
+begin
+ Inherited SetState (AState, Enable);
+ if AState = sfDragging then
+ DrawView;
+end; { TIndicator.SetState }
+
+
+procedure TIndicator.SetValue (ALocation : Objects.TPoint; IsAutoIndent : Boolean;
+ IsModified : Boolean;
+ IsWordWrap : Boolean);
+begin
+ if (Location.X<>ALocation.X) or
+ (Location.Y<>ALocation.Y) or
+ (AutoIndent <> IsAutoIndent) or
+ (Modified <> IsModified) or
+ (WordWrap <> IsWordWrap) then
+ begin
+ Location := ALocation;
+ AutoIndent := IsAutoIndent; { Added provisions to show AutoIndent. }
+ Modified := IsModified;
+ WordWrap := IsWordWrap; { Added provisions to show WordWrap. }
+ DrawView;
+ end;
+end; { TIndicator.SetValue }
+
+
+{****************************************************************************
+ TLineInfo
+****************************************************************************}
+
+constructor TLineInfo.Init;
+begin
+ MaxPos:=0;
+ Grow(1);
+end;
+
+
+destructor TLineInfo.Done;
+begin
+ FreeMem(Info,MaxPos*sizeof(TLineInfoRec));
+ Info := nil;
+end;
+
+
+procedure TLineInfo.Grow(pos:Sw_word);
+var
+ NewSize : Sw_word;
+ P : pointer;
+begin
+ NewSize:=(Pos+LineInfoGrow-(Pos mod LineInfoGrow));
+ GetMem(P,NewSize*sizeof(TLineInfoRec));
+ FillChar(P^,NewSize*sizeof(TLineInfoRec),0);
+ Move(Info^,P^,MaxPos*sizeof(TLineInfoRec));
+ Freemem(Info,MaxPos*sizeof(TLineInfoRec));
+ Info:=P;
+end;
+
+
+procedure TLineInfo.SetLen(pos,val:Sw_Word);
+begin
+ if pos>=MaxPos then
+ Grow(Pos);
+ Info^[Pos].Len:=val
+end;
+
+
+procedure TLineInfo.SetAttr(pos,val:Sw_Word);
+begin
+ if pos>=MaxPos then
+ Grow(Pos);
+ Info^[Pos].Attr:=val
+end;
+
+
+function TLineInfo.GetLen(pos:Sw_Word):Sw_Word;
+begin
+ GetLen:=Info^[Pos].Len;
+end;
+
+
+function TLineInfo.GetAttr(pos:Sw_Word):Sw_Word;
+begin
+ GetAttr:=Info^[Pos].Attr;
+end;
+
+
+
+{****************************************************************************
+ TEditor
+****************************************************************************}
+
+constructor TEditor.Init (var Bounds : TRect;
+ AHScrollBar, AVScrollBar : PScrollBar;
+ AIndicator : PIndicator; ABufSize : Sw_Word);
+var
+ Element : Byte; { Place_Marker array element to initialize array with. }
+begin
+ Inherited Init (Bounds);
+ GrowMode := gfGrowHiX + gfGrowHiY;
+ Options := Options or ofSelectable;
+ Flags := EditorFlags;
+ EventMask := evMouseDown + evKeyDown + evCommand + evBroadcast;
+ ShowCursor;
+
+ HScrollBar := AHScrollBar;
+ VScrollBar := AVScrollBar;
+
+ Indicator := AIndicator;
+ BufSize := ABufSize;
+ CanUndo := True;
+ InitBuffer;
+
+ if assigned(Buffer) then
+ IsValid := True
+ else
+ begin
+ EditorDialog (edOutOfMemory, nil);
+ BufSize := 0;
+ end;
+
+ SetBufLen (0);
+
+ for Element := 1 to 10 do
+ Place_Marker[Element] := 0;
+
+ Element := 1;
+ while Element <= 70 do
+ begin
+ if Element mod 5 = 0 then
+ Insert ('x', Tab_Settings, Element)
+ else
+ Insert (#32, Tab_Settings, Element);
+ Inc (Element);
+ end;
+ { Default Right_Margin value. Change it if you want another. }
+ Right_Margin := 76;
+ TabSize:=8;
+end; { TEditor.Init }
+
+
+constructor TEditor.Load (var S : Objects.TStream);
+begin
+ Inherited Load (S);
+ GetPeerViewPtr (S, HScrollBar);
+ GetPeerViewPtr (S, VScrollBar);
+ GetPeerViewPtr (S, Indicator);
+ S.Read (BufSize, SizeOf (BufSize));
+ S.Read (CanUndo, SizeOf (CanUndo));
+ S.Read (AutoIndent, SizeOf (AutoIndent));
+ S.Read (Line_Number, SizeOf (Line_Number));
+ S.Read (Place_Marker, SizeOf (Place_Marker));
+ S.Read (Right_Margin, SizeOf (Right_Margin));
+ S.Read (Tab_Settings, SizeOf (Tab_Settings));
+ S.Read (Word_Wrap, SizeOf (Word_Wrap));
+ InitBuffer;
+ if Assigned(Buffer) then
+ IsValid := True
+ else
+ begin
+ EditorDialog (edOutOfMemory, nil);
+ BufSize := 0;
+ end;
+ Lock;
+ SetBufLen (0);
+end; { TEditor.Load }
+
+
+destructor TEditor.Done;
+begin
+ DoneBuffer;
+ Inherited Done;
+end; { TEditor.Done }
+
+
+function TEditor.BufChar(P: Sw_Word): Char;
+begin
+ if P>=CurPtr then
+ inc(P,Gaplen);
+ BufChar:=Buffer^[P];
+end;
+
+
+function TEditor.BufPtr(P: Sw_Word): Sw_Word;
+begin
+ if P>=CurPtr then
+ BufPtr:=P+GapLen
+ else
+ BufPtr:=P;
+end;
+
+
+procedure TEditor.Center_Text (Select_Mode : Byte);
+{ This procedure will center the current line of text. }
+{ Centering is based on the current Right_Margin. }
+{ If the Line_Length exceeds the Right_Margin, or the }
+{ line is just a blank line, we exit and do nothing. }
+VAR
+ Spaces : array [1..80] of Char; { Array to hold spaces we'll insert. }
+ Index : Byte; { Index into Spaces array. }
+ Line_Length : Sw_Integer; { Holds the length of the line. }
+ E,S : Sw_Word; { End of the current line. }
+begin
+ E := LineEnd (CurPtr);
+ S := LineStart (CurPtr);
+ { If the line is blank (only a CR/LF on it) then do noting. }
+ if E = S then
+ Exit;
+ { Set CurPtr to start of line. Check if line begins with a space. }
+ { We must strip out any spaces from the beginning, or end of lines. }
+ { If line does not start with space, make sure line length does not }
+ { exceed the Right_Margin. If it does, then do nothing. }
+ SetCurPtr (S, Select_Mode);
+ Remove_EOL_Spaces (Select_Mode);
+ if Buffer^[CurPtr] = #32 then
+ begin
+ { If the next word is greater than the end of line then do nothing. }
+ { If the line length is greater than Right_Margin then do nothing. }
+ { Otherwise, delete all spaces at the start of line. }
+ { Then reset end of line and put CurPtr at start of modified line. }
+ E := LineEnd (CurPtr);
+ if NextWord (CurPtr) > E then
+ Exit;
+ if E - NextWord (CurPtr) > Right_Margin then
+ Exit;
+ DeleteRange (CurPtr, NextWord (CurPtr), True);
+ E := LineEnd (CurPtr);
+ SetCurPtr (LineStart (CurPtr), Select_Mode);
+ end
+ else
+ if E - CurPtr > Right_Margin then
+ Exit;
+ { Now we determine the real length of the line. }
+ { Then we subtract the Line_Length from Right_Margin. }
+ { Dividing the result by two tells us how many spaces }
+ { must be inserted at start of line to center it. }
+ { When we're all done, set the CurPtr to end of line. }
+ Line_Length := E - CurPtr;
+ for Index := 1 to ((Right_Margin - Line_Length) shr 1) do
+ Spaces[Index] := #32;
+ InsertText (@Spaces, Index, False);
+ SetCurPtr (LineEnd (CurPtr), Select_Mode);
+end; { TEditor.Center_Text }
+
+
+procedure TEditor.ChangeBounds (var Bounds : TRect);
+begin
+ SetBounds (Bounds);
+ Delta.X := Max (0, Min (Delta.X, Limit.X - Size.X));
+ Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
+ Update (ufView);
+end; { TEditor.ChangeBounds }
+
+
+function TEditor.CharPos (P, Target : Sw_Word) : Sw_Integer;
+VAR
+ Pos : Sw_Integer;
+begin
+ Pos := 0;
+ while P < Target do
+ begin
+ if BufChar (P) = #9 then
+ Pos := Pos or 7;
+ Inc (Pos);
+ Inc (P);
+ end;
+ CharPos := Pos;
+end; { TEditor.CharPos }
+
+
+function TEditor.CharPtr (P : Sw_Word; Target : Sw_Integer) : Sw_Word;
+VAR
+ Pos : Sw_Integer;
+begin
+ Pos := 0;
+ while (Pos < Target) and (P < BufLen) and not(BufChar (P) in [#10,#13]) do
+ begin
+ if BufChar (P) = #9 then
+ Pos := Pos or 7;
+ Inc (Pos);
+ Inc (P);
+ end;
+ if Pos > Target then
+ Dec (P);
+ CharPtr := P;
+end; { TEditor.CharPtr }
+
+
+procedure TEditor.Check_For_Word_Wrap (Select_Mode : Byte;
+ Center_Cursor : Boolean);
+{ This procedure checks if CurPos.X > Right_Margin. }
+{ If it is, then we Do_Word_Wrap. Simple, eh? }
+begin
+ if CurPos.X > Right_Margin then
+ Do_Word_Wrap (Select_Mode, Center_Cursor);
+end; {Check_For_Word_Wrap}
+
+
+function TEditor.ClipCopy : Boolean;
+begin
+ ClipCopy := False;
+ if Assigned(Clipboard) and (Clipboard <> @Self) then
+ begin
+ ClipCopy := Clipboard^.InsertFrom (@Self);
+ Selecting := False;
+ Update (ufUpdate);
+ end;
+end; { TEditor.ClipCopy }
+
+
+procedure TEditor.ClipCut;
+begin
+ if ClipCopy then
+ begin
+ Update_Place_Markers (0,
+ Self.SelEnd - Self.SelStart,
+ Self.SelStart,
+ Self.SelEnd);
+ DeleteSelect;
+ end;
+end; { TEditor.ClipCut }
+
+
+procedure TEditor.ClipPaste;
+begin
+ if Assigned(Clipboard) and (Clipboard <> @Self) then
+ begin
+ { Do not allow paste operations that will exceed }
+ { the Right_Margin when Word_Wrap is active and }
+ { cursor is at EOL. }
+ if Word_Wrap and (CurPos.X > Right_Margin) then
+ begin
+ EditorDialog (edPasteNotPossible, nil);
+ Exit;
+ end;
+ { The editor will not copy selected text if the CurPtr }
+ { is not the same value as the SelStart. However, it }
+ { does return an InsCount. This may, or may not, be a }
+ { bug. We don't want to update the Place_Marker if }
+ { there's no text copied. }
+ if CurPtr = SelStart then
+ Update_Place_Markers (Clipboard^.SelEnd - Clipboard^.SelStart,
+ 0,
+ Clipboard^.SelStart,
+ Clipboard^.SelEnd);
+ InsertFrom (Clipboard);
+ end;
+end; { TEditor.ClipPaste }
+
+
+procedure TEditor.ConvertEvent (var Event : Drivers.TEvent);
+VAR
+ ShiftState : Byte;
+ Key : Word;
+begin
+ ShiftState:=GetShiftState;
+ if Event.What = evKeyDown then
+ begin
+ if (ShiftState and $03 <> 0)
+ and (Event.ScanCode >= $47)
+ and (Event.ScanCode <= $51) then
+ Event.CharCode := #0;
+ Key := Event.KeyCode;
+ if KeyState <> 0 then
+ begin
+ if (Lo (Key) >= $01) and (Lo (Key) <= $1A) then
+ Inc (Key, $40);
+ if (Lo (Key) >= $61) and (Lo (Key) <= $7A) then
+ Dec (Key, $20);
+ end;
+ Key := ScanKeyMap (KeyMap[KeyState], Key);
+ KeyState := 0;
+ if Key <> 0 then
+ if Hi (Key) = $FF then
+ begin
+ KeyState := Lo (Key);
+ ClearEvent (Event);
+ end
+ else
+ begin
+ Event.What := evCommand;
+ Event.Command := Key;
+ end;
+ end;
+end; { TEditor.ConvertEvent }
+
+
+function TEditor.CursorVisible : Boolean;
+begin
+ CursorVisible := (CurPos.Y >= Delta.Y) and (CurPos.Y < Delta.Y + Size.Y);
+end; { TEditor.CursorVisible }
+
+
+procedure TEditor.DeleteRange (StartPtr, EndPtr : Sw_Word; DelSelect : Boolean);
+begin
+ { This will update Place_Marker for all deletions. }
+ { EXCEPT the Remove_EOL_Spaces deletion. }
+ Update_Place_Markers (0, EndPtr - StartPtr, StartPtr, EndPtr);
+ if HasSelection and DelSelect then
+ DeleteSelect
+ else
+ begin
+ SetSelect (CurPtr, EndPtr, True);
+ DeleteSelect;
+ SetSelect (StartPtr, CurPtr, False);
+ DeleteSelect;
+ end;
+end; { TEditor.DeleteRange }
+
+
+procedure TEditor.DeleteSelect;
+begin
+ InsertText (nil, 0, False);
+end; { TEditor.DeleteSelect }
+
+
+procedure TEditor.DoneBuffer;
+begin
+ ReAllocMem(Buffer, 0);
+end; { TEditor.DoneBuffer }
+
+
+procedure TEditor.DoSearchReplace;
+VAR
+ I : Sw_Word;
+ C : Objects.TPoint;
+begin
+ repeat
+ I := cmCancel;
+ if not Search (FindStr, Flags) then
+ begin
+ if Flags and (efReplaceAll + efDoReplace) <> (efReplaceAll + efDoReplace) then
+ EditorDialog (edSearchFailed, nil)
+ end
+ else
+ if Flags and efDoReplace <> 0 then
+ begin
+ I := cmYes;
+ if Flags and efPromptOnReplace <> 0 then
+ begin
+ MakeGlobal (Cursor, C);
+ I := EditorDialog (edReplacePrompt, Pointer(@C));
+ end;
+ if I = cmYes then
+ begin
+ { If Word_Wrap is active and we are at EOL }
+ { disallow replace by bringing up a dialog }
+ { stating that replace is not possible. }
+ if Word_Wrap and
+ ((CurPos.X + (Length (ReplaceStr) - Length (FindStr))) > Right_Margin) then
+ EditorDialog (edReplaceNotPossible, nil)
+ else
+ begin
+ Lock;
+ Search_Replace := True;
+ if length (ReplaceStr) < length (FindStr) then
+ Update_Place_Markers (0,
+ Length (FindStr) - Length (ReplaceStr),
+ CurPtr - Length (FindStr) + Length (ReplaceStr),
+ CurPtr)
+ else
+ if length (ReplaceStr) > length (FindStr) then
+ Update_Place_Markers (Length (ReplaceStr) - Length (FindStr),
+ 0,
+ CurPtr,
+ CurPtr + (Length (ReplaceStr) - Length (FindStr)));
+ InsertText (@ReplaceStr[1], Length (ReplaceStr), False);
+ Search_Replace := False;
+ TrackCursor (False);
+ Unlock;
+ end;
+ end;
+ end;
+ until (I = cmCancel) or (Flags and efReplaceAll = 0);
+end; { TEditor.DoSearchReplace }
+
+
+procedure TEditor.DoUpdate;
+begin
+ if UpdateFlags <> 0 then
+ begin
+ SetCursor (CurPos.X - Delta.X, CurPos.Y - Delta.Y);
+ if UpdateFlags and ufView <> 0 then
+ DrawView
+ else
+ if UpdateFlags and ufLine <> 0 then
+ DrawLines (CurPos.Y - Delta.Y, 1, LineStart (CurPtr));
+ if assigned(HScrollBar) then
+ HScrollBar^.SetParams (Delta.X, 0, Limit.X - Size.X, Size.X div 2, 1);
+ if assigned(VScrollBar) then
+ VScrollBar^.SetParams (Delta.Y, 0, Limit.Y - Size.Y, Size.Y - 1, 1);
+ if assigned(Indicator) then
+ Indicator^.SetValue (CurPos, AutoIndent, Modified, Word_Wrap);
+ if State and sfActive <> 0 then
+ UpdateCommands;
+ UpdateFlags := 0;
+ end;
+end; { TEditor.DoUpdate }
+
+
+function TEditor.Do_Word_Wrap (Select_Mode : Byte;
+ Center_Cursor : Boolean) : Boolean;
+{ This procedure does the actual wordwrap. It always assumes the CurPtr }
+{ is at Right_Margin + 1. It makes several tests for special conditions }
+{ and processes those first. If they all fail, it does a normal wrap. }
+VAR
+ A : Sw_Word; { Distance between line start and first word on line. }
+ C : Sw_Word; { Current pointer when we come into procedure. }
+ L : Sw_Word; { BufLen when we come into procedure. }
+ P : Sw_Word; { Position of pointer at any given moment. }
+ S : Sw_Word; { Start of a line. }
+begin
+ Do_Word_Wrap := False;
+ Select_Mode := 0;
+ if BufLen >= (BufSize - 1) then
+ exit;
+ C := CurPtr;
+ L := BufLen;
+ S := LineStart (CurPtr);
+ { If first character in the line is a space and autoindent mode is on }
+ { then we check to see if NextWord(S) exceeds the CurPtr. If it does, }
+ { we set CurPtr as the AutoIndent marker. If it doesn't, we will set }
+ { NextWord(S) as the AutoIndent marker. If neither, we set it to S. }
+ if AutoIndent and (Buffer^[S] = ' ') then
+ begin
+ if NextWord (S) > CurPtr then
+ A := CurPtr
+ else
+ A := NextWord (S);
+ end
+ else
+ A := NextWord (S);
+ { Though NewLine will remove EOL spaces, we do it here too. }
+ { This catches the instance where a user may try to space }
+ { completely across the line, in which case CurPtr.X = 0. }
+ Remove_EOL_Spaces (Select_Mode);
+ if CurPos.X = 0 then
+ begin
+ NewLine (Select_Mode);
+ Do_Word_Wrap := True;
+ Exit;
+ end;
+ { At this point we have one of five situations: }
+ { }
+ { 1) AutoIndent is on and this line is all spaces before CurPtr. }
+ { 2) AutoIndent is off and this line is all spaces before CurPtr. }
+ { 3) AutoIndent is on and this line is continuous characters before CurPtr. }
+ { 4) AutoIndent is off and this line is continuous characters before CurPtr. }
+ { 5) This is just a normal line of text. }
+ { }
+ { Conditions 1 through 4 have to be taken into account before condition 5. }
+ { First, we see if there are all spaces and/or all characters. }
+ { Then we determine which one it really is. Finally, we take }
+ { a course of action based on the state of AutoIndent. }
+ if PrevWord (CurPtr) <= S then
+ begin
+ P := CurPtr - 1;
+ while ((Buffer^[P] <> ' ') and (P > S)) do
+ Dec (P);
+ { We found NO SPACES. Conditions 4 and 5 are treated the same. }
+ { We can NOT do word wrap and put up a dialog box stating such. }
+ { Delete character just entered so we don't exceed Right_Margin. }
+ if P = S then
+ begin
+ EditorDialog (edWrapNotPossible, nil);
+ DeleteRange (PrevChar (CurPtr), CurPtr, True);
+ Exit;
+ end
+ else
+ begin
+ { There are spaces. Now find out if they are all spaces. }
+ { If so, see if AutoIndent is on. If it is, turn it off, }
+ { do a NewLine, and turn it back on. Otherwise, just do }
+ { the NewLine. We go through all of these gyrations for }
+ { AutoIndent. Being way out here with a preceding line }
+ { of spaces and wrapping with AutoIndent on is real dumb! }
+ { However, the user expects something. The wrap will NOT }
+ { autoindent, but they had no business being here anyway! }
+ P := CurPtr - 1;
+ while ((Buffer^[P] = ' ') and (P > S)) do
+ Dec (P);
+ if P = S then
+ begin
+ if Autoindent then
+ begin
+ AutoIndent := False;
+ NewLine (Select_Mode);
+ AutoIndent := True;
+ end
+ else
+ NewLine (Select_Mode);
+ end; { AutoIndent }
+ end; { P = S for spaces }
+ end { P = S for no spaces }
+ else { PrevWord (CurPtr) <= S }
+ begin
+ { Hooray! We actually had a plain old line of text to wrap! }
+ { Regardless if we are pushing out a line beyond the Right_Margin, }
+ { or at the end of a line itself, the following will determine }
+ { exactly where to do the wrap and re-set the cursor accordingly. }
+ { However, if P = A then we can't wrap. Show dialog and exit. }
+ P := CurPtr;
+ while P - S > Right_Margin do
+ P := PrevWord (P);
+ if (P = A) then
+ begin
+ EditorDialog (edReformNotPossible, nil);
+ SetCurPtr (P, Select_Mode);
+ Exit;
+ end;
+ SetCurPtr (P, Select_Mode);
+ NewLine (Select_Mode);
+ end; { PrevWord (CurPtr <= S }
+ { Track the cursor here (it is at CurPos.X = 0) so the view }
+ { will redraw itself at column 0. This eliminates having it }
+ { redraw starting at the current cursor and not being able }
+ { to see text before the cursor. Of course, we also end up }
+ { redrawing the view twice, here and back in HandleEvent. }
+ { }
+ { Reposition cursor so user can pick up where they left off. }
+ TrackCursor (Center_Cursor);
+ SetCurPtr (C - (L - BufLen), Select_Mode);
+ Do_Word_Wrap := True;
+end; { TEditor.Do_Word_Wrap }
+
+
+procedure TEditor.Draw;
+begin
+ if DrawLine <> Delta.Y then
+ begin
+ DrawPtr := LineMove (DrawPtr, Delta.Y - DrawLine);
+ DrawLine := Delta.Y;
+ end;
+ DrawLines (0, Size.Y, DrawPtr);
+end; { TEditor.Draw }
+
+
+procedure TEditor.DrawLines (Y, Count : Sw_Integer; LinePtr : Sw_Word);
+VAR
+ Color : Word;
+ B : array[0..MaxLineLength - 1] of Sw_Word;
+begin
+ Color := GetColor ($0201);
+ while Count > 0 do
+ begin
+ FormatLine (B, LinePtr, Delta.X + Size.X, Color);
+ WriteBuf (0, Y, Size.X, 1, B[Delta.X]);
+ LinePtr := NextLine (LinePtr);
+ Inc (Y);
+ Dec (Count);
+ end;
+end; { TEditor.DrawLines }
+
+
+procedure TEditor.Find;
+VAR
+ FindRec : TFindDialogRec;
+begin
+ with FindRec do
+ begin
+ Find := FindStr;
+ Options := Flags;
+ if EditorDialog (edFind, @FindRec) <> cmCancel then
+ begin
+ FindStr := Find;
+ Flags := Options and not efDoReplace;
+ DoSearchReplace;
+ end;
+ end;
+end; { TEditor.Find }
+
+
+procedure TEditor.FormatLine (var DrawBuf; LinePtr : Sw_Word;
+ Width : Sw_Integer;
+ Colors : Word);
+var
+ outptr : pword;
+ outcnt,
+ idxpos : Sw_Word;
+ attr : Word;
+
+ procedure FillSpace(i:Sw_Word);
+ var
+ w : word;
+ begin
+ inc(OutCnt,i);
+ w:=32 or attr;
+ while (i>0) do
+ begin
+ OutPtr^:=w;
+ inc(OutPtr);
+ dec(i);
+ end;
+ end;
+
+ function FormatUntil(endpos:Sw_word):boolean;
+ var
+ p : pchar;
+ begin
+ FormatUntil:=false;
+ p:=pchar(Buffer)+idxpos;
+ while endpos>idxpos do
+ begin
+ if OutCnt>=Width then
+ exit;
+ case p^ of
+ #9 :
+ FillSpace(Tabsize-(outcnt mod Tabsize));
+ #10,#13 :
+ begin
+ FillSpace(Width-OutCnt);
+ FormatUntil:=true;
+ exit;
+ end;
+ else
+ begin
+ inc(OutCnt);
+ OutPtr^:=ord(p^) or attr;
+ inc(OutPtr);
+ end;
+ end; { case }
+ inc(p);
+ inc(idxpos);
+ end;
+ end;
+
+begin
+ OutCnt:=0;
+ OutPtr:=@DrawBuf;
+ idxPos:=LinePtr;
+ attr:=lo(Colors) shl 8;
+ if FormatUntil(SelStart) then
+ exit;
+ attr:=hi(Colors) shl 8;
+ if FormatUntil(CurPtr) then
+ exit;
+ inc(idxPos,GapLen);
+ if FormatUntil(SelEnd+GapLen) then
+ exit;
+ attr:=lo(Colors) shl 8;
+ if FormatUntil(BufSize) then
+ exit;
+{ fill up until width }
+ FillSpace(Width-OutCnt);
+end; {TEditor.FormatLine}
+
+
+function TEditor.GetMousePtr (Mouse : Objects.TPoint) : Sw_Word;
+begin
+ MakeLocal (Mouse, Mouse);
+ Mouse.X := Max (0, Min (Mouse.X, Size.X - 1));
+ Mouse.Y := Max (0, Min (Mouse.Y, Size.Y - 1));
+ GetMousePtr := CharPtr (LineMove (DrawPtr, Mouse.Y + Delta.Y - DrawLine),
+ Mouse.X + Delta.X);
+end; { TEditor.GetMousePtr }
+
+
+function TEditor.GetPalette : PPalette;
+CONST
+ P : String[Length (CEditor)] = CEditor;
+begin
+ GetPalette := PPalette(@P);
+end; { TEditor.GetPalette }
+
+
+procedure TEditor.HandleEvent (var Event : Drivers.TEvent);
+VAR
+ ShiftState : Byte;
+ CenterCursor : Boolean;
+ SelectMode : Byte;
+ D : Objects.TPoint;
+ Mouse : Objects.TPoint;
+
+ function CheckScrollBar (P : PScrollBar; var D : Sw_Integer) : Boolean;
+ begin
+ CheckScrollBar := FALSE;
+ if (Event.InfoPtr = P) and (P^.Value <> D) then
+ begin
+ D := P^.Value;
+ Update (ufView);
+ CheckScrollBar := TRUE;
+ end;
+ end; {CheckScrollBar}
+
+begin
+ Inherited HandleEvent (Event);
+ ConvertEvent (Event);
+ CenterCursor := not CursorVisible;
+ SelectMode := 0;
+ ShiftState:=GetShiftState;
+ if Selecting or (ShiftState and $03 <> 0) then
+ SelectMode := smExtend;
+ case Event.What of
+ Drivers.evMouseDown:
+ begin
+ if Event.Double then
+ SelectMode := SelectMode or smDouble;
+ repeat
+ Lock;
+ if Event.What = evMouseAuto then
+ begin
+ MakeLocal (Event.Where, Mouse);
+ D := Delta;
+ if Mouse.X < 0 then
+ Dec (D.X);
+ if Mouse.X >= Size.X then
+ Inc (D.X);
+ if Mouse.Y < 0 then
+ Dec (D.Y);
+ if Mouse.Y >= Size.Y then
+ Inc (D.Y);
+ ScrollTo (D.X, D.Y);
+ end;
+ SetCurPtr (GetMousePtr (Event.Where), SelectMode);
+ SelectMode := SelectMode or smExtend;
+ Unlock;
+ until not MouseEvent (Event, evMouseMove + evMouseAuto);
+ end; { Drivers.evMouseDown }
+
+ Drivers.evKeyDown:
+ case Event.CharCode of
+ #32..#255:
+ begin
+ Lock;
+ if Overwrite and not HasSelection then
+ if CurPtr <> LineEnd (CurPtr) then
+ SelEnd := NextChar (CurPtr);
+ InsertText (@Event.CharCode, 1, False);
+ if Word_Wrap then
+ Check_For_Word_Wrap (SelectMode, CenterCursor);
+ TrackCursor (CenterCursor);
+ Unlock;
+ end;
+
+ else
+ Exit;
+ end; { Drivers.evKeyDown }
+
+ Drivers.evCommand:
+ case Event.Command of
+ cmFind : Find;
+ cmReplace : Replace;
+ cmSearchAgain : DoSearchReplace;
+ else
+ begin
+ Lock;
+ case Event.Command of
+ cmCut : ClipCut;
+ cmCopy : ClipCopy;
+ cmPaste : ClipPaste;
+ cmUndo : Undo;
+ cmClear : DeleteSelect;
+ cmCharLeft : SetCurPtr (PrevChar (CurPtr), SelectMode);
+ cmCharRight : SetCurPtr (NextChar (CurPtr), SelectMode);
+ cmWordLeft : SetCurPtr (PrevWord (CurPtr), SelectMode);
+ cmWordRight : SetCurPtr (NextWord (CurPtr), SelectMode);
+ cmLineStart : SetCurPtr (LineStart (CurPtr), SelectMode);
+ cmLineEnd : SetCurPtr (LineEnd (CurPtr), SelectMode);
+ cmLineUp : SetCurPtr (LineMove (CurPtr, -1), SelectMode);
+ cmLineDown : SetCurPtr (LineMove (CurPtr, 1), SelectMode);
+ cmPageUp : SetCurPtr (LineMove (CurPtr, - (Size.Y - 1)), SelectMode);
+ cmPageDown : SetCurPtr (LineMove (CurPtr, Size.Y - 1), SelectMode);
+ cmTextStart : SetCurPtr (0, SelectMode);
+ cmTextEnd : SetCurPtr (BufLen, SelectMode);
+ cmNewLine : NewLine (SelectMode);
+ cmBackSpace : DeleteRange (PrevChar (CurPtr), CurPtr, True);
+ cmDelChar : DeleteRange (CurPtr, NextChar (CurPtr), True);
+ cmDelWord : DeleteRange (CurPtr, NextWord (CurPtr), False);
+ cmDelStart : DeleteRange (LineStart (CurPtr), CurPtr, False);
+ cmDelEnd : DeleteRange (CurPtr, LineEnd (CurPtr), False);
+ cmDelLine : DeleteRange (LineStart (CurPtr), NextLine (CurPtr), False);
+ cmInsMode : ToggleInsMode;
+ cmStartSelect : StartSelect;
+ cmHideSelect : HideSelect;
+ cmIndentMode : begin
+ AutoIndent := not AutoIndent;
+ Update (ufStats);
+ end; { Added provision to update TIndicator if ^QI pressed. }
+ cmCenterText : Center_Text (SelectMode);
+ cmEndPage : SetCurPtr (LineMove (CurPtr, Delta.Y - CurPos.Y + Size.Y - 1), SelectMode);
+ cmHomePage : SetCurPtr (LineMove (CurPtr, -(CurPos.Y - Delta.Y)), SelectMode);
+ cmInsertLine : Insert_Line (SelectMode);
+ cmJumpLine : Jump_To_Line (SelectMode);
+ cmReformDoc : Reformat_Document (SelectMode, CenterCursor);
+ cmReformPara : Reformat_Paragraph (SelectMode, CenterCursor);
+ cmRightMargin : Set_Right_Margin;
+ cmScrollDown : Scroll_Down;
+ cmScrollUp : Scroll_Up;
+ cmSelectWord : Select_Word;
+ cmSetTabs : Set_Tabs;
+ cmTabKey : Tab_Key (SelectMode);
+ cmWordWrap : begin
+ Word_Wrap := not Word_Wrap;
+ Update (ufStats);
+ end; { Added provision to update TIndicator if ^OW pressed. }
+ cmSetMark0 : Set_Place_Marker (10);
+ cmSetMark1 : Set_Place_Marker (1);
+ cmSetMark2 : Set_Place_Marker (2);
+ cmSetMark3 : Set_Place_Marker (3);
+ cmSetMark4 : Set_Place_Marker (4);
+ cmSetMark5 : Set_Place_Marker (5);
+ cmSetMark6 : Set_Place_Marker (6);
+ cmSetMark7 : Set_Place_Marker (7);
+ cmSetMark8 : Set_Place_Marker (8);
+ cmSetMark9 : Set_Place_Marker (9);
+ cmJumpMark0 : Jump_Place_Marker (10, SelectMode);
+ cmJumpMark1 : Jump_Place_Marker (1, SelectMode);
+ cmJumpMark2 : Jump_Place_Marker (2, SelectMode);
+ cmJumpMark3 : Jump_Place_Marker (3, SelectMode);
+ cmJumpMark4 : Jump_Place_Marker (4, SelectMode);
+ cmJumpMark5 : Jump_Place_Marker (5, SelectMode);
+ cmJumpMark6 : Jump_Place_Marker (6, SelectMode);
+ cmJumpMark7 : Jump_Place_Marker (7, SelectMode);
+ cmJumpMark8 : Jump_Place_Marker (8, SelectMode);
+ cmJumpMark9 : Jump_Place_Marker (9, SelectMode);
+ else
+ Unlock;
+ Exit;
+ end; { Event.Command (Inner) }
+ TrackCursor (CenterCursor);
+ { If the user presses any key except cmNewline or cmBackspace }
+ { we need to check if the file has been modified yet. There }
+ { can be no spaces at the end of a line, or wordwrap doesn't }
+ { work properly. We don't want to do this if the file hasn't }
+ { been modified because the user could be bringing in an ASCII }
+ { file from an editor that allows spaces at the EOL. If we }
+ { took them out in that scenario the "M" would appear on the }
+ { TIndicator line and the user would get upset or confused. }
+ if (Event.Command <> cmNewLine) and
+ (Event.Command <> cmBackSpace) and
+ (Event.Command <> cmTabKey) and
+ Modified then
+ Remove_EOL_Spaces (SelectMode);
+ Unlock;
+ end; { Event.Command (Outer) }
+ end; { Drivers.evCommand }
+
+ Drivers.evBroadcast:
+ case Event.Command of
+ cmScrollBarChanged:
+ if (Event.InfoPtr = HScrollBar) or
+ (Event.InfoPtr = VScrollBar) then
+ begin
+ CheckScrollBar (HScrollBar, Delta.X);
+ CheckScrollBar (VScrollBar, Delta.Y);
+ end
+ else
+ exit;
+ else
+ Exit;
+ end; { Drivers.evBroadcast }
+
+ end;
+ ClearEvent (Event);
+end; { TEditor.HandleEvent }
+
+
+function TEditor.HasSelection : Boolean;
+begin
+ HasSelection := SelStart <> SelEnd;
+end; { TEditor.HasSelection }
+
+
+procedure TEditor.HideSelect;
+begin
+ Selecting := False;
+ SetSelect (CurPtr, CurPtr, False);
+end; { TEditor.HideSelect }
+
+
+procedure TEditor.InitBuffer;
+begin
+ Assert(Buffer = nil, 'TEditor.InitBuffer: Buffer is not nil');
+ ReAllocMem(Buffer, BufSize);
+end; { TEditor.InitBuffer }
+
+
+function TEditor.InsertBuffer (var P : PEditBuffer;
+ Offset, Length : Sw_Word;
+ AllowUndo, SelectText : Boolean) : Boolean;
+VAR
+ SelLen : Sw_Word;
+ DelLen : Sw_Word;
+ SelLines : Sw_Word;
+ Lines : Sw_Word;
+ NewSize : Longint;
+begin
+ InsertBuffer := True;
+ Selecting := False;
+ SelLen := SelEnd - SelStart;
+ if (SelLen = 0) and (Length = 0) then
+ Exit;
+ DelLen := 0;
+ if AllowUndo then
+ if CurPtr = SelStart then
+ DelLen := SelLen
+ else
+ if SelLen > InsCount then
+ DelLen := SelLen - InsCount;
+ NewSize := Longint (BufLen + DelCount - SelLen + DelLen) + Length;
+ if NewSize > BufLen + DelCount then
+ if (NewSize > MaxBufLength) or not SetBufSize (NewSize) then
+ begin
+ EditorDialog (edOutOfMemory, nil);
+ InsertBuffer := False;
+ SelEnd := SelStart;
+ Exit;
+ end;
+ SelLines := CountLines (Buffer^[BufPtr (SelStart)], SelLen);
+ if CurPtr = SelEnd then
+ begin
+ if AllowUndo then
+ begin
+ if DelLen > 0 then
+ Move (Buffer^[SelStart], Buffer^[CurPtr + GapLen - DelCount - DelLen], DelLen);
+ Dec (InsCount, SelLen - DelLen);
+ end;
+ CurPtr := SelStart;
+ Dec (CurPos.Y, SelLines);
+ end;
+ if Delta.Y > CurPos.Y then
+ begin
+ Dec (Delta.Y, SelLines);
+ if Delta.Y < CurPos.Y then
+ Delta.Y := CurPos.Y;
+ end;
+ if Length > 0 then
+ Move (P^[Offset], Buffer^[CurPtr], Length);
+ Lines := CountLines (Buffer^[CurPtr], Length);
+ Inc (CurPtr, Length);
+ Inc (CurPos.Y, Lines);
+ DrawLine := CurPos.Y;
+ DrawPtr := LineStart (CurPtr);
+ CurPos.X := CharPos (DrawPtr, CurPtr);
+ if not SelectText then
+ SelStart := CurPtr;
+ SelEnd := CurPtr;
+ if Length>Sellen then
+ begin
+ Inc (BufLen, Length - SelLen);
+ Dec (GapLen, Length - SelLen);
+ end
+ else
+ begin
+ Dec (BufLen, Sellen - Length);
+ Inc (GapLen, Sellen - Length);
+ end;
+ if AllowUndo then
+ begin
+ Inc (DelCount, DelLen);
+ Inc (InsCount, Length);
+ end;
+ Inc (Limit.Y, Lines - SelLines);
+ Delta.Y := Max (0, Min (Delta.Y, Limit.Y - Size.Y));
+ if not IsClipboard then
+ Modified := True;
+ SetBufSize (BufLen + DelCount);
+ if (SelLines = 0) and (Lines = 0) then
+ Update (ufLine)
+ else
+ Update (ufView);
+end; { TEditor.InsertBuffer }
+
+
+function TEditor.InsertFrom (Editor : PEditor) : Boolean;
+begin
+ InsertFrom := InsertBuffer (Editor^.Buffer,
+ Editor^.BufPtr (Editor^.SelStart),
+ Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
+end; { TEditor.InsertFrom }
+
+
+procedure TEditor.Insert_Line (Select_Mode : Byte);
+{ This procedure inserts a newline at the current cursor position }
+{ if a ^N is pressed. Unlike cmNewLine, the cursor will return }
+{ to its original position. If the cursor was at the end of a }
+{ line, and its spaces were removed, the cursor returns to the }
+{ end of the line instead. }
+begin
+ NewLine (Select_Mode);
+ SetCurPtr (LineEnd (LineMove (CurPtr, -1)), Select_Mode);
+end; { TEditor.Insert_Line }
+
+
+function TEditor.InsertText (Text : Pointer;
+ Length : Sw_Word;
+ SelectText : Boolean) : Boolean;
+begin
+ if assigned(Text) and not Search_Replace then
+ Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
+ InsertText := InsertBuffer (PEditBuffer (Text),
+ 0, Length, CanUndo, SelectText);
+end; { TEditor.InsertText }
+
+
+function TEditor.IsClipboard : Boolean;
+begin
+ IsClipboard := Clipboard = @Self;
+end; { TEditor.IsClipboard }
+
+
+procedure TEditor.Jump_Place_Marker (Element : Byte; Select_Mode : Byte);
+{ This procedure jumps to a place marker if ^Q# is pressed. }
+{ We don't go anywhere if Place_Marker[Element] is not zero. }
+begin
+ if (not IsClipboard) and (Place_Marker[Element] <> 0) then
+ SetCurPtr (Place_Marker[Element], Select_Mode);
+end; { TEditor.Jump_Place_Marker }
+
+
+procedure TEditor.Jump_To_Line (Select_Mode : Byte);
+{ This function brings up a dialog box that allows }
+{ the user to select a line number to jump to. }
+VAR
+ Code : Integer; { Used for Val conversion. }
+ Temp_Value : Longint; { Holds converted dialog value. }
+begin
+ if EditorDialog (edJumpToLine, @Line_Number) <> cmCancel then
+ begin
+ { Convert the Line_Number string to an interger. }
+ { Put it into Temp_Value. If the number is not }
+ { in the range 1..9999 abort. If the number is }
+ { our current Y position, abort. Otherwise, }
+ { go to top of document, and jump to the line. }
+ { There are faster methods. This one's easy. }
+ { Note that CurPos.Y is always 1 less than what }
+ { the TIndicator line says. }
+ val (Line_Number, Temp_Value, Code);
+ if (Temp_Value < 1) or (Temp_Value > 9999999) then
+ Exit;
+ if Temp_Value = CurPos.Y + 1 then
+ Exit;
+ SetCurPtr (0, Select_Mode);
+ SetCurPtr (LineMove (CurPtr, Temp_Value - 1), Select_Mode);
+ end;
+end; {TEditor.Jump_To_Line}
+
+
+function TEditor.LineEnd (P : Sw_Word) : Sw_Word;
+var
+ start,
+ i : Sw_word;
+ pc : pchar;
+begin
+ if P<CurPtr then
+ begin
+ i:=CurPtr-P;
+ pc:=pchar(Buffer)+P;
+ while (i>0) do
+ begin
+ if pc^ in [#10,#13] then
+ begin
+ LineEnd:=pc-pchar(Buffer);
+ exit;
+ end;
+ inc(pc);
+ dec(i);
+ end;
+ start:=CurPtr;
+ end
+ else
+ start:=P;
+ i:=BufLen-Start;
+ pc:=pchar(Buffer)+GapLen+start;
+ while (i>0) do
+ begin
+ if pc^ in [#10,#13] then
+ begin
+ LineEnd:=pc-(pchar(Buffer)+Gaplen);
+ exit;
+ end;
+ inc(pc);
+ dec(i);
+ end;
+ LineEnd:=pc-(pchar(Buffer)+Gaplen);
+end; { TEditor.LineEnd }
+
+
+function TEditor.LineMove (P : Sw_Word; Count : Sw_Integer) : Sw_Word;
+VAR
+ Pos : Sw_Integer;
+ I : Sw_Word;
+begin
+ I := P;
+ P := LineStart (P);
+ Pos := CharPos (P, I);
+ while Count <> 0 do
+ begin
+ I := P;
+ if Count < 0 then
+ begin
+ P := PrevLine (P);
+ Inc (Count);
+ end
+ else
+ begin
+ P := NextLine (P);
+ Dec (Count);
+ end;
+ end;
+ if P <> I then
+ P := CharPtr (P, Pos);
+ LineMove := P;
+end; { TEditor.LineMove }
+
+
+function TEditor.LineStart (P : Sw_Word) : Sw_Word;
+var
+ i : Sw_word;
+ start,pc : pchar;
+ oc : char;
+begin
+ if P>CurPtr then
+ begin
+ start:=pchar(Buffer)+GapLen;
+ pc:=start;
+ i:=P-CurPtr;
+ dec(pc);
+ while (i>0) do
+ begin
+ if pc^ in [#10,#13] then
+ break;
+ dec(pc);
+ dec(i);
+ end;
+ end
+ else
+ i:=0;
+ if i=0 then
+ begin
+ start:=pchar(Buffer);
+ i:=P;
+ pc:=start+p;
+ dec(pc);
+ while (i>0) do
+ begin
+ if pc^ in [#10,#13] then
+ break;
+ dec(pc);
+ dec(i);
+ end;
+ if i=0 then
+ begin
+ LineStart:=0;
+ exit;
+ end;
+ end;
+ oc:=pc^;
+ LineStart:=pc-start+1;
+end; { TEditor.LineStart }
+
+
+function TEditor.LineNr (P : Sw_Word) : Sw_Word;
+var
+ pc,endp : pchar;
+ lines : sw_word;
+begin
+ endp:=pchar(Buffer)+BufPtr(P);
+ pc:=pchar(Buffer);
+ lines:=0;
+ while (pc<endp) do
+ begin
+ if pc^ in [#10,#13] then
+ begin
+ inc(lines);
+ if ord((pc+1)^)+ord(pc^)=23 then
+ begin
+ inc(pc);
+ if (pc>=endp) then
+ break;
+ end;
+ end;
+ inc(pc);
+ end;
+ LineNr:=Lines;
+end;
+
+
+procedure TEditor.Lock;
+begin
+ Inc (LockCount);
+end; { TEditor.Lock }
+
+
+function TEditor.NewLine (Select_Mode : Byte) : Boolean;
+VAR
+ I : Sw_Word; { Used to track spaces for AutoIndent. }
+ P : Sw_Word; { Position of Cursor when we arrive and after Newline. }
+begin
+ P := LineStart (CurPtr);
+ I := P;
+ { The first thing we do is remove any End Of Line spaces. }
+ { Then we check to see how many spaces are on beginning }
+ { of a line. We need this check to add them after CR/LF }
+ { if AutoIndenting. Last of all we insert spaces required }
+ { for the AutoIndenting, if it was on. }
+ Remove_EOL_Spaces (Select_Mode);
+ while (I < CurPtr) and ((Buffer^[I] in [#9,' '])) do
+ Inc (I);
+ if InsertText (@LineBreak[1], length(LineBreak), False) = FALSE then
+ exit;
+ if AutoIndent then
+ InsertText (@Buffer^[P], I - P, False);
+ { Remember where the CurPtr is at this moment. }
+ { Remember the length of the buffer at the moment. }
+ { Go to the previous line and remove EOL spaces. }
+ { Once removed, re-set the cursor to where we were }
+ { minus any spaces that might have been removed. }
+ I := BufLen;
+ P := CurPtr;
+ SetCurPtr (LineMove (CurPtr, - 1), Select_Mode);
+ Remove_EOL_Spaces (Select_Mode);
+ if I - BufLen <> 0 then
+ SetCurPtr (P - (I - BufLen), Select_Mode)
+ else
+ SetCurPtr (P, Select_Mode);
+ NewLine:=true;
+end; { TEditor.NewLine }
+
+
+function TEditor.NextChar (P : Sw_Word) : Sw_Word;
+var
+ pc : pchar;
+begin
+ if P<>BufLen then
+ begin
+ inc(P);
+ if P<>BufLen then
+ begin
+ pc:=pchar(Buffer);
+ if P>=CurPtr then
+ inc(pc,GapLen);
+ inc(pc,P-1);
+ if ord(pc^)+ord((pc+1)^)=23 then
+ inc(p);
+ end;
+ end;
+ NextChar:=P;
+end; { TEditor.NextChar }
+
+
+function TEditor.NextLine (P : Sw_Word) : Sw_Word;
+begin
+ NextLine := NextChar (LineEnd (P));
+end; { TEditor.NextLine }
+
+
+function TEditor.NextWord (P : Sw_Word) : Sw_Word;
+begin
+ { skip word }
+ while (P < BufLen) and (BufChar (P) in WordChars) do
+ P := NextChar (P);
+ { skip spaces }
+ while (P < BufLen) and not (BufChar (P) in WordChars) do
+ P := NextChar (P);
+ NextWord := P;
+end; { TEditor.NextWord }
+
+
+function TEditor.PrevChar (P : Sw_Word) : Sw_Word;
+var
+ pc : pchar;
+begin
+ if p<>0 then
+ begin
+ dec(p);
+ if p<>0 then
+ begin
+ pc:=pchar(Buffer);
+ if P>=CurPtr then
+ inc(pc,GapLen);
+ inc(pc,P-1);
+ if ord(pc^)+ord((pc+1)^)=23 then
+ dec(p);
+ end;
+ end;
+ PrevChar:=P;
+end; { TEditor.PrevChar }
+
+
+function TEditor.PrevLine (P : Sw_Word) : Sw_Word;
+begin
+ PrevLine := LineStart (PrevChar (P));
+end; { TEditor.PrevLine }
+
+
+function TEditor.PrevWord (P : Sw_Word) : Sw_Word;
+begin
+ { skip spaces }
+ while (P > 0) and not (BufChar (PrevChar (P)) in WordChars) do
+ P := PrevChar (P);
+ { skip word }
+ while (P > 0) and (BufChar (PrevChar (P)) in WordChars) do
+ P := PrevChar (P);
+ PrevWord := P;
+end; { TEditor.PrevWord }
+
+
+procedure TEditor.Reformat_Document (Select_Mode : Byte; Center_Cursor : Boolean);
+{ This procedure will do a reformat of the entire document, or just }
+{ from the current line to the end of the document, if ^QU is pressed. }
+{ It simply brings up the correct dialog box, and then calls the }
+{ TEditor.Reformat_Paragraph procedure to do the actual reformatting. }
+CONST
+ efCurrentLine = $0000; { Radio button #1 selection for dialog box. }
+ efWholeDocument = $0001; { Radio button #2 selection for dialog box. }
+VAR
+ Reformat_Options : Word; { Holds the dialog options for reformatting. }
+begin
+ { Check if Word_Wrap is toggled on. If NOT on, check if programmer }
+ { allows reformatting of document and if not show user dialog that }
+ { says reformatting is not permissable. }
+ if not Word_Wrap then
+ begin
+ if not Allow_Reformat then
+ begin
+ EditorDialog (edReformatNotAllowed, nil);
+ Exit;
+ end;
+ Word_Wrap := True;
+ Update (ufStats);
+ end;
+ { Default radio button option to 1st one. Bring up dialog box. }
+ Reformat_Options := efCurrentLine;
+ if EditorDialog (edReformatDocument, @Reformat_Options) <> cmCancel then
+ begin
+ { If the option to reformat the whole document was selected }
+ { we need to go back to start of document. Otherwise we stay }
+ { on the current line. Call Reformat_Paragraph until we get }
+ { to the end of the document to do the reformatting. }
+ if Reformat_Options and efWholeDocument <> 0 then
+ SetCurPtr (0, Select_Mode);
+ Unlock;
+ repeat
+ Lock;
+ if NOT Reformat_Paragraph (Select_Mode, Center_Cursor) then
+ Exit;
+ TrackCursor (False);
+ Unlock;
+ until CurPtr = BufLen;
+ end;
+end; { TEditor.Reformat_Document }
+
+
+function TEditor.Reformat_Paragraph (Select_Mode : Byte;
+ Center_Cursor : Boolean) : Boolean;
+{ This procedure will do a reformat of the current paragraph if ^B pressed. }
+{ The feature works regardless if wordrap is on or off. It also supports }
+{ the AutoIndent feature. Reformat is not possible if the CurPos exceeds }
+{ the Right_Margin. Right_Margin is where the EOL is considered to be. }
+CONST
+ Space : array [1..2] of Char = #32#32;
+VAR
+ C : Sw_Word; { Position of CurPtr when we come into procedure. }
+ E : Sw_Word; { End of a line. }
+ S : Sw_Word; { Start of a line. }
+begin
+ Reformat_Paragraph := False;
+ { Check if Word_Wrap is toggled on. If NOT on, check if programmer }
+ { allows reformatting of paragraph and if not show user dialog that }
+ { says reformatting is not permissable. }
+ if not Word_Wrap then
+ begin
+ if not Allow_Reformat then
+ begin
+ EditorDialog (edReformatNotAllowed, nil);
+ Exit;
+ end;
+ Word_Wrap := True;
+ Update (ufStats);
+ end;
+ C := CurPtr;
+ E := LineEnd (CurPtr);
+ S := LineStart (CurPtr);
+ { Reformat possible only if current line is NOT blank! }
+ if E <> S then
+ begin
+ { Reformat is NOT possible if the first word }
+ { on the line is beyond the Right_Margin. }
+ S := LineStart (CurPtr);
+ if NextWord (S) - S >= Right_Margin - 1 then
+ begin
+ EditorDialog (edReformNotPossible, nil);
+ Exit;
+ end;
+ { First objective is to find the first blank line }
+ { after this paragraph so we know when to stop. }
+ { That could be the end of the document. }
+ Repeat
+ SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
+ E := LineEnd (CurPtr);
+ S := LineStart (CurPtr);
+ BlankLine := E;
+ until ((CurPtr = BufLen) or (E = S));
+ SetCurPtr (C, Select_Mode);
+ repeat
+ { Set CurPtr to LineEnd and remove the EOL spaces. }
+ { Pull up the next line and remove its EOL space. }
+ { First make sure the next line is not BlankLine! }
+ { Insert spaces as required between the two lines. }
+ SetCurPtr (LineEnd (CurPtr), Select_Mode);
+ Remove_EOL_Spaces (Select_Mode);
+ if CurPtr <> Blankline - 2 then
+ DeleteRange (CurPtr, Nextword (CurPtr), True);
+ Remove_EOL_Spaces (Select_Mode);
+ case Buffer^[CurPtr-1] of
+ '!' : InsertText (@Space, 2, False);
+ '.' : InsertText (@Space, 2, False);
+ ':' : InsertText (@Space, 2, False);
+ '?' : InsertText (@Space, 2, False);
+ else
+ InsertText (@Space, 1, False);
+ end;
+ { Reset CurPtr to EOL. While line length is > Right_Margin }
+ { go Do_Word_Wrap. If wordrap failed, exit routine. }
+ SetCurPtr (LineEnd (CurPtr), Select_Mode);
+ while LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin do
+ if not Do_Word_Wrap (Select_Mode, Center_Cursor) then
+ Exit;
+ { If LineEnd - LineStart > Right_Margin then set CurPtr }
+ { to Right_Margin on current line. Otherwise we set the }
+ { CurPtr to LineEnd. This gyration sets up the conditions }
+ { to test for time of loop exit. }
+ if LineEnd (CurPtr) - LineStart (CurPtr) > Right_Margin then
+ SetCurPtr (LineStart (CurPtr) + Right_Margin, Select_Mode)
+ else
+ SetCurPtr (LineEnd (CurPtr), Select_Mode);
+ until ((CurPtr >= BufLen) or (CurPtr >= BlankLine - 2));
+ end;
+ { If not at the end of the document reset CurPtr to start of next line. }
+ { This should be a blank line between paragraphs. }
+ if CurPtr < BufLen then
+ SetCurPtr (LineMove (CurPtr, 1), Select_Mode);
+ Reformat_Paragraph := True;
+end; { TEditor.Reformat_Paragraph }
+
+
+procedure TEditor.Remove_EOL_Spaces (Select_Mode : Byte);
+{ This procedure tests to see if there are consecutive spaces }
+{ at the end of a line (EOL). If so, we delete all spaces }
+{ after the last non-space character to the end of line. }
+{ We then reset the CurPtr to where we ended up at. }
+VAR
+ C : Sw_Word; { Current pointer when we come into procedure. }
+ E : Sw_Word; { End of line. }
+ P : Sw_Word; { Position of pointer at any given moment. }
+ S : Sw_Word; { Start of a line. }
+begin
+ C := CurPtr;
+ E := LineEnd (CurPtr);
+ P := E;
+ S := LineStart (CurPtr);
+ { Start at the end of a line and move towards the start. }
+ { Find first non-space character in that direction. }
+ while (P > S) and (BufChar (PrevChar (P)) = #32) do
+ P := PrevChar (P);
+ { If we found any spaces then delete them. }
+ if P < E then
+ begin
+ SetSelect (P, E, True);
+ DeleteSelect;
+ Update_Place_Markers (0, E - P, P, E);
+ end;
+ { If C, our pointer when we came into this procedure, }
+ { is less than the CurPtr then reset CurPtr to C so }
+ { cursor is where we started. Otherwise, set it to }
+ { the new CurPtr, for we have deleted characters. }
+ if C < CurPtr then
+ SetCurPtr (C, Select_Mode)
+ else
+ SetCurPtr (CurPtr, Select_Mode);
+end; { TEditor.Remove_EOL_Spaces }
+
+
+procedure TEditor.Replace;
+VAR
+ ReplaceRec : TReplaceDialogRec;
+begin
+ with ReplaceRec do
+ begin
+ Find := FindStr;
+ Replace := ReplaceStr;
+ Options := Flags;
+ if EditorDialog (edReplace, @ReplaceRec) <> cmCancel then
+ begin
+ FindStr := Find;
+ ReplaceStr := Replace;
+ Flags := Options or efDoReplace;
+ DoSearchReplace;
+ end;
+ end;
+end; { TEditor.Replace }
+
+
+procedure TEditor.Scroll_Down;
+{ This procedure will scroll the screen up, and always keep }
+{ the cursor on the CurPos.Y position, but not necessarily on }
+{ the CurPos.X. If CurPos.Y scrolls off the screen, the cursor }
+{ will stay in the upper left corner of the screen. This will }
+{ simulate the same process in the IDE. The CurPos.X coordinate }
+{ only messes up if we are on long lines and we then encounter }
+{ a shorter or blank line beneath the current one as we scroll. }
+{ In that case, it goes to the end of the new line. }
+VAR
+ C : Sw_Word; { Position of CurPtr when we enter procedure. }
+ P : Sw_Word; { Position of CurPtr at any given time. }
+ W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y). }
+begin
+ { Remember current cursor position. Remember current CurPos.Y position. }
+ { Now issue the equivalent of a [Ctrl]-[End] command so the cursor will }
+ { go to the bottom of the current screen. Reset the cursor to this new }
+ { position and then send FALSE to TrackCursor so we fool it into }
+ { incrementing Delta.Y by only +1. If we didn't do this it would try }
+ { to center the cursor on the screen by fiddling with Delta.Y. }
+ C := CurPtr;
+ W.X := CurPos.Y;
+ P := LineMove (CurPtr, Delta.Y - CurPos.Y + Size.Y);
+ SetCurPtr (P, 0);
+ TrackCursor (False);
+ { Now remember where the new CurPos.Y is. See if distance between new }
+ { CurPos.Y and old CurPos.Y are greater than the current screen size. }
+ { If they are, we need to move cursor position itself down by one. }
+ { Otherwise, send the cursor back to our original CurPtr. }
+ W.Y := CurPos.Y;
+ if W.Y - W.X > Size.Y - 1 then
+ SetCurPtr (LineMove (C, 1), 0)
+ else
+ SetCurPtr (C, 0);
+end; { TEditor.Scroll_Down }
+
+
+procedure TEditor.Scroll_Up;
+{ This procedure will scroll the screen down, and always keep }
+{ the cursor on the CurPos.Y position, but not necessarily on }
+{ the CurPos.X. If CurPos.Y scrolls off the screen, the cursor }
+{ will stay in the bottom left corner of the screen. This will }
+{ simulate the same process in the IDE. The CurPos.X coordinate }
+{ only messes up if we are on long lines and we then encounter }
+{ a shorter or blank line beneath the current one as we scroll. }
+{ In that case, it goes to the end of the new line. }
+VAR
+ C : Sw_Word; { Position of CurPtr when we enter procedure. }
+ P : Sw_Word; { Position of CurPtr at any given time. }
+ W : Objects.TPoint; { CurPos.Y of CurPtr and P ('.X and '.Y). }
+begin
+ { Remember current cursor position. Remember current CurPos.Y position. }
+ { Now issue the equivalent of a [Ctrl]-[Home] command so the cursor will }
+ { go to the top of the current screen. Reset the cursor to this new }
+ { position and then send FALSE to TrackCursor so we fool it into }
+ { decrementing Delta.Y by only -1. If we didn't do this it would try }
+ { to center the cursor on the screen by fiddling with Delta.Y. }
+ C := CurPtr;
+ W.Y := CurPos.Y;
+ P := LineMove (CurPtr, -(CurPos.Y - Delta.Y + 1));
+ SetCurPtr (P, 0);
+ TrackCursor (False);
+ { Now remember where the new CurPos.Y is. See if distance between new }
+ { CurPos.Y and old CurPos.Y are greater than the current screen size. }
+ { If they are, we need to move the cursor position itself up by one. }
+ { Otherwise, send the cursor back to our original CurPtr. }
+ W.X := CurPos.Y;
+ if W.Y - W.X > Size.Y - 1 then
+ SetCurPtr (LineMove (C, -1), 0)
+ else
+ SetCurPtr (C, 0);
+end; { TEditor.Scroll_Up }
+
+
+procedure TEditor.ScrollTo (X, Y : Sw_Integer);
+begin
+ X := Max (0, Min (X, Limit.X - Size.X));
+ Y := Max (0, Min (Y, Limit.Y - Size.Y));
+ if (X <> Delta.X) or (Y <> Delta.Y) then
+ begin
+ Delta.X := X;
+ Delta.Y := Y;
+ Update (ufView);
+ end;
+end; { TEditor.ScrollTo }
+
+
+function TEditor.Search (const FindStr : String; Opts : Word) : Boolean;
+VAR
+ I,Pos : Sw_Word;
+begin
+ Search := False;
+ Pos := CurPtr;
+ repeat
+ if Opts and efCaseSensitive <> 0 then
+ I := Scan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr)
+ else
+ I := IScan (Buffer^[BufPtr (Pos)], BufLen - Pos, FindStr);
+ if (I <> sfSearchFailed) then
+ begin
+ Inc (I, Pos);
+ if (Opts and efWholeWordsOnly = 0) or
+ not (((I <> 0) and (BufChar (I - 1) in WordChars)) or
+ ((I + Length (FindStr) <> BufLen) and
+ (BufChar (I + Length (FindStr)) in WordChars))) then
+ begin
+ Lock;
+ SetSelect (I, I + Length (FindStr), False);
+ TrackCursor (not CursorVisible);
+ Unlock;
+ Search := True;
+ Exit;
+ end
+ else
+ Pos := I + 1;
+ end;
+ until I = sfSearchFailed;
+end; { TEditor.Search }
+
+
+procedure TEditor.Select_Word;
+{ This procedure will select the a word to put into the clipboard. }
+{ I've added it just to maintain compatibility with the IDE editor. }
+{ Note that selection starts at the current cursor position and ends }
+{ when a space or the end of line is encountered. }
+VAR
+ E : Sw_Word; { End of the current line. }
+ Select_Mode : Byte; { Allows us to turn select mode on inside procedure. }
+begin
+ E := LineEnd (CurPtr);
+ { If the cursor is on a space or at the end of a line, abort. }
+ { Stupid action on users part for you can't select blanks! }
+ if (BufChar (CurPtr) = #32) or (CurPtr = E) then
+ Exit;
+ { Turn on select mode and tell editor to start selecting text. }
+ { As long as we have a character > a space (this is done to }
+ { exclude CR/LF pairs at end of a line) and we are NOT at the }
+ { end of a line, set the CurPtr to the next character. }
+ { Once we find a space or CR/LF, selection is done and we }
+ { automatically put the selected word into the Clipboard. }
+ Select_Mode := smExtend;
+ StartSelect;
+ while (BufChar (NextChar (CurPtr)) > #32) and (CurPtr < E) do
+ SetCurPtr (NextChar (CurPtr), Select_Mode);
+ SetCurPtr (NextChar (CurPtr), Select_Mode);
+ ClipCopy;
+end; {TEditor.Select_Word }
+
+
+procedure TEditor.SetBufLen (Length : Sw_Word);
+begin
+ BufLen := Length;
+ GapLen := BufSize - Length;
+ SelStart := 0;
+ SelEnd := 0;
+ CurPtr := 0;
+ CurPos.X:=0;
+ CurPos.Y:=0;
+ Delta.X:=0;
+ Delta.Y:=0;
+ GetLimits(Buffer^[GapLen], BufLen,Limit);
+ inc(Limit.X);
+ inc(Limit.Y);
+ DrawLine := 0;
+ DrawPtr := 0;
+ DelCount := 0;
+ InsCount := 0;
+ Modified := False;
+ Update (ufView);
+end; { TEditor.SetBufLen }
+
+
+function TEditor.SetBufSize (NewSize : Sw_Word) : Boolean;
+begin
+ ReAllocMem(Buffer, NewSize);
+ BufSize := NewSize;
+ SetBufSize := True;
+end; { TEditor.SetBufSize }
+
+
+procedure TEditor.SetCmdState (Command : Word; Enable : Boolean);
+VAR
+ S : TCommandSet;
+begin
+ S := [Command];
+ if Enable and (State and sfActive <> 0) then
+ EnableCommands (S)
+ else
+ DisableCommands (S);
+end; { TEditor.SetCmdState }
+
+
+procedure TEditor.SetCurPtr (P : Sw_Word; SelectMode : Byte);
+VAR
+ Anchor : Sw_Word;
+begin
+ if SelectMode and smExtend = 0 then
+ Anchor := P
+ else
+ if CurPtr = SelStart then
+ Anchor := SelEnd
+ else
+ Anchor := SelStart;
+ if P < Anchor then
+ begin
+ if SelectMode and smDouble <> 0 then
+ begin
+ P := PrevLine (NextLine (P));
+ Anchor := NextLine (PrevLine (Anchor));
+ end;
+ SetSelect (P, Anchor, True);
+ end
+ else
+ begin
+ if SelectMode and smDouble <> 0 then
+ begin
+ P := NextLine (P);
+ Anchor := PrevLine (NextLine (Anchor));
+ end;
+ SetSelect (Anchor, P, False);
+ end;
+end; { TEditor.SetCurPtr }
+
+
+procedure TEditor.Set_Place_Marker (Element : Byte);
+{ This procedure sets a place marker for the CurPtr if ^K# is pressed. }
+begin
+ if not IsClipboard then
+ Place_Marker[Element] := CurPtr;
+end; { TEditor.Set_Place_Marker }
+
+
+procedure TEditor.Set_Right_Margin;
+{ This procedure will bring up a dialog box }
+{ that allows the user to set Right_Margin. }
+{ Values must be < MaxLineLength and > 9. }
+VAR
+ Code : Integer; { Used for Val conversion. }
+ Margin_Data : TRightMarginRec; { Holds dialog results. }
+ Temp_Value : Sw_Integer; { Holds converted dialog value. }
+begin
+ with Margin_Data do
+ begin
+ Str (Right_Margin, Margin_Position);
+ if EditorDialog (edRightMargin, @Margin_Position) <> cmCancel then
+ begin
+ val (Margin_Position, Temp_Value, Code);
+ if (Temp_Value <= MaxLineLength) and (Temp_Value > 9) then
+ Right_Margin := Temp_Value;
+ end;
+ end;
+end; { TEditor.Set_Right_Margin }
+
+
+procedure TEditor.SetSelect (NewStart, NewEnd : Sw_Word; CurStart : Boolean);
+VAR
+ UFlags : Byte;
+ P : Sw_Word;
+ L : Sw_Word;
+begin
+ if CurStart then
+ P := NewStart
+ else
+ P := NewEnd;
+ UFlags := ufUpdate;
+ if (NewStart <> SelStart) or (NewEnd <> SelEnd) then
+ if (NewStart <> NewEnd) or (SelStart <> SelEnd) then
+ UFlags := ufView;
+ if P <> CurPtr then
+ begin
+ if P > CurPtr then
+ begin
+ L := P - CurPtr;
+ Move (Buffer^[CurPtr + GapLen], Buffer^[CurPtr], L);
+ Inc (CurPos.Y, CountLines (Buffer^[CurPtr], L));
+ CurPtr := P;
+ end
+ else
+ begin
+ L := CurPtr - P;
+ CurPtr := P;
+ Dec (CurPos.Y, CountLines (Buffer^[CurPtr], L));
+ Move (Buffer^[CurPtr], Buffer^[CurPtr + GapLen], L);
+ end;
+ DrawLine := CurPos.Y;
+ DrawPtr := LineStart (P);
+ CurPos.X := CharPos (DrawPtr, P);
+ DelCount := 0;
+ InsCount := 0;
+ SetBufSize (BufLen);
+ end;
+ SelStart := NewStart;
+ SelEnd := NewEnd;
+ Update (UFlags);
+end; { TEditor.Select }
+
+
+procedure TEditor.SetState (AState : Word; Enable : Boolean);
+begin
+ Inherited SetState (AState, Enable);
+ case AState of
+ sfActive: begin
+ if assigned(HScrollBar) then
+ HScrollBar^.SetState (sfVisible, Enable);
+ if assigned(VScrollBar) then
+ VScrollBar^.SetState (sfVisible, Enable);
+ if assigned(Indicator) then
+ Indicator^.SetState (sfVisible, Enable);
+ UpdateCommands;
+ end;
+ sfExposed: if Enable then Unlock;
+ end;
+end; { TEditor.SetState }
+
+
+procedure TEditor.Set_Tabs;
+{ This procedure will bring up a dialog box }
+{ that allows the user to set tab stops. }
+VAR
+ Index : Sw_Integer; { Index into string array. }
+ Tab_Data : TTabStopRec; { Holds dialog results. }
+begin
+ with Tab_Data do
+ begin
+ { Assign current Tab_Settings to Tab_String. }
+ { Bring up the tab dialog so user can set tabs. }
+ Tab_String := Copy (Tab_Settings, 1, Tab_Stop_Length);
+ if EditorDialog (edSetTabStops, @Tab_String) <> cmCancel then
+ begin
+ { If Tab_String comes back as empty then set Tab_Settings to nil. }
+ { Otherwise, find the last character in Tab_String that is not }
+ { a space and copy Tab_String into Tab_Settings up to that spot. }
+ if Length (Tab_String) = 0 then
+ begin
+ FillChar (Tab_Settings, SizeOf (Tab_Settings), #0);
+ Tab_Settings[0] := #0;
+ Exit;
+ end
+ else
+ begin
+ Index := Length (Tab_String);
+ while Tab_String[Index] <= #32 do
+ Dec (Index);
+ Tab_Settings := Copy (Tab_String, 1, Index);
+ end;
+ end;
+ end;
+end; { TEditor.Set_Tabs }
+
+
+procedure TEditor.StartSelect;
+begin
+ HideSelect;
+ Selecting := True;
+end; { TEditor.StartSelect }
+
+
+procedure TEditor.Store (var S : Objects.TStream);
+begin
+ Inherited Store (S);
+ PutPeerViewPtr (S, HScrollBar);
+ PutPeerViewPtr (S, VScrollBar);
+ PutPeerViewPtr (S, Indicator);
+ S.Write (BufSize, SizeOf (BufSize));
+ S.Write (Canundo, SizeOf (Canundo));
+ S.Write (AutoIndent, SizeOf (AutoIndent));
+ S.Write (Line_Number, SizeOf (Line_Number));
+ S.Write (Place_Marker, SizeOf (Place_Marker));
+ S.Write (Right_Margin, SizeOf (Right_Margin));
+ S.Write (Tab_Settings, SizeOf (Tab_Settings));
+ S.Write (Word_Wrap, SizeOf (Word_Wrap));
+end; { Editor.Store }
+
+
+procedure TEditor.Tab_Key (Select_Mode : Byte);
+{ This function determines if we are in overstrike or insert mode, }
+{ and then moves the cursor if overstrike, or adds spaces if insert. }
+VAR
+ E : Sw_Word; { End of current line. }
+ Index : Sw_Integer; { Loop counter. }
+ Position : Sw_Integer; { CurPos.X position. }
+ S : Sw_Word; { Start of current line. }
+ Spaces : array [1..80] of Char; { Array to hold spaces for insertion. }
+begin
+ E := LineEnd (CurPtr);
+ S := LineStart (CurPtr);
+ { Find the current horizontal cursor position. }
+ { Now loop through the Tab_Settings string and }
+ { find the next available tab stop. }
+ Position := CurPos.X + 1;
+ repeat
+ Inc (Position);
+ until (Tab_Settings[Position] <> #32) or (Position >= Ord (Tab_Settings[0]));
+ E := CurPos.X;
+ Index := 1;
+ { Now we enter a loop to go to the next tab position. }
+ { If we are in overwrite mode, we just move the cursor }
+ { through the text to the next tab stop. If we are in }
+ { insert mode, we add spaces to the Spaces array for }
+ { the number of times we loop. }
+ while Index < Position - E do
+ begin
+ if Overwrite then
+ begin
+ if (Position > LineEnd (CurPtr) - LineStart (CurPtr))
+ or (Position > Ord (Tab_Settings[0])) then
+ begin
+ SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
+ Exit;
+ end
+ else
+ if CurPtr < BufLen then
+ SetCurPtr (NextChar (CurPtr), Select_Mode);
+ end
+ else
+ begin
+ if (Position > Right_Margin) or (Position > Ord (Tab_Settings[0])) then
+ begin
+ SetCurPtr (LineStart (LineMove (CurPtr, 1)), Select_Mode);
+ Exit;
+ end
+ else
+ Spaces[Index] := #32;
+ end;
+ Inc (Index);
+ end;
+ { If we are insert mode, we insert spaces to the next tab stop. }
+ { When we're all done, the cursor will be sitting on the new tab stop. }
+ if not OverWrite then
+ InsertText (@Spaces, Index - 1, False);
+end; { TEditor.Tab_Key }
+
+
+procedure TEditor.ToggleInsMode;
+begin
+ Overwrite := not Overwrite;
+ SetState (sfCursorIns, not GetState (sfCursorIns));
+end; { TEditor.ToggleInsMode }
+
+
+procedure TEditor.TrackCursor (Center : Boolean);
+begin
+ if Center then
+ ScrollTo (CurPos.X - Size.X + 1, CurPos.Y - Size.Y div 2)
+ else
+ ScrollTo (Max (CurPos.X - Size.X + 1, Min (Delta.X, CurPos.X)),
+ Max (CurPos.Y - Size.Y + 1, Min (Delta.Y, CurPos.Y)));
+end; { TEditor.TrackCursor }
+
+
+procedure TEditor.Undo;
+VAR
+ Length : Sw_Word;
+begin
+ if (DelCount <> 0) or (InsCount <> 0) then
+ begin
+ Update_Place_Markers (DelCount, 0, CurPtr, CurPtr + DelCount);
+ SelStart := CurPtr - InsCount;
+ SelEnd := CurPtr;
+ Length := DelCount;
+ DelCount := 0;
+ InsCount := 0;
+ InsertBuffer (Buffer, CurPtr + GapLen - Length, Length, False, True);
+ end;
+end; { TEditor.Undo }
+
+
+procedure TEditor.Unlock;
+begin
+ if LockCount > 0 then
+ begin
+ Dec (LockCount);
+ if LockCount = 0 then
+ DoUpdate;
+ end;
+end; { TEditor.Unlock }
+
+
+procedure TEditor.Update (AFlags : Byte);
+begin
+ UpdateFlags := UpdateFlags or AFlags;
+ if LockCount = 0 then
+ DoUpdate;
+end; { TEditor.Update }
+
+
+procedure TEditor.UpdateCommands;
+begin
+ SetCmdState (cmUndo, (DelCount <> 0) or (InsCount <> 0));
+ if not IsClipboard then
+ begin
+ SetCmdState (cmCut, HasSelection);
+ SetCmdState (cmCopy, HasSelection);
+ SetCmdState (cmPaste, assigned(Clipboard) and (Clipboard^.HasSelection));
+ end;
+ SetCmdState (cmClear, HasSelection);
+ SetCmdState (cmFind, True);
+ SetCmdState (cmReplace, True);
+ SetCmdState (cmSearchAgain, True);
+end; { TEditor.UpdateCommands }
+
+
+procedure TEditor.Update_Place_Markers (AddCount : Word; KillCount : Word;
+ StartPtr,EndPtr : Sw_Word);
+{ This procedure updates the position of the place markers }
+{ as the user inserts and deletes text in the document. }
+VAR
+ Element : Byte; { Place_Marker array element to traverse array with. }
+begin
+ for Element := 1 to 10 do
+ begin
+ if AddCount > 0 then
+ begin
+ if (Place_Marker[Element] >= Curptr)
+ and (Place_Marker[Element] <> 0) then
+ Place_Marker[Element] := Place_Marker[Element] + AddCount;
+ end
+ else
+ begin
+ if Place_Marker[Element] >= StartPtr then
+ begin
+ if (Place_Marker[Element] >= StartPtr) and
+ (Place_Marker[Element] < EndPtr) then
+ Place_marker[Element] := 0
+ else
+ begin
+ if integer (Place_Marker[Element]) - integer (KillCount) > 0 then
+ Place_Marker[Element] := Place_Marker[Element] - KillCount
+ else
+ Place_Marker[Element] := 0;
+ end;
+ end;
+ end;
+ end;
+ if AddCount > 0 then
+ BlankLine := BlankLine + AddCount
+ else
+ begin
+ if integer (BlankLine) - Integer (KillCount) > 0 then
+ BlankLine := BlankLine - KillCount
+ else
+ BlankLine := 0;
+ end;
+end; { TEditor.Update_Place_Markers }
+
+
+function TEditor.Valid (Command : Word) : Boolean;
+begin
+ Valid := IsValid;
+end; { TEditor.Valid }
+
+
+{****************************************************************************
+ TMEMO
+****************************************************************************}
+
+constructor TMemo.Load (var S : Objects.TStream);
+VAR
+ Length : Sw_Word;
+begin
+ Inherited Load (S);
+ S.Read (Length, SizeOf (Length));
+ if IsValid then
+ begin
+ S.Read (Buffer^[BufSize - Length], Length);
+ SetBufLen (Length);
+ end
+ else
+ S.Seek (S.GetPos + Length);
+end; { TMemo.Load }
+
+
+function TMemo.DataSize : Sw_Word;
+begin
+ DataSize := BufSize + SizeOf (Sw_Word);
+end; { TMemo.DataSize }
+
+
+procedure TMemo.GetData (var Rec);
+VAR
+ Data : TMemoData absolute Rec;
+begin
+ Data.Length := BufLen;
+ Move (Buffer^, Data.Buffer, CurPtr);
+ Move (Buffer^[CurPtr + GapLen], Data.Buffer[CurPtr], BufLen - CurPtr);
+ FillChar (Data.Buffer[BufLen], BufSize - BufLen, 0);
+end; { TMemo.GetData }
+
+
+function TMemo.GetPalette : PPalette;
+CONST
+ P : String[Length (CMemo)] = CMemo;
+begin
+ GetPalette := PPalette(@P);
+end; { TMemo.GetPalette }
+
+
+procedure TMemo.HandleEvent (var Event : Drivers.TEvent);
+begin
+ if (Event.What <> Drivers.evKeyDown) or (Event.KeyCode <> Drivers.kbTab) then
+ Inherited HandleEvent (Event);
+end; { TMemo.HandleEvent }
+
+
+procedure TMemo.SetData (var Rec);
+VAR
+ Data : TMemoData absolute Rec;
+begin
+ Move (Data.Buffer, Buffer^[BufSize - Data.Length], Data.Length);
+ SetBufLen (Data.Length);
+end; { TMemo.SetData }
+
+
+procedure TMemo.Store (var S : Objects.TStream);
+begin
+ Inherited Store (S);
+ S.Write (BufLen, SizeOf (BufLen));
+ S.Write (Buffer^, CurPtr);
+ S.Write (Buffer^[CurPtr + GapLen], BufLen - CurPtr);
+end; { TMemo.Store }
+
+
+{****************************************************************************
+ TFILEEDITOR
+****************************************************************************}
+
+
+constructor TFileEditor.Init (var Bounds : TRect;
+ AHScrollBar, AVScrollBar : PScrollBar;
+ AIndicator : PIndicator;
+ AFileName : FNameStr);
+begin
+ Inherited Init (Bounds, AHScrollBar, AVScrollBar, AIndicator, 0);
+ if AFileName <> '' then
+ begin
+ FileName := FExpand (AFileName);
+ if IsValid then
+ IsValid := LoadFile;
+ end;
+end; { TFileEditor.Init }
+
+
+constructor TFileEditor.Load (var S : Objects.TStream);
+VAR
+ SStart,SEnd,Curs : Sw_Word;
+begin
+ Inherited Load (S);
+ BufSize := 0;
+ S.Read (FileName[0], SizeOf (Byte));
+ S.Read (Filename[1], Length (FileName));
+ if IsValid then
+ IsValid := LoadFile;
+ S.Read (SStart, SizeOf (SStart));
+ S.Read (SEnd, SizeOf (SEnd));
+ S.Read (Curs, SizeOf (Curs));
+ if IsValid and (SEnd <= BufLen) then
+ begin
+ SetSelect (SStart, SEnd, Curs = SStart);
+ TrackCursor (True);
+ end;
+end; { TFileEditor.Load }
+
+
+procedure TFileEditor.DoneBuffer;
+begin
+ ReAllocMem(Buffer, 0);
+end; { TFileEditor.DoneBuffer }
+
+
+procedure TFileEditor.HandleEvent (var Event : Drivers.TEvent);
+begin
+ Inherited HandleEvent (Event);
+ case Event.What of
+ Drivers.evCommand:
+ case Event.Command of
+ cmSave : Save;
+ cmSaveAs : SaveAs;
+ cmSaveDone : if Save then
+ Message (Owner, Drivers.evCommand, cmClose, nil);
+ else
+ Exit;
+ end;
+ else
+ Exit;
+ end;
+ ClearEvent (Event);
+end; { TFileEditor.HandleEvent }
+
+
+procedure TFileEditor.InitBuffer;
+begin
+ Assert(Buffer = nil, 'TFileEditor.InitBuffer: Buffer is not nil');
+ ReAllocMem(Buffer, MinBufLength);
+ BufSize := MinBufLength;
+end; { TFileEditor.InitBuffer }
+
+
+function TFileEditor.LoadFile: Boolean;
+VAR
+ Length : Sw_Word;
+ FSize : Longint;
+ FRead : Sw_Integer;
+ F : File;
+begin
+ LoadFile := False;
+ Length := 0;
+ Assign(F, FileName);
+ Reset(F, 1);
+ if IOResult <> 0 then
+ EditorDialog(edReadError, @FileName)
+ else
+ begin
+ FSize := FileSize(F);
+ if (FSize > MaxBufLength) or not SetBufSize(FSize) then
+ EditorDialog(edOutOfMemory, nil)
+ else
+ begin
+ BlockRead(F, Buffer^[BufSize-FSize], FSize, FRead);
+ if (IOResult <> 0) or (FRead<>FSize) then
+ EditorDialog(edReadError, @FileName)
+ else
+ begin
+ LoadFile := True;
+ Length := FRead;
+ end;
+ end;
+ Close(F);
+ end;
+ SetBufLen(Length);
+end; { TFileEditor.LoadFile }
+
+
+function TFileEditor.Save : Boolean;
+begin
+ if FileName = '' then
+ Save := SaveAs
+ else
+ Save := SaveFile;
+end; { TFileEditor.Save }
+
+
+function TFileEditor.SaveAs : Boolean;
+begin
+ SaveAs := False;
+ if EditorDialog (edSaveAs, @FileName) <> cmCancel then
+ begin
+ FileName := FExpand (FileName);
+ Message (Owner, Drivers.evBroadcast, cmUpdateTitle, nil);
+ SaveAs := SaveFile;
+ if IsClipboard then
+ FileName := '';
+ end;
+end; { TFileEditor.SaveAs }
+
+
+function TFileEditor.SaveFile : Boolean;
+VAR
+ F : File;
+ BackupName : Objects.FNameStr;
+ D : DOS.DirStr;
+ N : DOS.NameStr;
+ E : DOS.ExtStr;
+begin
+ SaveFile := False;
+ if Flags and efBackupFiles <> 0 then
+ begin
+ FSplit (FileName, D, N, E);
+ BackupName := D + N + '.bak';
+ Assign (F, BackupName);
+ Erase (F);
+ Assign (F, FileName);
+ Rename (F, BackupName);
+ InOutRes := 0;
+ end;
+ Assign (F, FileName);
+ Rewrite (F, 1);
+ if IOResult <> 0 then
+ EditorDialog (edCreateError, @FileName)
+ else
+ begin
+ BlockWrite (F, Buffer^, CurPtr);
+ BlockWrite (F, Buffer^[CurPtr + GapLen], BufLen - CurPtr);
+ if IOResult <> 0 then
+ EditorDialog (edWriteError, @FileName)
+ else
+ begin
+ Modified := False;
+ Update (ufUpdate);
+ SaveFile := True;
+ end;
+ Close (F);
+ end;
+end; { TFileEditor.SaveFile }
+
+
+function TFileEditor.SetBufSize (NewSize : Sw_Word) : Boolean;
+VAR
+ N : Sw_Word;
+begin
+ SetBufSize := False;
+ if NewSize = 0 then
+ NewSize := MinBufLength
+ else
+ if NewSize > (MaxBufLength-MinBufLength) then
+ NewSize := MaxBufLength
+ else
+ NewSize := (NewSize + (MinBufLength-1)) and (MaxBufLength and (not (MinBufLength-1)));
+ if NewSize <> BufSize then
+ begin
+ if NewSize > BufSize then ReAllocMem(Buffer, NewSize);
+ N := BufLen - CurPtr + DelCount;
+ Move(Buffer^[BufSize - N], Buffer^[NewSize - N], N);
+ if NewSize < BufSize then ReAllocMem(Buffer, NewSize);
+ BufSize := NewSize;
+ GapLen := BufSize - BufLen;
+ end;
+ SetBufSize := True;
+end; { TFileEditor.SetBufSize }
+
+
+procedure TFileEditor.Store (var S : Objects.TStream);
+begin
+ Inherited Store (S);
+ S.Write (FileName, Length (FileName) + 1);
+ S.Write (SelStart, SizeOf (SelStart));
+ S.Write (SelEnd, SizeOf (SelEnd));
+ S.Write (CurPtr, SizeOf (CurPtr));
+end; { TFileEditor.Store }
+
+
+procedure TFileEditor.UpdateCommands;
+begin
+ Inherited UpdateCommands;
+ SetCmdState (cmSave, True);
+ SetCmdState (cmSaveAs, True);
+ SetCmdState (cmSaveDone, True);
+end; { TFileEditor.UpdateCommands }
+
+
+function TFileEditor.Valid (Command : Word) : Boolean;
+VAR
+ D : Integer;
+begin
+ if Command = cmValid then
+ Valid := IsValid
+ else
+ begin
+ Valid := True;
+ if Modified then
+ begin
+ if FileName = '' then
+ D := edSaveUntitled
+ else
+ D := edSaveModify;
+ case EditorDialog (D, @FileName) of
+ cmYes : Valid := Save;
+ cmNo : Modified := False;
+ cmCancel : Valid := False;
+ end;
+ end;
+ end;
+end; { TFileEditor.Valid }
+
+
+{****************************************************************************
+ TEDITWINDOW
+****************************************************************************}
+
+constructor TEditWindow.Init (var Bounds : TRect;
+ FileName : Objects.FNameStr;
+ ANumber : Integer);
+var
+ HScrollBar : PScrollBar;
+ VScrollBar : PScrollBar;
+ Indicator : PIndicator;
+ R : TRect;
+begin
+ Inherited Init (Bounds, '', ANumber);
+ Options := Options or ofTileable;
+
+ R.Assign (18, Size.Y - 1, Size.X - 2, Size.Y);
+ HScrollBar := New (PScrollBar, Init (R));
+ HScrollBar^.Hide;
+ Insert (HScrollBar);
+
+ R.Assign (Size.X - 1, 1, Size.X, Size.Y - 1);
+ VScrollBar := New (PScrollBar, Init (R));
+ VScrollBar^.Hide;
+ Insert (VScrollBar);
+
+ R.Assign (2, Size.Y - 1, 16, Size.Y);
+ Indicator := New (PIndicator, Init (R));
+ Indicator^.Hide;
+ Insert (Indicator);
+
+ GetExtent (R);
+ R.Grow (-1, -1);
+ Editor := New (PFileEditor, Init (R, HScrollBar, VScrollBar, Indicator, FileName));
+ Insert (Editor);
+end; { TEditWindow.Init }
+
+
+constructor TEditWindow.Load (var S : Objects.TStream);
+begin
+ Inherited Load (S);
+ GetSubViewPtr (S, Editor);
+end; { TEditWindow.Load }
+
+
+procedure TEditWindow.Close;
+begin
+ if Editor^.IsClipboard then
+ Hide
+ else
+ Inherited Close;
+end; { TEditWindow.Close }
+
+
+function TEditWindow.GetTitle (MaxSize : Sw_Integer) : TTitleStr;
+begin
+ if Editor^.IsClipboard then
+ GetTitle := sClipboard
+ else
+ if Editor^.FileName = '' then
+ GetTitle := sUntitled
+ else
+ GetTitle := Editor^.FileName;
+end; { TEditWindow.GetTile }
+
+
+procedure TEditWindow.HandleEvent (var Event : Drivers.TEvent);
+begin
+ Inherited HandleEvent (Event);
+ if (Event.What = Drivers.evBroadcast) then
+ { and (Event.Command = cmUpdateTitle) then }
+ { Changed if statement above so I could test for cmBlugeonStats. }
+ { Stats would not show up when loading a file until a key was pressed. }
+ case Event.Command of
+ cmUpdateTitle :
+ begin
+ Frame^.DrawView;
+ ClearEvent (Event);
+ end;
+ cmBludgeonStats :
+ begin
+ Editor^.Update (ufStats);
+ ClearEvent (Event);
+ end;
+ end;
+end; { TEditWindow.HandleEvent }
+
+
+procedure TEditWindow.SizeLimits(var Min, Max: TPoint);
+begin
+ inherited SizeLimits(Min, Max);
+ Min.X := 23;
+end;
+
+
+procedure TEditWindow.Store (var S : Objects.TStream);
+begin
+ Inherited Store (S);
+ PutSubViewPtr (S, Editor);
+end; { TEditWindow.Store }
+
+
+procedure RegisterEditors;
+begin
+ RegisterType (REditor);
+ RegisterType (RMemo);
+ RegisterType (RFileEditor);
+ RegisterType (RIndicator);
+ RegisterType (REditWindow);
+end; { RegisterEditors }
+
+
+end. { Unit NewEdit }
diff --git a/packages/fv/src/fvcommon.pas b/packages/fv/src/fvcommon.pas
new file mode 100644
index 0000000000..9e1ba4a10c
--- /dev/null
+++ b/packages/fv/src/fvcommon.pas
@@ -0,0 +1,371 @@
+{********************[ COMMON UNIT ]***********************}
+{ }
+{ System independent COMMON TYPES & DEFINITIONS }
+{ }
+{ Parts Copyright (c) 1997 by Balazs Scheidler }
+{ bazsi@balabit.hu }
+{ }
+{ Parts Copyright (c) 1999, 2000 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@projectent.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ - Speed Pascal 1.0+ (32 Bit) }
+{ - C'T patch to BP (16 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Who Fix }
+{ ------- -------- --- ---------------------------- }
+{ 0.1 12 Jul 97 Bazsi Initial implementation }
+{ 0.2 18 Jul 97 Bazsi Linux specific error codes }
+{ 0.2.2 28 Jul 97 Bazsi Base error code for Video }
+{ 0.2.3 29 Jul 97 Bazsi Basic types added (PByte etc) }
+{ 0.2.5 08 Aug 97 Bazsi Error handling code added }
+{ 0.2.6 06 Sep 97 Bazsi Base code for keyboard }
+{ 0.2.7 06 Nov 97 Bazsi Base error code for filectrl }
+{ 0.2.8 21 Jan 99 LdB Max data sizes added. }
+{ 0.2.9 22 Jan 99 LdB General array types added. }
+{ 0.3.0 27 Oct 99 LdB Delphi3+ MaxAvail, MemAvail }
+{ 0.4.0 14 Nov 00 LdB Revamp of whole unit }
+{**********************************************************}
+
+UNIT FVCommon;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{$ifdef win32}
+ uses
+ Windows;
+{$endif}
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ SYSTEM ERROR BASE CONSTANTS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ The following ranges have been defined for error codes: }
+{---------------------------------------------------------------------------}
+{ 0 - 1000 OS dependant error codes }
+{ 1000 - 10000 API reserved error codes }
+{ 10000 - Add-On unit error codes }
+{---------------------------------------------------------------------------}
+
+{---------------------------------------------------------------------------}
+{ DEFINED BASE ERROR CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ errOk = 0; { No error }
+ errVioBase = 1000; { Video base offset }
+ errKbdBase = 1010; { Keyboard base offset }
+ errFileCtrlBase = 1020; { File IO base offset }
+ errMouseBase = 1030; { Mouse base offset }
+
+{---------------------------------------------------------------------------}
+{ MAXIUM DATA SIZES }
+{---------------------------------------------------------------------------}
+CONST
+{$IFDEF BIT_16} { 16 BIT DEFINITION }
+ MaxBytes = 65520; { Maximum data size }
+{$ENDIF}
+{$IFDEF BIT_32} { 32 BIT DEFINITION }
+ MaxBytes = 128*1024*1024; { Maximum data size }
+{$ENDIF}
+ MaxWords = MaxBytes DIV SizeOf(Word); { Max words }
+ MaxInts = MaxBytes DIV SizeOf(Integer); { Max integers }
+ MaxLongs = MaxBytes DIV SizeOf(LongInt); { Max longints }
+ MaxPtrs = MaxBytes DIV SizeOf(Pointer); { Max pointers }
+ MaxReals = MaxBytes DIV SizeOf(Real); { Max reals }
+ MaxStr = MaxBytes DIV SizeOf(String); { Max strings }
+
+{***************************************************************************}
+{ PUBLIC TYPE DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ CPU TYPE DEFINITIONS }
+{---------------------------------------------------------------------------}
+TYPE
+{$IFDEF BIT_32} { 32 BIT CODE }
+ CPUWord = Longint; { CPUWord is 32 bit }
+ CPUInt = Longint; { CPUInt is 32 bit }
+{$ELSE} { 16 BIT CODE }
+ CPUWord = Word; { CPUWord is 16 bit }
+ CPUInt = Integer; { CPUInt is 16 bit }
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ 16/32 BIT SWITCHED TYPE CONSTANTS }
+{---------------------------------------------------------------------------}
+TYPE
+{$IFDEF BIT_16} { 16 BIT DEFINITIONS }
+ Sw_Word = Word; { Standard word }
+ Sw_Integer = Integer; { Standard integer }
+{$ENDIF}
+{$IFDEF BIT_32} { 32 BIT DEFINITIONS }
+ Sw_Word = Cardinal; { Long integer now }
+ Sw_Integer = LongInt; { Long integer now }
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ GENERAL ARRAYS }
+{---------------------------------------------------------------------------}
+TYPE
+ TByteArray = ARRAY [0..MaxBytes-1] Of Byte; { Byte array }
+ PByteArray = ^TByteArray; { Byte array pointer }
+
+ TWordArray = ARRAY [0..MaxWords-1] Of Word; { Word array }
+ PWordArray = ^TWordArray; { Word array pointer }
+
+ TIntegerArray = ARRAY [0..MaxInts-1] Of Integer; { Integer array }
+ PIntegerArray = ^TIntegerArray; { Integer array pointer }
+
+ TLongIntArray = ARRAY [0..MaxLongs-1] Of LongInt; { LongInt array }
+ PLongIntArray = ^TLongIntArray; { LongInt array pointer }
+
+ TRealArray = Array [0..MaxReals-1] Of Real; { Real array }
+ PRealarray = ^TRealArray; { Real array pointer }
+
+ TPointerArray = Array [0..MaxPtrs-1] Of Pointer; { Pointer array }
+ PPointerArray = ^TPointerArray; { Pointer array ptr }
+
+ TStrArray = Array [0..MaxStr-1] Of String; { String array }
+ PStrArray = ^TStrArray; { String array ptr }
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{-GetErrorCode-------------------------------------------------------
+Returns the last error code and resets ErrorCode to errOk.
+07/12/97 Bazsi
+---------------------------------------------------------------------}
+FUNCTION GetErrorCode: LongInt;
+
+{-GetErrorInfo-------------------------------------------------------
+Returns the info assigned to the previous error, doesn't reset the
+value to nil. Would usually only be called if ErrorCode <> errOk.
+07/12/97 Bazsi
+---------------------------------------------------------------------}
+FUNCTION GetErrorInfo: Pointer;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MINIMUM AND MAXIMUM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+FUNCTION Min (I, J: Sw_Integer): Sw_Integer;
+FUNCTION Max (I, J: Sw_Integer): Sw_Integer;
+
+{-MinimumOf----------------------------------------------------------
+Given two real numbers returns the minimum real of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MinimumOf (A, B: Real): Real;
+
+{-MaximumOf----------------------------------------------------------
+Given two real numbers returns the maximum real of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MaximumOf (A, B: Real): Real;
+
+{-MinIntegerOf-------------------------------------------------------
+Given two integer values returns the lowest integer of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MinIntegerOf (A, B: Integer): Integer;
+
+{-MaxIntegerof-------------------------------------------------------
+Given two integer values returns the biggest integer of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MaxIntegerOf (A, B: Integer): Integer;
+
+{-MinLongIntOf-------------------------------------------------------
+Given two long integers returns the minimum longint of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MinLongIntOf (A, B: LongInt): LongInt;
+
+{-MaxLongIntOf-------------------------------------------------------
+Given two long integers returns the maximum longint of the two.
+04Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MaxLongIntOf (A, B: LongInt): LongInt;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MISSING DELPHI3 ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{ ******************************* REMARK ****************************** }
+{ Delphi 3+ does not define these standard routines so I have made }
+{ some public functions here to complete compatability. }
+{ ****************************** END REMARK *** Leon de Boer, 14Aug98 * }
+
+{-MemAvail-----------------------------------------------------------
+Returns the free memory available under Delphi 3+.
+14Aug98 LdB
+---------------------------------------------------------------------}
+FUNCTION MemAvail: LongInt;
+
+{-MaxAvail-----------------------------------------------------------
+Returns the max free memory block size available under Delphi 3+.
+14Aug98 LdB
+---------------------------------------------------------------------}
+FUNCTION MaxAvail: LongInt;
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ ErrorCode: Longint = errOk; { Last error code }
+ ErrorInfo: Pointer = Nil; { Last error info }
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{$IFDEF PPC_DELPHI3} { DELPHI 3+ COMPILER }
+USES WinTypes, WinProcs; { Stardard units }
+{$ENDIF}
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ GetErrorCode -> Platforms ALL - Updated 12Jul97 Bazsi }
+{---------------------------------------------------------------------------}
+FUNCTION GetErrorCode: LongInt;
+BEGIN
+ GetErrorCode := ErrorCode; { Return last error }
+ ErrorCode := 0; { Now clear errorcode }
+END;
+
+{---------------------------------------------------------------------------}
+{ GetErrorInfo -> Platforms ALL - Updated 12Jul97 Bazsi }
+{---------------------------------------------------------------------------}
+FUNCTION GetErrorInfo: Pointer;
+BEGIN
+ GetErrorInfo := ErrorInfo; { Return errorinfo ptr }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MINIMUM AND MAXIMUM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+FUNCTION Min (I, J: Sw_Integer): Sw_Integer;
+BEGIN
+ If (I < J) Then Min := I Else Min := J; { Select minimum }
+END;
+
+FUNCTION Max (I, J: Sw_Integer): Sw_Integer;
+BEGIN
+ If (I > J) Then Max := I Else Max := J; { Select maximum }
+END;
+
+
+{---------------------------------------------------------------------------}
+{ MinimumOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MinimumOf (A, B: Real): Real;
+BEGIN
+ If (B < A) Then MinimumOf := B { B smaller take it }
+ Else MinimumOf := A; { Else take A }
+END;
+
+{---------------------------------------------------------------------------}
+{ MaximumOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MaximumOf (A, B: Real): Real;
+BEGIN
+ If (B > A) Then MaximumOf := B { B bigger take it }
+ Else MaximumOf := A; { Else take A }
+END;
+
+{---------------------------------------------------------------------------}
+{ MinIntegerOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MinIntegerOf (A, B: Integer): Integer;
+BEGIN
+ If (B < A) Then MinIntegerOf := B { B smaller take it }
+ Else MinIntegerOf := A; { Else take A }
+END;
+
+{---------------------------------------------------------------------------}
+{ MaxIntegerOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MaxIntegerOf (A, B: Integer): Integer;
+BEGIN
+ If (B > A) Then MaxIntegerOf := B { B bigger take it }
+ Else MaxIntegerOf := A; { Else take A }
+END;
+
+{---------------------------------------------------------------------------}
+{ MinLongIntOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MinLongIntOf (A, B: LongInt): LongInt;
+BEGIN
+ If (B < A) Then MinLongIntOf := B { B smaller take it }
+ Else MinLongIntOf := A; { Else take A }
+END;
+
+{---------------------------------------------------------------------------}
+{ MaxLongIntOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 04Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MaxLongIntOf (A, B: LongInt): LongInt;
+BEGIN
+ If (B > A) Then MaxLongIntOf := B { B bigger take it }
+ Else MaxLongIntOf := A; { Else take A }
+END;
+
+FUNCTION MemAvail: LongInt;
+BEGIN
+ { Unlimited }
+ MemAvail:=high(longint);
+END;
+
+{---------------------------------------------------------------------------}
+{ MaxAvail -> Platforms WIN/NT - Updated 14Aug98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MaxAvail: LongInt;
+BEGIN
+ { Unlimited }
+ MaxAvail:=high(longint);
+END;
+
+END.
diff --git a/packages/fv/src/fvconsts.pas b/packages/fv/src/fvconsts.pas
new file mode 100644
index 0000000000..5d3c82f421
--- /dev/null
+++ b/packages/fv/src/fvconsts.pas
@@ -0,0 +1,642 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of DIALOGS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@starwon.com.au - backup e-mail addr }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+unit FVConsts;
+interface
+
+{
+ The FVConsts unit declares constants for all object type IDs used in the
+ FreeVision library. They have been moved here for easier management. No
+ values for views declared in TV 2.0 have been changed from so that original
+ resource files may still be used.
+}
+const
+ { Views Unit }
+ idView = 1;
+ idFrame = 2;
+ idScrollBar = 3;
+ idScroller = 4;
+ idListViewer = 5;
+ idGroup = 6;
+ idWindow = 7;
+
+ { Dialogs Unit 10 - ? }
+ idDialog = 10;
+ idInputLine = 11;
+ idButton = 12;
+ idCluster = 13;
+ idRadioButtons = 14;
+ idCheckBoxes = 15;
+ idListBox = 16;
+ idStaticText = 17;
+ idLabel = 18;
+ idHistory = 19;
+ idParamText = 20;
+ idCommandCheckBoxes = 21;
+ idCommandRadioButtons = 22;
+ idCommandIcon = 23;
+ idBrowseButton = 24;
+ idEditListBox = 25;
+ idModalInputLine = 26;
+ idMultiCheckBoxes = 27;
+ idListDlg = 28;
+
+ { App Unit }
+ idBackground = 30;
+ idDesktop = 31;
+
+ { Config Unit }
+ idConfig = 32;
+ idMouseDlg = 33;
+ idVideoDlg = 34;
+ idClickTester = 35;
+
+ { Menus Unit }
+ idMenuBar = 40;
+ idMenuBox = 41;
+ idStatusLine = 42;
+ idMenuPopup = 43;
+ idMenuButton = 44;
+
+ { Objects Unit }
+ idCollection = 50;
+ idStringCollection = 51;
+ idStringList = 52;
+ idStrListMaker = 52;
+ idStrCollection = 69;
+
+ { Resource Unit }
+ idMemStringList = 52;
+
+ { Tabs Unit }
+ idTab = 55;
+
+ { StdDlg Unit }
+ idFileInputLine = 60;
+ idFileCollection = 61;
+ idFileList = 62;
+ idFileInfoPane = 63;
+ idFileDialog = 64;
+ idDirCollection = 65;
+ idDirListBox = 66;
+ idChDirDialog = 67;
+ idSortedListBox = 68;
+ idEditChDirDialog = 69;
+
+ { Editors Unit 70 - ? }
+ idEditor = 70;
+ idMemo = 71;
+ idFileEditor = 72;
+ idIndicator = 73;
+ idEditWindow = 74;
+ idEditWindowCollection = 75; { this value may need to be changed }
+ idEditorEngine = 76;
+
+ { Validate Unit }
+ idPXPictureValidator = 80;
+ idFilterValidator = 81;
+ idRangeValidator = 82;
+ idStringLookupValidator = 83;
+ idRealValidator = 84;
+ idByteValidator = 85;
+ idIntegerValidator = 86;
+ idSingleValidator = 87;
+ idWordValidator = 88;
+ idDateValidator = 89;
+ idTimeValidator = 90;
+
+ { Outline Unit }
+ idOutline = 91;
+
+ { ColorSel Unit }
+ idColorSelector = 92;
+ idMonoSelector = 93;
+ idColorDisplay = 94;
+ idColorGroupList = 95;
+ idColorItemList = 96;
+ idColorDialog = 97;
+
+ { TimedDlg Unit }
+ idTimedDialog = 98;
+ idTimedDialogText = 99;
+
+ { Statuses Unit }
+ idStatus = 300;
+ idStatusDlg = 301;
+ idStatusMessageDlg = 302;
+ idGauge = 303;
+ idArrowGauge = 304;
+ idBarGauge = 305;
+ idPercentGauge = 306;
+ idSpinnerGauge = 307;
+ idAppStatus = 308;
+ idHeapMinAvail = 309;
+ idHeapMemAvail = 310;
+
+ { FVList Unit }
+
+ { ColorTxt Unit }
+ idColoredText = 611;
+
+ { InpLong Unit }
+ idInputLong = 711;
+
+ { ASCIITab Unit }
+ idTable = 10030;
+ idReport = 10031;
+ idASCIIChart = 10032;
+
+{
+ The FVConsts unit contains all command constants used in the FreeVision
+ library. They have been extracted from their original units and placed here
+ for easier maintainence and modification to remove conflicts, such as Borland
+ created with the cmChangeDir constant in the StdDlg and App units.
+}
+
+const
+ { App Unit }
+ cmNew = 30;
+ cmOpen = 31;
+ cmSave = 32;
+ cmSaveAs = 33;
+ cmSaveAll = 34;
+ cmSaveDone = 39; {! Needs to match value in app.pas}
+ cmChangeDir = 35; {!}
+ cmDosShell = 36; {!}
+ cmCloseAll = 37;
+ cmDelete = 38;
+ cmEdit = 40;
+ cmAbout = 41;
+ cmDesktopLoad = 42;
+ cmDesktopStore = 43;
+ cmNewDesktop = 44;
+ cmNewMenuBar = 45;
+ cmNewStatusLine = 46;
+ cmNewVideo = 47;
+ cmTransfer = 48;
+ cmResizeApp = 49;
+ cmQuitApp = 57;
+
+ cmRecordHistory = 60;
+ cmGrabDefault = 61;
+ cmReleaseDefault = 62;
+
+ cmHelpContents = 256;
+ cmHelpIndex = 257;
+ cmHelpTopic = 258;
+ cmHelpPrev = 259;
+ cmHelpUsingHelp = 260;
+ cmHelpAbout = 261;
+
+ cmBrowseDir = 262;
+ cmBrowseFile = 263;
+
+ { Views Unit }
+ cmValid = 0;
+ cmQuit = 1;
+ cmError = 2;
+ cmMenu = 3;
+ cmClose = 4;
+ cmZoom = 5;
+ cmResize = 6;
+ cmNext = 7;
+ cmPrev = 8;
+ cmHelp = 9;
+ cmOK = 10;
+ cmCancel = 11;
+ cmYes = 12;
+ cmNo = 13;
+ cmDefault = 14;
+ cmCut = 20;
+ cmCopy = 21;
+ cmPaste = 22;
+ cmUndo = 23;
+ cmClear = 24;
+ cmTile = 25;
+ cmCascade = 26;
+ cmHide = 27;
+ cmReceivedFocus = 50;
+ cmReleasedFocus = 51;
+ cmCommandSetChanged = 52;
+ cmScrollBarChanged = 53;
+ cmScrollBarClicked = 54;
+ cmSelectWindowNum = 55;
+ cmListItemSelected = 56;
+
+ { ColorSel Unit }
+ cmColorForegroundChanged = 71;
+ cmColorBackgroundChanged = 72;
+ cmColorSet = 73;
+ cmNewColorItem = 74;
+ cmNewColorIndex = 75;
+ cmSaveColorIndex = 76;
+
+ { StdDlg Unit 800 - ? }
+ cmFileOpen = 800; { Returned from TFileDialog when Open pressed }
+ cmFileReplace = 801; { Returned from TFileDialog when Replace pressed }
+ cmFileClear = 802; { Returned from TFileDialog when Clear pressed }
+ cmFileInit = 803; { Used by TFileDialog internally }
+ cmRevert = 805; { Used by TChDirDialog internally }
+ cmFileFocused = 806; { A new file was focused in the TFileList }
+ cmFileDoubleClicked = 807; { A file was selected in the TFileList }
+
+ { Config Unit 130-140, 900-999 }
+ cmConfigMouse = 130; { Mouse command disabled by Init if no mouse }
+ cmConfigOpen = 900;
+ cmConfigSave = 901;
+ cmConfigSaveAs = 902;
+ cmConfigMenu = 903;
+ cmConfigColors = 904;
+ cmConfigVideo = 905;
+ cmConfigCO80 = 906;
+ cmConfigBW80 = 907;
+ cmConfigMono = 908;
+ cmClock = 909;
+ cmClockSetFormat = 910;
+
+ { Editors Unit }
+ cmFind = 82;
+ cmReplace = 83;
+ cmSearchAgain = 84;
+ cmPrint = 85;
+ cmRedo = 86;
+ cmJumpLine = 87;
+ cmWindowList = 88;
+ cmCharLeft = 500;
+ cmCharRight = 501;
+ cmWordLeft = 502;
+ cmWordRight = 503;
+ cmLineStart = 504;
+ cmLineEnd = 505;
+ cmLineUp = 506;
+ cmLineDown = 507;
+ cmPageUp = 508;
+ cmPageDown = 509;
+ cmTextStart = 510;
+ cmTextEnd = 511;
+ cmNewLine = 512;
+ cmBackSpace = 513;
+ cmDelChar = 514;
+ cmDelWord = 515;
+ cmDelStart = 516;
+ cmDelEnd = 517;
+ cmDelLine = 518;
+ cmInsMode = 519;
+ cmStartSelect = 520;
+ cmHideSelect = 521;
+ cmEndSelect = 522;
+ cmIndentMode = 523;
+ cmUpdateTitle = 524;
+ cmReformPara = 525;
+ cmTabKey = 526;
+ cmInsertLine = 527;
+ cmScrollUp = 528;
+ cmScrollDown = 529;
+ cmHomePage = 530;
+ cmEndPage = 531;
+ cmJumpMark0 = 532;
+ cmJumpMark1 = 533;
+ cmJumpMark2 = 534;
+ cmJumpMark3 = 535;
+ cmJumpMark4 = 536;
+ cmJumpMark5 = 537;
+ cmJumpMark6 = 538;
+ cmJumpMark7 = 539;
+ cmJumpMark8 = 540;
+ cmJumpMark9 = 541;
+ cmReformDoc = 542;
+ cmSetMark0 = 543;
+ cmSetMark1 = 544;
+ cmSetMark2 = 545;
+ cmSetMark3 = 546;
+ cmSetMark4 = 547;
+ cmSetMark5 = 548;
+ cmSetMark6 = 549;
+ cmSetMark7 = 550;
+ cmSetMark8 = 551;
+ cmSetMark9 = 552;
+ cmSelectWord = 553;
+ cmSaveExit = 554;
+ cmCenterText = 555;
+ cmSetTabs = 556;
+ cmRightMargin = 557;
+ cmWordwrap = 558;
+ cmBludgeonStats = 559;
+ cmPrinterSetup = 560;
+ cmClipboard = 561;
+ cmSpellCheck = 562;
+ cmCopyBlock = 563;
+ cmMoveBlock = 564;
+ cmDelSelect = 565;
+ cmIdentBlock = 566;
+ cmUnidentBlock = 567;
+ cmFileHistory = 600;
+
+ { Statuses Unit }
+ cmStatusUpdate = 300; { note - need to set to valid value }
+ cmStatusDone = 301;
+ cmStatusPause = 302;
+ cmStatusResume = 303;
+
+ cmCursorChanged = 700;
+
+
+{
+ The FVConsts unit declares standard help contexts used in FreeVision. By
+ placing all help contexts in one unit, duplicate help contexts are more
+ easily prevented
+}
+
+const
+
+ hcNoContext = 0;
+ hcDragging = 1;
+ hcOk = 2;
+ hcCancel = 3;
+ hcEdit = 4;
+ hcDelete = 5;
+ hcInsert = 6;
+
+ { App Unit }
+ hcNew = 65281; hcFileNew = hcNew;
+ hcOpen = 65282; hcFileOpen = hcOpen;
+ hcSave = 65283; hcFileSave = hcSave;
+ hcSaveAs = 65284; hcFileSaveAs = hcSaveAs;
+ hcSaveAll = 65285; hcFileSaveAll = hcSaveAll;
+ hcChangeDir = 65286; hcFileChangeDir = hcChangeDir;
+ hcDosShell = 65287; hcFileDOSShell = hcDosShell;
+ hcExit = 65288; hcFileExit = hcExit;
+ hcEditMenu = 65289;
+ hcHelpMenu = 65291;
+ hcHelpContents = 65292;
+ hcHelpIndex = 65293;
+ hcHelpTopic = 65294;
+ hcHelpPrev = 65295;
+ hcHelpUsingHelp = 65296;
+ hcHelpAbout = 65297;
+ hcWindowMenu = 65298;
+ hcUndo = $FF10;
+ hcCut = $FF11;
+ hcCopy = $FF12;
+ hcPaste = $FF13;
+ hcClear = $FF14;
+ hcTile = $FF20;
+ hcCascade = $FF21;
+ hcCloseAll = $FF22;
+ hcResize = $FF23;
+ hcZoom = $FF24;
+ hcNext = $FF25;
+ hcPrev = $FF26;
+ hcClose = $FF27;
+ hcHide = $FF28;
+ hcFileMenu = 65320;
+ hcSearchAndReplace =65325;
+
+ { Editors Unit }
+ hcFile_Menu = 2100;
+{ hcOpen = 2101; }
+{ hcNew = 2102; }
+{ hcSave = 2103; }
+ hcSaveDone = 2104;
+{ hcSaveAs = 2105; }
+{ hcChangeDir = 2106; }
+{ hcShellToDos = 2107; }
+{ hcExit = 2108; }
+ hcFile_Menu_Items = hcExit;
+
+ hcEdit_Menu = 2200;
+{ hcUndo = 2201; }
+{ hcCopy = 2202; }
+{ hcCut = 2203; }
+{ hcPaste = 2204; }
+ hcClipboard = 2205;
+{ hcClear = 2206; }
+ hcSpellCheck = 2207;
+ hcEdit_Menu_Items = hcSpellCheck;
+
+ hcSearch_Menu = 2300;
+ hcFind = 2301;
+ hcReplace = 2302;
+ hcAgain = 2303;
+ hcSearch_Menu_Items = hcAgain;
+
+ hcWindows_Menu = 2400;
+{ hcResize = 2401; }
+{ hcZoom = 2402; }
+{ hcPrev = 2403; }
+{ hcNext = 2404; }
+{ hcClose = 2405; }
+{ hcTile = 2406; }
+{ hcCascade = 2407; }
+ hcWindows_Menu_Items = hcCascade;
+
+ hcDesktop_Menu = 2500;
+ hcLoadDesktop = 2501;
+ hcSaveDesktop = 2502;
+ hcToggleVideo = 2503;
+ hcDesktop_Menu_Items = hcToggleVideo;
+
+ hcMisc_Commands = 2600;
+ hckbShift = 2601;
+ hckbCtrl = 2602;
+ hckbAlt = 2603;
+ hcMisc_Items = hckbAlt;
+
+ hcEditor_Commands = 2700;
+ hcCursor = 2701;
+ hcDeleting = 2702;
+ hcFormatting = 2703;
+ hcMarking = 2704;
+ hcMoving = 2705;
+ hcSaving = 2706;
+ hcSelecting = 2707;
+ hcTabbing = 2708;
+ hcBackSpace = 2709;
+ hcCenterText = 2710;
+ hcCharLeft = 2711;
+ hcCharRight = 2712;
+ hcDelChar = 2713;
+ hcDelEnd = 2714;
+ hcDelLine = 2715;
+ hcDelStart = 2716;
+ hcDelWord = 2717;
+ hcEndPage = 2718;
+ hcHideSelect = 2719;
+ hcHomePage = 2720;
+ hcIndentMode = 2721;
+ hcInsertLine = 2722;
+ hcInsMode = 2723;
+ hcJumpLine = 2724;
+ hcLineDown = 2725;
+ hcLineEnd = 2726;
+ hcLineStart = 2727;
+ hcLineUp = 2728;
+ hcNewLine = 2729;
+ hcPageDown = 2730;
+ hcPageUp = 2731;
+ hcReformDoc = 2732;
+ hcReformPara = 2733;
+ hcRightMargin = 2734;
+ hcScrollDown = 2735;
+ hcScrollUp = 2736;
+ hcSearchAgain = 2737;
+ hcSelectWord = 2738;
+ hcSetTabs = 2739;
+ hcStartSelect = 2740;
+ hcTabKey = 2741;
+ hcTextEnd = 2742;
+ hcTextStart = 2743;
+ hcWordLeft = 2744;
+ hcWordRight = 2745;
+ hcWordWrap = 2746;
+
+ hcJMarker_Menu = 2750;
+ hcJumpMark1 = 2751;
+ hcJumpMark2 = 2752;
+ hcJumpMark3 = 2753;
+ hcJumpMark4 = 2754;
+ hcJumpMark5 = 2755;
+ hcJumpMark6 = 2756;
+ hcJumpMark7 = 2757;
+ hcJumpMark8 = 2758;
+ hcJumpMark9 = 2759;
+ hcJumpMark0 = 2760;
+ hcJMarker_Menu_Items = 2761;
+
+ hcSMarker_Menu = 2770;
+ hcSetMark1 = 2771;
+ hcSetMark2 = 2772;
+ hcSetMark3 = 2773;
+ hcSetMark4 = 2774;
+ hcSetMark5 = 2775;
+ hcSetMark6 = 2776;
+ hcSetMark7 = 2777;
+ hcSetMark8 = 2778;
+ hcSetMark9 = 2779;
+ hcSetMark0 = 2780;
+ hcSMarker_Menu_Items = 2781;
+
+ hcEditor_Items = hcSMarker_Menu_Items;
+
+ { Dialog }
+ hcDialogs = 2800;
+ hcDCancel = 2801;
+ hcDNo = 2802;
+ hcDOk = 2803;
+ hcDYes = 2804;
+ hcDAbout = 2805;
+ hcDDirName = 2806;
+ hcDDirTree = 2807;
+ hcDChDir = 2808;
+ hcDRevert = 2809;
+ hcDName = 2810;
+ hcDFiles = 2811;
+ hcDFindText = 2812;
+ hcDLineNumber = 2813;
+ hcDReformDoc = 2814;
+ hcDReplaceTExt = 2815;
+ hcDRightMargin = 2816;
+ hcDTabStops = 2817;
+ hcListDlg = 2818;
+
+ { Checkbox help }
+ hcCCaseSensitive = 2900;
+ hcCWholeWords = 2901;
+ hcCPromptReplace = 2902;
+ hcCReplaceAll = 2903;
+ hcCReformCurrent = 2904;
+ hcCReformEntire = 2905;
+
+ { Statuses unit }
+ hcStatusPause = 2950;
+ hcStatusResume = 2951;
+
+ { Glossary }
+ Glossary = 3000;
+ GCloseIcon = 3001;
+ GDesktop = 3002;
+ GDialogBox = 3003;
+ GHistoryIcon = 3004;
+ GInputLine = 3005;
+ GMemIndicator = 3006;
+ GMenuBar = 3007;
+ GPulldownMenu = 3008;
+ GResizeCorner = 3009;
+ GSelectedText = 3010;
+ GStatusBar = 3011;
+ GTitleBar = 3012;
+ GWindowBorder = 3013;
+ GZoomIcon = 3014;
+ hcGlossary_Items = GZoomIcon;
+
+ { INI Unit }
+ hcDateFormatDlg = 1;
+ hcDateParts = 1;
+ hcDateOrder = 1;
+ hcTimeFormatDlg = 1;
+ hcClockFormatDlg = 1;
+ hcClockDateParts = 1;
+ hcClockTimeFormat = 1;
+
+ hcListViewer = 1;
+
+ { Options Help Contexts }
+ hcConfigMenu = 100;
+ hcConfigColors = hcConfigMenu + 1;
+ hcConfigDate = hcConfigColors + 1;
+ hcConfigEnvironment = hcConfigDate + 1;
+ hcConfigMouse = hcConfigEnvironment + 1;
+ hcConfigOpen = hcConfigMouse + 1;
+ hcConfigSave = hcConfigOpen + 1;
+ hcConfigSaveAs = hcConfigSave + 1;
+ hcConfigTime = hcConfigSaveAs + 1;
+ hcConfigVideo = hcConfigTime + 1;
+ hcConfigDesktopDlg = hcConfigVideo + 1;
+ hcConfigMouseDlg = hcConfigDesktopDlg + 1;
+ hcConfigTimeFormatDlg = hcConfigMouseDlg + 1;
+ hcConfigTimeSeparator = hcConfigTimeFormatDlg + 1;
+ hcConfigTimeComponents = hcConfigTimeSeparator + 1;
+ hcConfigTimeStyle = hcConfigTimeComponents + 1;
+ hcConfigClock = hcConfigTimeStyle + 1;
+ hcBrowseDir = 1;
+ hcBrowseFile = 1;
+
+
+{
+ The FVConsts unit contains all history list constants used in the FreeVision
+ Library.
+}
+
+const
+ hiConfig = 1;
+ hiDirectories = 2; { non-specific }
+ hiDesktop = 3;
+ hiCurrentDirectories = 1;
+ hiFiles = 4;
+
+implementation
+
+end.
diff --git a/packages/fv/src/gadgets.pas b/packages/fv/src/gadgets.pas
new file mode 100644
index 0000000000..b802f4f888
--- /dev/null
+++ b/packages/fv/src/gadgets.pas
@@ -0,0 +1,306 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of GADGETS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@starwon.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ }
+{*******************[ DOCUMENTATION ]**********************}
+{ }
+{ This unit had to be for GFV due to some problems with }
+{ the original Borland International implementation. }
+{ }
+{ First it used the DOS unit for it's time calls in the }
+{ TClockView object. Since this unit can not be compiled }
+{ under WIN/NT/OS2 we use a new unit TIME.PAS which was }
+{ created and works under these O/S. }
+{ }
+{ Second the HeapView object accessed MemAvail from in }
+{ the Draw call. As GFV uses heap memory during the Draw }
+{ call the OldMem value always met the test condition in }
+{ the update procedure. The consequence was the view }
+{ would continually redraw. By moving the memavail call }
+{ the update procedure this eliminates this problem. }
+{ }
+{ Finally the original object relied on the font char }
+{ blocks being square to erase it's entire view area as }
+{ it used a simple writeline call in the Draw method. }
+{ Under GFV font blocks are not necessarily square and }
+{ so both objects had their Draw routines rewritten. As }
+{ the Draw had to be redone it was done in the GFV split }
+{ drawing method to accelerate the graphical speed. }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 12 Nov 99 First multi platform release }
+{**********************************************************}
+
+UNIT Gadgets;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Near calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES FVConsts, Time, Objects, Drivers, Views, App; { Standard GFV units }
+
+{***************************************************************************}
+{ PUBLIC OBJECT DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ THeapView OBJECT - ANCESTOR VIEW OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ THeapViewMode=(HVNormal,HVComma,HVKb,HVMb);
+
+ THeapView = OBJECT (TView)
+ Mode : THeapViewMode;
+ OldMem: LongInt; { Last memory count }
+ constructor Init(var Bounds: TRect);
+ constructor InitComma(var Bounds: TRect);
+ constructor InitKb(var Bounds: TRect);
+ constructor InitMb(var Bounds: TRect);
+ PROCEDURE Update;
+ PROCEDURE Draw; Virtual;
+ Function Comma ( N : LongInt ) : String;
+ END;
+ PHeapView = ^THeapView; { Heapview pointer }
+
+{---------------------------------------------------------------------------}
+{ TClockView OBJECT - ANCESTOR VIEW OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TClockView = OBJECT (TView)
+ am : Char;
+ Refresh : Byte; { Refresh rate }
+ LastTime: Longint; { Last time displayed }
+ TimeStr : String[10]; { Time string }
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ FUNCTION FormatTimeStr (H, M, S: Word): String; Virtual;
+ PROCEDURE Update; Virtual;
+ PROCEDURE Draw; Virtual;
+ END;
+ PClockView = ^TClockView; { Clockview ptr }
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ THeapView OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+constructor THeapView.Init(var Bounds: TRect);
+begin
+ inherited Init(Bounds);
+ mode:=HVNormal;
+ OldMem := 0;
+end;
+
+constructor THeapView.InitComma(var Bounds: TRect);
+begin
+ inherited Init(Bounds);
+ mode:=HVComma;
+ OldMem := 0;
+end;
+
+constructor THeapView.InitKb(var Bounds: TRect);
+begin
+ inherited Init(Bounds);
+ mode:=HVKb;
+ OldMem := 0;
+end;
+
+constructor THeapView.InitMb(var Bounds: TRect);
+begin
+ inherited Init(Bounds);
+ mode:=HVMb;
+ OldMem := 0;
+end;
+
+{--THeapView----------------------------------------------------------------}
+{ Update -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THeapView.Update;
+var
+ status : TFPCHeapStatus;
+BEGIN
+ status:=GetFPCHeapStatus;
+ If (OldMem <> status.CurrHeapUsed) Then Begin { Memory differs }
+ OldMem := status.CurrHeapUsed; { Hold memory avail }
+ DrawView; { Now redraw }
+ End;
+END;
+
+{--THeapView----------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE THeapView.Draw;
+VAR
+ C : Byte;
+ S : String;
+ B : TDrawBuffer;
+begin
+ case mode of
+ HVNormal :
+ Str(OldMem:Size.X, S);
+ HVComma :
+ S:=Comma(OldMem);
+ HVKb :
+ begin
+ Str(OldMem shr 10:Size.X-1, S);
+ S:=S+'K';
+ end;
+ HVMb :
+ begin
+ Str(OldMem shr 20:Size.X-1, S);
+ S:=S+'M';
+ end;
+ end;
+ C:=GetColor(2);
+ MoveChar(B,' ',C,Size.X);
+ MoveStr(B,S,C);
+ WriteLine(0,0,Size.X,1,B);
+END;
+
+Function THeapView.Comma ( n : LongInt) : String;
+Var
+ num, loc : Byte;
+ s : String;
+ t : String;
+Begin
+ Str (n,s);
+ Str (n:Size.X,t);
+
+ num := length(s) div 3;
+ if (length(s) mod 3) = 0 then dec (num);
+
+ delete (t,1,num);
+ loc := length(t)-2;
+
+ while num > 0 do
+ Begin
+ Insert (',',t,loc);
+ dec (num);
+ dec (loc,3);
+ End;
+
+ Comma := t;
+End;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TClockView OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TClockView---------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TClockView.Init (Var Bounds: TRect);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ FillChar(LastTime, SizeOf(LastTime), #$FF); { Fill last time }
+ TimeStr := ''; { Empty time string }
+ Refresh := 1; { Refresh per second }
+END;
+
+{--TClockView---------------------------------------------------------------}
+{ FormatStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TClockView.FormatTimeStr (H, M, S: Word): String;
+VAR Hs, Ms, Ss: String;
+BEGIN
+ Str(H, Hs); { Convert hour string }
+ While (Length(Hs) < 2) Do Hs := '0' + Hs; { Add lead zero's }
+ Str(M, Ms); { Convert min string }
+ While (Length(Ms) < 2) Do Ms := '0' + Ms; { Add lead zero's }
+ Str(S, Ss); { Convert sec string }
+ While (Length(Ss) < 2) Do Ss := '0' + Ss; { Add lead zero's }
+ FormatTimeStr := Hs + ':'+ Ms + ':' + Ss; { Return string }
+END;
+
+{--TClockView---------------------------------------------------------------}
+{ Update -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TClockView.Update;
+VAR Hour, Min, Sec, Sec100: Word;
+BEGIN
+ GetTime(Hour, Min, Sec, Sec100); { Get current time }
+ If (Abs(Sec - LastTime) >= Refresh) Then Begin { Refresh time elapsed }
+ LastTime := Sec; { Hold second }
+ TimeStr := FormatTimeStr(Hour, Min, Sec); { Create time string }
+ DrawView; { Now redraw }
+ End;
+END;
+
+{--TClockView---------------------------------------------------------------}
+{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Nov99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TClockView.Draw;
+VAR
+ C : Byte;
+ B : TDrawBuffer;
+BEGIN
+ C:=GetColor(2);
+ MoveChar(B,' ',C,Size.X);
+ MoveStr(B,TimeStr,C);
+ WriteLine(0,0,Size.X,1,B);
+END;
+
+END.
diff --git a/packages/fv/src/go32smsg.inc b/packages/fv/src/go32smsg.inc
new file mode 100644
index 0000000000..e2876ab08e
--- /dev/null
+++ b/packages/fv/src/go32smsg.inc
@@ -0,0 +1,93 @@
+{
+
+ System independent system interface for go32v2
+
+ Copyright (c) 2000 by Pierre Muller
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+Const
+ SystemEventActive : Boolean = false;
+
+
+procedure InitSystemMsg;
+var
+ res : word;
+begin
+ if SystemEventActive then
+ exit;
+ { enable close }
+ asm
+ movl $0x168f,%eax
+ movl $1,%edx
+ int $0x2f
+ movw %ax,Res
+ end;
+ SystemEventActive:=(Res=0);
+end;
+
+
+procedure DoneSystemMsg;
+begin
+ if not SystemEventActive then
+ exit;
+ { disable close }
+ asm
+ movl $0x168f,%eax
+ movl $0,%edx
+ int $0x2f
+ end;
+ SystemEventActive:=false;
+end;
+
+procedure GetSystemEvent(var SystemEvent: TSystemEvent);
+begin
+ PollSystemEvent(SystemEvent);
+end;
+
+function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
+var
+ CloseState : word;
+begin
+ SystemEvent.typ:=SysNothing;
+ if not SystemEventActive then
+ exit(false);
+ { Query close }
+ asm
+ movl $0x168f,%eax
+ movl $100,%edx
+ int $0x2f
+ movw %ax,CloseState
+ end;
+ if (CloseState = 0) then
+ begin
+ { acknowledge Close }
+ asm
+ movl $0x168f,%eax
+ movl $200,%edx
+ int $0x2f
+ movw %ax,CloseState
+ end;
+ { non zero means error ! }
+ if CloseState=0 then
+ begin
+ PollSystemEvent:=true;
+ SystemEvent.typ:=SysClose;
+ end;
+ end;
+end;
+
diff --git a/packages/fv/src/histlist.pas b/packages/fv/src/histlist.pas
new file mode 100644
index 0000000000..3b99a24b79
--- /dev/null
+++ b/packages/fv/src/histlist.pas
@@ -0,0 +1,416 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of HISTLIST.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@starwon.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 11 Nov 96 First DOS/DPMI platform release. }
+{ 1.10 13 Jul 97 Windows platform code added. }
+{ 1.20 29 Aug 97 Platform.inc sort added. }
+{ 1.30 13 Oct 97 Delphi 2 32 bit code added. }
+{ 1.40 05 May 98 Virtual pascal 2.0 code added. }
+{ 1.50 30 Sep 99 Complete recheck preformed }
+{ 1.51 03 Nov 99 FPC windows support added }
+{**********************************************************}
+
+UNIT HistList;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Short calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES FVCommon, Objects; { Standard GFV units }
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY SYSTEM CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-InitHistory--------------------------------------------------------
+Initializes the history system usually called from Application.Init
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE InitHistory;
+
+{-DoneHistory--------------------------------------------------------
+Destroys the history system usually called from Application.Done
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneHistory;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY ITEM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-HistoryCount-------------------------------------------------------
+Returns the number of strings in the history list with ID number Id.
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION HistoryCount (Id: Byte): Word;
+
+{-HistoryStr---------------------------------------------------------
+Returns the Index'th string in the history list with ID number Id.
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION HistoryStr (Id: Byte; Index: Sw_Integer): String;
+
+{-ClearHistory-------------------------------------------------------
+Removes all strings from all history lists.
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE ClearHistory;
+
+{-HistoryAdd---------------------------------------------------------
+Adds the string Str to the history list indicated by Id.
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE HistoryAdd (Id: Byte; Const Str: String);
+
+function HistoryRemove(Id: Byte; Index: Sw_Integer): boolean;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY STREAM STORAGE AND RETREIVAL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-LoadHistory--------------------------------------------------------
+Reads the application's history block from the stream S by reading the
+size of the block, then the block itself. Sets HistoryUsed to the end
+of the block read. Use LoadHistory to restore a history block saved
+with StoreHistory
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE LoadHistory (Var S: TStream);
+
+{-StoreHistory--------------------------------------------------------
+Writes the currently used portion of the history block to the stream
+S, first writing the length of the block then the block itself. Use
+the LoadHistory procedure to restore the history block.
+30Sep99 LdB
+---------------------------------------------------------------------}
+PROCEDURE StoreHistory (Var S: TStream);
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+{---------------------------------------------------------------------------}
+{ INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ HistorySize: sw_integer = 64*1024; { Maximum history size }
+ HistoryUsed: sw_integer = 0; { History used }
+ HistoryBlock: Pointer = Nil; { Storage block }
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{***************************************************************************}
+{ PRIVATE RECORD DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ THistRec RECORD DEFINITION
+
+ Zero 1 byte, start marker
+ Id 1 byte, History id
+ <shortstring> 1 byte length+string data, Contents
+}
+
+{***************************************************************************}
+{ UNINITIALIZED PRIVATE VARIABLES }
+{***************************************************************************}
+{---------------------------------------------------------------------------}
+{ UNINITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+VAR
+ CurId: Byte; { Current history id }
+ CurString: PString; { Current string }
+
+{***************************************************************************}
+{ PRIVATE UNIT ROUTINES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ StartId -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE StartId (Id: Byte);
+BEGIN
+ CurId := Id; { Set current id }
+ CurString := HistoryBlock; { Set current string }
+END;
+
+{---------------------------------------------------------------------------}
+{ DeleteString -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DeleteString;
+VAR Len: Sw_Integer; P, P2: PChar;
+BEGIN
+ P := PChar(CurString); { Current string }
+ P2 := PChar(CurString); { Current string }
+ Len := PByte(P2)^+3; { Length of data }
+ Dec(P, 2); { Correct position }
+ Inc(P2, PByte(P2)^+1); { Next hist record }
+ { Shuffle history }
+ Move(P2^, P^, Pointer(HistoryBlock) + HistoryUsed - Pointer(P2) );
+ Dec(HistoryUsed, Len); { Adjust history used }
+END;
+
+{---------------------------------------------------------------------------}
+{ AdvanceStringPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE AdvanceStringPtr;
+VAR P: PChar;
+BEGIN
+ While (CurString <> Nil) Do Begin
+ If (Pointer(CurString) >= Pointer(HistoryBlock) + HistoryUsed) Then Begin{ Last string check }
+ CurString := Nil; { Clear current string }
+ Exit; { Now exit }
+ End;
+ Inc(PChar(CurString), PByte(CurString)^+1); { Move to next string }
+ If (Pointer(CurString) >= Pointer(HistoryBlock) + HistoryUsed) Then Begin{ Last string check }
+ CurString := Nil; { Clear current string }
+ Exit; { Now exit }
+ End;
+ P := PChar(CurString); { Transfer record ptr }
+ Inc(PChar(CurString), 2); { Move to string }
+ if (P^<>#0) then
+ RunError(215);
+ Inc(P);
+ If (P^ = Chr(CurId)) Then Exit; { Found the string }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ InsertString -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InsertString (Id: Byte; Const Str: String);
+VAR P, P1, P2: PChar;
+BEGIN
+ while (HistoryUsed+Length(Str)+3>HistorySize) do
+ begin
+ P:=PChar(HistoryBlock);
+ while Pointer(P)<Pointer(HistoryBlock)+HistorySize do
+ begin
+ if Pointer(P)+Length(PShortString(P+2)^)+6+Length(Str) >
+ Pointer(HistoryBlock)+HistorySize then
+ begin
+ Dec(HistoryUsed,Length(PShortString(P+2)^)+3);
+ FillChar(P^,Pointer(HistoryBlock)+HistorySize-Pointer(P),#0);
+ break;
+ end;
+ Inc(P,Length(PShortString(P+2)^)+3);
+ end;
+ end;
+ P1 := PChar(HistoryBlock)+1; { First history record }
+ P2 := P1+Length(Str)+3; { History record after }
+ Move(P1^, P2^, HistoryUsed - 1); { Shuffle history data }
+ P1^:=#0; { Set marker byte }
+ Inc(P1);
+ P1^:=Chr(Id); { Set history id }
+ Inc(P1);
+ Move(Str[0], P1^, Length(Str)+1); { Set history string }
+ Inc(HistoryUsed, Length(Str)+3); { Inc history used }
+END;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY SYSTEM CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ InitHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InitHistory;
+BEGIN
+ if HistorySize>0 then
+ GetMem(HistoryBlock, HistorySize); { Allocate block }
+ ClearHistory; { Clear the history }
+END;
+
+{---------------------------------------------------------------------------}
+{ DoneHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneHistory;
+BEGIN
+ If (HistoryBlock <> Nil) Then { History block valid }
+ begin
+ FreeMem(HistoryBlock); { Release history block }
+ HistoryBlock:=nil;
+ end;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY ITEM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ HistoryCount -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION HistoryCount(Id: Byte): Word;
+VAR Count: Word;
+BEGIN
+ StartId(Id); { Set to first record }
+ Count := 0; { Clear count }
+ If (HistoryBlock <> Nil) Then Begin { History initalized }
+ AdvanceStringPtr; { Move to first string }
+ While (CurString <> Nil) Do Begin
+ Inc(Count); { Add one to count }
+ AdvanceStringPtr; { Move to next string }
+ End;
+ End;
+ HistoryCount := Count; { Return history count }
+END;
+
+{---------------------------------------------------------------------------}
+{ HistoryStr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION HistoryStr(Id: Byte; Index: Sw_Integer): String;
+VAR I: Sw_Integer;
+BEGIN
+ StartId(Id); { Set to first record }
+ If (HistoryBlock <> Nil) Then Begin { History initalized }
+ For I := 0 To Index Do AdvanceStringPtr; { Find indexed string }
+ If (CurString <> Nil) Then
+ HistoryStr := CurString^ Else { Return string }
+ HistoryStr := ''; { Index not found }
+ End Else HistoryStr := ''; { History uninitialized }
+END;
+
+{---------------------------------------------------------------------------}
+{ ClearHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE ClearHistory;
+BEGIN
+ If (HistoryBlock <> Nil) Then Begin { History initiated }
+ PChar(HistoryBlock)^ := #0; { Clear first byte }
+ HistoryUsed := 1; { Set position }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ HistoryAdd -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE HistoryAdd (Id: Byte; Const Str: String);
+BEGIN
+ If (Str = '') Then Exit; { Empty string exit }
+ If (HistoryBlock = Nil) Then Exit; { History uninitialized }
+ StartId(Id); { Set current data }
+ AdvanceStringPtr; { Find the string }
+ While (CurString <> nil) Do Begin
+ If (Str = CurString^) Then DeleteString; { Delete duplicates }
+ AdvanceStringPtr; { Find next string }
+ End;
+ InsertString(Id, Str); { Add new history item }
+END;
+
+function HistoryRemove(Id: Byte; Index: Sw_Integer): boolean;
+var
+ I: Sw_Integer;
+begin
+ StartId(Id);
+ for I := 0 to Index do
+ AdvanceStringPtr; { Find the string }
+ if CurString <> nil then
+ begin
+ DeleteString;
+ HistoryRemove:=true;
+ end
+ else
+ HistoryRemove:=false;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ HISTORY STREAM STORAGE AND RETREIVAL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ LoadHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE LoadHistory (Var S: TStream);
+VAR Size: sw_integer;
+BEGIN
+ S.Read(Size, sizeof(Size)); { Read history size }
+ If (HistoryBlock <> Nil) Then Begin { History initialized }
+ If (Size <= HistorySize) Then Begin
+ S.Read(HistoryBlock^, Size); { Read the history }
+ HistoryUsed := Size; { History used }
+ End Else S.Seek(S.GetPos + Size); { Move stream position }
+ End Else S.Seek(S.GetPos + Size); { Move stream position }
+END;
+
+{---------------------------------------------------------------------------}
+{ StoreHistory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE StoreHistory (Var S: TStream);
+VAR Size: sw_integer;
+BEGIN
+ If (HistoryBlock = Nil) Then Size := 0 Else { No history data }
+ Size := HistoryUsed; { Size of history data }
+ S.Write(Size, sizeof(Size)); { Write history size }
+ If (Size > 0) Then S.Write(HistoryBlock^, Size); { Write history data }
+END;
+
+END.
diff --git a/packages/fv/src/inplong.pas b/packages/fv/src/inplong.pas
new file mode 100644
index 0000000000..dc2da1a3fd
--- /dev/null
+++ b/packages/fv/src/inplong.pas
@@ -0,0 +1,305 @@
+Unit InpLong;
+
+(*--
+TInputLong is a derivitave of TInputline designed to accept LongInt
+numeric input. Since both the upper and lower limit of acceptable numeric
+input can be set, TInputLong may be used for Integer, Word, or Byte input
+as well. Option flag bits allow optional hex input and display. A blank
+field may optionally be rejected or interpreted as zero.
+
+Methods
+
+constructor Init(var R : TRect; AMaxLen : Integer;
+ LowerLim, UpperLim : LongInt; Flgs : Word);
+
+Calls TInputline.Init and saves the desired limits and Flags. Flags may
+be a combination of:
+
+ilHex will accept hex input (preceded by '$') as well as decimal.
+ilBlankEqZero if set, will interpret a blank field as '0'.
+ilDisplayHex if set, will display numeric as hex when possible.
+
+
+constructor Load(var S : TStream);
+procedure Store(var S : TStream);
+
+The usual Load and Store routines. Be sure to call RegisterType(RInputLong)
+to register the type.
+
+
+FUNCTION DataSize : Word; virtual;
+PROCEDURE GetData(var Rec); virtual;
+PROCEDURE SetData(var Rec); virtual;
+
+The transfer methods. DataSize is Sizeof(LongInt) and Rec should be
+the address of a LongInt.
+
+
+FUNCTION RangeCheck : Boolean; virtual;
+
+Returns True if the entered string evaluates to a number >= LowerLim and
+<= UpperLim.
+
+
+PROCEDURE Error; virtual;
+
+Error is called when RangeCheck fails. It displays a messagebox indicating
+the label (if any) of the faulting view, as well as the allowable range.
+
+
+PROCEDURE HandleEvent(var Event : TEvent); virtual;
+
+HandleEvent filters out characters which are not appropriate to numeric
+input. Tab and Shift Tab cause a call to RangeCheck and a call to Error
+if RangeCheck returns false. The input must be valid to Tab from the view.
+There's no attempt made to stop moving to another view with the mouse.
+
+
+FUNCTION Valid(Cmd : Word) : Boolean; virtual;
+
+if TInputline.Valid is true and Cmd is neither cmValid or cmCancel, Valid
+then calls RangeCheck. If RangeCheck is false, then Error is called and
+Valid returns False.
+
+----*)
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+
+Interface
+uses objects, drivers, views, dialogs, msgbox, fvconsts;
+
+{flags for TInputLong constructor}
+const
+ ilHex = 1; {will enable hex input with leading '$'}
+ ilBlankEqZero = 2; {No input (blank) will be interpreted as '0'}
+ ilDisplayHex = 4; {Number displayed as hex when possible}
+Type
+ TInputLong = Object(TInputLine)
+ ILOptions : Word;
+ LLim, ULim : LongInt;
+ constructor Init(var R : TRect; AMaxLen : Sw_Integer;
+ LowerLim, UpperLim : LongInt; Flgs : Word);
+ constructor Load(var S : TStream);
+ procedure Store(var S : TStream);
+ FUNCTION DataSize : Sw_Word; virtual;
+ PROCEDURE GetData(var Rec); virtual;
+ PROCEDURE SetData(var Rec); virtual;
+ FUNCTION RangeCheck : Boolean; virtual;
+ PROCEDURE Error; virtual;
+ PROCEDURE HandleEvent(var Event : TEvent); virtual;
+ FUNCTION Valid(Cmd : Word) : Boolean; virtual;
+ end;
+ PInputLong = ^TInputLong;
+
+const
+ RInputLong : TStreamRec = (
+ ObjType: idInputLong;
+ VmtLink: Ofs(Typeof(TInputLong)^);
+ Load : @TInputLong.Load;
+ Store : @TInputLong.Store);
+
+Implementation
+
+{-----------------TInputLong.Init}
+constructor TInputLong.Init(var R : TRect; AMaxLen : Sw_Integer;
+ LowerLim, UpperLim : LongInt; Flgs : Word);
+begin
+if not TInputLine.Init(R, AMaxLen) then fail;
+ULim := UpperLim;
+LLim := LowerLim;
+if Flgs and ilDisplayHex <> 0 then Flgs := Flgs or ilHex;
+ILOptions := Flgs;
+if ILOptions and ilBlankEqZero <> 0 then Data^ := '0';
+end;
+
+{-------------------TInputLong.Load}
+constructor TInputLong.Load(var S : TStream);
+begin
+TInputLine.Load(S);
+S.Read(ILOptions, Sizeof(ILOptions));
+S.Read(LLim, Sizeof(LLim));
+S.Read(ULim, Sizeof(ULim));
+end;
+
+{-------------------TInputLong.Store}
+procedure TInputLong.Store(var S : TStream);
+begin
+TInputLine.Store(S);
+S.Write(ILOptions, Sizeof(ILOptions));
+S.Write(LLim, Sizeof(LLim));
+S.Write(ULim, Sizeof(ULim));
+end;
+
+{-------------------TInputLong.DataSize}
+FUNCTION TInputLong.DataSize:Sw_Word;
+begin
+DataSize := Sizeof(LongInt);
+end;
+
+{-------------------TInputLong.GetData}
+PROCEDURE TInputLong.GetData(var Rec);
+var code : Integer;
+begin
+Val(Data^, LongInt(Rec), code);
+end;
+
+FUNCTION Hex2(B : Byte) : String;
+Const
+ HexArray : array[0..15] of char = '0123456789ABCDEF';
+begin
+Hex2[0] := #2;
+Hex2[1] := HexArray[B shr 4];
+Hex2[2] := HexArray[B and $F];
+end;
+
+FUNCTION Hex4(W : Word) : String;
+begin Hex4 := Hex2(Hi(W))+Hex2(Lo(W)); end;
+
+FUNCTION Hex8(L : LongInt) : String;
+begin Hex8 := Hex4(LongRec(L).Hi)+Hex4(LongRec(L).Lo); end;
+
+function FormHexStr(L : LongInt) : String;
+var
+ Minus : boolean;
+ S : string[20];
+begin
+Minus := L < 0;
+if Minus then L := -L;
+S := Hex8(L);
+while (Length(S) > 1) and (S[1] = '0') do Delete(S, 1, 1);
+S := '$' + S;
+if Minus then System.Insert('-', S, 2);
+FormHexStr := S;
+end;
+
+{-------------------TInputLong.SetData}
+PROCEDURE TInputLong.SetData(var Rec);
+var
+ L : LongInt;
+ S : string;
+begin
+L := LongInt(Rec);
+if L > ULim then L := ULim
+else if L < LLim then L := LLim;
+if ILOptions and ilDisplayHex <> 0 then
+ S := FormHexStr(L)
+else
+ Str(L : -1, S);
+if Length(S) > MaxLen then S[0] := chr(MaxLen);
+Data^ := S;
+end;
+
+{-------------------TInputLong.RangeCheck}
+FUNCTION TInputLong.RangeCheck : Boolean;
+var
+ L : LongInt;
+ code : Integer;
+begin
+if (Data^ = '') and (ILOptions and ilBlankEqZero <> 0) then
+ Data^ := '0';
+Val(Data^, L, code);
+RangeCheck := (Code = 0) and (L >= LLim) and (L <= ULim);
+end;
+
+{-------------------TInputLong.Error}
+PROCEDURE TInputLong.Error;
+var
+ SU, SL : string[40];
+ PMyLabel : PLabel;
+ Labl : string;
+ I : Integer;
+
+ function FindIt(P : PView) : boolean;{$ifdef PPC_BP}far;{$endif}
+ begin
+ FindIt := (Typeof(P^) = Typeof(TLabel)) and (PLabel(P)^.Link = PView(@Self));
+ end;
+
+begin
+Str(LLim : -1, SL);
+Str(ULim : -1, SU);
+if ILOptions and ilHex <> 0 then
+ begin
+ SL := SL+'('+FormHexStr(LLim)+')';
+ SU := SU+'('+FormHexStr(ULim)+')';
+ end;
+if Owner <> Nil then
+ PMyLabel := PLabel(Owner^.FirstThat(@FindIt))
+else PMyLabel := Nil;
+if PMyLabel <> Nil then PMyLabel^.GetText(Labl)
+else Labl := '';
+if Labl <> '' then
+ begin
+ I := Pos('~', Labl);
+ while I > 0 do
+ begin
+ System.Delete(Labl, I, 1);
+ I := Pos('~', Labl);
+ end;
+ Labl := '"'+Labl+'"';
+ end;
+MessageBox(Labl + ^M^J'Value not within range '+SL+' to '+SU, Nil,
+ mfError+mfOKButton);
+end;
+
+{-------------------TInputLong.HandleEvent}
+PROCEDURE TInputLong.HandleEvent(var Event : TEvent);
+begin
+if (Event.What = evKeyDown) then
+ begin
+ case Event.KeyCode of
+ kbTab, kbShiftTab
+ : if not RangeCheck then
+ begin
+ Error;
+ SelectAll(True);
+ ClearEvent(Event);
+ end;
+ end;
+ if Event.CharCode <> #0 then {a character key}
+ begin
+ Event.Charcode := Upcase(Event.Charcode);
+ case Event.Charcode of
+ '0'..'9', #1..#$1B : ; {acceptable}
+
+ '-' : if (LLim >= 0) or (CurPos <> 0) then
+ ClearEvent(Event);
+ '$' : if ILOptions and ilHex = 0 then ClearEvent(Event);
+ 'A'..'F' : if Pos('$', Data^) = 0 then ClearEvent(Event);
+
+ else ClearEvent(Event);
+ end;
+ end;
+ end;
+TInputLine.HandleEvent(Event);
+end;
+
+{-------------------TInputLong.Valid}
+FUNCTION TInputLong.Valid(Cmd : Word) : Boolean;
+var
+ Rslt : boolean;
+begin
+Rslt := TInputLine.Valid(Cmd);
+if Rslt and (Cmd <> 0) and (Cmd <> cmCancel) then
+ begin
+ Rslt := RangeCheck;
+ if not Rslt then
+ begin
+ Error;
+ Select;
+ SelectAll(True);
+ end;
+ end;
+Valid := Rslt;
+end;
+
+end.
diff --git a/packages/fv/src/memory.pas b/packages/fv/src/memory.pas
new file mode 100644
index 0000000000..79607d6cd5
--- /dev/null
+++ b/packages/fv/src/memory.pas
@@ -0,0 +1,875 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent clone of MEMORY.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@starwon.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 19 feb 96 Initial DOS/DPMI code released. }
+{ 1.10 18 Jul 97 Windows conversion added. }
+{ 1.20 29 Aug 97 Platform.inc sort added. }
+{ 1.30 05 May 98 Virtual pascal 2.0 code added. }
+{ 1.40 01 Oct 99 Complete multiplatform rewrite }
+{ 1.41 03 Nov 99 FPC Windows support added }
+{**********************************************************}
+
+UNIT Memory;
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F+} { Force far calls }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES FVCommon;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MEMORY ACCESS ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-MemAlloc-----------------------------------------------------------
+Allocates the requested size of memory if this takes memory free below
+the safety pool then a nil pointer is returned.
+01Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION MemAlloc (Size: Word): Pointer;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MEMORY MANAGER SYSTEM CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-LowMemory----------------------------------------------------------
+Returns if the free memory left is below the safety pool value.
+01Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION LowMemory: Boolean;
+
+{-InitMemory---------------------------------------------------------
+Initializes the memory and safety pool manager. This should be called
+prior to using any of the memory manager routines.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE InitMemory;
+
+{-DoneMemory---------------------------------------------------------
+Closes the memory and safety pool manager. This should be called after
+using the memory manager routines so as to clean up.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneMemory;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ CACHE MEMORY ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-NewCache-----------------------------------------------------------
+Create a new cache of given size in pointer P failure will return nil.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE NewCache (Var P: Pointer; Size: Word);
+
+{-DisposeCache-------------------------------------------------------
+Dispose of a cache buffer given by pointer P.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE DisposeCache (P: Pointer);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ BUFFER MEMORY ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-GetBufferSize------------------------------------------------------
+Returns the size of memory buffer given by pointer P.
+01Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION GetBufferSize (P: Pointer): Word;
+
+{-SetBufferSize------------------------------------------------------
+Change the size of buffer given by pointer P to the size requested.
+01Oct99 LdB
+---------------------------------------------------------------------}
+FUNCTION SetBufferSize (var P: Pointer; Size: Word): Boolean;
+
+{-DisposeBuffer------------------------------------------------------
+Dispose of buffer given by pointer P.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE DisposeBuffer (P: Pointer);
+
+{-NewBuffer----------------------------------------------------------
+Create a new buffer of given size in ptr P failure will return nil.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE NewBuffer (Var P: Pointer; Size: Word);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ DOS MEMORY CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-InitDosMem---------------------------------------------------------
+Initialize memory manager routine for a shell to launch a DOS window.
+Interface for compatability only under DPMI/WIN/NT/OS2 platforms.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE InitDosMem;
+
+{-DoneDosMem---------------------------------------------------------
+Finished shell to a DOS window so reset memory manager again.
+Interface for compatability only under DPMI/WIN/NT/OS2 platforms.
+01Oct99 LdB
+---------------------------------------------------------------------}
+PROCEDURE DoneDosMem;
+
+{***************************************************************************}
+{ PUBLIC INITIALIZED VARIABLES }
+{***************************************************************************}
+CONST
+ LowMemSize : Word = 4096 DIV 16; { 4K }
+ SafetyPoolSize: Word = 8192; { Safety pool size }
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ MaxHeapSize : Word = 655360 DIV 16; { 640K }
+ MaxBufMem : Word = 65536 DIV 16; { 64K }
+{$ENDIF}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+{$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
+ USES Windows; { Standard unit }
+ {$ELSE} { OTHER COMPILERS }
+ USES WinProcs, WinTypes; { Standard units }
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF OS_OS2} { OS2 CODE }
+ {$IFDEF PPC_FPC}
+ USES DosCalls; { Standard unit }
+ {$ELSE}
+ USES Os2Base; { Standard unit }
+ {$ENDIF}
+{$ENDIF}
+
+{***************************************************************************}
+{ PRIVATE RECORD TYPE DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TBuffer RECORD DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ PBuffer = ^TBuffer; { Buffer pointer }
+ TBuffer =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ Size : Word; { Buffer size }
+ Master: ^Word; { Master buffer }
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ Next: PBuffer; { Next buffer }
+ Size: Word; { Buffer size }
+ Data: RECORD END; { Buffer data }
+ {$ENDIF}
+ END;
+
+{---------------------------------------------------------------------------}
+{ POINTER TYPE CONVERSION RECORDS }
+{---------------------------------------------------------------------------}
+TYPE
+ PtrRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Ofs, Seg: Word; { Pointer to words }
+ END;
+
+{---------------------------------------------------------------------------}
+{ TCache RECORD DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ PCache = ^TCache; { Cache pointer }
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ TCache =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Size : Word; { Cache size }
+ Master: ^Pointer; { Master cache }
+ Data : RECORD END; { Cache data }
+ END;
+{$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ TCache =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Next : PCache; { Next cache }
+ Master: ^Pointer; { Master cache }
+ Size : Word; { Size of cache }
+ Data : RECORD END; { Cache data }
+ End;
+{$ENDIF}
+
+{***************************************************************************}
+{ INITIALIZED PRIVATE VARIABLES }
+{***************************************************************************}
+CONST
+ DisablePool: Boolean = False; { Disable safety pool }
+ SafetyPool : Pointer = Nil; { Safety pool memory }
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ HeapResult: Integer = 0; { Heap result }
+ BufHeapPtr: Word = 0; { Heap position }
+ BufHeapEnd: Word = 0; { Heap end }
+ CachePtr : Pointer = Nil; { Cache list }
+{$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ CacheList : PCache = Nil; { Cache list }
+ BufferList: PBuffer = Nil; { Buffer list }
+{$ENDIF}
+
+{***************************************************************************}
+{ PRIVATE UNIT ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ PRIVATE UNIT ROUTINES - REAL MODE DOS PLATFORMS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+{---------------------------------------------------------------------------}
+{ GetBufSize -> Platforms DOS REAL MODE - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetBufSize (P: PBuffer): Word; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+BEGIN
+ GetBufSize := (P^.Size + 15) SHR 4 + 1; { Buffer paragraphs }
+END;
+
+{---------------------------------------------------------------------------}
+{ FreeCacheMem -> Platforms DOS REAL MODE - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE FreeCacheMem; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+BEGIN
+ While (CachePtr <> HeapEnd) Do
+ DisposeCache(CachePtr); { Release blocks }
+END;
+
+{---------------------------------------------------------------------------}
+{ SetMemTop -> Platforms DOS REAL MODE - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SetMemTop (MemTop: Pointer); ASSEMBLER;
+ASM
+ MOV BX, MemTop.Word[0]; { Top of memory }
+ ADD BX, 15;
+ MOV CL, 4;
+ SHR BX, CL; { Size in paragraphs }
+ ADD BX, MemTop.Word[2];
+ MOV AX, PrefixSeg; { Add prefix seg }
+ SUB BX, AX;
+ MOV ES, AX;
+ MOV AH, 4AH;
+ INT 21H; { Call to DOS }
+END;
+
+{---------------------------------------------------------------------------}
+{ MoveSeg -> Platforms DOS REAL MODE - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MoveSeg (Source, Dest, Size: Word); NEAR; ASSEMBLER;
+ASM
+ PUSH DS; { Save register }
+ MOV AX, Source;
+ MOV DX, Dest; { Destination }
+ MOV BX, Size;
+ CMP AX, DX; { Does Source=Dest? }
+ JB @@3;
+ CLD; { Go forward }
+@@1:
+ MOV CX, 0FFFH;
+ CMP CX, BX;
+ JB @@2;
+ MOV CX, BX;
+@@2:
+ MOV DS, AX;
+ MOV ES, DX;
+ ADD AX, CX;
+ ADD DX, CX;
+ SUB BX, CX;
+ SHL CX, 3; { Mult x8 }
+ XOR SI, SI;
+ XOR DI, DI;
+ REP MOVSW;
+ OR BX, BX;
+ JNE @@1;
+ JMP @@6;
+@@3: { Source=Dest }
+ ADD AX, BX; { Hold register }
+ ADD DX, BX; { Must go backwards }
+ STD;
+@@4:
+ MOV CX, 0FFFH;
+ CMP CX, BX;
+ JB @@5;
+ MOV CX, BX;
+@@5:
+ SUB AX, CX;
+ SUB DX, CX;
+ SUB BX, CX;
+ MOV DS, AX;
+ MOV ES, DX;
+ SHL CX, 3; { Mult x8 }
+ MOV SI, CX;
+ DEC SI;
+ SHL SI, 1;
+ MOV DI, SI;
+ REP MOVSW; { Move data }
+ OR BX, BX;
+ JNE @@4;
+@@6:
+ POP DS; { Recover register }
+END;
+
+{---------------------------------------------------------------------------}
+{ SetBufSize -> Platforms DOS REAL MODE - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SetBufSize (P: PBuffer; NewSize: Word); {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+VAR CurSize: Word;
+BEGIN
+ CurSize := GetBufSize(P); { Current size }
+ MoveSeg(PtrRec(P).Seg + CurSize, PtrRec(P).Seg+
+ NewSize, BufHeapPtr - PtrRec(P).Seg - CurSize); { Move data }
+ Inc(BufHeapPtr, NewSize - CurSize); { Adjust heap space }
+ Inc(PtrRec(P).Seg, NewSize); { Adjust pointer }
+ While PtrRec(P).Seg < BufHeapPtr Do Begin
+ Inc(P^.Master^, NewSize - CurSize); { Adjust master }
+ Inc(PtrRec(P).Seg, (P^.Size + 15) SHR 4 + 1); { Adjust paragraphs }
+ End;
+END;
+{$ENDIF}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ PRIVATE UNIT ROUTINES - DPMI/WIN/NT/OS2 PLATFORMS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{$IFNDEF PROC_REAL} { DPMI/WIN/NT/OS2 CODE }
+{---------------------------------------------------------------------------}
+{ FreeCache -> Platforms DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION FreeCache: Boolean; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+BEGIN
+ FreeCache := False; { Preset fail }
+ If (CacheList <> Nil) Then Begin
+ DisposeCache(CacheList^.Next^.Master^); { Dispose cache }
+ FreeCache := True; { Return success }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ FreeCache -> Platforms DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION FreeSafetyPool: Boolean; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+BEGIN
+ FreeSafetyPool := False; { Preset fail }
+ If (SafetyPool <> Nil) Then Begin { Pool exists }
+ FreeMem(SafetyPool, SafetyPoolSize); { Release memory }
+ SafetyPool := Nil; { Clear pointer }
+ FreeSafetyPool := True; { Return true }
+ End;
+END;
+{$ENDIF}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ PRIVATE UNIT ROUTINES - ALL PLATFORMS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ HeapNotify -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION HeapNotify (Size: Word): Integer; {$IFNDEF PPC_FPC}FAR;{$ENDIF}
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ASSEMBLER;
+ASM
+ CMP Size, 0; { Check for zero size }
+ JNE @@3; { Exit if size = zero }
+@@1:
+ MOV AX, CachePtr.Word[2];
+ CMP AX, HeapPtr.Word[2]; { Compare segments }
+ JA @@3;
+ JB @@2;
+ MOV AX, CachePtr.Word[0];
+ CMP AX, HeapPtr.Word[0]; { Compare offsets }
+ JAE @@3;
+@@2:
+ XOR AX, AX; { Clear register }
+ PUSH AX; { Push zero }
+ PUSH AX; { Push zero }
+ CALL DisposeCache; { Dispose cache }
+ JMP @@1;
+@@3:
+ MOV AX, HeapResult; { Return result }
+END;
+{$ELSE} { DPMI/WIN/NT/OS2 }
+BEGIN
+ If FreeCache Then HeapNotify := 2 Else { Release cache }
+ If DisablePool Then HeapNotify := 1 Else { Safetypool disabled }
+ If FreeSafetyPool Then HeapNotify := 2 Else { Free safety pool }
+ HeapNotify := 0; { Return success }
+END;
+{$ENDIF}
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MEMORY ACCESS ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ MemAlloc -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MemAlloc (Size: Word): Pointer;
+VAR P: Pointer;
+BEGIN
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ HeapResult := 1; { Stop error calls }
+ GetMem(P, Size); { Get memory }
+ HeapResult := 0; { Reset error calls }
+ If (P <> Nil) AND LowMemory Then Begin { Low memory }
+ FreeMem(P, Size); { Release memory }
+ P := Nil; { Clear pointer }
+ End;
+ MemAlloc := P; { Return result }
+ {$ELSE} { DPMI/WIN/NT/OS2 }
+ DisablePool := True; { Disable safety }
+ GetMem(P, Size); { Allocate memory }
+ DisablePool := False; { Enable safety }
+ MemAlloc := P; { Return result }
+ {$ENDIF}
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MEMORY MANAGER SYSTEM CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ LowMemory -> Platforms DOS/DPMI/WIN/NT/OS2 - Checked 29Jun98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION LowMemory: Boolean;
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ASSEMBLER;
+ASM
+ MOV AX, HeapEnd.Word[2]; { Get heap end }
+ SUB AX, HeapPtr.Word[2];
+ SUB AX, LowMemSize; { Subtract size }
+ SBB AX, AX;
+ NEG AX; { Return result }
+END;
+{$ELSE} { DPMI/WIN/NT/OS2 CODE }
+BEGIN
+ LowMemory := False; { Preset false }
+ If (SafetyPool = Nil) Then Begin { Not initialized }
+ SafetyPool := MemAlloc(SafetyPoolSize); { Allocate safety pool }
+ If (SafetyPool = Nil) Then LowMemory := True; { Return if low memory }
+ End;
+END;
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ InitMemory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InitMemory;
+{$IFDEF PROC_REAL} VAR HeapSize: Word; {$ENDIF}
+BEGIN
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ HeapError := @HeapNotify; { Point to error proc }
+ If (BufHeapPtr = 0) Then Begin
+ HeapSize := PtrRec(HeapEnd).Seg
+ - PtrRec(HeapOrg).Seg; { Calculate size }
+ If (HeapSize > MaxHeapSize) Then
+ HeapSize := MaxHeapSize; { Restrict max size }
+ BufHeapEnd := PtrRec(HeapEnd).Seg; { Set heap end }
+ PtrRec(HeapEnd).Seg := PtrRec(HeapOrg).Seg
+ + HeapSize; { Add heapsize }
+ BufHeapPtr := PtrRec(HeapEnd).Seg; { Set heap pointer }
+ End;
+ CachePtr := HeapEnd; { Cache starts at end }
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ {$IFNDEF PPC_FPC}
+ HeapError := @HeapNotify; { Set heap error proc }
+ {$ENDIF}
+ SafetyPoolSize := LowMemSize * 16; { Fix safety pool size }
+ LowMemory; { Check for low memory }
+ {$ENDIF}
+END;
+
+{---------------------------------------------------------------------------}
+{ DoneMemory -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneMemory;
+BEGIN
+ {$IFDEF PROC_REAL} { REAl MODE DOS CODE }
+ FreeCacheMem; { Release cache memory }
+ {$ELSE} { DPMI/WIN/NT/OS2 }
+ While FreeCache Do; { Free cache memory }
+ FreeSafetyPool; { Release safety pool }
+ {$ENDIF}
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ CACHE MEMORY ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ NewCache -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE NewCache (Var P: Pointer; Size: Word);
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ASSEMBLER;
+ASM
+ LES DI, P; { Addres of var P }
+ MOV AX, Size;
+ ADD AX, (TYPE TCache)+15; { Add offset }
+ MOV CL, 4;
+ SHR AX, CL;
+ MOV DX, CachePtr.Word[2]; { Reteive cache ptr }
+ SUB DX, AX;
+ JC @@1;
+ CMP DX, HeapPtr.Word[2]; { Heap ptr end }
+ JBE @@1;
+ MOV CX, HeapEnd.Word[2];
+ SUB CX, DX;
+ CMP CX, MaxBufMem; { Compare to maximum }
+ JA @@1;
+ MOV CachePtr.Word[2], DX; { Exchange ptr }
+ PUSH DS;
+ MOV DS, DX;
+ XOR SI, SI;
+ MOV DS:[SI].TCache.Size, AX; { Get cache size }
+ MOV DS:[SI].TCache.Master.Word[0], DI;
+ MOV DS:[SI].TCache.Master.Word[2], ES; { Get master ptr }
+ POP DS;
+ MOV AX, OFFSET TCache.Data;
+ JMP @@2;
+@@1:
+ XOR AX, AX;
+ CWD; { Make double word }
+@@2:
+ CLD;
+ STOSW; { Write low word }
+ XCHG AX, DX;
+ STOSW; { Write high word }
+END;
+{$ELSE} { DPMI/WIN/NT/OS2 CODE }
+VAR Cache: PCache;
+BEGIN
+ Inc(Size, SizeOf(TCache)); { Add cache size }
+ If (MaxAvail >= Size) Then GetMem(Cache, Size) { Allocate memory }
+ Else Cache := Nil; { Not enough memory }
+ If (Cache <> Nil) Then Begin { Cache is valid }
+ If (CacheList = Nil) Then Cache^.Next := Cache
+ Else Begin
+ Cache^.Next := CacheList^.Next; { Insert in list }
+ CacheList^.Next := Cache; { Complete link }
+ End;
+ CacheList := Cache; { Hold cache ptr }
+ Cache^.Size := Size; { Hold cache size }
+ Cache^.Master := @P; { Hold master ptr }
+{$ifdef fpc}
+ Inc(Pointer(Cache), SizeOf(TCache)); { Set cache offset }
+{$else fpc}
+ Inc(PtrRec(Cache).Ofs, SizeOf(TCache)); { Set cache offset }
+{$endif fpc}
+ End;
+ P := Cache; { Return pointer }
+END;
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DisposeCache -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DisposeCache (P: Pointer);
+{$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ASSEMBLER;
+ASM
+ MOV AX, CachePtr.Word[2]; { Cache high word }
+ XOR BX, BX;
+ XOR CX, CX;
+ MOV DX, P.Word[2]; { P high word }
+@@1:
+ MOV ES, AX;
+ CMP AX, DX; { Check for match }
+ JE @@2;
+ ADD AX, ES:[BX].TCache.Size; { Move to next cache }
+ CMP AX, HeapEnd.Word[2];
+ JE @@2; { Are we at heap end }
+ PUSH ES;
+ INC CX; { No so try next }
+ JMP @@1;
+@@2:
+ PUSH ES;
+ LES DI, ES:[BX].TCache.Master; { Pointe to master }
+ XOR AX, AX;
+ CLD;
+ STOSW; { Clear master ptr }
+ STOSW;
+ POP ES;
+ MOV AX, ES:[BX].TCache.Size; { Next cache }
+ JCXZ @@4;
+@@3:
+ POP DX;
+ PUSH DS;
+ PUSH CX; { Hold registers }
+ MOV DS, DX;
+ ADD DX, AX;
+ MOV ES, DX;
+ MOV SI, DS:[BX].TCache.Size; { Get cache size }
+ MOV CL, 3;
+ SHL SI, CL; { Multiply x8 }
+ MOV CX, SI;
+ SHL SI, 1;
+ DEC SI; { Adjust position }
+ DEC SI;
+ MOV DI, SI;
+ STD;
+ REP MOVSW; { Move cache memory }
+ LDS SI, ES:[BX].TCache.Master;
+ MOV DS:[SI].Word[2], ES; { Store new master }
+ POP CX;
+ POP DS; { Recover registers }
+ LOOP @@3;
+@@4:
+ ADD CachePtr.Word[2], AX; { Add offset }
+END;
+{$ELSE} { DPMI/WIN/NT/OS2 CODE }
+VAR Cache, C: PCache;
+BEGIN
+{$ifdef fpc}
+ Cache:=pointer(p)-SizeOf(TCache);
+{$else fpc}
+ PtrRec(Cache).Ofs := PtrRec(P).Ofs-SizeOf(TCache); { Previous cache }
+ PtrRec(Cache).Seg := PtrRec(P).Seg; { Segment }
+{$endif fpc}
+ C := CacheList; { Start at 1st cache }
+ While (C^.Next <> Cache) AND (C^.Next <> CacheList)
+ Do C := C^.Next; { Find previous }
+ If (C^.Next = Cache) Then Begin { Cache found }
+ If (C = Cache) Then CacheList := Nil Else Begin { Only cache in list }
+ If CacheList = Cache Then CacheList := C; { First in list }
+ C^.Next := Cache^.Next; { Remove from list }
+ End;
+ Cache^.Master^ := Nil; { Clear master }
+ FreeMem(Cache, Cache^.Size); { Release memory }
+ End;
+END;
+{$ENDIF}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ BUFFER MEMORY ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ GetBufferSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION GetBufferSize (P: Pointer): Word;
+BEGIN
+ {$IFDEF PROC_REAL} { DOS CODE }
+ Dec(PtrRec(P).Seg); { Segment prior }
+ GetBufferSize := PBuffer(P)^.Size; { Size of this buffer }
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ If (P <> Nil) Then { Check pointer }
+ Begin
+{$ifdef fpc}
+ Dec(Pointer(P),SizeOf(TBuffer)); { Correct to buffer }
+{$else fpc}
+ Dec(PtrRec(P).Ofs,SizeOf(TBuffer)); { Correct to buffer }
+{$endif fpc}
+ GetBufferSize := PBuffer(P)^.Size; { Return buffer size }
+ End
+ Else
+ GetBufferSize := 0; { Invalid pointer }
+ {$ENDIF}
+END;
+
+{---------------------------------------------------------------------------}
+{ SetBufferSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION SetBufferSize (var P: Pointer; Size: Word): Boolean;
+VAR NewSize: Word;
+BEGIN
+ SetBufferSize := False; { Preset failure }
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ Dec(PtrRec(P).Seg); { Prior segment }
+ NewSize := (Size + 15) SHR 4 + 1; { Paragraph size }
+ If (BufHeapPtr+NewSize-GetBufSize(P)<=BufHeapEnd) { Check enough heap }
+ Then Begin
+ SetBufSize(P, NewSize); { Set the buffer size }
+ PBuffer(P)^.Size := Size; { Set the size }
+ SetBufferSize := True; { Return success }
+ End;
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ {$ifdef fpc}
+ Dec(Pointer(P),SizeOf(TBuffer)); { Correct to buffer }
+ SetBufferSize := ReAllocMem(P, Size + SizeOf(TBuffer)) <> nil;
+ if SetBufferSize then
+ TBuffer(P^).Size := Size + SizeOf(TBuffer);
+ Inc(Pointer(P), SizeOf(TBuffer)); { Correct to buffer }
+{$endif fpc}
+ {$ENDIF}
+END;
+
+{---------------------------------------------------------------------------}
+{ DisposeBuffer -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DisposeBuffer (P: Pointer);
+{$IFNDEF PROC_REAL} VAR Buffer,PrevBuf: PBuffer; {$ENDIF}
+BEGIN
+ If (P <> Nil) Then Begin
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ Dec(PtrRec(P).Seg); { Prior segement }
+ SetBufSize(P, 0); { Release memory }
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+{$ifdef fpc}
+ Dec(Pointer(P), SizeOf(TBuffer)); { Actual buffer pointer }
+{$else fpc}
+ Dec(PtrRec(P).Ofs, SizeOf(TBuffer)); { Actual buffer pointer }
+{$endif fpc}
+ Buffer := BufferList; { Start on first }
+ PrevBuf := Nil; { Preset prevbuf to nil }
+ While (Buffer <> Nil) AND (P <> Buffer) Do Begin { Search for buffer }
+ PrevBuf := Buffer; { Hold last buffer }
+ Buffer := Buffer^.Next; { Move to next buffer }
+ End;
+ If (Buffer <> Nil) Then Begin { Buffer was found }
+ If (PrevBuf = Nil) Then { We were first on list }
+ BufferList := Buffer^.Next Else { Set bufferlist entry }
+ PrevBuf^.Next := Buffer^.Next; { Remove us from chain }
+ FreeMem(Buffer, Buffer^.Size); { Release buffer }
+ End;
+ {$ENDIF}
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ NewBuffer -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE NewBuffer (Var P: Pointer; Size: Word);
+VAR BufSize: Word; Buffer: PBuffer;
+BEGIN
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ BufSize := (Size + 15) SHR 4 + 1; { Paragraphs to alloc }
+ If (BufHeapPtr+BufSize > BufHeapEnd) Then P := Nil { Exceeeds heap }
+ Else Begin
+ Buffer := Ptr(BufHeapPtr, 0); { Current position }
+ Buffer^.Size := Size; { Set size }
+ Buffer^.Master := @PtrRec(P).Seg; { Set master }
+ P := Ptr(BufHeapPtr + 1, 0); { Position ptr }
+ Inc(BufHeapPtr, BufSize); { Allow space on heap }
+ End;
+ {$ELSE} { DPMI/WIN/NT/OS2 CODE }
+ BufSize := Size + SizeOf(TBuffer); { Size to allocate }
+ Buffer := MemAlloc(BufSize); { Allocate the memory }
+ If (Buffer <> Nil) Then Begin
+ Buffer^.Next := BufferList; { First part of chain }
+ BufferList := Buffer; { Complete the chain }
+ Buffer^.Size := BufSize; { Hold the buffer size }
+{$ifdef fpc}
+ Inc(Pointer(Buffer), SizeOf(TBuffer)); { Buffer to data area }
+{$else fpc}
+ Inc(PtrRec(Buffer).Ofs, SizeOf(TBuffer)); { Buffer to data area }
+{$endif fpc}
+ End;
+ P := Buffer; { Return the buffer ptr }
+ {$ENDIF}
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ DOS MEMORY CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ InitDosMem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE InitDosMem;
+BEGIN
+ {$IFDEF PROC_REAL} { REAl MODE DOS CODE }
+ SetMemTop(Ptr(BufHeapEnd, 0)); { Move heap to empty }
+ {$ENDIF}
+END;
+
+{---------------------------------------------------------------------------}
+{ DoneDosMem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 01Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DoneDosMem;
+{$IFDEF PROC_REAL} VAR MemTop: Pointer; {$ENDIF}
+BEGIN
+ {$IFDEF PROC_REAL} { REAL MODE DOS CODE }
+ MemTop := Ptr(BufHeapPtr, 0); { Top of memory }
+ If (BufHeapPtr = PtrRec(HeapEnd).Seg) Then Begin { Is memory empty }
+ FreeCacheMem; { Release memory }
+ MemTop := HeapPtr; { Set pointer }
+ End;
+ SetMemTop(MemTop); { Release memory }
+ {$ENDIF}
+END;
+
+END.
diff --git a/packages/fv/src/menus.pas b/packages/fv/src/menus.pas
new file mode 100644
index 0000000000..7d8896dc14
--- /dev/null
+++ b/packages/fv/src/menus.pas
@@ -0,0 +1,1632 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of MENUS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@starwon.com.au - backup e-mail addr }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+
+UNIT Menus;
+
+{$CODEPAGE cp437}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Near calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES
+ {$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ {$IFNDEF PPC_SPEED} { NON SPEED COMPILER }
+ {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
+ Windows, { Standard unit }
+ {$ELSE} { OTHER COMPILERS }
+ WinTypes,WinProcs, { Standard units }
+ {$ENDIF}
+ {$ELSE} { SPEEDSOFT COMPILER }
+ WinBase, WinDef, { Standard units }
+ {$ENDIF}
+ {$ENDIF}
+
+ objects, drivers, views, fvconsts; { GFV standard units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ COLOUR PALETTES }
+{---------------------------------------------------------------------------}
+CONST
+ CMenuView = #2#3#4#5#6#7; { Menu colours }
+ CStatusLine = #2#3#4#5#6#7; { Statusline colours }
+
+{***************************************************************************}
+{ RECORD DEFINITIONS }
+{***************************************************************************}
+TYPE
+ TMenuStr = String[31]; { Menu string }
+
+ PMenu = ^TMenu; { Pointer to menu }
+
+{---------------------------------------------------------------------------}
+{ TMenuItem RECORD }
+{---------------------------------------------------------------------------}
+ PMenuItem = ^TMenuItem;
+ TMenuItem =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Next: PMenuItem; { Next menu item }
+ Name: PString; { Menu item name }
+ Command: Word; { Menu item command }
+ Disabled: Boolean; { Menu item state }
+ KeyCode: Word; { Menu item keycode }
+ HelpCtx: Word; { Menu item help ctx }
+ Case Integer Of
+ 0: (Param: PString);
+ 1: (SubMenu: PMenu);
+ END;
+
+{---------------------------------------------------------------------------}
+{ TMenu RECORD }
+{---------------------------------------------------------------------------}
+ TMenu =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Items: PMenuItem; { Menu item list }
+ Default: PMenuItem; { Default menu }
+ END;
+
+{---------------------------------------------------------------------------}
+{ TStatusItem RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ PStatusItem = ^TStatusItem;
+ TStatusItem =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Next: PStatusItem; { Next status item }
+ Text: PString; { Text of status item }
+ KeyCode: Word; { Keycode of item }
+ Command: Word; { Command of item }
+ END;
+
+{---------------------------------------------------------------------------}
+{ TStatusDef RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ PStatusDef = ^TStatusDef;
+ TStatusDef =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ Next: PStatusDef; { Next status defined }
+ Min, Max: Word; { Range of item }
+ Items: PStatusItem; { Item list }
+ END;
+
+{***************************************************************************}
+{ OBJECT DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TMenuView OBJECT - MENU VIEW ANCESTOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ PMenuView = ^TMenuView;
+ TMenuView = OBJECT (TView)
+ ParentMenu: PMenuView; { Parent menu }
+ Menu : PMenu; { Menu item list }
+ Current : PMenuItem; { Current menu item }
+ OldItem : PMenuItem; { Old item for draws }
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION Execute: Word; Virtual;
+ FUNCTION GetHelpCtx: Word; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION FindItem (Ch: Char): PMenuItem;
+ FUNCTION HotKey (KeyCode: Word): PMenuItem;
+ FUNCTION NewSubView (Var Bounds: TRect; AMenu: PMenu;
+ AParentMenu: PMenuView): PMenuView; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE GetItemRect (Item: PMenuItem; Var R: TRect); Virtual;
+ private
+ PROCEDURE GetItemRectX (Item: PMenuItem; Var R: TRect); Virtual;
+ END;
+
+{---------------------------------------------------------------------------}
+{ TMenuBar OBJECT - MENU BAR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TMenuBar = OBJECT (TMenuView)
+ CONSTRUCTOR Init (Var Bounds: TRect; AMenu: PMenu);
+ DESTRUCTOR Done; Virtual;
+ PROCEDURE Draw; Virtual;
+ private
+ PROCEDURE GetItemRectX (Item: PMenuItem; Var R: TRect); Virtual;
+ END;
+ PMenuBar = ^TMenuBar;
+
+{---------------------------------------------------------------------------}
+{ TMenuBox OBJECT - BOXED MENU OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TMenuBox = OBJECT (TMenuView)
+ CONSTRUCTOR Init (Var Bounds: TRect; AMenu: PMenu;
+ AParentMenu: PMenuView);
+ PROCEDURE Draw; Virtual;
+ private
+ PROCEDURE GetItemRectX (Item: PMenuItem; Var R: TRect); Virtual;
+ END;
+ PMenuBox = ^TMenuBox;
+
+{---------------------------------------------------------------------------}
+{ TMenuPopUp OBJECT - POPUP MENU OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TMenuPopup = OBJECT (TMenuBox)
+ CONSTRUCTOR Init (Var Bounds: TRect; AMenu: PMenu);
+ DESTRUCTOR Done; Virtual;
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ END;
+ PMenuPopup = ^TMenuPopup;
+
+{---------------------------------------------------------------------------}
+{ TStatusLine OBJECT - STATUS LINE OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TStatusLine = OBJECT (TView)
+ Items: PStatusItem; { Status line items }
+ Defs : PStatusDef; { Status line default }
+ CONSTRUCTOR Init (Var Bounds: TRect; ADefs: PStatusDef);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION Hint (AHelpCtx: Word): String; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Update; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PRIVATE
+ PROCEDURE FindItems;
+ PROCEDURE DrawSelect (Selected: PStatusItem);
+ END;
+ PStatusLine = ^TStatusLine;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MENU INTERFACE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-NewMenu------------------------------------------------------------
+Allocates and returns a pointer to a new TMenu record. Sets the Items
+and Default fields of the record to the value given by the parameter.
+An error creating will return a nil pointer.
+14May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewMenu (Items: PMenuItem): PMenu;
+
+{-DisposeMenu--------------------------------------------------------
+Disposes of all the elements of the specified menu (and all submenus).
+14May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE DisposeMenu (Menu: PMenu);
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MENU ITEM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-NewLine------------------------------------------------------------
+Allocates and returns a pointer to a new TMenuItem record that
+represents a separator line in a menu box.
+An error creating will return a nil pointer.
+14May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewLine (Next: PMenuItem): PMenuItem;
+
+{-NewItem------------------------------------------------------------
+Allocates and returns a pointer to a new TMenuItem record that
+represents a menu item (using NewStr to allocate the Name and Param).
+An error creating will return a nil pointer.
+14May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewItem (Name, Param: TMenuStr; KeyCode: Word; Command: Word;
+ AHelpCtx: Word; Next: PMenuItem): PMenuItem;
+
+{-NewSubMenu---------------------------------------------------------
+Allocates and returns a pointer to a new TMenuItem record, which
+represents a submenu (using NewStr to allocate the Name).
+An error creating will return a nil pointer.
+14May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewSubMenu (Name: TMenuStr; AHelpCtx: Word; SubMenu: PMenu;
+ Next: PMenuItem): PMenuItem;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STATUS INTERFACE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-NewStatusDef-------------------------------------------------------
+Allocates and returns a pointer to a new TStatusDef record initialized
+with the given parameter values. Calls to NewStatusDef can be nested.
+An error creating will return a nil pointer.
+15May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewStatusDef (AMin, AMax: Word; AItems: PStatusItem;
+ ANext: PStatusDef): PStatusDef;
+
+{-NewStatusKey-------------------------------------------------------
+Allocates and returns a pointer to a new TStatusItem record initialized
+with the given parameter values (using NewStr to allocate the Text).
+An error in creating will return a nil pointer.
+15May98 LdB
+---------------------------------------------------------------------}
+FUNCTION NewStatusKey (AText: String; AKeyCode: Word; ACommand: Word;
+ ANext: PStatusItem): PStatusItem;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{-RegisterMenus-------------------------------------------------------
+Calls RegisterType for each of the object types defined in this unit.
+15May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE RegisterMenus;
+
+{***************************************************************************}
+{ OBJECT REGISTRATION }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TMenuBar STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RMenuBar: TStreamRec = (
+ ObjType: idMenuBar; { Register id = 40 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TMenuBar)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TMenuBar);
+ {$ENDIF}
+ Load: @TMenuBar.Load; { Object load method }
+ Store: @TMenuBar.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TMenuBox STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RMenuBox: TStreamRec = (
+ ObjType: idMenuBox; { Register id = 41 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TMenuBox)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TMenuBox);
+ {$ENDIF}
+ Load: @TMenuBox.Load; { Object load method }
+ Store: @TMenuBox.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TStatusLine STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RStatusLine: TStreamRec = (
+ ObjType: 42; { Register id = 42 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TStatusLine)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TStatusLine);
+ {$ENDIF}
+ Load: @TStatusLine.Load; { Object load method }
+ Store: @TStatusLine.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TMenuPopup STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RMenuPopup: TStreamRec = (
+ ObjType: 43; { Register id = 43 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TMenuPopup)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TMenuPopup);
+ {$ENDIF}
+ Load: @TMenuPopup.Load; { Object load method }
+ Store: @TMenuPopup.Store { Object store method }
+ );
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED PUBLIC VARIABLES }
+{---------------------------------------------------------------------------}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+USES
+ Video;
+
+CONST
+ SubMenuChar : array[boolean] of char = ('>',#16);
+ { SubMenuChar is the character displayed at right of submenu }
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TMenuView OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TMenuView----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMenuView.Init (Var Bounds: TRect);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ EventMask := EventMask OR evBroadcast; { See broadcast events }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMenuView.Load (Var S: TStream);
+
+ FUNCTION DoLoadMenu: PMenu;
+ VAR Tok: Byte; Item: PMenuItem; Last: ^PMenuItem; HMenu: PMenu;
+ BEGIN
+ New(HMenu); { Create new menu }
+ Last := @HMenu^.Items; { Start on first item }
+ Item := Nil; { Clear pointer }
+ S.Read(Tok, SizeOf(Tok)); { Read token }
+ While (Tok <> 0) Do Begin
+ New(Item); { Create new item }
+ Last^ := Item; { First part of chain }
+ If (Item <> Nil) Then Begin { Check item valid }
+ Last := @Item^.Next; { Complete chain }
+ With Item^ Do Begin
+ Name := S.ReadStr; { Read menu name }
+ S.Read(Command, SizeOf(Command)); { Menu item command }
+ S.Read(Disabled, SizeOf(Disabled)); { Menu item state }
+ S.Read(KeyCode, SizeOf(KeyCode)); { Menu item keycode }
+ S.Read(HelpCtx, SizeOf(HelpCtx)); { Menu item help ctx }
+ If (Name <> Nil) Then
+ If Command = 0 Then
+{$ifdef PPC_FPC}
+ SubMenu := DoLoadMenu() { Load submenu }
+{$else not PPC_FPC}
+ SubMenu := DoLoadMenu { Load submenu }
+{$endif not PPC_FPC}
+ Else Param := S.ReadStr; { Read param string }
+ End;
+ End;
+ S.Read(Tok, SizeOf(Tok)); { Read token }
+ End;
+ Last^ := Nil; { List complete }
+ HMenu^.Default := HMenu^.Items; { Set menu default }
+ DoLoadMenu := HMenu; { Return menu }
+ End;
+
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Menu := DoLoadMenu; { Load menu items }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ Execute -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.Execute: Word;
+TYPE MenuAction = (DoNothing, DoSelect, DoReturn);
+VAR AutoSelect: Boolean; Action: MenuAction; Ch: Char; Res: Word; R: TRect;
+ ItemShown, P: PMenuItem; Target: PMenuView; E: TEvent; MouseActive: Boolean;
+
+ PROCEDURE TrackMouse;
+ VAR Mouse: TPoint; R: TRect;
+ BEGIN
+ Mouse.X := E.Where.X - Origin.X; { Local x position }
+ Mouse.Y := E.Where.Y - oRigin.Y; { Local y position }
+ Current := Menu^.Items; { Start with current }
+ While (Current <> Nil) Do Begin
+ GetItemRectX(Current, R); { Get item rectangle }
+ If R.Contains(Mouse) Then Begin { Contains mouse }
+ MouseActive := True; { Return true }
+ Exit; { Then exit }
+ End;
+ Current := Current^.Next; { Try next item }
+ End;
+ END;
+
+ PROCEDURE TrackKey (FindNext: Boolean);
+
+ PROCEDURE NextItem;
+ BEGIN
+ Current := Current^.Next; { Move to next item }
+ If (Current = Nil) Then
+ Current := Menu^.Items; { Return first menu }
+ END;
+
+ PROCEDURE PrevItem;
+ VAR P: PMenuItem;
+ BEGIN
+ P := Current; { Start on current }
+ If (P = Menu^.Items) Then P := Nil; { Check if at start }
+ Repeat NextItem Until Current^.Next = P; { Prev item found }
+ END;
+
+ BEGIN
+ If (Current <> Nil) Then { Current view valid }
+ Repeat
+ If FindNext Then NextItem Else PrevItem; { Find next/prev item }
+ Until (Current^.Name <> Nil); { Until we have name }
+ END;
+
+ FUNCTION MouseInOwner: Boolean;
+ VAR Mouse: TPoint; R: TRect;
+ BEGIN
+ MouseInOwner := False; { Preset false }
+ If (ParentMenu <> Nil) AND (ParentMenu^.Size.Y = 1)
+ Then Begin { Valid parent menu }
+ Mouse.X := E.Where.X - ParentMenu^.Origin.X;{ Local x position }
+ Mouse.Y := E.Where.Y - ParentMenu^.Origin.Y;{ Local y position }
+ ParentMenu^.GetItemRectX(ParentMenu^.Current,R);{ Get item rect }
+ MouseInOwner := R.Contains(Mouse); { Return result }
+ End;
+ END;
+
+ FUNCTION MouseInMenus: Boolean;
+ VAR P: PMenuView;
+ BEGIN
+ P := ParentMenu; { Parent menu }
+ While (P <> Nil) AND NOT P^.MouseInView(E.Where)
+ Do P := P^.ParentMenu; { Check next menu }
+ MouseInMenus := (P <> Nil); { Return result }
+ END;
+
+ FUNCTION TopMenu: PMenuView;
+ VAR P: PMenuView;
+ BEGIN
+ P := @Self; { Start with self }
+ While (P^.ParentMenu <> Nil) Do
+ P := P^.ParentMenu; { Check next menu }
+ TopMenu := P; { Top menu }
+ END;
+
+BEGIN
+ AutoSelect := False; { Clear select flag }
+ MouseActive := False; { Clear mouse flag }
+ Res := 0; { Clear result }
+ ItemShown := Nil; { Clear item pointer }
+ If (Menu <> Nil) Then Current := Menu^.Default { Set current item }
+ Else Current := Nil; { No menu = no current }
+ Repeat
+ Action := DoNothing; { Clear action flag }
+ GetEvent(E); { Get next event }
+ Case E.What Of
+ evMouseDown: If MouseInView(E.Where) { Mouse in us }
+ OR MouseInOwner Then Begin { Mouse in owner area }
+ TrackMouse; { Track the mouse }
+ If (Size.Y = 1) Then AutoSelect := True; { Set select flag }
+ End Else Action := DoReturn; { Set return action }
+ evMouseUp: Begin
+ TrackMouse; { Track the mouse }
+ If MouseInOwner Then { Mouse in owner }
+ Current := Menu^.Default { Set as current }
+ Else If (Current <> Nil) AND
+ (Current^.Name <> Nil) Then
+ Action := DoSelect { Set select action }
+ Else If MouseActive OR MouseInView(E.Where)
+ Then Action := DoReturn { Set return action }
+ Else Begin
+ Current := Menu^.Default; { Set current item }
+ If (Current = Nil) Then
+ Current := Menu^.Items; { Select first item }
+ Action := DoNothing; { Do nothing action }
+ End;
+ End;
+ evMouseMove: If (E.Buttons <> 0) Then Begin { Mouse moved }
+ TrackMouse; { Track the mouse }
+ If NOT (MouseInView(E.Where) OR MouseInOwner)
+ AND MouseInMenus Then Action := DoReturn; { Set return action }
+ End;
+ evKeyDown:
+ Case CtrlToArrow(E.KeyCode) Of { Check arrow keys }
+ kbUp, kbDown: If (Size.Y <> 1) Then
+ TrackKey(CtrlToArrow(E.KeyCode) = kbDown){ Track keyboard }
+ Else If (E.KeyCode = kbDown) Then { Down arrow }
+ AutoSelect := True; { Select item }
+ kbLeft, kbRight: If (ParentMenu = Nil) Then
+ TrackKey(CtrlToArrow(E.KeyCode)=kbRight) { Track keyboard }
+ Else Action := DoReturn; { Set return action }
+ kbHome, kbEnd: If (Size.Y <> 1) Then Begin
+ Current := Menu^.Items; { Set to first item }
+ If (E.KeyCode = kbEnd) Then { If the 'end' key }
+ TrackKey(False); { Move to last item }
+ End;
+ kbEnter: Begin
+ If Size.Y = 1 Then AutoSelect := True; { Select item }
+ Action := DoSelect; { Return the item }
+ End;
+ kbEsc: Begin
+ Action := DoReturn; { Set return action }
+ If (ParentMenu = Nil) OR
+ (ParentMenu^.Size.Y <> 1) Then { Check parent }
+ ClearEvent(E); { Kill the event }
+ End;
+ Else Target := @Self; { Set target as self }
+ Ch := GetAltChar(E.KeyCode);
+ If (Ch = #0) Then Ch := E.CharCode Else
+ Target := TopMenu; { Target is top menu }
+ P := Target^.FindItem(Ch); { Check for item }
+ If (P = Nil) Then Begin
+ P := TopMenu^.HotKey(E.KeyCode); { Check for hot key }
+ If (P <> Nil) AND { Item valid }
+ CommandEnabled(P^.Command) Then Begin { Command enabled }
+ Res := P^.Command; { Set return command }
+ Action := DoReturn; { Set return action }
+ End
+ End Else If Target = @Self Then Begin
+ If Size.Y = 1 Then AutoSelect := True; { Set auto select }
+ Action := DoSelect; { Select item }
+ Current := P; { Set current item }
+ End Else If (ParentMenu <> Target) OR
+ (ParentMenu^.Current <> P) Then { Item different }
+ Action := DoReturn; { Set return action }
+ End;
+ evCommand: If (E.Command = cmMenu) Then Begin { Menu command }
+ AutoSelect := False; { Dont select item }
+ If (ParentMenu <> Nil) Then
+ Action := DoReturn; { Set return action }
+ End Else Action := DoReturn; { Set return action }
+ End;
+ If (ItemShown <> Current) Then Begin { New current item }
+ OldItem := ItemShown; { Hold old item }
+ ItemShown := Current; { Hold new item }
+ DrawView; { Redraw the items }
+ OldItem := Nil; { Clear old item }
+ End;
+ If (Action = DoSelect) OR ((Action = DoNothing)
+ AND AutoSelect) Then { Item is selecting }
+ If (Current <> Nil) Then With Current^ Do { Current item valid }
+ If (Name <> Nil) Then { Item has a name }
+ If (Command = 0) Then Begin { Has no command }
+ If (E.What AND (evMouseDown+evMouseMove) <> 0)
+ Then PutEvent(E); { Put event on queue }
+ GetItemRectX(Current, R); { Get area of item }
+ R.A.X := R.A.X + Origin.X; { Left start point }
+ R.A.Y := R.B.Y + Origin.Y;{ Top start point }
+ R.B.X := Owner^.Size.X; { X screen area left }
+ R.B.Y := Owner^.Size.Y; { Y screen area left }
+ Target := TopMenu^.NewSubView(R, SubMenu,
+ @Self); { Create drop menu }
+ Res := Owner^.ExecView(Target); { Execute dropped view }
+ Dispose(Target, Done); { Dispose drop view }
+ End Else If Action = DoSelect Then
+ Res := Command; { Return result }
+ If (Res <> 0) AND CommandEnabled(Res) { Check command }
+ Then Begin
+ Action := DoReturn; { Return command }
+ ClearEvent(E); { Clear the event }
+ End Else Res := 0; { Clear result }
+ Until (Action = DoReturn);
+ If (E.What <> evNothing) Then
+ If (ParentMenu <> Nil) OR (E.What = evCommand) { Check event type }
+ Then PutEvent(E); { Put event on queue }
+ If (Current <> Nil) Then Begin
+ Menu^.Default := Current; { Set new default }
+ Current := Nil; { Clear current }
+ DrawView; { Redraw the view }
+ End;
+ Execute := Res; { Return result }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.GetHelpCtx: Word;
+VAR C: PMenuView;
+BEGIN
+ C := @Self; { Start at self }
+ While (C <> Nil) AND ((C^.Current = Nil) OR
+ (C^.Current^.HelpCtx = hcNoContext) OR { Has no context }
+ (C^.Current^.Name = Nil)) Do C := C^.ParentMenu; { Parent menu context }
+ If (C<>Nil) Then GetHelpCtx := C^.Current^.HelpCtx { Current context }
+ Else GetHelpCtx := hcNoContext; { No help context }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.GetPalette: PPalette;
+{$IFDEF PPC_DELPHI3} { DELPHI3+ COMPILER }
+CONST P: String = CMenuView; { Possible huge string }
+{$ELSE} { OTHER COMPILERS }
+CONST P: String[Length(CMenuView)] = CMenuView; { Always normal string }
+{$ENDIF}
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ FindItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.FindItem (Ch: Char): PMenuItem;
+VAR I: Integer; P: PMenuItem;
+BEGIN
+ Ch := UpCase(Ch); { Upper case of char }
+ P := Menu^.Items; { First menu item }
+ While (P <> Nil) Do Begin { While item valid }
+ If (P^.Name <> Nil) AND (NOT P^.Disabled) { Valid enabled cmd }
+ Then Begin
+ I := Pos('~', P^.Name^); { Scan for highlight }
+ If (I <> 0) AND (Ch = UpCase(P^.Name^[I+1])) { Hotkey char found }
+ Then Begin
+ FindItem := P; { Return item }
+ Exit; { Now exit }
+ End;
+ End;
+ P := P^.Next; { Next item }
+ End;
+ FindItem := Nil; { No item found }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ HotKey -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.HotKey (KeyCode: Word): PMenuItem;
+
+ FUNCTION FindHotKey (P: PMenuItem): PMenuItem;
+ VAR T: PMenuItem;
+ BEGIN
+ While (P <> Nil) Do Begin { While item valid }
+ If (P^.Name <> Nil) Then { If valid name }
+ If (P^.Command = 0) Then Begin { Valid command }
+ T := FindHotKey(P^.SubMenu^.Items); { Search for hot key }
+ If (T <> Nil) Then Begin
+ FindHotKey := T; { Return hotkey }
+ Exit; { Now exit }
+ End;
+ End Else If NOT P^.Disabled AND { Hotkey is enabled }
+ (P^.KeyCode <> kbNoKey) AND { Valid keycode }
+ (P^.KeyCode = KeyCode) Then Begin { Key matches request }
+ FindHotKey := P; { Return hotkey code }
+ Exit; { Exit }
+ End;
+ P := P^.Next; { Next item }
+ End;
+ FindHotKey := Nil; { No item found }
+ END;
+
+BEGIN
+ HotKey := FindHotKey(Menu^.Items); { Hot key function }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ NewSubView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TMenuView.NewSubView (Var Bounds: TRect; AMenu: PMenu;
+ AParentMenu: PMenuView): PMenuView;
+BEGIN
+ NewSubView := New(PMenuBox, Init(Bounds, AMenu,
+ AParentMenu)); { Create a menu box }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuView.Store (Var S: TStream);
+
+ PROCEDURE DoStoreMenu (AMenu: PMenu);
+ VAR Item: PMenuItem; Tok: Byte;
+ BEGIN
+ Tok := $FF; { Preset max count }
+ Item := AMenu^.Items; { Start first item }
+ While (Item <> Nil) Do Begin
+ With Item^ Do Begin
+ S.Write(Tok, SizeOf(Tok)); { Write tok value }
+ S.WriteStr(Name); { Write item name }
+ S.Write(Command, SizeOf(Command)); { Menu item command }
+ S.Write(Disabled, SizeOf(Disabled)); { Menu item state }
+ S.Write(KeyCode, SizeOf(KeyCode)); { Menu item keycode }
+ S.Write(HelpCtx, SizeOf(HelpCtx)); { Menu item help ctx }
+ If (Name <> Nil) Then
+ If Command = 0 Then DoStoreMenu(SubMenu)
+ Else S.WriteStr(Param); { Write parameter }
+ End;
+ Item := Item^.Next; { Next item }
+ End;
+ Tok := 0; { Clear tok count }
+ S.Write(Tok, SizeOf(Tok)); { Write tok value }
+ END;
+
+BEGIN
+ TView.Store(S); { TView.Store called }
+ DoStoreMenu(Menu); { Store menu items }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuView.HandleEvent (Var Event: TEvent);
+VAR CallDraw: Boolean; P: PMenuItem;
+
+ PROCEDURE UpdateMenu (AMenu: PMenu);
+ VAR P: PMenuItem; CommandState: Boolean;
+ BEGIN
+ P := AMenu^.Items; { Start on first item }
+ While (P <> Nil) Do Begin
+ If (P^.Name <> Nil) Then { Valid name }
+ If (P^.Command = 0) Then UpdateMenu(P^.SubMenu){ Update menu }
+ Else Begin
+ CommandState := CommandEnabled(P^.Command); { Menu item state }
+ If (P^.Disabled = CommandState) Then Begin
+ P^.Disabled := NOT CommandState; { Disable item }
+ CallDraw := True; { Must draw }
+ End;
+ End;
+ P := P^.Next; { Next item }
+ End;
+ END;
+
+ PROCEDURE DoSelect;
+ BEGIN
+ PutEvent(Event); { Put event on queue }
+ Event.Command := Owner^.ExecView(@Self); { Execute view }
+ If (Event.Command <> 0) AND
+ CommandEnabled(Event.Command) Then Begin
+ Event.What := evCommand; { Command event }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ End;
+ ClearEvent(Event); { Clear the event }
+ END;
+
+BEGIN
+ If (Menu <> Nil) Then
+ Case Event.What Of
+ evMouseDown: DoSelect; { Select menu item }
+ evKeyDown:
+ If (FindItem(GetAltChar(Event.KeyCode)) <> Nil)
+ Then DoSelect Else Begin { Select menu item }
+ P := HotKey(Event.KeyCode); { Check for hotkey }
+ If (P <> Nil) AND
+ (CommandEnabled(P^.Command)) Then Begin
+ Event.What := evCommand; { Command event }
+ Event.Command := P^.Command; { Set command event }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ evCommand:
+ If Event.Command = cmMenu Then DoSelect; { Select menu item }
+ evBroadcast:
+ If (Event.Command = cmCommandSetChanged) { Commands changed }
+ Then Begin
+ CallDraw := False; { Preset no redraw }
+ UpdateMenu(Menu); { Update menu }
+ If CallDraw Then DrawView; { Redraw if needed }
+ End;
+ End;
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ GetItemRectX -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuView.GetItemRectX (Item: PMenuItem; Var R: TRect);
+BEGIN { Abstract method }
+END;
+
+{--TMenuView----------------------------------------------------------------}
+{ GetItemRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuView.GetItemRect (Item: PMenuItem; Var R: TRect);
+BEGIN
+ GetItemRectX(Item,R);
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TMenuBar OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TMenuBar-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMenuBar.Init (Var Bounds: TRect; AMenu: PMenu);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ GrowMode := gfGrowHiX; { Set grow mode }
+ Menu := AMenu; { Hold menu item }
+ Options := Options OR ofPreProcess; { Preprocessing view }
+END;
+
+{--TMenuBar-----------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TMenuBar.Done;
+BEGIN
+ If (Menu <> Nil) Then DisposeMenu(Menu); { Dispose menu items }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TMenuBar-----------------------------------------------------------------}
+{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuBar.Draw;
+VAR I, J, CNormal, CSelect, CNormDisabled, CSelDisabled, Color: Word;
+ P: PMenuItem; B: TDrawBuffer;
+BEGIN
+ CNormal := GetColor($0301); { Normal colour }
+ CSelect := GetColor($0604); { Select colour }
+ CNormDisabled := GetColor($0202); { Disabled colour }
+ CSelDisabled := GetColor($0505); { Select disabled }
+ MoveChar(B, ' ', Byte(CNormal), Size.X); { Empty bar }
+ If (Menu <> Nil) Then Begin { Valid menu }
+ I := 0; { Set start position }
+ P := Menu^.Items; { First item }
+ While (P <> Nil) Do Begin
+ If (P^.Name <> Nil) Then Begin { Name valid }
+ If P^.Disabled Then Begin
+ If (P = Current) Then Color := CSelDisabled{ Select disabled }
+ Else Color := CNormDisabled { Normal disabled }
+ End Else Begin
+ If (P = Current) Then Color := CSelect { Select colour }
+ Else Color := CNormal; { Normal colour }
+ End;
+ J := CStrLen(P^.Name^); { Length of string }
+ MoveChar(B[I], ' ', Byte(Color), 1);
+ MoveCStr(B[I+1], P^.Name^, Color); { Name to buffer }
+ MoveChar(B[I+1+J], ' ', Byte(Color), 1);
+ Inc(I, J+2); { Advance position }
+ End;
+ P := P^.Next; { Next item }
+ End;
+ End;
+ WriteBuf(0, 0, Size.X, 1, B); { Write the string }
+END;
+
+{--TMenuBar-----------------------------------------------------------------}
+{ GetItemRectX -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 08May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuBar.GetItemRectX (Item: PMenuItem; Var R: TRect);
+VAR I: Integer; P: PMenuItem;
+BEGIN
+ I := 0; { Preset to zero }
+ R.Assign(0, 0, 0, 1); { Initial rect size }
+ P := Menu^.Items; { First item }
+ While (P <> Nil) Do Begin { While valid item }
+ R.A.X := I; { Move area along }
+ If (P^.Name <> Nil) Then Begin { Valid name }
+ R.B.X := R.A.X+CTextWidth(' ' + P^.Name^ + ' ');{ Add text width }
+ I := I + CStrLen(P^.Name^) + 2; { Add item length }
+ End Else R.B.X := R.A.X;
+ If (P = Item) Then break; { Requested item found }
+ P := P^.Next; { Next item }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TMenuBox OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TMenuBox-----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMenuBox.Init (Var Bounds: TRect; AMenu: PMenu;
+ AParentMenu: PMenuView);
+VAR W, H, L: Integer; S: String; P: PMenuItem; R: TRect;
+BEGIN
+ W := 0; { Clear initial width }
+ H := 2; { Set initial height }
+ If (AMenu <> Nil) Then Begin { Valid menu }
+ P := AMenu^.Items; { Start on first item }
+ While (P <> Nil) Do Begin { If item valid }
+ If (P^.Name <> Nil) Then Begin { Check for name }
+ S := ' ' + P^.Name^ + ' '; { Transfer string }
+ If (P^.Command <> 0) AND (P^.Param <> Nil)
+ Then S := S + ' - ' + P^.Param^; { Add any parameter }
+ End;
+ L := CTextWidth(S); { Width of string }
+ If (L > W) Then W := L; { Hold maximum }
+ Inc(H); { Inc count of items }
+ P := P^.Next; { Move to next item }
+ End;
+ End;
+ W := 5 + W; { Longest text width }
+ R.Copy(Bounds); { Copy the bounds }
+ If (R.A.X + W < R.B.X) Then R.B.X := R.A.X + W { Shorten if possible }
+ Else R.A.X := R.B.X - W; { Insufficent space }
+ R.B.X := R.A.X + W;
+ If (R.A.Y + H < R.B.Y) Then R.B.Y := R.A.Y + H { Shorten if possible }
+ Else R.A.Y := R.B.Y - H; { Insufficent height }
+ Inherited Init(R); { Call ancestor }
+ State := State OR sfShadow; { Set shadow state }
+ Options := Options OR ofFramed or ofPreProcess; { View pre processes }
+ Menu := AMenu; { Hold menu }
+ ParentMenu := AParentMenu; { Hold parent }
+END;
+
+{--TMenuBox-----------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuBox.Draw;
+VAR CNormal, CSelect, CSelectDisabled, CDisabled, Color: Word; Index, Y: Integer;
+ S: String; P: PMenuItem; B: TDrawBuffer;
+Type
+ FrameLineType = (UpperLine,NormalLine,SeparationLine,LowerLine);
+ FrameLineChars = Array[0..2] of char;
+Const
+ FrameLines : Array[FrameLineType] of FrameLineChars =
+ ('ÚÄ¿','³ ³','ÃÄ´','ÀÄÙ');
+ Procedure CreateBorder(LineType : FrameLineType);
+ Begin
+ MoveChar(B, ' ', CNormal, 1);
+ MoveChar(B[1], FrameLines[LineType][0], CNormal, 1);
+ MoveChar(B[2], FrameLines[LineType][1], Color, Size.X-4);
+ MoveChar(B[Size.X-2], FrameLines[LineType][2], CNormal, 1);
+ MoveChar(B[Size.X-1], ' ', CNormal, 1);
+ End;
+
+
+BEGIN
+ CNormal := GetColor($0301); { Normal colour }
+ CSelect := GetColor($0604); { Selected colour }
+ CDisabled := GetColor($0202); { Disabled colour }
+ CSelectDisabled := GetColor($0505); { Selected, but disabled }
+ Color := CNormal; { Normal colour }
+ CreateBorder(UpperLine);
+ WriteBuf(0, 0, Size.X, 1, B); { Write the line }
+ Y := 1;
+ If (Menu <> Nil) Then Begin { We have a menu }
+ P := Menu^.Items; { Start on first }
+ While (P <> Nil) Do Begin { Valid menu item }
+ Color := CNormal; { Normal colour }
+ If (P^.Name <> Nil) Then Begin { Item has text }
+ If P^.Disabled Then
+ begin
+ if (P = Current) then
+ Color := CSelectDisabled
+ else
+ Color := CDisabled; { Is item disabled }
+ end
+ else
+ If (P = Current) Then Color := CSelect; { Select colour }
+ CreateBorder(NormalLine);
+ Index:=2;
+ S := ' ' + P^.Name^ + ' '; { Menu string }
+ MoveCStr(B[Index], S, Color); { Transfer string }
+ if P^.Command = 0 then
+ MoveChar(B[Size.X - 4],SubMenuChar[LowAscii],
+ Byte(Color), 1) else
+ If (P^.Command <> 0) AND(P^.Param <> Nil) Then
+ Begin
+ MoveCStr(B[Size.X - 3 - Length(P^.Param^)], P^.Param^, Color); { Add param chars }
+ S := S + ' - ' + P^.Param^; { Add to string }
+ End;
+ If (OldItem = Nil) OR (OldItem = P) OR
+ (Current = P) Then
+ Begin { We need to fix draw }
+ WriteBuf(0, Y, Size.X, 1, B); { Write the whole line }
+ End;
+ End Else Begin { no text NewLine }
+ Color := CNormal; { Normal colour }
+ CreateBorder(SeparationLine);
+ WriteBuf(0, Y, Size.X, 1, B); { Write the line }
+ End;
+ Inc(Y); { Next line down }
+ P := P^.Next; { fetch next item }
+ End;
+ End;
+ Color := CNormal; { Normal colour }
+ CreateBorder(LowerLine);
+ WriteBuf(0, Size.Y-1, Size.X, 1, B); { Write the line }
+END;
+
+
+{--TMenuBox-----------------------------------------------------------------}
+{ GetItemRectX -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuBox.GetItemRectX (Item: PMenuItem; Var R: TRect);
+VAR X, Y: Integer; P: PMenuItem;
+BEGIN
+ Y := 1; { Initial y position }
+ P := Menu^.Items; { Initial item }
+ While (P <> Item) Do Begin { Valid item }
+ Inc(Y); { Inc position }
+ P := P^.Next; { Next item }
+ End;
+ X := 2; { Left/Right margin }
+ R.Assign(X, Y, Size.X - X, Y + 1); { Assign area }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TMenuPopUp OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TMenuPopUp---------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TMenuPopup.Init (Var Bounds: TRect; AMenu: PMenu);
+BEGIN
+ Inherited Init(Bounds, AMenu, Nil); { Call ancestor }
+END;
+
+{--TMenuPopUp---------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TMenuPopup.Done;
+BEGIN
+ If (Menu <> Nil) Then DisposeMenu(Menu); { Dispose menu items }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TMenuPopUp---------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TMenuPopup.HandleEvent (Var Event: TEvent);
+VAR P: PMenuItem;
+BEGIN
+ Case Event.What Of
+ evKeyDown: Begin
+ P := FindItem(GetCtrlChar(Event.KeyCode)); { Find the item }
+ If (P = Nil) Then P := HotKey(Event.KeyCode);{ Try hot key }
+ If (P <> Nil) AND (CommandEnabled(P^.Command))
+ Then Begin { Command valid }
+ Event.What := evCommand; { Command event }
+ Event.Command := P^.Command; { Set command value }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ ClearEvent(Event); { Clear the event }
+ End Else If (GetAltChar(Event.KeyCode) <> #0)
+ Then ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ Inherited HandleEvent(Event); { Call ancestor }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TStatusLine OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TStatusLine--------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStatusLine.Init (Var Bounds: TRect; ADefs: PStatusDef);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR ofPreProcess; { Pre processing view }
+ EventMask := EventMask OR evBroadcast; { See broadcasts }
+ GrowMode := gfGrowLoY + gfGrowHiX + gfGrowHiY; { Set grow modes }
+ Defs := ADefs; { Set default items }
+ FindItems; { Find the items }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStatusLine.Load (Var S: TStream);
+
+ FUNCTION DoLoadStatusItems: PStatusItem;
+ VAR Count: Integer; Cur, First: PStatusItem; Last: ^PStatusItem;
+ BEGIN
+ Cur := Nil; { Preset nil }
+ Last := @First; { Start on first item }
+ S.Read(Count, SizeOf(Count)); { Read count }
+ While (Count > 0) Do Begin
+ New(Cur); { New status item }
+ Last^ := Cur; { First chain part }
+ If (Cur <> Nil) Then Begin { Check pointer valid }
+ Last := @Cur^.Next; { Chain complete }
+ Cur^.Text := S.ReadStr; { Read item text }
+ S.Read(Cur^.KeyCode, SizeOf(Cur^.KeyCode)); { Keycode of item }
+ S.Read(Cur^.Command, SizeOf(Cur^.Command)); { Command of item }
+ End;
+ Dec(Count); { One item loaded }
+ End;
+ Last^ := Nil; { Now chain end }
+ DoLoadStatusItems := First; { Return the list }
+ END;
+
+ FUNCTION DoLoadStatusDefs: PStatusDef;
+ VAR Count: Integer; Cur, First: PStatusDef; Last: ^PStatusDef;
+ BEGIN
+ Last := @First; { Start on first }
+ S.Read(Count, SizeOf(Count)); { Read item count }
+ While (Count > 0) Do Begin
+ New(Cur); { New status def }
+ Last^ := Cur; { First part of chain }
+ If (Cur <> Nil) Then Begin { Check pointer valid }
+ Last := @Cur^.Next; { Chain complete }
+ S.Read(Cur^.Min, SizeOf(Cur^.Min)); { Read min data }
+ S.Read(Cur^.Max, SizeOf(Cur^.Max)); { Read max data }
+ Cur^.Items := DoLoadStatusItems; { Set pointer }
+ End;
+ Dec(Count); { One item loaded }
+ End;
+ Last^ := Nil; { Now chain ends }
+ DoLoadStatusDefs := First; { Return item list }
+ END;
+
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Defs := DoLoadStatusDefs; { Retreive items }
+ FindItems; { Find the items }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TStatusLine.Done;
+VAR T: PStatusDef;
+
+ PROCEDURE DisposeItems (Item: PStatusItem);
+ VAR T: PStatusItem;
+ BEGIN
+ While (Item <> Nil) Do Begin { Item to dispose }
+ T := Item; { Hold pointer }
+ Item := Item^.Next; { Move down chain }
+ DisposeStr(T^.Text); { Dispose string }
+ Dispose(T); { Dispose item }
+ End;
+ END;
+
+BEGIN
+ While (Defs <> Nil) Do Begin
+ T := Defs; { Hold pointer }
+ Defs := Defs^.Next; { Move down chain }
+ DisposeItems(T^.Items); { Dispose the item }
+ Dispose(T); { Dispose status item }
+ End;
+ Inherited Done; { Call ancestor }
+END;
+
+
+{--TStatusLine--------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TStatusLine.GetPalette: PPalette;
+{$IFDEF PPC_DELPHI3} { DELPHI3+ COMPILER }
+CONST P: String = CStatusLine; { Possible huge string }
+{$ELSE} { OTHER COMPILERS }
+CONST P: String[Length(CStatusLine)] = CStatusLine; { Always normal string }
+{$ENDIF}
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Hint -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TStatusLine.Hint (AHelpCtx: Word): String;
+BEGIN
+ Hint := ''; { Return nothing }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.Draw;
+BEGIN
+ DrawSelect(Nil); { Call draw select }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Update -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.Update;
+VAR H: Word; P: PView;
+BEGIN
+ P := TopView; { Get topmost view }
+ If (P <> Nil) Then H := P^.GetHelpCtx Else { Top views context }
+ H := hcNoContext; { No context }
+ If (HelpCtx <> H) Then Begin { Differs from last }
+ HelpCtx := H; { Hold new context }
+ FindItems; { Find the item }
+ DrawView; { Redraw the view }
+ End;
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.Store (Var S: TStream);
+
+ PROCEDURE DoStoreStatusItems (Cur: PStatusItem);
+ VAR Count: Integer; T: PStatusItem;
+ BEGIN
+ Count := 0; { Clear count }
+ T := Cur; { Start on current }
+ While (T <> Nil) Do Begin
+ Inc(Count); { Count items }
+ T := T^.Next; { Next item }
+ End;
+ S.Write(Count, SizeOf(Count)); { Write item count }
+ While (Cur <> Nil) Do Begin
+ S.WriteStr(Cur^.Text); { Store item text }
+ S.Write(Cur^.KeyCode, SizeOf(Cur^.KeyCode)); { Keycode of item }
+ S.Write(Cur^.Command, SizeOf(Cur^.Command)); { Command of item }
+ Cur := Cur^.Next; { Move to next item }
+ End;
+ END;
+
+ PROCEDURE DoStoreStatusDefs (Cur: PStatusDef);
+ VAR Count: Integer; T: PStatusDef;
+ BEGIN
+ Count := 0; { Clear count }
+ T := Cur; { Current status item }
+ While (T <> Nil) Do Begin
+ Inc(Count); { Count items }
+ T := T^.Next { Next item }
+ End;
+ S.Write(Count, 2); { Write item count }
+ While (Cur <> Nil) Do Begin
+ With Cur^ Do Begin
+ S.Write(Cur^.Min, 2); { Write min data }
+ S.Write(Cur^.Max, 2); { Write max data }
+ DoStoreStatusItems(Items); { Store the items }
+ End;
+ Cur := Cur^.Next; { Next status item }
+ End;
+ END;
+
+BEGIN
+ TView.Store(S); { TView.Store called }
+ DoStoreStatusDefs(Defs); { Store status items }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.HandleEvent (Var Event: TEvent);
+VAR Mouse: TPoint; T, Tt: PStatusItem;
+
+ FUNCTION ItemMouseIsIn: PStatusItem;
+ VAR X, Xi: Word; T: PStatusItem;
+ BEGIN
+ ItemMouseIsIn := Nil; { Preset fail }
+ If (Mouse.Y < 0) OR (Mouse.Y > 1) { Outside view height }
+ Then Exit; { Not in view exit }
+ X := 0; { Zero x position }
+ T := Items; { Start at first item }
+ While (T <> Nil) Do Begin { While item valid }
+ If (T^.Text <> Nil) Then Begin { Check valid text }
+ Xi := X; { Hold initial x value }
+ X := Xi + CTextWidth(' ' + T^.Text^ + ' '); { Add text width }
+ If (Mouse.X >= Xi) AND (Mouse.X < X)
+ Then Begin
+ ItemMouseIsIn := T; { Selected item }
+ Exit; { Now exit }
+ End;
+ End;
+ T := T^.Next; { Next item }
+ End;
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evMouseDown: Begin
+ T := Nil; { Preset ptr to nil }
+ Repeat
+ Mouse.X := Event.Where.X - Origin.X; { Local x position }
+ Mouse.Y := Event.Where.Y - Origin.Y; { Local y position }
+ Tt := ItemMouseIsIn; { Find selected item }
+ If (T <> Tt) Then { Item has changed }
+ DrawSelect(Tt); { Draw new item }
+ T := Tt { Transfer item }
+ Until NOT MouseEvent(Event, evMouseMove); { Mouse stopped moving }
+ If (T <> Nil) AND CommandEnabled(T^.Command) { Check cmd enabled }
+ Then Begin
+ Event.What := evCommand; { Command event }
+ Event.Command := T^.Command; { Set command value }
+ Event.InfoPtr := Nil; { No info ptr }
+ PutEvent(Event); { Put event on queue }
+ End;
+ ClearEvent(Event); { Clear the event }
+ DrawSelect(Nil); { Clear the highlight }
+ End;
+ evKeyDown: Begin { Key down event }
+ T := Items; { Start on first item }
+ While (T <> Nil) Do Begin { For each valid item }
+ If (Event.KeyCode = T^.KeyCode) AND { Check for hot key }
+ CommandEnabled(T^.Command) Then Begin { Check cmd enabled }
+ Event.What := evCommand; { Change to command }
+ Event.Command := T^.Command; { Set command value }
+ Event.InfoPtr := Nil; { Clear info ptr }
+ PutEvent(Event); { Put event on queue }
+ ClearEvent(Event); { Clear the event }
+ Exit; Exit; { Now exit }
+ End;
+ T := T^.Next; { Next item }
+ End;
+ End;
+ evBroadcast:
+ If (Event.Command = cmCommandSetChanged) Then { Command set change }
+ DrawView; { Redraw view }
+ End;
+END;
+
+{***************************************************************************}
+{ TStatusLine OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{--TStatusLine--------------------------------------------------------------}
+{ FindItems -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.FindItems;
+VAR P: PStatusDef;
+BEGIN
+ P := Defs; { First status item }
+ While (P <> Nil) AND ((HelpCtx < P^.Min) OR
+ (HelpCtx > P^.Max)) Do P := P^.Next; { Find status item }
+ If (P = Nil) Then Items := Nil Else
+ Items := P^.Items; { Return found item }
+END;
+
+{--TStatusLine--------------------------------------------------------------}
+{ DrawSelect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStatusLine.DrawSelect (Selected: PStatusItem);
+VAR I, L: Integer; Color, CSelect, CNormal, CSelDisabled, CNormDisabled: Word;
+ HintBuf: String; B: TDrawBuffer; T: PStatusItem;
+BEGIN
+ CNormal := GetColor($0301); { Normal colour }
+ CSelect := GetColor($0604); { Select colour }
+ CNormDisabled := GetColor($0202); { Disabled colour }
+ CSelDisabled := GetColor($0505); { Select disabled }
+ MoveChar(B, ' ', Byte(CNormal), Size.X); { Clear the buffer }
+ T := Items; { First item }
+ I := 0; { Clear the count }
+ L := 0;
+ While (T <> Nil) Do Begin { While valid item }
+ If (T^.Text <> Nil) Then Begin { While valid text }
+ L := CStrLen(' '+T^.Text^+' '); { Text length }
+ If CommandEnabled(T^.Command) Then Begin { Command enabled }
+ If T = Selected Then Color := CSelect { Selected colour }
+ Else Color := CNormal { Normal colour }
+ End Else
+ If T = Selected Then Color := CSelDisabled { Selected disabled }
+ Else Color := CNormDisabled; { Disabled colour }
+ MoveCStr(B[I], ' '+T^.Text^+' ', Color); { Move text to buf }
+ Inc(I, L); { Advance position }
+ End;
+ T := T^.Next; { Next item }
+ End;
+ HintBuf := Hint(HelpCtx); { Get hint string }
+ If (HintBuf <> '') Then Begin { Hint present }
+ {$IFNDEF OS_WINDOWS}
+ MoveChar(B[I], #179, Byte(CNormal), 1); { '|' char to buffer }
+ {$ELSE}
+ MoveChar(B[I], #166, Byte(CNormal), 1); { '|' char to buffer }
+ {$ENDIF}
+ Inc(I, 2); { Move along }
+ MoveStr(B[I], HintBuf, Byte(CNormal)); { Move hint to buffer }
+ I := I + Length(HintBuf); { Hint length }
+ End;
+ WriteLine(0, 0, Size.X, 1, B); { Write the buffer }
+END;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MENU INTERFACE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ NewMenu -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewMenu (Items: PMenuItem): PMenu;
+VAR P: PMenu;
+BEGIN
+ New(P); { Create new menu }
+ FillChar(P^,sizeof(TMenu),0);
+ If (P <> Nil) Then Begin { Check valid pointer }
+ P^.Items := Items; { Hold item list }
+ P^.Default := Items; { Set default item }
+ End;
+ NewMenu := P; { Return menu }
+END;
+
+{---------------------------------------------------------------------------}
+{ DisposeMenu -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE DisposeMenu (Menu: PMenu);
+VAR P, Q: PMenuItem;
+BEGIN
+ If (Menu <> Nil) Then Begin { Valid menu item }
+ P := Menu^.Items; { First item in list }
+ While (P <> Nil) Do Begin { Item is valid }
+ If (P^.Name <> Nil) Then Begin { Valid name pointer }
+ DisposeStr(P^.Name); { Dispose of name }
+ If (P^.Command <> 0) Then
+ DisposeStr(P^.Param) Else { Dispose parameter }
+ DisposeMenu(P^.SubMenu); { Dispose submenu }
+ End;
+ Q := P; { Hold pointer }
+ P := P^.Next; { Move to next item }
+ Dispose(Q); { Dispose of item }
+ End;
+ Dispose(Menu); { Dispose of menu }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ MENU ITEM ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ NewLine -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewLine (Next: PMenuItem): PMenuItem;
+VAR P: PMenuItem;
+BEGIN
+ New(P); { Allocate memory }
+ FillChar(P^,sizeof(TMenuItem),0);
+ If (P <> Nil) Then Begin { Check valid pointer }
+ P^.Next := Next; { Hold next menu item }
+ End;
+ NewLine := P; { Return new line }
+END;
+
+{---------------------------------------------------------------------------}
+{ NewItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewItem (Name, Param: TMenuStr; KeyCode: Word; Command: Word;
+ AHelpCtx: Word; Next: PMenuItem): PMenuItem;
+VAR P: PMenuItem; R: TRect; T: PView;
+BEGIN
+ If (Name <> '') AND (Command <> 0) Then Begin
+ New(P); { Allocate memory }
+ FillChar(P^,sizeof(TMenuItem),0);
+ If (P <> Nil) Then Begin { Check valid pointer }
+ P^.Next := Next; { Hold next item }
+ P^.Name := NewStr(Name); { Hold item name }
+ P^.Command := Command; { Hold item command }
+ R.Assign(1, 1, 10, 10); { Random assignment }
+ T := New(PView, Init(R)); { Create a view }
+ If (T <> Nil) Then Begin
+ P^.Disabled := NOT T^.CommandEnabled(Command);
+ Dispose(T, Done); { Dispose of view }
+ End Else P^.Disabled := True;
+ P^.KeyCode := KeyCode; { Hold item keycode }
+ P^.HelpCtx := AHelpCtx; { Hold help context }
+ P^.Param := NewStr(Param); { Hold parameter }
+ End;
+ NewItem := P; { Return item }
+ End Else NewItem := Next; { Move forward }
+END;
+
+{---------------------------------------------------------------------------}
+{ NewSubMenu -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 14May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewSubMenu (Name: TMenuStr; AHelpCtx: Word; SubMenu: PMenu;
+ Next: PMenuItem): PMenuItem;
+VAR P: PMenuItem;
+BEGIN
+ If (Name <> '') AND (SubMenu <> Nil) Then Begin
+ New(P); { Allocate memory }
+ FillChar(P^,sizeof(TMenuItem),0);
+ If (P <> Nil) Then Begin { Check valid pointer }
+ P^.Next := Next; { Hold next item }
+ P^.Name := NewStr(Name); { Hold submenu name }
+ P^.HelpCtx := AHelpCtx; { Set help context }
+ P^.SubMenu := SubMenu; { Hold next submenu }
+ End;
+ NewSubMenu := P; { Return submenu }
+ End Else NewSubMenu := Next; { Return next item }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STATUS INTERFACE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ NewStatusDef -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewStatusDef (AMin, AMax: Word; AItems: PStatusItem;
+ANext:PStatusDef): PStatusDef;
+VAR T: PStatusDef;
+BEGIN
+ New(T); { Allocate memory }
+ If (T <> Nil) Then Begin { Check valid pointer }
+ T^.Next := ANext; { Set next item }
+ T^.Min := AMin; { Hold min value }
+ T^.Max := AMax; { Hold max value }
+ T^.Items := AItems; { Hold item list }
+ End;
+ NewStatusDef := T; { Return status }
+END;
+
+{---------------------------------------------------------------------------}
+{ NewStatusKey -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewStatusKey (AText: String; AKeyCode: Word; ACommand: Word;
+ ANext: PStatusItem): PStatusItem;
+VAR T: PStatusItem;
+BEGIN
+ New(T); { Allocate memory }
+ If (T <> Nil) Then Begin { Check valid pointer }
+ T^.Text := NewStr(AText); { Hold text string }
+ T^.KeyCode := AKeyCode; { Hold keycode }
+ T^.Command := ACommand; { Hold command }
+ T^.Next := ANext; { Pointer to next }
+ End;
+ NewStatusKey := T; { Return status item }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ RegisterMenus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE RegisterMenus;
+BEGIN
+ RegisterType(RMenuBar); { Register bar menu }
+ RegisterType(RMenuBox); { Register menu box }
+ RegisterType(RStatusLine); { Register status line }
+ RegisterType(RMenuPopup); { Register popup menu }
+END;
+
+END.
diff --git a/packages/fv/src/msgbox.pas b/packages/fv/src/msgbox.pas
new file mode 100644
index 0000000000..e9b867c530
--- /dev/null
+++ b/packages/fv/src/msgbox.pas
@@ -0,0 +1,321 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of MSGBOX.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail addr }
+{ ldeboer@starwon.com.au - backup e-mail addr }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 12 Jun 96 Initial DOS/DPMI code released. }
+{ 1.10 18 Oct 97 Code converted to GUI & TEXT mode. }
+{ 1.20 18 Jul 97 Windows conversion added. }
+{ 1.30 29 Aug 97 Platform.inc sort added. }
+{ 1.40 22 Oct 97 Delphi3 32 bit code added. }
+{ 1.50 05 May 98 Virtual pascal 2.0 code added. }
+{ 1.60 30 Sep 99 Complete recheck preformed }
+{**********************************************************}
+
+UNIT MsgBox;
+
+{2.0 compatibility}
+{$ifdef VER2_0}
+ {$macro on}
+ {$define resourcestring := const}
+{$endif}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Near calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES objects, dialogs; { Standard GFV units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ MESSAGE BOX CLASSES }
+{---------------------------------------------------------------------------}
+CONST
+ mfWarning = $0000; { Display a Warning box }
+ mfError = $0001; { Dispaly a Error box }
+ mfInformation = $0002; { Display an Information Box }
+ mfConfirmation = $0003; { Display a Confirmation Box }
+
+ mfInsertInApp = $0080; { Insert message box into }
+ { app instead of the Desktop }
+{---------------------------------------------------------------------------}
+{ MESSAGE BOX BUTTON FLAGS }
+{---------------------------------------------------------------------------}
+CONST
+ mfYesButton = $0100; { Yes button into the dialog }
+ mfNoButton = $0200; { No button into the dialog }
+ mfOKButton = $0400; { OK button into the dialog }
+ mfCancelButton = $0800; { Cancel button into the dialog }
+
+ mfYesNoCancel = mfYesButton + mfNoButton + mfCancelButton;
+ { Yes, No, Cancel dialog }
+ mfOKCancel = mfOKButton + mfCancelButton;
+ { Standard OK, Cancel dialog }
+
+var
+ MsgBoxTitles: array[0..3] of string[40];
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+procedure InitMsgBox;
+procedure DoneMsgBox;
+ { Init initializes the message box display system's text strings. Init is
+ called by TApplication.Init after a successful call to Resource.Init or
+ Resource.Load. }
+
+{-MessageBox---------------------------------------------------------
+MessageBox displays the given string in a standard sized dialog box.
+Before the dialog is displayed the Msg and Params are passed to FormatStr.
+The resulting string is displayed as a TStaticText view in the dialog.
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION MessageBox (Const Msg: String; Params: Pointer;
+ AOptions: Word): Word;
+
+{-MessageBoxRect-----------------------------------------------------
+MessageBoxRec allows the specification of a TRect for the message box
+to occupy.
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION MessageBoxRect (Var R: TRect; Const Msg: String; Params: Pointer;
+ AOptions: Word): Word;
+
+{-MessageBoxRectDlg--------------------------------------------------
+MessageBoxRecDlg allows the specification of a TRect for the message box
+to occupy plus the dialog window (to allow different dialog window types).
+---------------------------------------------------------------------}
+FUNCTION MessageBoxRectDlg (Dlg: PDialog; Var R: TRect; Const Msg: String;
+ Params: Pointer; AOptions: Word): Word;
+
+{-InputBox-----------------------------------------------------------
+InputBox displays a simple dialog that allows user to type in a string
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION InputBox (Const Title, ALabel: String; Var S: String;
+ Limit: Byte): Word;
+
+{-InputBoxRect-------------------------------------------------------
+InputBoxRect is like InputBox but allows the specification of a rectangle.
+30Sep99 LdB
+---------------------------------------------------------------------}
+FUNCTION InputBoxRect (Var Bounds: TRect; Const Title, ALabel: String;
+ Var S: String; Limit: Byte): Word;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+USES Drivers, Views, App{, Resource}; { Standard GFV units }
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+const
+ Commands: array[0..3] of word =
+ (cmYes, cmNo, cmOK, cmCancel);
+var
+ ButtonName: array[0..3] of string[40];
+
+resourcestring sConfirm='Confirm';
+ sError='Error';
+ sInformation='Information';
+ sWarning='Warning';
+
+
+{---------------------------------------------------------------------------}
+{ MessageBox -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MessageBox(Const Msg: String; Params: Pointer; AOptions: Word): Word;
+VAR R: TRect;
+BEGIN
+ R.Assign(0, 0, 40, 9); { Assign area }
+ If (AOptions AND mfInsertInApp = 0) Then { Non app insert }
+ R.Move((Desktop^.Size.X - R.B.X) DIV 2,
+ (Desktop^.Size.Y - R.B.Y) DIV 2) Else { Calculate position }
+ R.Move((Application^.Size.X - R.B.X) DIV 2,
+ (Application^.Size.Y - R.B.Y) DIV 2); { Calculate position }
+ MessageBox := MessageBoxRect(R, Msg, Params,
+ AOptions); { Create message box }
+END;
+
+FUNCTION MessageBoxRectDlg (Dlg: PDialog; Var R: TRect; Const Msg: String;
+ Params: Pointer; AOptions: Word): Word;
+VAR I, X, ButtonCount: Integer; S: String; Control: PView;
+ ButtonList: Array[0..4] Of PView;
+BEGIN
+ With Dlg^ Do Begin
+ FormatStr(S, Msg, Params^); { Format the message }
+ Control := New(PStaticText, Init(R, S)); { Create static text }
+ Insert(Control); { Insert the text }
+ X := -2; { Set initial value }
+ ButtonCount := 0; { Clear button count }
+ For I := 0 To 3 Do
+ If (AOptions AND ($0100 SHL I) <> 0) Then Begin
+ R.Assign(0, 0, 10, 2); { Assign screen area }
+ Control := New(PButton, Init(R, ButtonName[I],
+ Commands[i], bfNormal)); { Create button }
+ Inc(X, Control^.Size.X + 2); { Adjust position }
+ ButtonList[ButtonCount] := Control; { Add to button list }
+ Inc(ButtonCount); { Inc button count }
+ End;
+ X := (Size.X - X) SHR 1; { Calc x position }
+ If (ButtonCount > 0) Then
+ For I := 0 To ButtonCount - 1 Do Begin { For each button }
+ Control := ButtonList[I]; { Transfer button }
+ Insert(Control); { Insert button }
+ Control^.MoveTo(X, Size.Y - 3); { Position button }
+ Inc(X, Control^.Size.X + 2); { Adjust position }
+ End;
+ SelectNext(False); { Select first button }
+ End;
+ If (AOptions AND mfInsertInApp = 0) Then
+ MessageBoxRectDlg := DeskTop^.ExecView(Dlg) Else { Execute dialog }
+ MessageBoxRectDlg := Application^.ExecView(Dlg); { Execute dialog }
+end;
+
+
+{---------------------------------------------------------------------------}
+{ MessageBoxRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MessageBoxRect(Var R: TRect; Const Msg: String; Params: Pointer;
+ AOptions: Word): Word;
+var
+ Dialog: PDialog;
+BEGIN
+ Dialog := New (PDialog, Init (R, MsgBoxTitles [AOptions
+ AND $3])); { Create dialog }
+ with Dialog^ do
+ R.Assign(3, 2, Size.X - 2, Size.Y - 3); { Assign area for text }
+ MessageBoxRect := MessageBoxRectDlg (Dialog, R, Msg, Params, AOptions);
+ Dispose (Dialog, Done); { Dispose of dialog }
+END;
+
+{---------------------------------------------------------------------------}
+{ InputBox -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION InputBox(Const Title, ALabel: String; Var S: String;
+ Limit: Byte): Word;
+VAR R: TRect;
+BEGIN
+ R.Assign(0, 0, 60, 8); { Assign screen area }
+ R.Move((Desktop^.Size.X - R.B.X) DIV 2,
+ (Desktop^.Size.Y - R.B.Y) DIV 2); { Position area }
+ InputBox := InputBoxRect(R, Title, ALabel, S,
+ Limit); { Create input box }
+END;
+
+{---------------------------------------------------------------------------}
+{ InputBoxRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION InputBoxRect(Var Bounds: TRect; Const Title, ALabel: String;
+ Var S: String; Limit: Byte): Word;
+VAR C: Word; R: TRect; Control: PView; Dialog: PDialog;
+BEGIN
+ Dialog := New(PDialog, Init(Bounds, Title)); { Create dialog }
+ With Dialog^ Do Begin
+ R.Assign(4 + CStrLen(ALabel), 2, Size.X - 3, 3); { Assign screen area }
+ Control := New(PInputLine, Init(R, Limit)); { Create input line }
+ Insert(Control); { Insert input line }
+ R.Assign(2, 2, 3 + CStrLen(ALabel), 3); { Assign screen area }
+ Insert(New(PLabel, Init(R, ALabel, Control))); { Insert label }
+ R.Assign(Size.X - 24, Size.Y - 4, Size.X - 14,
+ Size.Y - 2); { Assign screen area }
+ Insert(New(PButton, Init(R, 'O~K~', cmOk,
+ bfDefault))); { Insert okay button }
+ Inc(R.A.X, 12); { New start x position }
+ Inc(R.B.X, 12); { New end x position }
+ Insert(New(PButton, Init(R, 'Cancel', cmCancel,
+ bfNormal))); { Insert cancel button }
+ Inc(R.A.X, 12); { New start x position }
+ Inc(R.B.X, 12); { New end x position }
+ SelectNext(False); { Select first button }
+ End;
+ Dialog^.SetData(S); { Set data in dialog }
+ C := DeskTop^.ExecView(Dialog); { Execute the dialog }
+ If (C <> cmCancel) Then Dialog^.GetData(S); { Get data from dialog }
+ Dispose(Dialog, Done); { Dispose of dialog }
+ InputBoxRect := C; { Return execute result }
+END;
+
+
+procedure InitMsgBox;
+begin
+ ButtonName[0] := slYes;
+ ButtonName[1] := slNo;
+ ButtonName[2] := slOk;
+ ButtonName[3] := slCancel;
+ MsgBoxTitles[0] := sWarning;
+ MsgBoxTitles[1] := sError;
+ MsgBoxTitles[2] := sInformation;
+ MsgBoxTitles[3] := sConfirm;
+end;
+
+procedure DoneMsgBox;
+begin
+end;
+
+END.
diff --git a/packages/fv/src/outline.pas b/packages/fv/src/outline.pas
new file mode 100644
index 0000000000..38a9803f4f
--- /dev/null
+++ b/packages/fv/src/outline.pas
@@ -0,0 +1,685 @@
+unit outline;
+
+{$CODEPAGE cp437}
+
+{***************************************************************************}
+ interface
+{***************************************************************************}
+
+uses drivers,objects,views;
+
+type Pnode=^Tnode;
+ Tnode=record
+ next:Pnode;
+ text:Pstring;
+ childlist:Pnode;
+ expanded:boolean;
+ end;
+
+ Poutlineviewer=^Toutlineviewer;
+ Toutlineviewer=object(Tscroller)
+ foc:sw_integer;
+ constructor init(var bounds:Trect;
+ AHscrollbar,AVscrollbar:Pscrollbar);
+ procedure adjust(node:pointer;expand:boolean);virtual;
+ function creategraph(level:integer;lines:longint;
+ flags:word;levwidth,endwidth:integer;
+ const chars:string):string;
+ procedure draw;virtual;
+ procedure expandall(node:pointer);
+ function firstthat(test:pointer):pointer;
+ procedure focused(i:sw_integer);virtual;
+ procedure foreach(action:pointer);
+ function getchild(node:pointer;i:sw_integer):pointer;virtual;
+ function getgraph(level:integer;lines:longint;flags:word):string;
+ function getnode(i:sw_integer):pointer;virtual;
+ function getnumchildren(node:pointer):sw_integer;virtual;
+ function getpalette:Ppalette;virtual;
+ function getroot:pointer;virtual;
+ function gettext(node:pointer):string;virtual;
+ procedure handleevent(var event:Tevent);virtual;
+ function haschildren(node:pointer):boolean;virtual;
+ function isexpanded(node:pointer):boolean;virtual;
+ function isselected(i:sw_integer):boolean;virtual;
+ procedure selected(i:sw_integer);virtual;
+ procedure setstate(Astate:word;enable:boolean);virtual;
+ procedure update;
+ private
+ procedure set_focus(Afocus:sw_integer);
+ function do_recurse(action,callerframe:pointer;
+ stop_if_found:boolean):pointer;
+ end;
+
+ Poutline=^Toutline;
+ Toutline=object(Toutlineviewer)
+ root:Pnode;
+ constructor init(var bounds:Trect;
+ AHscrollbar,AVscrollbar:Pscrollbar;
+ Aroot:Pnode);
+ procedure adjust(node:pointer;expand:boolean);virtual;
+ function getchild(node:pointer;i:sw_integer):pointer;virtual;
+ function getnumchildren(node:pointer):sw_integer;virtual;
+ function getroot:pointer;virtual;
+ function gettext(node:pointer):string;virtual;
+ function haschildren(node:pointer):boolean;virtual;
+ function isexpanded(node:pointer):boolean;virtual;
+ destructor done;virtual;
+ end;
+
+const ovExpanded = $1;
+ ovChildren = $2;
+ ovLast = $4;
+
+ Coutlineviewer=Cscroller+#8#8;
+
+function newnode(const Atext:string;Achildren,Anext:Pnode):Pnode;
+procedure disposenode(node:Pnode);
+
+
+{***************************************************************************}
+ implementation
+{***************************************************************************}
+
+type TMyFunc = function(_EBP: Pointer; Cur: Pointer;
+ Level, Position: sw_integer; Lines: LongInt;
+ Flags: Word): Boolean;
+
+
+function newnode(const Atext:string;Achildren,Anext:Pnode):Pnode;
+
+begin
+ newnode:=new(Pnode);
+ with newnode^ do
+ begin
+ next:=Anext;
+ text:=newstr(Atext);
+ childlist:=Achildren;
+ expanded:=true;
+ end;
+end;
+
+procedure disposenode(node:Pnode);
+
+var next:Pnode;
+
+begin
+ while node<>nil do
+ begin
+ disposenode(node^.childlist);
+ disposestr(node^.text);
+ next:=node^.next;
+ dispose(node);
+ node:=next;
+ end;
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ Toutlineviewer object methods }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+constructor Toutlineviewer.init(var bounds:Trect;
+ AHscrollbar,AVscrollbar:Pscrollbar);
+
+begin
+ inherited init(bounds,AHscrollbar,AVscrollbar);
+ foc:=0;
+ growmode:=gfGrowHiX+gfGrowHiY;
+end;
+
+procedure Toutlineviewer.adjust(node:pointer;expand:boolean);
+
+begin
+ abstract;
+end;
+
+function TOutlineViewer.CreateGraph(Level: Integer; Lines: LongInt;
+ Flags: Word; LevWidth, EndWidth: Integer;
+ const Chars: String): String;
+const
+ FillerOrBar = 0;
+ YorL = 2;
+ StraightOrTee= 4;
+ Retracted = 6;
+var
+ Last, Children, Expanded: Boolean;
+ I , J : Byte;
+ Graph : String;
+
+begin
+ { Load registers }
+ graph:=space(Level*LevWidth+EndWidth+1);
+
+ { Write bar characters }
+ J := 1;
+ while (Level > 0) do
+ begin
+ Inc(J);
+ if (Lines and 1) <> 0 then
+ Graph[J] := Chars[FillerOrBar+2]
+ else
+ Graph[J] := Chars[FillerOrBar+1];
+ for I := 1 to LevWidth - 1 do
+ Graph[I]:= Chars[FillerOrBar+1];
+ J := J + LevWidth - 1;
+ Dec(Level);
+ Lines := Lines shr 1;
+ end;
+
+ { Write end characters }
+ Dec(EndWidth);
+ if EndWidth > 0 then
+ begin
+ Inc(J);
+ if Flags and ovLast <> 0 then
+ Graph[J] := Chars[YorL+2]
+ else
+ Graph[J] := Chars[YorL+1];
+ Dec(EndWidth);
+ if EndWidth > 0 then
+ begin
+ Dec(EndWidth);
+ for I := 1 to EndWidth do
+ Graph[I]:= Chars[StraightOrTee+1];
+ J := J + EndWidth;
+ Inc(J);
+ if (Flags and ovChildren) <> 0 then
+ Graph[J] := Chars[StraightOrTee+2]
+ else
+ Graph[J] := Chars[StraightOrTee+1];
+ end;
+ Inc(J);
+ if Flags and ovExpanded <> 0 then
+ Graph[J] := Chars[Retracted+2]
+ else
+ Graph[J] := Chars[Retracted+1];
+ end;
+ Graph[0] := Char(J);
+
+ CreateGraph := Graph;
+end;
+
+function Toutlineviewer.do_recurse(action,callerframe:pointer;
+ stop_if_found:boolean):pointer;
+
+var position:sw_integer;
+ r:pointer;
+
+ function recurse(cur:pointer;level:integer;lines:longint;lastchild:boolean):pointer;
+
+ var i,childcount:sw_integer;
+ child:pointer;
+ flags:word;
+ children,expanded,found:boolean;
+
+ begin
+ inc(position);
+ recurse:=nil;
+
+ children:=haschildren(cur);
+ expanded:=isexpanded(cur);
+
+ {Determine flags.}
+ flags:=0;
+ if not children or expanded then
+ inc(flags,ovExpanded);
+ if children and expanded then
+ inc(flags,ovChildren);
+ if lastchild then
+ inc(flags,ovLast);
+
+ {Call the function.}
+ found:=TMyFunc(action)(callerframe,cur,level,position,lines,flags);
+
+ if stop_if_found and found then
+ recurse:=cur
+ else if children and expanded then {Recurse children?}
+ begin
+ if not lastchild then
+ lines:=lines or (1 shl level);
+ {Iterate all childs.}
+ childcount:=getnumchildren(cur);
+ for i:=0 to childcount-1 do
+ begin
+ child:=getchild(cur,i);
+ if (child<>nil) and (level<31) then
+ recurse:=recurse(child,level+1,lines,i=childcount-1);
+ {Did we find a node?}
+ if recurse<>nil then
+ break;
+ end;
+ end;
+ end;
+
+begin
+ position:=-1;
+ r:=getroot;
+ if r<>nil then
+ do_recurse:=recurse(r,0,0,true)
+ else
+ do_recurse:=nil;
+end;
+
+procedure Toutlineviewer.draw;
+
+var c_normal,c_normal_x,c_select,c_focus:byte;
+ maxpos:sw_integer;
+ b:Tdrawbuffer;
+
+ function draw_item(cur:pointer;level,position:sw_integer;
+ lines:longint;flags:word):boolean;
+
+ var c,i:byte;
+ s,t:string;
+
+ begin
+ draw_item:=position>=delta.y+size.y;
+ if (position<delta.y) or draw_item then
+ exit;
+
+ maxpos:=position;
+ s:=getgraph(level,lines,flags);
+ t:=gettext(cur);
+
+ {Determine text colour.}
+ if (foc=position) and (state and sffocused<>0) then
+ c:=c_focus
+ else if isselected(position) then
+ c:=c_select
+ else if flags and ovexpanded<>0 then
+ c:=c_normal_x
+ else
+ c:=c_normal;
+
+ {Fill drawbuffer with graph and text to draw.}
+ for i:=0 to size.x-1 do
+ begin
+ wordrec(b[i]).hi:=c;
+ if i+delta.x<length(s) then
+ wordrec(b[i]).lo:=byte(s[1+i+delta.x])
+ else if 1+i+delta.x-length(s)<=length(t) then
+ wordrec(b[i]).lo:=byte(t[1+i+delta.x-length(s)])
+ else
+ wordrec(b[i]).lo:=byte(' ');
+ end;
+
+ {Draw!}
+ writeline(0,position-delta.y,size.x,1,b);
+ end;
+
+begin
+ c_normal:=getcolor(4);
+ c_normal_x:=getcolor(1);
+ c_focus:=getcolor(2);
+ c_select:=getcolor(3);
+ maxpos:=-1;
+ foreach(@draw_item);
+ movechar(b,' ',c_normal,size.x);
+ writeline(0,maxpos+1,size.x,size.y-(maxpos-delta.y),b);
+end;
+
+procedure Toutlineviewer.expandall(node:pointer);
+
+var i:sw_integer;
+
+begin
+ if haschildren(node) then
+ begin
+ for i:=0 to getnumchildren(node)-1 do
+ expandall(getchild(node,i));
+ adjust(node,true);
+ end;
+end;
+
+function Toutlineviewer.firstthat(test:pointer):pointer;
+
+begin
+ firstthat:=do_recurse(test,get_caller_frame(get_frame),true);
+end;
+
+procedure Toutlineviewer.focused(i:sw_integer);
+
+begin
+ foc:=i;
+end;
+
+procedure Toutlineviewer.foreach(action:pointer);
+
+begin
+ do_recurse(action,get_caller_frame(get_frame),false);
+end;
+
+function Toutlineviewer.getchild(node:pointer;i:sw_integer):pointer;
+
+begin
+ abstract;
+end;
+
+function Toutlineviewer.getgraph(level:integer;lines:longint;
+ flags:word):string;
+
+begin
+ getgraph:=creategraph(level,lines,flags,3,3,' ³ÃÀÄÄ+Ä');
+end;
+
+function Toutlineviewer.getnode(i:sw_integer):pointer;
+
+ function test_position(node:pointer;level,position:sw_integer;lines:longInt;
+ flags:word):boolean;
+
+ begin
+ test_position:=position=i;
+ end;
+
+begin
+ getnode:=firstthat(@test_position);
+end;
+
+function Toutlineviewer.getnumchildren(node:pointer):sw_integer;
+
+begin
+ abstract;
+end;
+
+function Toutlineviewer.getpalette:Ppalette;
+
+const p:string[length(Coutlineviewer)]=Coutlineviewer;
+
+begin
+ getpalette:=@p;
+end;
+
+function Toutlineviewer.getroot:pointer;
+
+begin
+ abstract;
+end;
+
+function Toutlineviewer.gettext(node:pointer):string;
+
+begin
+ abstract;
+end;
+
+procedure Toutlineviewer.handleevent(var event:Tevent);
+
+var mouse:Tpoint;
+ cur:pointer;
+ new_focus:sw_integer;
+ count:byte;
+ handled,m,mouse_drag:boolean;
+ graph:string;
+
+ function graph_of_focus(var graph:string):pointer;
+
+ var _level:sw_integer;
+ _lines:longInt;
+ _flags:word;
+
+ function find_focused(cur:pointer;level,position:sw_integer;
+ lines:longint;flags:word):boolean;
+
+ begin
+ find_focused:=position=foc;
+ if find_focused then
+ begin
+ _level:=level;
+ _lines:=lines;
+ _flags:=flags;
+ end;
+ end;
+
+ begin
+ graph_of_focus:=firstthat(@find_focused);
+ graph:=getgraph(_level,_lines,_flags);
+ end;
+
+const skip_mouse_events=3;
+
+begin
+ inherited handleevent(event);
+ case event.what of
+ evKeyboard:
+ begin
+ new_focus:=foc;
+ handled:=true;
+ case ctrltoarrow(event.keycode) of
+ kbUp,kbLeft:
+ dec(new_focus);
+ kbDown,kbRight:
+ inc(new_focus);
+ kbPgDn:
+ inc(new_focus,size.y-1);
+ kbPgUp:
+ dec(new_focus,size.y-1);
+ kbCtrlPgUp:
+ new_focus:=0;
+ kbCtrlPgDn:
+ new_focus:=limit.y-1;
+ kbHome:
+ new_focus:=delta.y;
+ kbEnd:
+ new_focus:=delta.y+size.y-1;
+ kbCtrlEnter,kbEnter:
+ selected(new_focus);
+ else
+ case event.charcode of
+ '-','+':
+ begin
+ adjust(getnode(new_focus),event.charcode='+');
+ update;
+ end;
+ '*':
+ begin
+ expandall(getnode(new_focus));
+ update;
+ end;
+ else
+ handled:=false;
+ end;
+ end;
+ if new_focus<0 then
+ new_focus:=0;
+ if new_focus>=limit.y then
+ new_focus:=limit.y-1;
+ if foc<>new_focus then
+ set_focus(new_focus);
+ if handled then
+ clearevent(event);
+ end;
+ evMouseDown:
+ begin
+ count:=1;
+ mouse_drag:=false;
+ repeat
+ makelocal(event.where,mouse);
+ if mouseinview(event.where) then
+ new_focus:=delta.y+mouse.y
+ else
+ begin
+ inc(count,byte(event.what=evMouseAuto));
+ if count and skip_mouse_events=0 then
+ begin
+ if mouse.y<0 then
+ dec(new_focus);
+ if mouse.y>=size.y then
+ inc(new_focus);
+ end;
+ end;
+ if new_focus<0 then
+ new_focus:=0;
+ if new_focus>=limit.y then
+ new_focus:=limit.y-1;
+ if foc<>new_focus then
+ set_focus(new_focus);
+ m:=mouseevent(event,evMouseMove+evMouseAuto);
+ if m then
+ mouse_drag:=true;
+ until not m;
+ if event.double then
+ selected(foc)
+ else if not mouse_drag then
+ begin
+ cur:=graph_of_focus(graph);
+ if mouse.x<length(graph) then
+ begin
+ adjust(cur,not isexpanded(cur));
+ update;
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+function Toutlineviewer.haschildren(node:pointer):boolean;
+
+begin
+ abstract;
+end;
+
+function Toutlineviewer.isexpanded(node:pointer):boolean;
+
+begin
+ abstract;
+end;
+
+function Toutlineviewer.isselected(i:sw_integer):boolean;
+
+begin
+ isselected:=foc=i;
+end;
+
+procedure Toutlineviewer.selected(i:sw_integer);
+
+begin
+ {Does nothing by default.}
+end;
+
+procedure Toutlineviewer.set_focus(Afocus:sw_integer);
+
+begin
+ assert((Afocus>=0) and (Afocus<limit.y));
+ focused(Afocus);
+ if Afocus<delta.y then
+ scrollto(delta.x,Afocus)
+ else if Afocus-size.y>=delta.y then
+ scrollto(delta.x,Afocus-size.y+1);
+ drawview;
+end;
+
+procedure Toutlineviewer.setstate(Astate:word;enable:boolean);
+
+begin
+ if Astate and sffocused<>0 then
+ drawview;
+ inherited setstate(Astate,enable);
+end;
+
+procedure Toutlineviewer.update;
+
+var count:sw_integer;
+ maxwidth:byte;
+
+ procedure check_item(cur:pointer;level,position:sw_integer;
+ lines:longint;flags:word);
+
+ var width:word;
+
+ begin
+ inc(count);
+ width:=length(gettext(cur))+length(getgraph(level,lines,flags));
+ if width>maxwidth then
+ maxwidth:=width;
+ end;
+
+begin
+ count:=0;
+ maxwidth:=0;
+ foreach(@check_item);
+ setlimit(maxwidth,count);
+ set_focus(foc);
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ Toutline object methods }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+constructor Toutline.init(var bounds:Trect;
+ AHscrollbar,AVscrollbar:Pscrollbar;
+ Aroot:Pnode);
+
+begin
+ inherited init(bounds,AHscrollbar,AVscrollbar);
+ root:=Aroot;
+ update;
+end;
+
+procedure Toutline.adjust(node:pointer;expand:boolean);
+
+begin
+ assert(node<>nil);
+ Pnode(node)^.expanded:=expand;
+end;
+
+function Toutline.getnumchildren(node:pointer):sw_integer;
+
+var p:Pnode;
+
+begin
+ assert(node<>nil);
+ p:=Pnode(node)^.childlist;
+ getnumchildren:=0;
+ while p<>nil do
+ begin
+ inc(getnumchildren);
+ p:=p^.next;
+ end;
+end;
+
+function Toutline.getchild(node:pointer;i:sw_integer):pointer;
+
+begin
+ assert(node<>nil);
+ getchild:=Pnode(node)^.childlist;
+ while i<>0 do
+ begin
+ dec(i);
+ getchild:=Pnode(getchild)^.next;
+ end;
+end;
+
+function Toutline.getroot:pointer;
+
+begin
+ getroot:=root;
+end;
+
+function Toutline.gettext(node:pointer):string;
+
+begin
+ assert(node<>nil);
+ gettext:=Pnode(node)^.text^;
+end;
+
+function Toutline.haschildren(node:pointer):boolean;
+
+begin
+ assert(node<>nil);
+ haschildren:=Pnode(node)^.childlist<>nil;
+end;
+
+function Toutline.isexpanded(node:pointer):boolean;
+
+begin
+ assert(node<>nil);
+ isexpanded:=Pnode(node)^.expanded;
+end;
+
+destructor Toutline.done;
+
+begin
+ disposenode(root);
+ inherited done;
+end;
+
+end.
diff --git a/packages/fv/src/platform.inc b/packages/fv/src/platform.inc
new file mode 100644
index 0000000000..4e35ffa59d
--- /dev/null
+++ b/packages/fv/src/platform.inc
@@ -0,0 +1,415 @@
+{***************[ PLATFORM INCLUDE UNIT ]******************}
+{ }
+{ System independent INCLUDE file to sort PLATFORMS }
+{ }
+{ Parts Copyright (c) 1997 by Balazs Scheidler }
+{ bazsi@tas.vein.hu }
+{ }
+{ Parts Copyright (c) 1999, 2000 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@projectent.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ - C'T patch to BP (16 Bit) }
+{ LINUX - FPC 0.9912+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Who Fix }
+{ ------- -------- --- ---------------------------- }
+{ 0.1 02 Jul 97 Bazsi Initial implementation }
+{ 0.2 28 Aug 97 LdB Fixed OS2 platform sort }
+{ 0.3 29 Aug 97 LdB Added assembler type changes }
+{ 0.4 29 Aug 97 LdB OS_DOS removed from WINDOWS }
+{ 0.5 23 Oct 97 LdB Delphi & speed compilers }
+{ 0.6 05 May 98 LdB Virtual Pascal 2.0 added }
+{ 0.7 19 May 98 LdB Delphi 2/3 definitions added }
+{ 0.8 06 Aug 98 CEC FPC only support fixed WIN32 }
+{ 0.9 10 Aug 98 LdB BP_VMTLink def/Undef added }
+{ 1.0 27 Aug 98 LdB Atari, Mac etc not undef dos }
+{ 1.1 25 Oct 98 PfV Delphi 4 definitions added }
+{ 1.2 06 Jun 99 LdB Sybil 2.0 support added }
+{ 1.3 13 Jun 99 LdB Sybil 2.0 undef BP_VMT link }
+{ 1.31 03 Nov 99 LdB FPC windows defines WIN32 }
+{ 1.32 04 Nov 99 LdB Delphi 5 definitions added }
+{ 1.33 16 Oct 00 LdB WIN32/WIN16 defines added }
+{ 1.34 02 May 02 MvdV FreeBSD, NetBSD, OS_UNIX }
+{**********************************************************}
+
+{ ****************************************************************************
+
+ This include file defines some conditional defines to allow us to select
+ the compiler/platform/target in a consequent way.
+
+ OS_XXXX The operating system used (XXXX may be one of:
+ DOS, OS2, Linux, Windows, Go32)
+ PPC_XXXX The compiler used: BP, FPK, Virtual, Speed
+ BIT_XX The number of bits of the target platform: 16 or 32
+ PROC_XXXX The mode of the target processor (Real or Protected)
+ This shouldn't be used, except for i386 specific parts.
+ ASM_XXXX This is the assembler type: BP, ISO-ANSI, FPK
+
+ ****************************************************************************
+
+ This is how the IFDEF and UNDEF statements below should translate.
+
+
+ PLATFORM SYSTEM COMPILER COMP ID CPU MODE BITS ASSEMBLER
+ -------- ------ -------- ------- -------- ---- ---------
+
+ DOS OS_DOS BP/TP7 PPC_BP PROC_Real BIT_16 ASM_BP
+
+ DPMI OS_DOS BP/TP7 PPC_BP PROC_Protected BIT_16 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+
+ LINUX OS_LINUX FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+ OS_UNIX
+
+ FREEBSD OS_FREEBSD FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+ OS_UNIX
+
+ NETBSD OS_NETBSD FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+ OS_UNIX
+
+ WINDOWS OS_WINDOWS BP/TP7 PPC_BP PROC_Protected BIT_16 ASM_BP
+ DELPHI PPC_DELPHI PROC_Protected BIT_16 ASM_BP
+ DELPHI2 PPC_DELPHI2 PROC_Protected BIT_16 ASM_BP
+
+ WIN95/NT OS_WINDOWS DELPHI2 PPC_DELPHI2 PROC_Protected BIT_32 ASM_BP
+ DELPHI3 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ DELPHI4 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ DELPHI5 PPC_DELPHI3 PROC_Protected BIT_32 ASM_BP
+ VIRTUAL PPC_VIRTUAL PROC_Protected BIT 32 ASM_BP
+ SYBIL2 PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+
+ OS2 OS_OS2 BPOS2 PPC_BPOS2 PROC_Protected BIT_16 ASM_BP
+ VIRTUAL PPC_VIRTUAL PROC_Protected BIT_32 ASM_BP
+ SPEED PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ SYBIL2 PPC_SPEED PROC_Protected BIT_32 ASM_BP
+ FPC PPC_FPC PROC_Protected BIT_32 ASM_FPC
+ ****************************************************************************}
+{****************************************************************************
+
+FOR ALL COMPILERS BP_VMTLink defined but FPC and Delphi3/Delphi4 undefine it
+
+ ****************************************************************************}
+{****************************************************************************
+
+FOR FPC THESE ARE THE TRANSLATIONS
+
+ PLATFORM SYSTEM COMPILER HANDLE SIZE ASM CPU
+ -------- ------ -------- ----------- ---- ---
+
+ DOS OS_DOS,OS_GO32 FPC 32-bit AT&T CPU86
+
+ WIN32 OS_WINDOWS FPC 32-bit AT&T ----
+
+ LINUX OS_LINUX,OS_UNIX FPC 32-bit AT&T ----
+ FREEBSD OS_NETBSD,OS_UNIX FPC 32-bit AT&T ----
+ NETBSD OS_FREEBSD,OS_UNIX FPC 32-bit AT&T ----
+
+ OS2 OS_OS2 FPC ????? AT&T CPU86
+
+ ATARI OS_ATARI FPC 32-bit Internal CPU68
+
+ MACOS OS_MAC FPC ????? Internal CPU68
+
+ AMIGA OS_AMIGA FPC 32-bit Internal CPU68
+
+ ****************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ Initial assume BORLAND 16 BIT DOS COMPILER - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$DEFINE OS_DOS}
+{$DEFINE PROC_Real}
+{$DEFINE BIT_16}
+{$DEFINE PPC_BP}
+{$DEFINE ASM_BP}
+{$DEFINE BP_VMTLink}
+{$DEFINE CPU86}
+
+{---------------------------------------------------------------------------}
+{ FPC 32 BIT COMPILER changes ASM, 32 bits etc - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF FPC}
+ {$mode fpc}
+
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_FPC}
+ {$UNDEF ASM_BP}
+ {$DEFINE ASM_FPC}
+ {$UNDEF BP_VMTLink}
+ {$DEFINE Use_API}
+ {$DEFINE NO_WINDOW}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC LINUX COMPILER changes operating system - Updated 27Aug98 LdB }
+{ Note: Other linux compilers would need to change other details }
+{---------------------------------------------------------------------------}
+{$IFDEF LINUX}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_LINUX}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+{$IFDEF FreeBSD}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_FREEBSD}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+{$IFDEF NETBSD}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_NETBSD}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+
+{$IFDEF Darwin}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_DARWIN}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+
+{$IFDEF SOLARIS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_SOLARIS}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+{$IFDEF BEOS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_BEOS}
+ {$DEFINE OS_UNIX}
+{$ENDIF}
+
+{------------------------------------------------}
+{ FPC Netware COMPILER changes operating system }
+{------------------------------------------------}
+{$IFDEF Netware}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_NETWARE}
+ {$IFDEF NETWARE_LIBC}
+ {$DEFINE OS_NETWARE_LIBC}
+ {$ELSE}
+ {$DEFINE OS_NETWARE_CLIB}
+ {$ENDIF}
+ {$DEFINE HasSysMsgUnit}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC GO32V2 COMPILER changes operating system - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF GO32V2}
+ {$DEFINE OS_GO32}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ 32 BIT WINDOWS COMPILERS changes bit size - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF WIN32}
+ {$IFNDEF WINDOWS}
+ {$DEFINE WINDOWS}
+ {$ENDIF}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ WINDOWS COMPILERS change op system and proc mode - Updated 03Nov99 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF WINDOWS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_WINDOWS}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$IFDEF FPC}
+ {$DEFINE WIN32}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI1 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER80}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI2 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER90}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI2}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI3 COMPILER changes compiler type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF VER100}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI4 COMPILER changes compiler type - Updated 25Oct98 pfv }
+{---------------------------------------------------------------------------}
+{$IFDEF VER120}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$DEFINE PPC_DELPHI4}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ DELPHI5 COMPILER changes compiler type - Updated 04Nov99 pfv }
+{---------------------------------------------------------------------------}
+{$IFDEF VER130}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_DELPHI}
+ {$DEFINE PPC_DELPHI3}
+ {$DEFINE PPC_DELPHI4}
+ {$DEFINE PPC_DELPHI5}
+ {$UNDEF BP_VMTLink
+ }
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ OS2 COMPILERS change compiler type and mode - Updated 27Aug98 LdB }
+{ Note: Assumes BPOS2 16BIT OS2 patch except for FPC which undefines this }
+{---------------------------------------------------------------------------}
+{$IFDEF OS2}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_OS2}
+ {$UNDEF PROC_Real}
+ {$DEFINE PROC_Protected}
+ {$UNDEF PPC_BP}
+ {$DEFINE PPC_BPOS2}
+ {$IFDEF FPC}
+ {$UNDEF PPC_BPOS2}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ VIRTUAL PASCAL changes compiler type/32 bit - Updated 27Aug98 LdB }
+{ Note: VP2 can compile win 32 code so changes op system as needed }
+{---------------------------------------------------------------------------}
+{$IFDEF VirtualPascal}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$IFDEF PPC_BPOS2}
+ {$UNDEF PPC_BPOS2}
+ {$ENDIF}
+ {$DEFINE PPC_VIRTUAL}
+ {$IFDEF WIN32}
+ {$UNDEF PPC_BP}
+ {$UNDEF OS_OS2}
+ {$DEFINE OS_WINDOWS}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ SPEED COMPILER changes compiler type/32 bit - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF Speed}
+ {$UNDEF BIT_16}
+ {$DEFINE BIT_32}
+ {$UNDEF PPC_BPOS2}
+ {$DEFINE PPC_SPEED}
+ {$UNDEF BP_VMTLink}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC AMIGA COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF AMIGA}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_AMIGA}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC ATARI COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF ATARI}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_ATARI}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ FPC MAC COMPILER changes op system and CPU type - Updated 27Aug98 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF MACOS}
+ {$UNDEF OS_DOS}
+ {$DEFINE OS_MAC}
+ {$IFDEF CPU86}
+ {$UNDEF CPU86}
+ {$ENDIF}
+ {$IFNDEF CPU68}
+ {$DEFINE CPU68}
+ {$ENDIF}
+{$ENDIF}
+
+{$IFDEF OS_DOS}
+ {$DEFINE NO_WINDOW}
+{$ENDIF}
+
+{---------------------------------------------------------------------------}
+{ WIN16 AND WIN32 set if in windows - Updated 16Oct2000 LdB }
+{---------------------------------------------------------------------------}
+{$IFDEF OS_WINDOWS} { WINDOWS SYSTEM }
+ {$IFDEF BIT_16}
+ {$DEFINE WIN16} { 16 BIT WINDOWS }
+ {$ENDIF}
+ {$IFDEF BIT_32}
+ {$DEFINE WIN32} { 32 BIT WINDOWS }
+ {$ENDIF}
+{$ENDIF}
+
+
+
diff --git a/packages/fv/src/resource.pas b/packages/fv/src/resource.pas
new file mode 100644
index 0000000000..fe2a6cbc88
--- /dev/null
+++ b/packages/fv/src/resource.pas
@@ -0,0 +1,741 @@
+
+asjgfsdkjsfld
+{ Resource Unit
+
+ Programmer: Brad Williams
+ BitSoft Development, L.L.C.
+ Copyright (c) 1996
+ Version 1.1
+
+Revision History
+
+1.1 (12/26/97)
+ - updated to add cdResource directive so that can use standard TStringList
+ resources created by TVRW and TVDT
+
+1.0
+ - original implementation }
+
+unit Resource;
+
+interface
+
+{
+ The Resource unit provides global variables which are used to build and
+ access resource files. InitRez must always be called before accessing any
+ variables in the Resource unit. The programmer should also always call
+ Done to free all file handles allocated to the program.
+}
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+
+uses
+
+ FVConsts, Objects, Dos;
+
+const
+
+ RezExt: ExtStr = '.RES';
+ { The file extension used on all resource files. }
+ RezBufferSize: Word = 4096;
+ { RezBufferSize is the number of bytes to use for the resource file's
+ stream's buffer. RezBufferSize is passed to TBufStream.Init. }
+
+ { reXXXX constants are used with resource files to retrieve the standard
+ Free Vision dialogs. The constant is followed by the Unit in which it
+ is used and the resource which is stored separated by a period. }
+
+ reChDirDialog = 'ChDirDialog'; { StdDlg.TChDirDialog }
+ reEditChDirDialog = 'EditChDirDialog'; { StdDlg.TEditChDirDialog }
+ reFindTextDlg = 'FindTextDlg'; { Editors.CreateFindDialog }
+ reHints = 'Hints'; { Resource.Hints }
+ reJumpLineDlg = 'JumpLineDlg'; { Editors.MakeJumpLineDlg }
+ reLabels = 'Labels'; { Resource.Labels }
+ reMenuBar = 'MenuBar'; { App.MenuBar }
+ reOpenDlg = 'OpenDlg'; { StdDlg.TFileDialog - Open }
+ reReformDocDlg = 'ReformDocDlg'; { Editors.MakeReformDocDlg }
+ reReplaceDlg = 'ReplaceDlg'; { Editors.CreateReplaceDialog }
+ reRightMarginDlg = 'RightMarginDlg'; { Editors.MakeRightMarginDlg }
+ reStatusLine = 'StatusLine'; { App.StatusLine }
+ reStrings = 'Strings'; { Resource.Strings }
+ reSaveAsDlg = 'SaveAsDlg'; { StdDlg.TFileDialog - Save As }
+ reTabStopDlg = 'TabStopDlg'; { Editors.MakeTabStopDlg }
+ reWindowListDlg = 'WindowListDlg'; { Editors.MakeWindowListDlg }
+ reAboutDlg = 'About'; { App unit about dialog }
+
+ {$I str.inc}
+ { STR.INC declares all the string list constants used in the standard
+ Free Vision library units. They are placed in a separate file as a
+ template for use by the resource file generator, MakeRez.
+
+ Applications which use resource files and need to add strings of their
+ own should use STR.INC as the start for the resource file.
+
+ See MakeRez.PAS for more information about generating resource files.}
+
+type
+
+
+ PConstant = ^TConstant;
+ TConstant = object(TObject)
+ Value: Word;
+ { The value assigned to the constant. }
+ constructor Init (AValue: Word; AText: string);
+ { Init assigns AValue to Value to AText to Text. AText may be an empty
+ string.
+
+ If an error occurs Init fails. }
+ destructor Done; virtual;
+ { Done disposes of Text then calls the inherited destructor. }
+ procedure SetText (AText: string);
+ { SetText changes FText to the word equivalent of AText. }
+ procedure SetValue (AValue: string);
+ { SetValue changes Value to the word equivalent of AValue. }
+ function Text: string;
+ { Text returns a string equivalent to FText. If FText is nil, an
+ empty string is returned. }
+ function ValueAsString: string;
+ { ValueAsString returns the string equivalent of Value. }
+ private
+ FText: PString;
+ { The text to display for the constant. }
+ end; { of TConstant }
+
+
+ PMemStringList = ^TMemStringList;
+ TMemStringList = object(TSortedCollection)
+ { A TMemStringList combines the functions of a TStrListMaker and a
+ TStringList into one object, allowing generation and use of string
+ lists in the same application. TMemStringList is fully compatible
+ with string lists created using TStrListMaker, so legacy applications
+ will work without problems.
+
+ When using a string list in the same program as it is created, a
+ resource file is not required. This allows language independant coding
+ of units without the need for conditional defines and recompiling. }
+ constructor Init;
+ { Creates an empty, in-memory string list that is not associated with a
+ resource file. }
+ constructor Load (var S: TStream);
+ { Load creates a TStringList from which it gets its strings upon a call
+ to Get. The strings on the resource file may be loaded into memory
+ for editing by calling LoadList.
+
+ If initialized with Load, the stream must remain valid for the life
+ of this object. }
+ destructor Done; virtual;
+ { Done deallocates the memory allocated to the string list. }
+ function Compare (Key1, Key2: Pointer): Sw_Integer; virtual;
+ { Compare assumes Key1 and Key2 are Word values and returns:
+
+ -1 if Key1 < Key2
+ 0 if Key1 = Key2
+ 1 if Key1 > Key2 }
+ function Get (Key: Word): String; virtual;
+ { GetKey searches for a string with a key matching Key and returns it.
+ An empty string is returned if a string with a matching Key is not
+ found.
+
+ If Count > 0, the in memory collection is searched. If List^.Count
+ is 0, the inherited Get method is called. }
+ procedure Insert (Item: Pointer); virtual;
+ { If Item is not nil, Insert attempts to insert the item into the
+ collection. If a collection expansion error occurs Insert disposes
+ of Item by calling FreeItem.
+
+ Item must be a pointer to a TConstant or its descendant. }
+ function KeyOf (Item: Pointer): Pointer; virtual;
+ { KeyOf returns a pointer to TConstant.Value. }
+ function LoadStrings: Sw_Integer;
+ { LoadStrings reads all strings the associated resource file into
+ memory, places them in the collection, and returns 0.
+
+ If an error occurs LoadStrings returns the stream status error code
+ or a DOS error code. Possible DOS error codes include:
+
+ 2: no associated resource file
+ 8: out of memory }
+ function NewConstant (Value: Word; S: string): PConstant; virtual;
+ { NewConstant is called by LoadStrings. }
+ procedure Put (Key: Word; S: String); virtual;
+ { Put creates a new PConstant containing Key and Word then calls
+ Insert to place it in the collection. }
+ procedure Store (var S: TStream);
+ { Store creates a TStrListMaker, fills it with the items in List,
+ writes the TStrListMaker to the stream by calling
+ TStrListMaker.Store, then disposes of the TStrListMaker. }
+ private
+ StringList: PStringList;
+ end; { of TMemStringList) }
+
+
+var
+
+ {$ifdef cdResource}
+ Hints: PStringList;
+ {$else}
+ Hints: PMemStringList;
+ {$endif cdResource}
+ { Hints is a string list for use within the application to provide
+ context sensitive help on the command line. Hints is always used in
+ the application. }
+
+ {$ifdef cdResource}
+ Strings: PStringList;
+ {$else}
+ Strings: PMemStringList;
+ {$endif cdResource}
+ { Strings holds messages such as errors and general information that are
+ displayed at run-time, normally with MessageBox. Strings is always
+ used in the application. }
+
+ {$ifdef cdResource}
+ Labels: PStringList;
+ {$else}
+ Labels: PMemStringList;
+ {$endif cdResource}
+ { Labels is a string list for use within the application when a
+ resource file is not used, or when creating a resource file. Labels
+ contains all text used in dialog titles, labels, buttons, menus,
+ statuslines, etc., used in the application which can be burned into
+ language specific resources. It does not contain any messages
+ displayed at run-time using MessageBox or the status line hints.
+
+ Using the Labels variable when creating views allows language
+ independant coding of views such as the MessageBox, StdDlg and Editors
+ units. }
+
+ RezFile: PResourceFile;
+ { RezFile is a global variable used when the Free Vision library
+ is compiled using the cdResource conditional define, or when creating
+ resource files.
+
+ All standard Free Vision application resources are accessed from the
+ resource file using the reXXXX constants. Modify the STR.INC under a
+ new file name to create new language specific resource files. See the
+ MakeRez program file for more information. }
+
+
+
+procedure DoneResource;
+ { Done destructs all objects initialized in this unit and frees all
+ allocated heap. }
+
+{$ifndef cdResource}
+function InitResource: Boolean;
+{$endif cdResource}
+ { Init initializes the Hints and Strings for use with in memory strings
+ lists. Init should be used in applications which do not use a resource
+ file, or when creating resource files. }
+
+{$ifdef cdResource}
+function InitRezFile (AFile: FNameStr; Mode: Word;
+ var AResFile: PResourceFile): Sw_Integer;
+{$endif cdResource}
+ { InitRezFile initializes a new PResourceFile using the name passed in
+ AFile and the stream mode passed in Mode and returns 0.
+
+ If an error occurs InitRezFile returns the DOS error and AResFile is
+ invalid. Possible DOS error values include:
+
+ 2: file not found or other stream initialization error
+ 11: invalid format - not a valid resource file }
+
+{$ifdef cdResource}
+function LoadResource (AFile: FNameStr): Boolean;
+{$endif cdResource}
+ { Load is used to open a resource file for use in the application.
+
+ For Load to return True, the resource file must be properly opened and
+ assigned to RezFile and the Hints string list must be successfully loaded
+ from the stream. If an error occurs, Load displays an English error
+ message using PrintStr and returns False. }
+
+function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
+ { MergeLists moves all key/string pairs from Source to destination,
+ deleting them from Source. Duplicate strings are ignored. }
+
+
+const
+ RMemStringList: TStreamRec = (
+ ObjType: idMemStringList;
+ VmtLink: Ofs(TypeOf(TMemStringList)^);
+ Load: @TMemStringList.Load;
+ Store: @TMemStringList.Store);
+
+
+implementation
+
+{****************************************************************************}
+{ Private Declarations }
+{****************************************************************************}
+
+uses
+ {Memory, }Drivers;
+
+{****************************************************************************}
+{ TConstant object }
+{****************************************************************************}
+{****************************************************************************}
+{ TConstant.Init }
+{****************************************************************************}
+constructor TConstant.Init (AValue: Word; AText: string);
+begin
+ if not inherited Init then
+ Fail;
+ Value := AValue;
+ FText := NewStr(AText);
+ if (FText = nil) and (AText <> '') then
+ begin
+ inherited Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TConstant.Done }
+{****************************************************************************}
+destructor TConstant.Done;
+begin
+ DisposeStr(FText);
+ inherited Done;
+end;
+
+{****************************************************************************}
+{ TConstant.SetText }
+{****************************************************************************}
+procedure TConstant.SetText (AText: string);
+begin
+ DisposeStr(FText);
+ FText := NewStr(AText);
+end;
+
+{****************************************************************************}
+{ TConstant.SetValue }
+{****************************************************************************}
+procedure TConstant.SetValue (AValue: string);
+var
+ N: Word;
+ ErrorCode: Integer;
+begin
+ Val(AValue,N,ErrorCode);
+ if ErrorCode = 0 then
+ Value := N;
+end;
+
+{****************************************************************************}
+{ TConstant.Text }
+{****************************************************************************}
+function TConstant.Text: string;
+begin
+ if (FText = nil) then
+ Text := ''
+ else Text := FText^;
+end;
+
+{****************************************************************************}
+{ TConstant.ValueAsString }
+{****************************************************************************}
+function TConstant.ValueAsString: string;
+var
+ S: string[5];
+begin
+ Str(Value,S);
+ ValueAsString := S;
+end;
+
+{****************************************************************************}
+{ TMemStringList Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TMemStringList.Init }
+{****************************************************************************}
+constructor TMemStringList.Init;
+begin
+ if not inherited Init(10,10) then
+ Fail;
+ StringList := nil;
+end;
+
+{****************************************************************************}
+{ TMemStringList.Load }
+{****************************************************************************}
+constructor TMemStringList.Load (var S: TStream);
+begin
+ if not inherited Init(10,10) then
+ Fail;
+ StringList := New(PStringList,Load(S));
+end;
+
+{****************************************************************************}
+{ TMemStringList.Done }
+{****************************************************************************}
+destructor TMemStringList.Done;
+begin
+ if (StringList <> nil) then
+ Dispose(StringList,Done);
+ inherited Done;
+end;
+
+{****************************************************************************}
+{ TMemStringList.Compare }
+{****************************************************************************}
+function TMemStringList.Compare (Key1, Key2: Pointer): Sw_Integer;
+begin
+ if Word(Key1^) < Word(Key2^) then
+ Compare := -1
+ else Compare := Byte(Word(Key1^) > Word(Key2^));
+end;
+
+{****************************************************************************}
+{ TMemStringList.Get }
+{****************************************************************************}
+function TMemStringList.Get (Key: Word): string;
+var
+ i: Sw_Integer;
+ S: string;
+begin
+ if (StringList = nil) then
+ begin { started with Init, use in memory string list }
+ if Search(@Key,i) then
+ Get := PConstant(At(i))^.Text
+ else Get := '';
+ end
+ else begin
+ S := StringList^.Get(Key);
+ Get := S;
+ end;
+end;
+
+{****************************************************************************}
+{ TMemStringList.Insert }
+{****************************************************************************}
+procedure TMemStringList.Insert (Item: Pointer);
+var
+ i: Sw_Integer;
+begin
+ if (Item <> nil) then
+ begin
+ i := Count;
+ inherited Insert(Item);
+ if (i = Count) then { collection expansion failed }
+ Dispose(PConstant(Item),Done);
+ end;
+end;
+
+{****************************************************************************}
+{ TMemStringList.KeyOf }
+{****************************************************************************}
+function TMemStringList.KeyOf (Item: Pointer): Pointer;
+begin
+ KeyOf := @(PConstant(Item)^.Value);
+end;
+
+{****************************************************************************}
+{ TMemStringList.LoadStrings }
+{****************************************************************************}
+function TMemStringList.LoadStrings: Sw_Integer;
+ procedure MakeEditableString (var Str: string);
+ const
+ SpecialChars: array[1..3] of Char = #3#10#13;
+ var
+ i, j: Byte;
+ begin
+ for i := 1 to 3 do
+ while (Pos(SpecialChars[i],Str) <> 0) do
+ begin
+ j := Pos(SpecialChars[i],Str);
+ System.Delete(Str,j,1);
+ case i of
+ 1: System.Insert('#3',Str,j);
+ 2: System.Insert('#10',Str,j);
+ 3: System.Insert('#13',Str,j);
+ end;
+ end;
+ end;
+var
+ Constant: PConstant;
+ i: Word;
+ S: string;
+begin
+ LoadStrings := 0;
+ if (StringList = nil) then
+ begin
+ LoadStrings := 2;
+ Exit;
+ end;
+ for i := 0 to 65535 do
+ begin
+ S := StringList^.Get(i);
+ if (S <> '') then
+ begin
+ MakeEditableString(S);
+ Constant := NewConstant(i,S);
+(*
+ if LowMemory then
+ begin
+ if (Constant <> nil) then
+ Dispose(Constant,Done);
+ LoadStrings := 8; { out of memory }
+ Exit;
+ end;
+*)
+ Insert(Constant);
+ end;
+ end;
+end;
+
+{****************************************************************************}
+{ TMemStringList.NewConstant }
+{****************************************************************************}
+function TMemStringList.NewConstant (Value: Word; S: string): PConstant;
+begin
+ NewConstant := New(PConstant,Init(Value,S));
+end;
+
+{****************************************************************************}
+{ TMemStringList.Put }
+{****************************************************************************}
+procedure TMemStringList.Put (Key: Word; S: string);
+begin
+ Insert(New(PConstant,Init(Key,S)));
+end;
+
+{****************************************************************************}
+{ TMemStringList.Store }
+{****************************************************************************}
+procedure TMemStringList.Store (var S: TStream);
+var
+ StrList: PStrListMaker;
+ Size: Word;
+ procedure Total (Constant: PConstant);{$ifndef FPC}far;{$endif}
+ begin
+ with Constant^ do
+ Inc(Size,Succ(Length(Text)));
+ end;
+ procedure AddString (Constant: PConstant);{$ifndef FPC}far;{$endif}
+ const
+ Numbers = ['0'..'9'];
+ var
+ i, j: Byte;
+ N: Byte;
+ ErrorCode: Integer;
+ S: string;
+ begin
+ with Constant^ do
+ begin
+ { convert formatting characters }
+ S := Text;
+ while (Pos('#',S) <> 0) do
+ begin
+ i := Succ(Pos('#',S));
+ j := i;
+ if (Length(S) > j) then
+ Inc(j,Byte(S[Succ(j)] in Numbers));
+ Val(Copy(S,i,j-i+1),N,ErrorCode);
+ System.Delete(S,Pred(i),j-i+2);
+ System.Insert(Char(N),S,Pred(i));
+ end;
+ StrList^.Put(Value,Text)
+ end;
+ end;
+begin
+ Size := 0;
+ ForEach(@Total);
+ StrList := New(PStrListMaker,Init(Size,Count * 6));
+ if (StrList = nil) then
+ begin
+ S.Status := 8; { DOS error not enough memory }
+ Exit;
+ end;
+ ForEach(@AddString);
+ StrList^.Store(S);
+ Dispose(StrList,Done);
+end;
+
+{****************************************************************************}
+{ Public Procedures and Functions }
+{****************************************************************************}
+
+{****************************************************************************}
+{ Done }
+{****************************************************************************}
+procedure DoneResource;
+begin
+ if (RezFile <> nil) then
+ begin
+ Dispose(RezFile,Done);
+ RezFile:=nil;
+ end;
+ if (Strings <> nil) then
+ begin
+ Dispose(Strings,Done);
+ Strings:=nil;
+ end;
+ if (Hints <> nil) then
+ begin
+ Dispose(Hints,Done);
+ Hints:=nil;
+ end;
+ if (Labels <> nil) then
+ begin
+ Dispose(Labels,Done);
+ Labels:=nil;
+ end;
+end;
+
+{****************************************************************************}
+{ Init }
+{****************************************************************************}
+{$ifndef cdResource}
+
+{$I strtxt.inc}
+ { strtxt.inc contains the real strings and procedures InitRes... which
+ is converted from str.inc }
+
+function InitResource: Boolean;
+begin
+ InitResource := False;
+ Hints := New(PMemStringList,Init);
+ if (Hints = nil) then
+ begin
+ PrintStr('Fatal error. Could not create Hints list.');
+ Exit;
+ end;
+ Strings := New(PMemStringList,Init);
+ if (Strings = nil) then
+ begin
+ DoneResource;
+ Exit;
+ end;
+ Labels := New(PMemStringList,Init);
+ if (Labels = nil) then
+ begin
+ DoneResource;
+ Exit;
+ end;
+{ now load the defaults }
+ InitResLabels;
+ InitResStrings;
+ InitResource := True;
+end;
+{$endif cdResource}
+
+{****************************************************************************}
+{ InitRezFile }
+{****************************************************************************}
+{$ifdef cdResource}
+function InitRezFile (AFile: FNameStr; Mode: Word;
+ var AResFile: PResourceFile): Sw_Integer;
+var
+ Stream: PBufStream;
+ Result: Sw_Integer;
+begin
+ Stream := New(PBufStream,Init(AFile,Mode,RezBufferSize));
+ if (Stream = nil) then
+ Result := 2 { file not found; could also be out of memory }
+ else begin
+ AResFile := New(PResourceFile,Init(Stream));
+ if (AResFile = nil) then
+ begin
+ Dispose(Stream,Done);
+ Result := 11;
+ end
+ else Result := 0;
+ end;
+ InitRezFile := Result;
+end;
+{$endif cdResource}
+
+{****************************************************************************}
+{ Load }
+{****************************************************************************}
+{$ifdef cdResource}
+function LoadResource (AFile: FNameStr): Boolean;
+var
+ Stream: PBufStream;
+begin
+ Load := False;
+ Stream := New(PBufStream,Init(AFile,stOpenRead,RezBufferSize));
+ if (Stream = nil) or (Stream^.Status <> 0) then
+ begin
+ Done;
+ PrintStr('Fatal error. Could not open resource file: ' + AFile);
+ Exit;
+ end;
+ RezFile := New(PResourceFile,Init(Stream));
+ if (RezFile = nil) then
+ begin
+ Dispose(Stream,Done);
+ Done;
+ PrintStr('Fatal error. Could not initialize resource file.');
+ Exit;
+ end;
+ Hints := PStringList(RezFile^.Get(reHints));
+ if (Hints = nil) then
+ begin
+ Done;
+ PrintStr('Fatal error. Could not load Hints string list.');
+ Exit;
+ end;
+ Strings := PStringList(RezFile^.Get(reStrings));
+ if (Strings = nil) then
+ begin
+ Done;
+ PrintStr('Fatal error. Could not load Strings string list.');
+ Exit;
+ end;
+ Load := True;
+end;
+{$endif cdResource}
+
+{****************************************************************************}
+{ MergeLists }
+{****************************************************************************}
+function MergeLists (Source, Dest: PMemStringList): Sw_Integer;
+var
+ Result: Sw_Integer;
+ procedure MoveItem (Constant: PConstant);{$ifndef FPC}far;{$endif}
+ var
+ j: Sw_Integer;
+ begin
+ if (Result = 0) and (not Dest^.Search(Dest^.KeyOf(Constant),j)) then
+ begin
+ j := Dest^.Count;
+ Dest^.Insert(Constant);
+ if (j = Dest^.Count) then
+ Result := 8
+ else Source^.Delete(Constant);
+ end;
+ end;
+begin
+ if (Source = nil) or (Dest = nil) then
+ begin
+ MergeLists := 6;
+ Exit;
+ end;
+ Result := 0;
+ Source^.ForEach(@MoveItem);
+ MergeLists := Result;
+end;
+
+{****************************************************************************}
+{ Unit Initialization }
+{****************************************************************************}
+
+begin
+ RezFile := nil;
+ Hints := nil;
+ Strings := nil;
+ Labels := nil;
+end.
diff --git a/packages/fv/src/statuses.pas b/packages/fv/src/statuses.pas
new file mode 100644
index 0000000000..143848ba25
--- /dev/null
+++ b/packages/fv/src/statuses.pas
@@ -0,0 +1,1404 @@
+{$V-}
+unit Statuses;
+
+{$CODEPAGE cp437}
+
+{#Z+}
+{ Free Vision Status Objects Unit
+ Free VIsion
+ Written by : Brad Williams, DVM
+
+Revision History
+
+1.2.3 (96/04/13)
+ - moved Pause and Resume to methods of TStatus leaving TStatus Pause and
+ Resume "aware"
+ - eliminated many bugs
+ - moved Pause, Resume and Cancel from TStatusDlg to TStatus
+
+1.2.1 (95/12/6)
+ - minor typo corrections in opening unit documentation
+ - F+ to Z+ around stream registration records
+ - removed redundant sentence in TAppStatus definition
+ - updated CBarStatus documentation and constant
+ - removed TGauge.Init cross-reference from TSpinner.Init
+ - added THeapMemAvail and RegistertvStatus documentation
+ - numerous other documentation updates
+ - changed all calls to Send to Message
+
+1.2.0 (95/11/24)
+ - conversion to Bsd format
+
+1.1.0 (05/01/94)
+ - initial WVS release
+
+
+Known Bugs
+
+ScanHelp Errors
+ - sdXXXX constants help documentation doesn't show TStatusDlg and
+ TMessageStatusDlg
+ - ScanHelp produces garbage in evStatus help context
+
+tvStatus Bugs
+ - CAppStatus may not be correct }
+{#Z-}
+
+{ The tvStatus unit implements several views for providing information to
+the user which needs to be updated during program execution, such as a
+progress indicator, clock, heap viewer, gauges, etc. All tvStatus views
+respond to a new message event class, evStatus. An individual status view
+only processes an event with its associated command. }
+
+interface
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+
+uses
+
+ FVCommon, FVConsts, Objects, Drivers, Views, Dialogs;
+{ Resource;}
+
+const
+
+ evStatus = $8000;
+ { evStatus represents the event class all status views know how to
+ respond to. }
+ {#X Statuses }
+
+
+ CStatus = #1#2#3;
+{$ifndef cdPrintDoc}
+{#F+}
+{ÝTStatus.CStatus palette
+ßßßßßßßßßßßßßßßßßßßßßßßßß}
+{#F-}
+{$endif cdPrintDoc}
+{ Status views use the default palette, CStatus, to map onto the first three
+entries in the standard window palette. }
+{#F+}
+{ 1 2 3
+ ÉÍÍÍÍÑÍÍÍÍÑÍÍÍÍ»
+ CStatus º 1 ³ 2 ³ 3 º
+ ÈÍÍÑÍÏÍÍÑÍÏÍÍÑͼ
+Normal TextÄÄÄÙ ³ ³
+OtherÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
+Highlighted TextÄÄÄÄÄÄÄÄÙ }
+{#F-}
+{#X TStatus }
+
+ CAppStatus = #2#5#4;
+{$ifndef cdPrintDoc}
+{#F+}
+{ÝTAppStatus.CAppStatus palette
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß}
+{#F-}
+{$endif cdPrintDoc}
+{ Status views which are inserted into the application rather than a dialog
+or window use the default palette, CAppStatus, to map onto the application
+object's palette. }
+{#F+}
+{ 1 2 3
+ ÉÍÍÍÍÑÍÍÍÍÑÍÍÍÍ»
+ CAppStatus º 2 ³ 5 ³ 4 º
+ ÈÍÍÑÍÏÍÍÑÍÏÍÍÑͼ
+Normal TextÄÄÄÄÄÄÙ ³ ³
+OtherÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³
+Highlighted TextÄÄÄÄÄÄÄÄÄÄÄÙ }
+{#F-}
+ {#X tvStatus TAppStatus }
+
+
+ CBarGauge = CStatus + #16#19;
+{$ifndef cdPrintDoc}
+{#F+}
+{ÝTBarGauge.CBarGauge palette
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßß}
+{#F-}
+{$endif cdPrintDoc}
+{ TBarGauge's use the default palette, CBarGauge, to map onto the dialog or
+window owner's palette. }
+{#F+}
+{ 1 2 3 4 5
+ ÉÍÍÍÍÑÍÍÍÍÑÍÍÍÍÑÍÍÍÍÑÍÍÍÍ»
+ CAppStatus º 2 ³ 5 ³ 4 ³ 16 ³ 19 º
+ ÈÍÍÑÍÏÍÍÑÍÏÍÍÑÍÏÍÍÑÍÏÍÍÑͼ
+Normal TextÄÄÄÄÄÄÙ ³ ³ ³ ÀÄÄÄÄ filled in bar
+OtherÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ÀÄÄÄÄÄÄÄÄÄ empty bar
+Highlighted TextÄÄÄÄÄÄÄÄÄÄÄÙ }
+{#F-}
+ {#X tvStatus TBarGauge }
+
+
+{#T sdXXXX }
+{$ifndef cdPrintDoc}
+{#F+}
+{ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
+Ý sdXXXX constants (STDDLG unit) Þ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß}
+{#F-}
+{$endif cdNoPrintDoc}
+{ sdXXXX constants are used to determine the types of buttons displayed in a
+#TStatusDlg# or #TStatusMessageDlg#. }
+{#F+}
+{ Constant ³ Value ³ Meaning
+ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
+ sdNone ³ $0000 ³ no buttons
+ sdCancelButton ³ $0001 ³ show Cancel button
+ sdPauseButton ³ $0002 ³ show Pause button
+ sdResumeButton ³ $0004 ³ show Resume button
+ sdAllButtons ³ $0008 ³ show Cancel, Pause and Resume
+ ³ ³ buttons }
+{#Z+}
+ sdNone = $0000;
+ sdCancelButton = $0001;
+ sdPauseButton = $0002;
+ sdResumeButton = $0004;
+ sdAllButtons = sdCancelButton or sdPauseButton or sdResumeButton;
+{#Z-}
+ {#X tvStatus TStatusDlg TStatusMessageDlg }
+
+ SpinChars : String[4] = '³/Ä\';
+ { SpinChars are the characters used by a #TSpinnerGauge# when it is drawn.
+ Only one character is displayed at a time. The string is cycled
+ through then started over again until the view is disposed. }
+ {#X tvStatus }
+
+ sfPause = $F000;
+ { sfPause is an additional state flag used internally by status views to
+ indicate they are in a paused state and should not respond to their
+ command. }
+
+type
+ {#Z+}
+ PStatus = ^TStatus;
+ {#Z-}
+ TStatus = Object(TParamText)
+ { TStatus is the base object type from which all status views descend.
+ Status views are used to display information that will change at
+ run-time based upon some state or process in the application, such as
+ printing.
+
+ All status views that are to be inserted into the application should
+ descend from #TAppStatus# for proper color mapping. }
+ Command : Word;
+ { Command is the only command the status view will respond to. When
+ the status view receives an evStatus event it checks the value of the
+ Event.Command field against Command before handling the event. }
+ {#X HandleEvent }
+ constructor Init (R : TRect; ACommand : Word; AText : String;
+ AParamCount : Integer);
+ { Init calls the inherited constructor then sets #Command# to ACommand.
+
+ If an error occurs Init fails. }
+ {#X Load }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor then reads #Command# from the
+ stream.
+
+ If an error occurs Load fails. }
+ {#X Store Init }
+ function Cancel : Boolean; virtual;
+ { Cancel should prompt the user when necessary for validation of
+ canceling the process which the status view is displaying. If the
+ user elects to continue the process Cancel must return False,
+ otherwise Cancel must return True. }
+ {#X Pause Resume }
+ function GetPalette : PPalette; virtual;
+ { GetPalette returns a pointer to the default status view palette,
+ #CStatus#. }
+ {#X TAppStatus CAppStatus }
+ procedure HandleEvent (var Event : TEvent); virtual;
+ { HandleEvent captures any #evStatus# messages with its command value
+ equal to #Command#, then calls #Update# with Data set to
+ Event.InfoPtr. If the State field has its #sfPause# bit set, the
+ view ignores the event. }
+ procedure Pause; virtual;
+ { Pause sends an evStatus message to the application with Event.Command
+ set to cmStatusPause and Event.InfoPtr set to #Status#^.Command. The
+ #Status# view's sfPause bit of the State flag is set by calling
+ SetState. In the paused state, the status view does not respond to
+ its associated command. }
+ {#X Resume sdXXXX Cancel }
+ procedure Reset; virtual;
+ { Reset causes the status view to be reset to its beginning or default
+ value, then be redrawn. Reset is used after an event is aborted
+ which can only be performed in its entirety. }
+ procedure Resume; virtual;
+ { Resume is called in response to pressing the Resume button. Resume
+ sends an evStatus message to the application with Event.Command set
+ to cmStatusPause and Event.InfoPtr set to #Status#^.Command. The
+ Status view's sfPause bit is turned off by calling SetState. }
+ {#X Pause sdXXXX Cancel }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes #Command# to the
+ stream. }
+ {#X Load }
+ procedure Update (Data : Pointer); virtual;
+ { Update changes the status' displayed text as necessary based on
+ Data. }
+ {#X Command HandleEvent }
+ end; { of TStatus }
+
+
+ {#Z+}
+ PStatusDlg = ^TStatusDlg;
+ {#Z-}
+ TStatusDlg = Object(TDialog)
+ { A TStatusDlg displays a status view and optional buttons. It may be
+ used to display any status message and optionally provide end user
+ cancelation or pausing of an ongoing operation, such as printing.
+
+ All status views that are to be inserted into a window or dialog should
+ descend from #TStatus# for proper color mapping. }
+ Status : PStatus;
+ { Status is the key status view for the dialog. When a cmStatusPause
+ command is broadcast in response to pressing the pause button,
+ Event.InfoPtr is set to point to the command associated with Status. }
+ {#X TStatus cmXXXX }
+ constructor Init (ATitle : TTitleStr; AStatus : PStatus; AFlags : Word);
+ { Init calls the inherited constructor to create the dialog and sets
+ the EventMask to handle #evStatus# events. AStatus is assigned to
+ #Status# and inserted into the dialog at position 2,2.
+
+ The dialog is anchored at AStatus^.Origin and its size is at least
+ AStatus^.Size + 2 in both dimensions. The actual size is determined
+ by the AFlags byte. The #sdXXXX# constants should be used to signify
+ which buttons to display.
+
+ If an error occurs Init fails. }
+ {#X TStatus.Pause TStatus.Resume }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor then loads #Status#.
+
+ If an error occurs Load fails. }
+ {#X Store }
+ procedure Cancel (ACommand : Word); virtual;
+ { Cancel sends an evStatus message to the Application object with
+ command set to cmCancel and InfoPtr set to the calling status view's
+ command, then calls the inherited Cancel method. }
+ {#X TBSDDialog.Cancel }
+ procedure HandleEvent (var Event : TEvent); virtual;
+ { All evStatus events are accepted by the dialog and sent to each
+ subview in Z-order until cleared.
+
+ If the dialog recieves an evCommand or evBroadcast event with the
+ Command parameter set to cmCancel, HandleEvent sends an #evStatus#
+ message to the Application variable with Event.Command set to the
+ cmStatusCancel and Event.InfoPtr set to the #Status#.Command and
+ disposes of itself.
+
+ When a pause button is included, a cmStatusPause broadcast event is
+ associated with the button. When the button is pressed a call to
+ #TStatus.Pause# results. The status view is inactivated until it
+ receives an evStatus event with a commond of cmStatusResume and
+ Event.InfoPtr set to the status view's Command value. When a pause
+ button is used, the application should respond to the evStatus event
+ (with Event.Command of cmStatusPause) appropriately, then dispatch a
+ cmStatusResume evStatus event when ready to resume activity. }
+ {#X TStatus.Command }
+ procedure InsertButtons (AFlags : Word); virtual;
+ { InsertButtons enlarges the dialog to the necessary size and inserts
+ the buttons specified in AFlags into the last row of the dialog. }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes #Status# to the
+ stream. }
+ {#X Load }
+ end; { of TStatusDlg }
+
+
+ {#Z+}
+ PStatusMessageDlg = ^TStatusMessageDlg;
+ {#Z-}
+ TStatusMessageDlg = Object(TStatusDlg)
+ { A TStatusMessageDlg displays a message as static text with a status
+ view on the line below it.
+
+ All status views that are to be inserted into a window or dialog should
+ descend from #TStatus# for proper color mapping. }
+ constructor Init (ATitle : TTitleStr; AStatus : PStatus; AFlags : Word;
+ AMessage : String);
+ { Init calls the inherited constructor then inserts a TStaticText view
+ containing AMessage at the top line of the dialog.
+
+ The size of the dialog is determined by the size of the AStatus. The
+ dialog is anchored at AStatus^.Origin and is of at least
+ AStatus^.Size + 2 in heighth and width. The exact width and heighth
+ are determined by AOptions.
+
+ AFlags contains flags which determine the buttons to be displayed
+ in the dialog.
+
+ If an error occurs Init fails. }
+ end; { of TStatusMessageDlg }
+
+
+ {#Z+}
+ PGauge = ^TGauge;
+ {#Z-}
+ TGauge = Object(TStatus)
+ { A gauge is used to represent the current numerical position within a
+ range of values. When Current equals Max a gauge dispatches an
+ #evStatus# event with the command set to cmStatusDone to the
+ Application object. }
+ Min : LongInt;
+ { Min is the minimum value which #Current# may be set to. }
+ {#X Max }
+ Max : LongInt;
+ { Max is the maximum value which #Current# may be set to. }
+ {#X Min }
+ Current : LongInt;
+ { Current is the current value represented in the gauge. }
+ {#X Max Min }
+ constructor Init (R : TRect; ACommand : Word; AMin, AMax : LongInt);
+ { Init calls the inherited constructor then sets #Min# and #Max# to
+ AMin and AMax, respectively. #Current# is set to AMin.
+
+ If an error occurs Init fails. }
+ {#X Load }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor then reads #Min#, #Max# and
+ #Current# from the stream.
+
+ If an error occurs Load fails. }
+ {#X Init Store }
+ procedure Draw; virtual;
+ { Draw writes the following to the screen: }
+{#F+}
+{
+Min = XXX Max = XXX Current = XXX }
+{#F-}
+ { where XXX are the current values of the corresponding variables. }
+ procedure GetData (var Rec); virtual;
+ { GetData assumes Rec is a #TGaugeRec# and returns the current settings
+ of the gauge. }
+ {#X SetData }
+ procedure Reset; virtual;
+ { Reset sets #Current# to #Min# then redraws the status view. }
+ {#X TStatus.Reset }
+ procedure SetData (var Rec); virtual;
+ { SetData assumes Rec is a #TGaugeRec# and sets the gauge's variables
+ accordingly. }
+ {#X GetData }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes #Min#, #Max# and
+ #Current# to the stream. }
+ {#X Load }
+ procedure Update (Data : Pointer); virtual;
+ { Update increments #Current#. }
+ end; { of TGauge }
+
+
+ {#Z+}
+ PGaugeRec = ^TGaugeRec;
+ {#Z-}
+ TGaugeRec = record
+ { A TGaugeRec is used to set and get a #TGauge#'s variables. }
+ {#X TGauge.GetData TGauge.SetData }
+ Min, Max, Current : LongInt;
+ end; { of TGaugeRec }
+
+
+ {#Z+}
+ PArrowGauge = ^TArrowGauge;
+ {#Z-}
+ TArrowGauge = Object(TGauge)
+ { An arrow gauge draws a progressively larger series of arrows across the
+ view. If Right is True, the arrows are right facing, '>', and are
+ drawn from left to right. If Right is False, the arrows are left
+ facing, '<', and are drawn from right to left. }
+ Right : Boolean;
+ { Right determines the direction of arrow used and the direction which
+ the status view is filled. If Right is True, the arrows are right
+ facing, '>', and are drawn from left to right. If Right is False,
+ the arrows are left facing, '<', and are drawn from right to left. }
+ {#X Draw }
+ constructor Init (R : TRect; ACommand : Word; AMin, AMax : Word;
+ RightArrow : Boolean);
+ { Init calls the inherited constructor then sets #Right# to RightArrow.
+
+ If an error occurs Init fails. }
+ {#X Load }
+ constructor Load (var S : TStream);
+ { Load calls the inherited constructor then reads #Right# from the
+ stream.
+
+ If an error occurs Load fails. }
+ {#X Init Store }
+ procedure Draw; virtual;
+ { Draw fills the Current / Max percent of the view with arrows. }
+ {#X Right }
+ procedure GetData (var Rec); virtual;
+ { GetData assumes Rec is a #TArrowGaugeRec# and returns the current
+ settings of the views variables. }
+ {#X SetData }
+ procedure SetData (var Rec); virtual;
+ { SetData assumes Rec is a #TArrowGaugeRec# and sets the view's
+ variables accordingly. }
+ {#X GetData }
+ procedure Store (var S : TStream); { store should never be virtual;}
+ { Store calls the inherited Store method then writes #Right# to the
+ stream. }
+ {#X Load }
+ end; { of TArrowGauge }
+
+
+ {#Z+}
+ PArrowGaugeRec = ^TArrowGaugeRec;
+ {#Z-}
+ TArrowGaugeRec = record
+ { A TArrowGaugeRec is used to set and get the variables of a
+ #TArrowGauge#. }
+ {#X TArrowGauge.GetData TArrowGauge.SetData }
+ Min, Max, Count : LongInt;
+ Right : Boolean;
+ end; { of TGaugeRec }
+
+
+ {#Z+}
+ PPercentGauge = ^TPercentGauge;
+ {#Z-}
+ TPercentGauge = Object(TGauge)
+ { A TPercentGauge displays a numerical percentage as returned by
+ #Percent# followed by a '%' sign. }
+ function Percent : Integer; virtual;
+ { Percent returns the whole number value of (Current / Max) * 100. }
+ {#X TGauge.Current TGauge.Max }
+ procedure Draw; virtual;
+ { Draw writes the current percentage to the screen. }
+ {#X Percent }
+ end; { of TPercentGauge }
+
+
+ {#Z+}
+ PBarGauge = ^TBarGauge;
+ {#Z-}
+ TBarGauge = Object(TPercentGauge)
+ { A TBarGauge displays a bar which increases in size from the left to
+ the right of the view as Current increases. A numeric percentage
+ representing the value of (Current / Max) * 100 is displayed in the
+ center of the bar. }
+ {#x TPercentGauge.Percent }
+ procedure Draw; virtual;
+ { Draw draws the bar and percentage to the screen representing the
+ current status of the view's variables. }
+ {#X TGauge.Update }
+ function GetPalette : PPalette; virtual;
+ { GetPalette returns a pointer to the default status view palette,
+ #CBarStatus#. }
+ end; { of TBarGauge }
+
+
+ {#Z+}
+ PSpinnerGauge = ^TSpinnerGauge;
+ {#Z-}
+ TSpinnerGauge = Object(TGauge)
+ { A TSpinnerGauge displays a series of characters in one spot on the
+ screen giving the illusion of a spinning line. }
+ constructor Init (X, Y : Integer; ACommand : Word);
+ { Init calls the inherited constructor with AMin set to 0 and AMax set
+ to 4. }
+ procedure Draw; virtual;
+ { Draw uses the #SpinChars# variable to draw the view's Current
+ character. }
+ {#X Update }
+ procedure HandleEvent (var Event : TEvent); virtual;
+ { HandleEvent calls TStatus.HandleEvent so that a cmStatusDone event
+ is not generated when Current equals Max. }
+ {#X TGauge.Current TGauge.Max }
+ procedure Update (Data : Pointer); virtual;
+ { Update increments Current until Current equals Max, when it resets
+ Current to Min. }
+ {#X Draw HandleEvent }
+ end; { of TSpinnerGauge }
+
+
+ {#Z+}
+ PAppStatus = ^TAppStatus;
+ {#Z-}
+ TAppStatus = Object(TStatus)
+ { TAppStatus is a base object which implements color control for status
+ views that are normally inserted in the Application object. }
+ {#X TStatus }
+ function GetPalette : PPalette; virtual;
+ { GetPalette returns a pointer to the default application status view
+ palette, #CAppStatus#. }
+ {#X TStatus CStatus }
+ end; { of TAppStatus }
+
+
+ {#Z+}
+ PHeapMaxAvail = ^THeapMaxAvail;
+ {#Z-}
+ THeapMaxAvail = Object(TAppStatus)
+ { A THeapMaxAvail displays the largest available contiguous area of heap
+ memory. It responds to a cmStatusUpdate event by calling MaxAvail and
+ comparing the result to #Max#, then updating the view if necessary. }
+ {#X THeapMemAvail }
+ constructor Init (X, Y : Integer);
+ { Init creates the view with the following text:
+
+ MaxAvail = xxxx
+
+ where xxxx is the result returned by MaxAvail. }
+ procedure Update (Data : Pointer); virtual;
+ { Update changes #Mem# to the current MemAvail and redraws the status
+ if necessary. }
+ private
+ Max : LongInt;
+ { Max is the last reported value from MaxAvail. }
+ {#X Update }
+ end; { of THeapMaxAvail }
+
+
+ {#Z+}
+ PHeapMemAvail = ^THeapMemAvail;
+ {#Z-}
+ THeapMemAvail = Object(TAppStatus)
+ { A THeapMemAvail displays the total amount of heap memory available to
+ the application. It responds to a cmStatusUpdate event by calling
+ MemAvail and comparing the result to #Max#, then updating the view if
+ necessary. }
+ {#X THeapMaxAvail }
+ constructor Init (X, Y : Integer);
+ { Init creates the view with the following text:
+
+ MemAvail = xxxx
+
+ where xxxx is the result returned by MemAvail. }
+ {#X Load }
+ procedure Update (Data : Pointer); virtual;
+ { Update changes #Mem# to the current MemAvail and redraws the status
+ if necessary. }
+ private
+ Mem : LongInt;
+ { Mem is the last available value reported by MemAvail. }
+ {#X Update }
+ end; { of THeapMemAvail }
+
+
+{$ifndef cdPrintDoc}
+{#Z+}
+{$endif cdPrintDoc}
+const
+ RStatus : TStreamRec = (
+ ObjType : idStatus;
+ VmtLink : Ofs(TypeOf(TStatus)^);
+ Load : @TStatus.Load;
+ Store : @TStatus.Store);
+
+ RStatusDlg : TStreamRec = (
+ ObjType : idStatusDlg;
+ VmtLink : Ofs(TypeOf(TStatusDlg)^);
+ Load : @TStatusDlg.Load;
+ Store : @TStatusDlg.Store);
+
+ RStatusMessageDlg : TStreamRec = (
+ ObjType : idStatusMessageDlg;
+ VmtLink : Ofs(TypeOf(TStatusMessageDlg)^);
+ Load : @TStatusMessageDlg.Load;
+ Store : @TStatusMessageDlg.Store);
+
+ RGauge : TStreamRec = (
+ ObjType : idGauge;
+ VmtLink : Ofs(TypeOf(TGauge)^);
+ Load : @TGauge.Load;
+ Store : @TGauge.Store);
+
+ RArrowGauge : TStreamRec = (
+ ObjType : idArrowGauge;
+ VmtLink : Ofs(TypeOf(TArrowGauge)^);
+ Load : @TArrowGauge.Load;
+ Store : @TArrowGauge.Store);
+
+ RBarGauge : TStreamRec = (
+ ObjType : idBarGauge;
+ VmtLink : Ofs(TypeOf(TBarGauge)^);
+ Load : @TBarGauge.Load;
+ Store : @TBarGauge.Store);
+
+ RPercentGauge : TStreamRec = (
+ ObjType : idPercentGauge;
+ VmtLink : Ofs(TypeOf(TPercentGauge)^);
+ Load : @TPercentGauge.Load;
+ Store : @TPercentGauge.Store);
+
+ RSpinnerGauge : TStreamRec = (
+ ObjType : idSpinnerGauge;
+ VmtLink : Ofs(TypeOf(TSpinnerGauge)^);
+ Load : @TSpinnerGauge.Load;
+ Store : @TSpinnerGauge.Store);
+
+ RAppStatus : TStreamRec = (
+ ObjType : idAppStatus;
+ VmtLink : Ofs(TypeOf(TAppStatus)^);
+ Load : @TAppStatus.Load;
+ Store : @TAppStatus.Store);
+
+ RHeapMinAvail : TStreamRec = (
+ ObjType : idHeapMinAvail;
+ VmtLink : Ofs(TypeOf(THeapMaxAvail)^);
+ Load : @THeapMaxAvail.Load;
+ Store : @THeapMaxAvail.Store);
+
+ RHeapMemAvail : TStreamRec = (
+ ObjType : idHeapMemAvail;
+ VmtLink : Ofs(TypeOf(THeapMemAvail)^);
+ Load : @THeapMemAvail.Load;
+ Store : @THeapMemAvail.Store);
+{$ifndef cdPrintDoc}
+{#Z-}
+{$endif cdPrintDoc}
+
+procedure RegisterStatuses;
+{$ifndef cdPrintDoc}
+{#F+}
+{ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ
+ÝRegisterStatuses procedure (Statuses unit)Þ
+ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß}
+{#F-}
+{$endif cdPrintDoc}
+ { RegisterStatuses calls RegisterType for each of the status view and
+ status dialog object types defined in the tvStatus unit. After calling
+ RegisterStatuses, your application can read or write any of those types
+ with streams. }
+
+
+implementation
+
+uses
+ MsgBox, App;
+
+{****************************************************************************}
+{ Local procedures and functions }
+{****************************************************************************}
+
+{****************************************************************************}
+{ TAppStatus Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TAppStatus.GetPalette }
+{****************************************************************************}
+function TAppStatus.GetPalette : PPalette;
+const P : String[Length(CAppStatus)] = CAppStatus;
+begin
+ GetPalette := PPalette(@P);
+end;
+
+{****************************************************************************}
+{ TArrowGauge Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TArrowGauge.Init }
+{****************************************************************************}
+constructor TArrowGauge.Init (R : TRect; ACommand : Word; AMin, AMax : Word;
+ RightArrow : Boolean);
+begin
+ if not TGauge.Init(R,ACommand,AMin,AMax) then
+ Fail;
+ Right := RightArrow;
+end;
+
+{****************************************************************************}
+{ TArrowGauge.Load }
+{****************************************************************************}
+constructor TArrowGauge.Load (var S : TStream);
+begin
+ if not TGauge.Load(S) then
+ Fail;
+ S.Read(Right,SizeOf(Right));
+ if (S.Status <> stOk) then
+ begin
+ TGauge.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TArrowGauge.Draw }
+{****************************************************************************}
+procedure TArrowGauge.Draw;
+const Arrows : array[0..1] of Char = '<>';
+var
+ B : TDrawBuffer;
+ C : Word;
+ Len : Byte;
+begin
+ C := GetColor(1);
+ Len := Round(Size.X * Current/(Max - Min));
+ MoveChar(B,' ',C,Size.X);
+ if Right then
+ MoveChar(B,Arrows[Byte(Right)],C,Len)
+ else MoveChar(B[Size.X - Len],Arrows[Byte(Right)],C,Len);
+ WriteLine(0,0,Size.X,1,B);
+end;
+
+{****************************************************************************}
+{ TArrowGauge.GetData }
+{****************************************************************************}
+procedure TArrowGauge.GetData (var Rec);
+begin
+ PArrowGaugeRec(Rec)^.Min := Min;
+ PArrowGaugeRec(Rec)^.Max := Max;
+ PArrowGaugeRec(Rec)^.Count := Current;
+ PArrowGaugeRec(Rec)^.Right := Right;
+end;
+
+{****************************************************************************}
+{ TArrowGauge.SetData }
+{****************************************************************************}
+procedure TArrowGauge.SetData (var Rec);
+begin
+ Min := PArrowGaugeRec(Rec)^.Min;
+ Max := PArrowGaugeRec(Rec)^.Max;
+ Current := PArrowGaugeRec(Rec)^.Count;
+ Right := PArrowGaugeRec(Rec)^.Right;
+end;
+
+{****************************************************************************}
+{ TArrowGauge.Store }
+{****************************************************************************}
+procedure TArrowGauge.Store (var S : TStream);
+begin
+ TGauge.Store(S);
+ S.Write(Right,SizeOf(Right));
+end;
+
+{****************************************************************************}
+{ TBarGauge Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TBarGauge.Draw }
+{****************************************************************************}
+procedure TBarGauge.Draw;
+var
+ B : TDrawBuffer;
+ C : Word;
+ FillSize : Word;
+ PercentDone : LongInt;
+ S : String[4];
+begin
+ { fill entire view }
+ MoveChar(B,' ',GetColor(4),Size.X);
+ { make progress bar }
+ C := GetColor(5);
+ FillSize := Round(Size.X * (Current / Max));
+ MoveChar(B,' ',C,FillSize);
+ { display percent done }
+ PercentDone := Percent;
+ FormatStr(S,'%d%%',PercentDone);
+ if PercentDone < 50 then
+ C := GetColor(4);
+ FillSize := (Size.X - Length(S)) div 2;
+ MoveStr(B[FillSize],S,C);
+ WriteLine(0,0,Size.X,Size.Y,B);
+end;
+
+{****************************************************************************}
+{ TBarGauge.GetPalette }
+{****************************************************************************}
+function TBarGauge.GetPalette : PPalette;
+const
+ S : String[Length(CBarGauge)] = CBarGauge;
+begin
+ GetPalette := PPalette(@S);
+end;
+
+{****************************************************************************}
+{ TGauge Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TGauge.Init }
+{****************************************************************************}
+constructor TGauge.Init (R : TRect; ACommand : Word; AMin, AMax : LongInt);
+begin
+ if not TStatus.Init(R,ACommand,'',1) then
+ Fail;
+ Min := AMin;
+ Max := AMax;
+ Current := Min;
+end;
+
+{****************************************************************************}
+{ TGauge.Load }
+{****************************************************************************}
+constructor TGauge.Load (var S : TStream);
+begin
+ if not TStatus.Load(S) then
+ Fail;
+ S.Read(Min,SizeOf(Min));
+ S.Read(Max,SizeOf(Max));
+ S.Read(Current,SizeOf(Current));
+ if S.Status <> stOk then
+ begin
+ TStatus.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TGauge.Draw }
+{****************************************************************************}
+procedure TGauge.Draw;
+var
+ S : String;
+ B : TDrawBuffer;
+begin
+ { Blank the gauge }
+ MoveChar(B,' ',GetColor(1),Size.X);
+ WriteBuf(0,0,Size.X,Size.Y,B);
+ { write current status }
+ FormatStr(S,'%d',Current);
+ MoveStr(B,S,GetColor(1));
+ WriteBuf(0,0,Size.X,Size.Y,B);
+end;
+
+{****************************************************************************}
+{ TGauge.GetData }
+{****************************************************************************}
+procedure TGauge.GetData (var Rec);
+begin
+ TGaugeRec(Rec).Min := Min;
+ TGaugeRec(Rec).Max := Max;
+ TGaugeRec(Rec).Current := Current;
+end;
+
+{****************************************************************************}
+{ TGauge.Reset }
+{****************************************************************************}
+procedure TGauge.Reset;
+begin
+ Current := Min;
+ DrawView;
+end;
+
+{****************************************************************************}
+{ TGauge.SetData }
+{****************************************************************************}
+procedure TGauge.SetData (var Rec);
+begin
+ Min := TGaugeRec(Rec).Min;
+ Max := TGaugeRec(Rec).Max;
+ Current := TGaugeRec(Rec).Current;
+end;
+
+{****************************************************************************}
+{ TGauge.Store }
+{****************************************************************************}
+procedure TGauge.Store (var S : TStream);
+begin
+ TStatus.Store(S);
+ S.Write(Min,SizeOf(Min));
+ S.Write(Max,SizeOf(Max));
+ S.Write(Current,SizeOf(Current));
+end;
+
+{****************************************************************************}
+{ TGauge.Update }
+{****************************************************************************}
+procedure TGauge.Update (Data : Pointer);
+begin
+ if Current < Max then
+ begin
+ Inc(Current);
+ DrawView;
+ end
+ else Message(@Self,evStatus,cmStatusDone,@Self);
+end;
+
+{****************************************************************************}
+{ THeapMaxAvail Object }
+{****************************************************************************}
+{****************************************************************************}
+{ THeapMaxAvail.Init }
+{****************************************************************************}
+constructor THeapMaxAvail.Init (X, Y : Integer);
+var
+ R : TRect;
+begin
+ R.Assign(X,Y,X+20,Y+1);
+ if not TAppStatus.Init(R,cmStatusUpdate,' MaxAvail = %d',1) then
+ Fail;
+ Max := -1;
+end;
+
+{****************************************************************************}
+{ THeapMaxAvail.Update }
+{****************************************************************************}
+procedure THeapMaxAvail.Update (Data : Pointer);
+var
+ M : LongInt;
+begin
+ M := MaxAvail;
+ if (Max <> M) then
+ begin
+ Max := MaxAvail;
+ SetData(Max);
+ end;
+end;
+
+{****************************************************************************}
+{ THeapMemAvail Object }
+{****************************************************************************}
+{****************************************************************************}
+{ THeapMemAvail.Init }
+{****************************************************************************}
+constructor THeapMemAvail.Init (X, Y : Integer);
+var
+ R : TRect;
+begin
+ R.Assign(X,Y,X+20,Y+1);
+ if not TAppStatus.Init(R,cmStatusUpdate,' MemAvail = %d',1) then
+ Fail;
+ Mem := -1;
+end;
+
+{****************************************************************************}
+{ THeapMemAvail.Update }
+{****************************************************************************}
+procedure THeapMemAvail.Update (Data : Pointer);
+ { Total bytes available on the heap. May not be contiguous. }
+var
+ M : LongInt;
+begin
+ M := MemAvail;
+ if (Mem <> M) then
+ begin
+ Mem := M;
+ SetData(Mem);
+ end;
+end;
+
+{****************************************************************************}
+{ TPercentGauge Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TPercentGauge.Draw }
+{****************************************************************************}
+procedure TPercentGauge.Draw;
+var
+ B : TDrawBuffer;
+ C : Word;
+ S : String;
+ PercentDone : LongInt;
+ FillSize : Integer;
+begin
+ C := GetColor(1);
+ MoveChar(B,' ',C,Size.X);
+ WriteLine(0,0,Size.X,Size.Y,B);
+ PercentDone := Percent;
+ FormatStr(S,'%d%%',PercentDone);
+ MoveStr(B[(Size.X - Byte(S[0])) div 2],S,C);
+ WriteLine(0,0,Size.X,Size.Y,B);
+end;
+
+{****************************************************************************}
+{ TPercentGauge.Percent }
+{****************************************************************************}
+function TPercentGauge.Percent : Integer;
+ { Returns percent as a whole integer Current of Max }
+begin
+ Percent := Round((Current/Max) * 100);
+end;
+
+{****************************************************************************}
+{ TSpinnerGauge Object }
+{****************************************************************************}
+
+{****************************************************************************}
+{ TSpinnerGauge.Init }
+{****************************************************************************}
+constructor TSpinnerGauge.Init (X, Y : Integer; ACommand : Word);
+var R : TRect;
+begin
+ R.Assign(X,Y,X+1,Y+1);
+ if not TGauge.Init(R,ACommand,1,4) then
+ Fail;
+end;
+
+{****************************************************************************}
+{ TSpinnerGauge.Draw }
+{****************************************************************************}
+procedure TSpinnerGauge.Draw;
+var
+ B : TDrawBuffer;
+ C : Word;
+begin
+ C := GetColor(1);
+ MoveChar(B,' ',C,Size.X);
+ WriteLine(0,0,Size.X,Size.Y,B);
+ MoveChar(B[Size.X div 2],SpinChars[Current],C,1);
+ WriteLine(0,0,Size.X,Size.Y,B);
+end;
+
+{****************************************************************************}
+{ TSpinnerGauge.HandleEvent }
+{****************************************************************************}
+procedure TSpinnerGauge.HandleEvent (var Event : TEvent);
+begin
+ TStatus.HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TSpinnerGauge.Update }
+{****************************************************************************}
+procedure TSpinnerGauge.Update (Data : Pointer);
+begin
+ if Current = Max then
+ Current := Min
+ else Inc(Current);
+ DrawView;
+end;
+
+{****************************************************************************}
+{ TStatus Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TStatus.Init }
+{****************************************************************************}
+constructor TStatus.Init (R : TRect; ACommand : Word; AText : String;
+ AParamCount : Integer);
+begin
+ if (not TParamText.Init(R,AText,AParamCount)) then
+ Fail;
+ EventMask := EventMask or evStatus;
+ Command := ACommand;
+end;
+
+{****************************************************************************}
+{ TStatus.Load }
+{****************************************************************************}
+constructor TStatus.Load (var S : TStream);
+begin
+ if not TParamText.Load(S) then
+ Fail;
+ S.Read(Command,SizeOf(Command));
+ if (S.Status <> stOk) then
+ begin
+ TParamText.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TStatus.Cancel }
+{****************************************************************************}
+function TStatus.Cancel : Boolean;
+begin
+ Cancel := True;
+end;
+
+{****************************************************************************}
+{ TStatus.GetPalette }
+{****************************************************************************}
+function TStatus.GetPalette : PPalette;
+const
+ P : String[Length(CStatus)] = CStatus;
+begin
+ GetPalette := PPalette(@P);
+end;
+
+{****************************************************************************}
+{ TStatus.HandleEvent }
+{****************************************************************************}
+procedure TStatus.HandleEvent (var Event : TEvent);
+begin
+ if (Event.What = evCommand) and (Event.Command = cmStatusPause) then
+ begin
+ Pause;
+ ClearEvent(Event);
+ end;
+ case Event.What of
+ evStatus :
+ case Event.Command of
+ cmStatusDone :
+ if (Event.InfoPtr = @Self) then
+ begin
+ Message(Owner,evStatus,cmStatusDone,@Self);
+ ClearEvent(Event);
+ end;
+ cmStatusUpdate :
+ if (Event.InfoWord = Command) and ((State and sfPause) = 0) then
+ begin
+ Update(Event.InfoPtr);
+ { ClearEvent(Event); } { don't clear the event so multiple }
+ { status views can respond to the same event }
+ end;
+ cmStatusResume :
+ if (Event.InfoWord = Command) and
+ ((State and sfPause) = sfPause) then
+ begin
+ Resume;
+ ClearEvent(Event);
+ end;
+ cmStatusPause :
+ if (Event.InfoWord = Command) and ((State and sfPause) = 0) then
+ begin
+ Pause;
+ ClearEvent(Event);
+ end;
+ end;
+ end;
+ TParamText.HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TStatus.Pause }
+{****************************************************************************}
+procedure TStatus.Pause;
+begin
+ SetState(sfPause,True);
+end;
+
+{****************************************************************************}
+{ TStatus.Reset }
+{****************************************************************************}
+procedure TStatus.Reset;
+begin
+ DrawView;
+end;
+
+{****************************************************************************}
+{ TStatus.Resume }
+{****************************************************************************}
+procedure TStatus.Resume;
+begin
+ SetState(sfPause,False);
+end;
+
+{****************************************************************************}
+{ TStatus.Store }
+{****************************************************************************}
+procedure TStatus.Store (var S : TStream);
+begin
+ TParamText.Store(S);
+ S.Write(Command,SizeOf(Command));
+end;
+
+{****************************************************************************}
+{ TStatus.Update }
+{****************************************************************************}
+procedure TStatus.Update (Data : Pointer);
+begin
+ DisposeStr(Text);
+ Text := NewStr(String(Data^));
+ DrawView;
+end;
+
+{****************************************************************************}
+{ TStatusDlg Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TStatusDlg.Init }
+{****************************************************************************}
+constructor TStatusDlg.Init (ATitle : TTitleStr; AStatus : PStatus;
+ AFlags : Word);
+var
+ R : TRect;
+ i : LongInt;
+ Buttons : Byte;
+begin
+ if (AStatus = nil) then
+ Fail;
+ R.A := AStatus^.Origin;
+ R.B := AStatus^.Size;
+ Inc(R.B.Y,R.A.Y+4);
+ Inc(R.B.X,R.A.X+5);
+ if not TDialog.Init(R,ATitle) then
+ Fail;
+ EventMask := EventMask or evStatus;
+ Status := AStatus;
+ Status^.MoveTo(2,2);
+ Insert(Status);
+ InsertButtons(AFlags);
+end;
+
+{****************************************************************************}
+{ TStatusDlg.Load }
+{****************************************************************************}
+constructor TStatusDlg.Load (var S : TStream);
+begin
+ if not TDialog.Load(S) then
+ Fail;
+ GetSubViewPtr(S,Status);
+ if (S.Status <> stOk) then
+ begin
+ if (Status <> nil) then
+ Dispose(Status,Done);
+ TDialog.Done;
+ Fail;
+ end;
+end;
+
+{****************************************************************************}
+{ TStatusDlg.Cancel }
+{****************************************************************************}
+procedure TStatusDlg.Cancel (ACommand : Word);
+begin
+ if Status^.Cancel then
+ TDialog.Cancel(ACommand);
+end;
+
+{****************************************************************************}
+{ TStatusDlg.HandleEvent }
+{****************************************************************************}
+procedure TStatusDlg.HandleEvent (var Event : TEvent);
+begin
+ case Event.What of
+ evStatus :
+ case Event.Command of
+ cmStatusDone :
+ if Event.InfoPtr = Status then
+ begin
+ TDialog.Cancel(cmOk);
+ ClearEvent(Event);
+ end;
+ end;
+ { else let TDialog.HandleEvent send to all subviews for handling }
+ evBroadcast, evCommand :
+ case Event.Command of
+ cmCancel, cmClose :
+ begin
+ Cancel(cmCancel);
+ ClearEvent(Event);
+ end;
+ cmStatusPause :
+ begin
+ Status^.Pause;
+ ClearEvent(Event);
+ end;
+ cmStatusResume :
+ begin
+ Status^.Resume;
+ ClearEvent(Event);
+ end;
+ end;
+ end;
+ TDialog.HandleEvent(Event);
+end;
+
+{****************************************************************************}
+{ TStatusDlg.InsertButtons }
+{****************************************************************************}
+procedure TStatusDlg.InsertButtons (AFlags : Word);
+var
+ R : TRect;
+ P : PButton;
+ Buttons : Byte;
+ X, Y, Gap : Integer;
+ i : Word;
+begin
+ Buttons := Byte(((AFlags and sdCancelButton) = sdCancelButton));
+ { do this Inc twice, once for Pause and once for Resume buttons }
+ Inc(Buttons,2 * Byte(((AFlags and sdPauseButton) = sdPauseButton)));
+ if Buttons > 0 then
+ begin
+ Status^.GrowMode := gfGrowHiX;
+ { resize dialog to hold all requested buttons }
+ if Size.X < ((Buttons * 12) + 2) then
+ GrowTo((Buttons * 12) + 2,Size.Y + 2)
+ else GrowTo(Size.X,Size.Y + 2);
+ { find correct starting position for first button }
+ Gap := Size.X - (Buttons * 10) - 2;
+ Gap := Gap div Succ(Buttons);
+ X := Gap;
+ if X < 2 then
+ X := 2;
+ Y := Size.Y - 3;
+ { insert buttons }
+ if ((AFlags and sdCancelButton) = sdCancelButton) then
+ begin
+ P := NewButton(X,Y,10,2,'Cancel',cmCancel,hcCancel,bfDefault);
+ P^.GrowMode := gfGrowHiY or gfGrowLoY;
+ Inc(X,12 + Gap);
+ end;
+ if ((AFlags and sdPauseButton) = sdPauseButton) then
+ begin
+ P := NewButton(X,Y,10,2,'~P~ause',cmStatusPause,hcStatusPause,bfNormal);
+ P^.GrowMode := gfGrowHiY or gfGrowLoY;
+ Inc(X,12 + Gap);
+ P := NewButton(X,Y,10,2,'~R~esume',cmStatusResume,hcStatusResume,
+ bfBroadcast);
+ P^.GrowMode := gfGrowHiY or gfGrowLoY;
+ end;
+ end; { of if }
+ SelectNext(False);
+end;
+
+{****************************************************************************}
+{ TStatusDlg.Store }
+{****************************************************************************}
+procedure TStatusDlg.Store (var S : TStream);
+begin
+ TDialog.Store(S);
+ PutSubViewPtr(S,Status);
+end;
+
+{****************************************************************************}
+{ TStatusMessageDlg Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TStatusMessageDlg.Init }
+{****************************************************************************}
+constructor TStatusMessageDlg.Init (ATitle : TTitleStr; AStatus : PStatus;
+ AFlags : Word; AMessage : String);
+var
+ P : PStaticText;
+ X, Y : Integer;
+ R : TRect;
+begin
+ if not TStatusDlg.Init(ATitle,AStatus,AFlags) then
+ Fail;
+ Status^.GrowMode := gfGrowLoY or gfGrowHiY;
+ GetExtent(R);
+ X := R.B.X - R.A.X;
+ if X < Size.X then
+ X := Size.X;
+ Y := R.B.Y - R.A.Y;
+ if Y < Size.Y then
+ Y := Size.Y;
+ GrowTo(X,Y);
+ R.Assign(2,2,Size.X-2,Size.Y-3);
+ P := New(PStaticText,Init(R,AMessage));
+ if (P = nil) then
+ begin
+ TStatusDlg.Done;
+ Fail;
+ end;
+ GrowTo(Size.X,Size.Y + P^.Size.Y + 1);
+ Insert(P);
+end;
+
+{****************************************************************************}
+{ Global procedures and functions }
+{****************************************************************************}
+
+{****************************************************************************}
+{ RegisterStatuses }
+{****************************************************************************}
+procedure RegisterStatuses;
+begin
+{ RegisterType(RStatus);
+ RegisterType(RStatusDlg);
+ RegisterType(RGauge);
+ RegisterType(RArrowGauge);
+ RegisterType(RPercentGauge);
+ RegisterType(RBarGauge);
+ RegisterType(RSpinnerGauge); }
+end;
+
+{****************************************************************************}
+{ Unit Initialization }
+{****************************************************************************}
+begin
+end.
diff --git a/packages/fv/src/stddlg.pas b/packages/fv/src/stddlg.pas
new file mode 100644
index 0000000000..4b584e4e62
--- /dev/null
+++ b/packages/fv/src/stddlg.pas
@@ -0,0 +1,2770 @@
+{*******************************************************}
+{ Free Vision Runtime Library }
+{ StdDlg Unit }
+{ Version: 0.1.0 }
+{ Release Date: July 23, 1998 }
+{ }
+{*******************************************************}
+{ }
+{ This unit is a port of Borland International's }
+{ StdDlg.pas unit. It is for distribution with the }
+{ Free Pascal (FPK) Compiler as part of the 32-bit }
+{ Free Vision library. The unit is still fully }
+{ functional under BP7 by using the tp compiler }
+{ directive when rebuilding the library. }
+{ }
+{*******************************************************}
+
+{ Revision History
+
+1.1a (97/12/29)
+ - fixed bug in TFileDialog.HandleEvent that prevented the user from being
+ able to have an action taken automatically when the FileList was
+ selected and kbEnter pressed
+
+1.1
+ - modified OpenNewFile to take a history list ID
+ - implemented OpenNewFile
+
+1.0 (1992)
+ - original implementation }
+
+unit StdDlg;
+
+{
+ This unit has been modified to make some functions global, apply patches
+ from version 3.1 of the TVBUGS list, added TEditChDirDialog, and added
+ several new global functions and procedures.
+}
+
+{$i platform.inc}
+
+{$ifdef PPC_FPC}
+ {$H-}
+{$else}
+ {$F+,O+,E+,N+}
+{$endif}
+{$X+,R-,I-,Q-,V-}
+{$ifndef OS_UNIX}
+ {$S-}
+{$endif}
+{$ifdef OS_DOS}
+ {$define HAS_DOS_DRIVES}
+{$endif}
+{$ifdef OS_WINDOWS}
+ {$define HAS_DOS_DRIVES}
+{$endif}
+{$ifdef OS_OS2}
+ {$define HAS_DOS_DRIVES}
+{$endif}
+
+{2.0 compatibility}
+{$ifdef VER2_0}
+ {$macro on}
+ {$define resourcestring := const}
+{$endif}
+
+interface
+
+uses
+ FVConsts, Objects, Drivers, Views, Dialogs, Validate, Dos;
+
+const
+ MaxDir = 255; { Maximum length of a DirStr. }
+ MaxFName = 255; { Maximum length of a FNameStr. }
+
+ DirSeparator : Char = system.DirectorySeparator;
+
+{$ifdef Unix}
+ AllFiles = '*';
+{$else}
+ AllFiles = '*.*';
+{$endif}
+
+type
+ { TSearchRec }
+
+ { Record used to store directory information by TFileDialog
+ This is a part of Dos.Searchrec for Bp !! }
+
+ TSearchRec =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ packed
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ record
+ Attr: Longint;
+ Time: Longint;
+ Size: Longint;
+ Name: string[MaxFName];
+ end;
+ PSearchRec = ^TSearchRec;
+
+type
+
+ { TFileInputLine is a special input line that is used by }
+ { TFileDialog that will update its contents in response to a }
+ { cmFileFocused command from a TFileList. }
+
+ PFileInputLine = ^TFileInputLine;
+ TFileInputLine = object(TInputLine)
+ constructor Init(var Bounds: TRect; AMaxLen: Sw_Integer);
+ procedure HandleEvent(var Event: TEvent); virtual;
+ end;
+
+ { TFileCollection is a collection of TSearchRec's. }
+
+ PFileCollection = ^TFileCollection;
+ TFileCollection = object(TSortedCollection)
+ function Compare(Key1, Key2: Pointer): Sw_Integer; virtual;
+ procedure FreeItem(Item: Pointer); virtual;
+ function GetItem(var S: TStream): Pointer; virtual;
+ procedure PutItem(var S: TStream; Item: Pointer); virtual;
+ end;
+
+ {#Z+}
+ PFileValidator = ^TFileValidator;
+ {#Z-}
+ TFileValidator = Object(TValidator)
+ end; { of TFileValidator }
+
+ { TSortedListBox is a TListBox that assumes it has a }
+ { TStoredCollection instead of just a TCollection. It will }
+ { perform an incremental search on the contents. }
+
+ PSortedListBox = ^TSortedListBox;
+ TSortedListBox = object(TListBox)
+ SearchPos: Byte;
+ {ShiftState: Byte;}
+ HandleDir : boolean;
+ constructor Init(var Bounds: TRect; ANumCols: Sw_Word;
+ AScrollBar: PScrollBar);
+ procedure HandleEvent(var Event: TEvent); virtual;
+ function GetKey(var S: String): Pointer; virtual;
+ procedure NewList(AList: PCollection); virtual;
+ end;
+
+ { TFileList is a TSortedList box that assumes it contains }
+ { a TFileCollection as its collection. It also communicates }
+ { through broadcast messages to TFileInput and TInfoPane }
+ { what file is currently selected. }
+
+ PFileList = ^TFileList;
+ TFileList = object(TSortedListBox)
+ constructor Init(var Bounds: TRect; AScrollBar: PScrollBar);
+ destructor Done; virtual;
+ function DataSize: Sw_Word; virtual;
+ procedure FocusItem(Item: Sw_Integer); virtual;
+ procedure GetData(var Rec); virtual;
+ function GetText(Item,MaxLen: Sw_Integer): String; virtual;
+ function GetKey(var S: String): Pointer; virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ procedure ReadDirectory(AWildCard: PathStr);
+ procedure SetData(var Rec); virtual;
+ end;
+
+ { TFileInfoPane is a TView that displays the information }
+ { about the currently selected file in the TFileList }
+ { of a TFileDialog. }
+
+ PFileInfoPane = ^TFileInfoPane;
+ TFileInfoPane = object(TView)
+ S: TSearchRec;
+ constructor Init(var Bounds: TRect);
+ procedure Draw; virtual;
+ function GetPalette: PPalette; virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ end;
+
+ { TFileDialog is a standard file name input dialog }
+
+ TWildStr = PathStr;
+
+const
+ fdOkButton = $0001; { Put an OK button in the dialog }
+ fdOpenButton = $0002; { Put an Open button in the dialog }
+ fdReplaceButton = $0004; { Put a Replace button in the dialog }
+ fdClearButton = $0008; { Put a Clear button in the dialog }
+ fdHelpButton = $0010; { Put a Help button in the dialog }
+ fdNoLoadDir = $0100; { Do not load the current directory }
+ { contents into the dialog at Init. }
+ { This means you intend to change the }
+ { WildCard by using SetData or store }
+ { the dialog on a stream. }
+
+type
+
+ PFileHistory = ^TFileHistory;
+ TFileHistory = object(THistory)
+ CurDir : PString;
+ procedure HandleEvent(var Event: TEvent);virtual;
+ destructor Done; virtual;
+ procedure AdaptHistoryToDir(Dir : string);
+ end;
+
+ PFileDialog = ^TFileDialog;
+ TFileDialog = object(TDialog)
+ FileName: PFileInputLine;
+ FileList: PFileList;
+ FileHistory: PFileHistory;
+ WildCard: TWildStr;
+ Directory: PString;
+ constructor Init(AWildCard: TWildStr; const ATitle,
+ InputName: String; AOptions: Word; HistoryId: Byte);
+ constructor Load(var S: TStream);
+ destructor Done; virtual;
+ procedure GetData(var Rec); virtual;
+ procedure GetFileName(var S: PathStr);
+ procedure HandleEvent(var Event: TEvent); virtual;
+ procedure SetData(var Rec); virtual;
+ procedure Store(var S: TStream);
+ function Valid(Command: Word): Boolean; virtual;
+ private
+ procedure ReadDirectory;
+ end;
+
+ { TDirEntry }
+
+ PDirEntry = ^TDirEntry;
+ TDirEntry = record
+ DisplayText: PString;
+ Directory: PString;
+ end; { of TDirEntry }
+
+ { TDirCollection is a collection of TDirEntry's used by }
+ { TDirListBox. }
+
+ PDirCollection = ^TDirCollection;
+ TDirCollection = object(TCollection)
+ function GetItem(var S: TStream): Pointer; virtual;
+ procedure FreeItem(Item: Pointer); virtual;
+ procedure PutItem(var S: TStream; Item: Pointer); virtual;
+ end;
+
+ { TDirListBox displays a tree of directories for use in the }
+ { TChDirDialog. }
+
+ PDirListBox = ^TDirListBox;
+ TDirListBox = object(TListBox)
+ Dir: DirStr;
+ Cur: Word;
+ constructor Init(var Bounds: TRect; AScrollBar: PScrollBar);
+ destructor Done; virtual;
+ function GetText(Item,MaxLen: Sw_Integer): String; virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ function IsSelected(Item: Sw_Integer): Boolean; virtual;
+ procedure NewDirectory(var ADir: DirStr);
+ procedure SetState(AState: Word; Enable: Boolean); virtual;
+ end;
+
+ { TChDirDialog is a standard change directory dialog. }
+
+const
+ cdNormal = $0000; { Option to use dialog immediately }
+ cdNoLoadDir = $0001; { Option to init the dialog to store on a stream }
+ cdHelpButton = $0002; { Put a help button in the dialog }
+
+type
+
+ PChDirDialog = ^TChDirDialog;
+ TChDirDialog = object(TDialog)
+ DirInput: PInputLine;
+ DirList: PDirListBox;
+ OkButton: PButton;
+ ChDirButton: PButton;
+ constructor Init(AOptions: Word; HistoryId: Sw_Word);
+ constructor Load(var S: TStream);
+ function DataSize: Sw_Word; virtual;
+ procedure GetData(var Rec); virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ procedure SetData(var Rec); virtual;
+ procedure Store(var S: TStream);
+ function Valid(Command: Word): Boolean; virtual;
+ private
+ procedure SetUpDialog;
+ end;
+
+ PEditChDirDialog = ^TEditChDirDialog;
+ TEditChDirDialog = Object(TChDirDialog)
+ { TEditChDirDialog allows setting/getting the starting directory. The
+ transfer record is a DirStr. }
+ function DataSize : Sw_Word; virtual;
+ procedure GetData (var Rec); virtual;
+ procedure SetData (var Rec); virtual;
+ end; { of TEditChDirDialog }
+
+
+ {#Z+}
+ PDirValidator = ^TDirValidator;
+ {#Z-}
+ TDirValidator = Object(TFilterValidator)
+ constructor Init;
+ function IsValid(const S: string): Boolean; virtual;
+ function IsValidInput(var S: string; SuppressFill: Boolean): Boolean;
+ virtual;
+ end; { of TDirValidator }
+
+
+ FileConfirmFunc = function (AFile : FNameStr) : Boolean;
+ { Functions of type FileConfirmFunc's are used to prompt the end user for
+ confirmation of an operation.
+
+ FileConfirmFunc's should ask the user whether to perform the desired
+ action on the file named AFile. If the user elects to perform the
+ function FileConfirmFunc's return True, otherwise they return False.
+
+ Using FileConfirmFunc's allows routines to be coded independant of the
+ user interface implemented. OWL and TurboVision are supported through
+ conditional defines. If you do not use either user interface you must
+ compile this unit with the conditional define cdNoMessages and set all
+ FileConfirmFunc variables to a valid function prior to calling any
+ routines in this unit. }
+ {#X ReplaceFile DeleteFile }
+
+
+var
+
+ ReplaceFile : FileConfirmFunc;
+ { ReplaceFile returns True if the end user elects to replace the existing
+ file with the new file, otherwise it returns False.
+
+ ReplaceFile is only called when #CheckOnReplace# is True. }
+ {#X DeleteFile }
+
+ DeleteFile : FileConfirmFunc;
+ { DeleteFile returns True if the end user elects to delete the file,
+ otherwise it returns False.
+
+ DeleteFile is only called when #CheckOnDelete# is True. }
+ {#X ReplaceFile }
+
+
+const
+
+ CInfoPane = #30;
+
+ { TStream registration records }
+
+function Contains(S1, S2: String): Boolean;
+ { Contains returns true if S1 contains any characters in S2. }
+
+function DriveValid(Drive: Char): Boolean;
+ { DriveValid returns True if Drive is a valid DOS drive. Drive valid works
+ by attempting to change the current directory to Drive, then restoring
+ the original directory. }
+
+function ExtractDir(AFile: FNameStr): DirStr;
+ { ExtractDir returns the path of AFile terminated with a trailing '\'. If
+ AFile contains no directory information, an empty string is returned. }
+
+function ExtractFileName(AFile: FNameStr): NameStr;
+ { ExtractFileName returns the file name without any directory or file
+ extension information. }
+
+function Equal(const S1, S2: String; Count: Sw_word): Boolean;
+ { Equal returns True if S1 equals S2 for up to Count characters. Equal is
+ case-insensitive. }
+
+function FileExists (AFile : FNameStr) : Boolean;
+ { FileExists looks for the file specified in AFile. If AFile is present
+ FileExists returns true, otherwise FileExists returns False.
+
+ The search is performed relative to the current system directory, but
+ other directories may be searched by prefacing a file name with a valid
+ directory path.
+
+ There is no check for a vaild file name or drive. Errrors are handled
+ internally and not reported in DosError. Critical errors are left to
+ the system's critical error handler. }
+ {#X OpenFile }
+
+function GetCurDir: DirStr;
+ { GetCurDir returns the current directory. The directory returned always
+ ends with a trailing backslash '\'. }
+
+function GetCurDrive: Char;
+ { GetCurDrive returns the letter of the current drive as reported by the
+ operating system. }
+
+function IsWild(const S: String): Boolean;
+ { IsWild returns True if S contains a question mark (?) or asterix (*). }
+
+function IsList(const S: String): Boolean;
+ { IsList returns True if S contains list separator (;) char }
+
+function IsDir(const S: String): Boolean;
+ { IsDir returns True if S is a valid DOS directory. }
+
+{procedure MakeResources;}
+ { MakeResources places a language specific version of all resources
+ needed for the StdDlg unit to function on the RezFile using the string
+ constants and variables in the Resource unit. The Resource unit and the
+ appropriate string lists must be initialized prior to calling this
+ procedure. }
+
+function NoWildChars(S: String): String;
+ { NoWildChars deletes the wild card characters ? and * from the string S
+ and returns the result. }
+
+function OpenFile (var AFile : FNameStr; HistoryID : Byte) : Boolean;
+ { OpenFile prompts the user to select a file using the file specifications
+ in AFile as the starting file and path. Wildcards are accepted. If the
+ user accepts a file OpenFile returns True, otherwise OpenFile returns
+ False.
+
+ Note: The file returned may or may not exist. }
+
+function OpenNewFile (var AFile: FNameStr; HistoryID: Byte): Boolean;
+ { OpenNewFile allows the user to select a directory from disk and enter a
+ new file name. If the file name entered is an existing file the user is
+ optionally prompted for confirmation of replacing the file based on the
+ value in #CheckOnReplace#. If a file name is successfully entered,
+ OpenNewFile returns True. }
+ {#X OpenFile }
+
+function PathValid(var Path: PathStr): Boolean;
+ { PathValid returns True if Path is a valid DOS path name. Path may be a
+ file or directory name. Trailing '\'s are removed. }
+
+procedure RegisterStdDlg;
+ { RegisterStdDlg registers all objects in the StdDlg unit for stream
+ usage. }
+
+function SaveAs (var AFile : FNameStr; HistoryID : Word) : Boolean;
+ { SaveAs prompts the user for a file name using AFile as a template. If
+ AFile already exists and CheckOnReplace is True, the user is prompted
+ to replace the file.
+
+ If a valid file name is entered SaveAs returns True, other SaveAs returns
+ False. }
+
+function SelectDir (var ADir : DirStr; HistoryID : Byte) : Boolean;
+ { SelectDir prompts the user to select a directory using ADir as the
+ starting directory. If a directory is selected, SelectDir returns True.
+ The directory returned is gauranteed to exist. }
+
+function ShrinkPath (AFile : FNameStr; MaxLen : Byte) : FNameStr;
+ { ShrinkPath returns a file name with a maximu length of MaxLen.
+ Internal directories are removed and replaced with elipses as needed to
+ make the file name fit in MaxLen.
+
+ AFile must be a valid path name. }
+
+function StdDeleteFile (AFile : FNameStr) : Boolean;
+ { StdDeleteFile returns True if the end user elects to delete the file,
+ otherwise it returns False.
+
+ DeleteFile is only called when CheckOnDelete is True. }
+
+function StdReplaceFile (AFile : FNameStr) : Boolean;
+ { StdReplaceFile returns True if the end user elects to replace the existing
+ AFile with the new AFile, otherwise it returns False.
+
+ ReplaceFile is only called when CheckOnReplace is True. }
+
+function ValidFileName(var FileName: PathStr): Boolean;
+ { ValidFileName returns True if FileName is a valid DOS file name. }
+
+
+const
+ CheckOnReplace : Boolean = True;
+ { CheckOnReplace is used by file functions. If a file exists, it is
+ optionally replaced based on the value of CheckOnReplace.
+
+ If CheckOnReplace is False the file is replaced without asking the
+ user. If CheckOnReplace is True, the end user is asked to replace the
+ file using a call to ReplaceFile.
+
+ CheckOnReplace is set to True by default. }
+
+ CheckOnDelete : Boolean = True;
+ { CheckOnDelete is used by file and directory functions. If a file
+ exists, it is optionally deleted based on the value of CheckOnDelete.
+
+ If CheckOnDelete is False the file or directory is deleted without
+ asking the user. If CheckOnDelete is True, the end user is asked to
+ delete the file/directory using a call to DeleteFile.
+
+ CheckOnDelete is set to True by default. }
+
+
+
+const
+ RFileInputLine: TStreamRec = (
+ ObjType: idFileInputLine;
+ VmtLink: Ofs(TypeOf(TFileInputLine)^);
+ Load: @TFileInputLine.Load;
+ Store: @TFileInputLine.Store
+ );
+
+ RFileCollection: TStreamRec = (
+ ObjType: idFileCollection;
+ VmtLink: Ofs(TypeOf(TFileCollection)^);
+ Load: @TFileCollection.Load;
+ Store: @TFileCollection.Store
+ );
+
+ RFileList: TStreamRec = (
+ ObjType: idFileList;
+ VmtLink: Ofs(TypeOf(TFileList)^);
+ Load: @TFileList.Load;
+ Store: @TFileList.Store
+ );
+
+ RFileInfoPane: TStreamRec = (
+ ObjType: idFileInfoPane;
+ VmtLink: Ofs(TypeOf(TFileInfoPane)^);
+ Load: @TFileInfoPane.Load;
+ Store: @TFileInfoPane.Store
+ );
+
+ RFileDialog: TStreamRec = (
+ ObjType: idFileDialog;
+ VmtLink: Ofs(TypeOf(TFileDialog)^);
+ Load: @TFileDialog.Load;
+ Store: @TFileDialog.Store
+ );
+
+ RDirCollection: TStreamRec = (
+ ObjType: idDirCollection;
+ VmtLink: Ofs(TypeOf(TDirCollection)^);
+ Load: @TDirCollection.Load;
+ Store: @TDirCollection.Store
+ );
+
+ RDirListBox: TStreamRec = (
+ ObjType: idDirListBox;
+ VmtLink: Ofs(TypeOf(TDirListBox)^);
+ Load: @TDirListBox.Load;
+ Store: @TDirListBox.Store
+ );
+
+ RChDirDialog: TStreamRec = (
+ ObjType: idChDirDialog;
+ VmtLink: Ofs(TypeOf(TChDirDialog)^);
+ Load: @TChDirDialog.Load;
+ Store: @TChDirDialog.Store
+ );
+
+ RSortedListBox: TStreamRec = (
+ ObjType: idSortedListBox;
+ VmtLink: Ofs(TypeOf(TSortedListBox)^);
+ Load: @TSortedListBox.Load;
+ Store: @TSortedListBox.Store
+ );
+
+ REditChDirDialog : TStreamRec = (
+ ObjType : idEditChDirDialog;
+ VmtLink : Ofs(TypeOf(TEditChDirDialog)^);
+ Load : @TEditChDirDialog.Load;
+ Store : @TEditChDirDialog.Store);
+
+
+implementation
+
+{****************************************************************************}
+{ Local Declarations }
+{****************************************************************************}
+
+uses
+ App, {Memory,} HistList, MsgBox{, Resource};
+
+type
+
+ PStringRec = record
+ { PStringRec is needed for properly displaying PStrings using
+ MessageBox. }
+ AString : PString;
+ end;
+
+resourcestring sChangeDirectory='Change Directory';
+ sDeleteFile='Delete file?'#13#10#13#3'%s';
+ sDirectory='Directory';
+ sDrives='Drives';
+ sInvalidDirectory='Invalid directory.';
+ sInvalidDriveOrDir='Invalid drive or directory.';
+ sInvalidFileName='Invalid file name.';
+ sOpen='Open';
+ sReplaceFile='Replace file?'#13#10#13#3'%s';
+ sSaveAs='Save As';
+ sTooManyFiles='Too many files.';
+
+ smApr='Apr';
+ smAug='Aug';
+ smDec='Dec';
+ smFeb='Feb';
+ smJan='Jan';
+ smJul='Jul';
+ smJun='Jun';
+ smMar='Mar';
+ smMay='May';
+ smNov='Nov';
+ smOct='Oct';
+ smSep='Sep';
+
+ slChDir='~C~hdir';
+ slClear='C~l~ear';
+ slDirectoryName='Directory ~n~ame';
+ slDirectoryTree='Directory ~t~ree';
+ slFiles='~F~iles';
+ slReplace='~R~eplace';
+ slRevert='~R~evert';
+
+{****************************************************************************}
+{ PathValid }
+{****************************************************************************}
+{$ifdef go32v2}
+{$define NetDrive}
+{$endif go32v2}
+{$ifdef win32}
+{$define NetDrive}
+{$endif win32}
+
+procedure RemoveDoubleDirSep(var ExpPath : PathStr);
+var
+ p: longint;
+{$ifdef NetDrive}
+ OneDirSepRemoved: boolean;
+{$endif NetDrive}
+begin
+ p:=pos(DirSeparator+DirSeparator,ExpPath);
+{$ifdef NetDrive}
+ if p=1 then
+ begin
+ ExpPath:=Copy(ExpPath,1,high(ExpPath));
+ OneDirSepRemoved:=true;
+ p:=pos(DirSeparator+DirSeparator,ExpPath);
+ end
+ else
+ OneDirSepRemoved:=false;
+{$endif NetDrive}
+ while p>0 do
+ begin
+ ExpPath:=Copy(ExpPath,1,p)+Copy(ExpPath,p+2,high(ExpPath));
+ p:=pos(DirSeparator+DirSeparator,ExpPath);
+ end;
+{$ifdef NetDrive}
+ if OneDirSepRemoved then
+ ExpPath:=DirSeparator+ExpPath;
+{$endif NetDrive}
+end;
+
+function PathValid (var Path: PathStr): Boolean;
+var
+ ExpPath: PathStr;
+ SR: SearchRec;
+begin
+ RemoveDoubleDirSep(Path);
+ ExpPath := FExpand(Path);
+{$ifdef HAS_DOS_DRIVES}
+ if (Length(ExpPath) <= 3) then
+ PathValid := DriveValid(ExpPath[1])
+ else
+{$endif}
+ begin
+ { do not change '/' into '' }
+ if (Length(ExpPath)>1) and (ExpPath[Length(ExpPath)] = DirSeparator) then
+ Dec(ExpPath[0]);
+ FindFirst(ExpPath, Directory, SR);
+ PathValid := (DosError = 0) and (SR.Attr and Directory <> 0);
+{$ifdef NetDrive}
+ if (DosError<>0) and (length(ExpPath)>2) and
+ (ExpPath[1]='\') and (ExpPath[2]='\')then
+ begin
+ { Checking '\\machine\sharedfolder' directly always fails..
+ rather try '\\machine\sharedfolder\*' PM }
+ {$ifdef fpc}
+ FindClose(SR);
+ {$endif}
+ FindFirst(ExpPath+'\*',AnyFile,SR);
+ PathValid:=(DosError = 0);
+ end;
+{$endif NetDrive}
+ {$ifdef fpc}
+ FindClose(SR);
+ {$endif}
+ end;
+end;
+
+{****************************************************************************}
+{ TDirValidator Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TDirValidator.Init }
+{****************************************************************************}
+constructor TDirValidator.Init;
+const { What should this list be? The commented one doesn't allow home,
+ end, right arrow, left arrow, Ctrl+XXXX, etc. }
+ Chars: TCharSet = ['A'..'Z','a'..'z','.','~',':','_','-'];
+{ Chars: TCharSet = [#0..#255]; }
+begin
+ Chars := Chars + [DirSeparator];
+ if not inherited Init(Chars) then
+ Fail;
+end;
+
+{****************************************************************************}
+{ TDirValidator.IsValid }
+{****************************************************************************}
+function TDirValidator.IsValid(const S: string): Boolean;
+begin
+{ IsValid := False; }
+ IsValid := True;
+end;
+
+{****************************************************************************}
+{ TDirValidator.IsValidInput }
+{****************************************************************************}
+function TDirValidator.IsValidInput(var S: string; SuppressFill: Boolean): Boolean;
+begin
+{ IsValid := False; }
+ IsValidInput := True;
+end;
+
+{****************************************************************************}
+{ TFileInputLine Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TFileInputLine.Init }
+{****************************************************************************}
+constructor TFileInputLine.Init(var Bounds: TRect; AMaxLen: Sw_Integer);
+begin
+ TInputLine.Init(Bounds, AMaxLen);
+ EventMask := EventMask or evBroadcast;
+end;
+
+{****************************************************************************}
+{ TFileInputLine.HandleEvent }
+{****************************************************************************}
+procedure TFileInputLine.HandleEvent(var Event: TEvent);
+begin
+ TInputLine.HandleEvent(Event);
+ if (Event.What = evBroadcast) and (Event.Command = cmFileFocused) and
+ (State and sfSelected = 0) then
+ begin
+ if PSearchRec(Event.InfoPtr)^.Attr and Directory <> 0 then
+ begin
+ Data^ := PSearchRec(Event.InfoPtr)^.Name + DirSeparator +
+ PFileDialog(Owner)^.WildCard;
+ { PFileDialog(Owner)^.FileHistory^.AdaptHistoryToDir(
+ PSearchRec(Event.InfoPtr)^.Name+DirSeparator);}
+ end
+ else Data^ := PSearchRec(Event.InfoPtr)^.Name;
+ DrawView;
+ end;
+end;
+
+{****************************************************************************}
+{ TFileCollection Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TFileCollection.Compare }
+{****************************************************************************}
+ function uppername(const s : string) : string;
+ var
+ i : Sw_integer;
+ in_name : boolean;
+ begin
+ in_name:=true;
+ for i:=length(s) downto 1 do
+ if in_name and (s[i] in ['a'..'z']) then
+ uppername[i]:=char(byte(s[i])-32)
+ else
+ begin
+ uppername[i]:=s[i];
+ if s[i] = DirSeparator then
+ in_name:=false;
+ end;
+ uppername[0]:=s[0];
+ end;
+
+function TFileCollection.Compare(Key1, Key2: Pointer): Sw_Integer;
+begin
+ if PSearchRec(Key1)^.Name = PSearchRec(Key2)^.Name then Compare := 0
+ else if PSearchRec(Key1)^.Name = '..' then Compare := 1
+ else if PSearchRec(Key2)^.Name = '..' then Compare := -1
+ else if (PSearchRec(Key1)^.Attr and Directory <> 0) and
+ (PSearchRec(Key2)^.Attr and Directory = 0) then Compare := 1
+ else if (PSearchRec(Key2)^.Attr and Directory <> 0) and
+ (PSearchRec(Key1)^.Attr and Directory = 0) then Compare := -1
+ else if UpperName(PSearchRec(Key1)^.Name) > UpperName(PSearchRec(Key2)^.Name) then
+ Compare := 1
+{$ifdef unix}
+ else if UpperName(PSearchRec(Key1)^.Name) < UpperName(PSearchRec(Key2)^.Name) then
+ Compare := -1
+ else if PSearchRec(Key1)^.Name > PSearchRec(Key2)^.Name then
+ Compare := 1
+{$endif def unix}
+ else
+ Compare := -1;
+end;
+
+{****************************************************************************}
+{ TFileCollection.FreeItem }
+{****************************************************************************}
+procedure TFileCollection.FreeItem(Item: Pointer);
+begin
+ Dispose(PSearchRec(Item));
+end;
+
+{****************************************************************************}
+{ TFileCollection.GetItem }
+{****************************************************************************}
+function TFileCollection.GetItem(var S: TStream): Pointer;
+var
+ Item: PSearchRec;
+begin
+ New(Item);
+ S.Read(Item^, SizeOf(TSearchRec));
+ GetItem := Item;
+end;
+
+{****************************************************************************}
+{ TFileCollection.PutItem }
+{****************************************************************************}
+procedure TFileCollection.PutItem(var S: TStream; Item: Pointer);
+begin
+ S.Write(Item^, SizeOf(TSearchRec));
+end;
+
+
+{*****************************************************************************
+ TFileList
+*****************************************************************************}
+
+const
+ ListSeparator=';';
+
+function MatchesMask(What, Mask: string): boolean;
+
+ function upper(const s : string) : string;
+ var
+ i : Sw_integer;
+ begin
+ for i:=1 to length(s) do
+ if s[i] in ['a'..'z'] then
+ upper[i]:=char(byte(s[i])-32)
+ else
+ upper[i]:=s[i];
+ upper[0]:=s[0];
+ end;
+
+ Function CmpStr(const hstr1,hstr2:string):boolean;
+ var
+ found : boolean;
+ i1,i2 : Sw_integer;
+ begin
+ i1:=0;
+ i2:=0;
+ if hstr1='' then
+ begin
+ CmpStr:=(hstr2='');
+ exit;
+ end;
+ found:=true;
+ repeat
+ inc(i1);
+ if (i1>length(hstr1)) then
+ break;
+ inc(i2);
+ if (i2>length(hstr2)) then
+ break;
+ case hstr1[i1] of
+ '?' :
+ found:=true;
+ '*' :
+ begin
+ found:=true;
+ if (i1=length(hstr1)) then
+ i2:=length(hstr2)
+ else
+ if (i1<length(hstr1)) and (hstr1[i1+1]<>hstr2[i2]) then
+ begin
+ if i2<length(hstr2) then
+ dec(i1)
+ end
+ else
+ if i2>1 then
+ dec(i2);
+ end;
+ else
+ found:=(hstr1[i1]=hstr2[i2]) or (hstr2[i2]='?');
+ end;
+ until not found;
+ if found then
+ begin
+ found:=(i2>=length(hstr2)) and
+ (
+ (i1>length(hstr1)) or
+ ((i1=length(hstr1)) and
+ (hstr1[i1]='*'))
+ );
+ end;
+ CmpStr:=found;
+ end;
+
+var
+ D1,D2 : DirStr;
+ N1,N2 : NameStr;
+ E1,E2 : Extstr;
+begin
+{$ifdef Unix}
+ FSplit(What,D1,N1,E1);
+ FSplit(Mask,D2,N2,E2);
+{$else}
+ FSplit(Upper(What),D1,N1,E1);
+ FSplit(Upper(Mask),D2,N2,E2);
+{$endif}
+ MatchesMask:=CmpStr(N2,N1) and CmpStr(E2,E1);
+end;
+
+function MatchesMaskList(What, MaskList: string): boolean;
+var P: integer;
+ Match: boolean;
+begin
+ Match:=false;
+ if What<>'' then
+ repeat
+ P:=Pos(ListSeparator, MaskList);
+ if P=0 then P:=length(MaskList)+1;
+ Match:=MatchesMask(What,copy(MaskList,1,P-1));
+ Delete(MaskList,1,P);
+ until Match or (MaskList='');
+ MatchesMaskList:=Match;
+end;
+
+constructor TFileList.Init(var Bounds: TRect; AScrollBar: PScrollBar);
+begin
+ TSortedListBox.Init(Bounds, 2, AScrollBar);
+end;
+
+destructor TFileList.Done;
+begin
+ if List <> nil then Dispose(List, Done);
+ TListBox.Done;
+end;
+
+function TFileList.DataSize: Sw_Word;
+begin
+ DataSize := 0;
+end;
+
+procedure TFileList.FocusItem(Item: Sw_Integer);
+begin
+ TSortedListBox.FocusItem(Item);
+ if (List^.Count > 0) then
+ Message(Owner, evBroadcast, cmFileFocused, List^.At(Item));
+end;
+
+procedure TFileList.GetData(var Rec);
+begin
+end;
+
+function TFileList.GetKey(var S: String): Pointer;
+const
+ SR: TSearchRec = ();
+
+procedure UpStr(var S: String);
+var
+ I: Sw_Integer;
+begin
+ for I := 1 to Length(S) do S[I] := UpCase(S[I]);
+end;
+
+begin
+ if (HandleDir{ShiftState and $03 <> 0}) or ((S <> '') and (S[1]='.')) then
+ SR.Attr := Directory
+ else SR.Attr := 0;
+ SR.Name := S;
+{$ifndef Unix}
+ UpStr(SR.Name);
+{$endif Unix}
+ GetKey := @SR;
+end;
+
+function TFileList.GetText(Item,MaxLen: Sw_Integer): String;
+var
+ S: String;
+ SR: PSearchRec;
+begin
+ SR := PSearchRec(List^.At(Item));
+ S := SR^.Name;
+ if SR^.Attr and Directory <> 0 then
+ begin
+ S[Length(S)+1] := DirSeparator;
+ Inc(S[0]);
+ end;
+ GetText := S;
+end;
+
+procedure TFileList.HandleEvent(var Event: TEvent);
+var
+ S : String;
+ K : pointer;
+ Value : Sw_integer;
+begin
+ if (Event.What = evMouseDown) and (Event.Double) then
+ begin
+ Event.What := evCommand;
+ Event.Command := cmOK;
+ PutEvent(Event);
+ ClearEvent(Event);
+ end
+ else if (Event.What = evKeyDown) and (Event.CharCode='<') then
+ begin
+ { select '..' }
+ S := '..';
+ K := GetKey(S);
+ If PSortedCollection(List)^.Search(K, Value) then
+ FocusItem(Value);
+ end
+ else TSortedListBox.HandleEvent(Event);
+end;
+
+procedure TFileList.ReadDirectory(AWildCard: PathStr);
+const
+ FindAttr = ReadOnly + Archive;
+ PrevDir = '..';
+var
+ S: SearchRec;
+ P: PSearchRec;
+ FileList: PFileCollection;
+ NumFiles: Word;
+ FindStr,
+ WildName : string;
+ Dir: DirStr;
+ Ext: ExtStr;
+ Name: NameStr;
+ Event : TEvent;
+ Tmp: PathStr;
+begin
+ NumFiles := 0;
+ FileList := New(PFileCollection, Init(5, 5));
+ AWildCard := FExpand(AWildCard);
+ FSplit(AWildCard, Dir, Name, Ext);
+ if pos(ListSeparator,AWildCard)>0 then
+ begin
+ WildName:=Copy(AWildCard,length(Dir)+1,255);
+ FindStr:=Dir+AllFiles;
+ end
+ else
+ begin
+ WildName:=Name+Ext;
+ FindStr:=AWildCard;
+ end;
+ FindFirst(FindStr, FindAttr, S);
+ P := PSearchRec(@P);
+ while assigned(P) and (DosError = 0) do
+ begin
+ if (S.Attr and Directory = 0) and
+ MatchesMaskList(S.Name,WildName) then
+ begin
+{ P := MemAlloc(SizeOf(P^));
+ if assigned(P) then
+ begin}
+ new(P);
+ P^.Attr:=S.Attr;
+ P^.Time:=S.Time;
+ P^.Size:=S.Size;
+ P^.Name:=S.Name;
+ FileList^.Insert(P);
+{ end;}
+ end;
+ FindNext(S);
+ end;
+ {$ifdef fpc}
+ FindClose(S);
+ {$endif}
+
+ Tmp := Dir + AllFiles;
+ FindFirst(Tmp, Directory, S);
+ while (P <> nil) and (DosError = 0) do
+ begin
+ if (S.Attr and Directory <> 0) and (S.Name <> '.') and (S.Name <> '..') then
+ begin
+{ P := MemAlloc(SizeOf(P^));
+ if P <> nil then
+ begin}
+ new(p);
+ P^.Attr:=S.Attr;
+ P^.Time:=S.Time;
+ P^.Size:=S.Size;
+ P^.Name:=S.Name;
+ FileList^.Insert(P);
+{ end;}
+ end;
+ FindNext(S);
+ end;
+ {$ifdef fpc}
+ FindClose(S);
+ {$endif}
+ {$ifndef Unix}
+ if Length(Dir) > 4 then
+ {$endif not Unix}
+ begin
+{
+ P := MemAlloc(SizeOf(P^));
+ if P <> nil then
+ begin}
+ new(p);
+ FindFirst(Tmp, Directory, S);
+ FindNext(S);
+ if (DosError = 0) and (S.Name = PrevDir) then
+ begin
+ P^.Attr:=S.Attr;
+ P^.Time:=S.Time;
+ P^.Size:=S.Size;
+ P^.Name:=S.Name;
+ end
+ else
+ begin
+ P^.Name := PrevDir;
+ P^.Size := 0;
+ P^.Time := $210000;
+ P^.Attr := Directory;
+ end;
+ FileList^.Insert(PSearchRec(P));
+ {$ifdef fpc}
+ FindClose(S);
+ {$endif}
+{ end;}
+ end;
+ if P = nil then
+ MessageBox(sTooManyFiles, nil, mfOkButton + mfWarning);
+ NewList(FileList);
+ if List^.Count > 0 then
+ begin
+ Event.What := evBroadcast;
+ Event.Command := cmFileFocused;
+ Event.InfoPtr := List^.At(0);
+ Owner^.HandleEvent(Event);
+ end;
+end;
+
+procedure TFileList.SetData(var Rec);
+begin
+ with PFileDialog(Owner)^ do
+ Self.ReadDirectory(Directory^ + WildCard);
+end;
+
+{****************************************************************************}
+{ TFileInfoPane Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TFileInfoPane.Init }
+{****************************************************************************}
+constructor TFileInfoPane.Init(var Bounds: TRect);
+begin
+ TView.Init(Bounds);
+ FillChar(S,SizeOf(S),#0);
+ EventMask := EventMask or evBroadcast;
+end;
+
+{****************************************************************************}
+{ TFileInfoPane.Draw }
+{****************************************************************************}
+procedure TFileInfoPane.Draw;
+var
+ B: TDrawBuffer;
+ D: String[9];
+ M: String[3];
+ PM: Boolean;
+ Color: Word;
+ Time: DateTime;
+ Path: PathStr;
+ FmtId: String;
+ Params: array[0..7] of PtruInt;
+ Str: String[80];
+const
+ sDirectoryLine = ' %-12s %-9s %3s %2d, %4d %2d:%02d%cm';
+ sFileLine = ' %-12s %-9d %3s %2d, %4d %2d:%02d%cm';
+ InValidFiles : array[0..2] of string[12] = ('','.','..');
+var
+ Month: array[1..12] of String[3];
+begin
+ Month[1] := smJan;
+ Month[2] := smFeb;
+ Month[3] := smMar;
+ Month[4] := smApr;
+ Month[5] := smMay;
+ Month[6] := smJun;
+ Month[7] := smJul;
+ Month[8] := smAug;
+ Month[9] := smSep;
+ Month[10] := smOct;
+ Month[11] := smNov;
+ Month[12] := smDec;
+ { Display path }
+ if (PFileDialog(Owner)^.Directory <> nil) then
+ Path := PFileDialog(Owner)^.Directory^
+ else Path := '';
+ Path := FExpand(Path+PFileDialog(Owner)^.WildCard);
+ { avoid B Buffer overflow PM }
+ Path := ShrinkPath(Path, Size.X - 1);
+ Color := GetColor($01);
+ MoveChar(B, ' ', Color, Size.X); { fill with empty spaces }
+ WriteLine(0, 0, Size.X, Size.Y, B);
+ MoveStr(B[1], Path, Color);
+ WriteLine(0, 0, Size.X, 1, B);
+ if (S.Name = InValidFiles[0]) or (S.Name = InValidFiles[1]) or
+ (S.Name = InValidFiles[2]) then
+ Exit;
+
+ { Display file }
+ Params[0] := ptruint(@S.Name);
+ if S.Attr and Directory <> 0 then
+ begin
+ FmtId := sDirectoryLine;
+ D := sDirectory;
+ Params[1] := ptruint(@D);
+ end else
+ begin
+ FmtId := sFileLine;
+ Params[1] := S.Size;
+ end;
+ UnpackTime(S.Time, Time);
+ M := Month[Time.Month];
+ Params[2] := ptruint(@M);
+ Params[3] := Time.Day;
+ Params[4] := Time.Year;
+ PM := Time.Hour >= 12;
+ Time.Hour := Time.Hour mod 12;
+ if Time.Hour = 0 then Time.Hour := 12;
+ Params[5] := Time.Hour;
+ Params[6] := Time.Min;
+ if PM then
+ Params[7] := Byte('p')
+ else Params[7] := Byte('a');
+ FormatStr(Str, FmtId, Params);
+ MoveStr(B, Str, Color);
+ WriteLine(0, 1, Size.X, 1, B);
+
+ { Fill in rest of rectangle }
+ MoveChar(B, ' ', Color, Size.X);
+ WriteLine(0, 2, Size.X, Size.Y-2, B);
+end;
+
+function TFileInfoPane.GetPalette: PPalette;
+const
+ P: String[Length(CInfoPane)] = CInfoPane;
+begin
+ GetPalette := PPalette(@P);
+end;
+
+procedure TFileInfoPane.HandleEvent(var Event: TEvent);
+begin
+ TView.HandleEvent(Event);
+ if (Event.What = evBroadcast) and (Event.Command = cmFileFocused) then
+ begin
+ S := PSearchRec(Event.InfoPtr)^;
+ DrawView;
+ end;
+end;
+
+{****************************************************************************
+ TFileHistory
+****************************************************************************}
+
+ function LTrim(const S: String): String;
+ var
+ I: Sw_Integer;
+ begin
+ I := 1;
+ while (I < Length(S)) and (S[I] = ' ') do Inc(I);
+ LTrim := Copy(S, I, 255);
+ end;
+
+ function RTrim(const S: String): String;
+ var
+ I: Sw_Integer;
+ begin
+ I := Length(S);
+ while S[I] = ' ' do Dec(I);
+ RTrim := Copy(S, 1, I);
+ end;
+
+ function RelativePath(var S: PathStr): Boolean;
+ begin
+ S := LTrim(RTrim(S));
+ RelativePath := not ((S <> '') and ((S[1] = DirSeparator) or (S[2] = ':')));
+ end;
+
+{ try to reduce the length of S+dir as a file path+pattern }
+
+ function Simplify (var S,Dir : string) : string;
+ var i : sw_integer;
+ begin
+ if RelativePath(Dir) then
+ begin
+ if (S<>'') and (Copy(Dir,1,3)='..'+DirSeparator) then
+ begin
+ i:=Length(S);
+ for i:=Length(S)-1 downto 1 do
+ if S[i]=DirSeparator then
+ break;
+ if S[i]=DirSeparator then
+ Simplify:=Copy(S,1,i)+Copy(Dir,4,255)
+ else
+ Simplify:=S+Dir;
+ end
+ else
+ Simplify:=S+Dir;
+ end
+ else
+ Simplify:=Dir;
+ end;
+
+{****************************************************************************}
+{ TFileHistory.HandleEvent }
+{****************************************************************************}
+
+procedure TFileHistory.HandleEvent(var Event: TEvent);
+var
+ HistoryWindow: PHistoryWindow;
+ R,P: TRect;
+ C: Word;
+ Rslt: String;
+begin
+ TView.HandleEvent(Event);
+ if (Event.What = evMouseDown) or
+ ((Event.What = evKeyDown) and (CtrlToArrow(Event.KeyCode) = kbDown) and
+ (Link^.State and sfFocused <> 0)) then
+ begin
+ if not Link^.Focus then
+ begin
+ ClearEvent(Event);
+ Exit;
+ end;
+ if assigned(CurDir) then
+ Rslt:=CurDir^
+ else
+ Rslt:='';
+ Rslt:=Simplify(Rslt,Link^.Data^);
+ RemoveDoubleDirSep(Rslt);
+ If IsWild(Rslt) then
+ RecordHistory(Rslt);
+ Link^.GetBounds(R);
+ Dec(R.A.X); Inc(R.B.X); Inc(R.B.Y,7); Dec(R.A.Y,1);
+ Owner^.GetExtent(P);
+ R.Intersect(P);
+ Dec(R.B.Y,1);
+ HistoryWindow := InitHistoryWindow(R);
+ if HistoryWindow <> nil then
+ begin
+ C := Owner^.ExecView(HistoryWindow);
+ if C = cmOk then
+ begin
+ Rslt := HistoryWindow^.GetSelection;
+ if Length(Rslt) > Link^.MaxLen then Rslt[0] := Char(Link^.MaxLen);
+ Link^.Data^ := Rslt;
+ Link^.SelectAll(True);
+ Link^.DrawView;
+ end;
+ Dispose(HistoryWindow, Done);
+ end;
+ ClearEvent(Event);
+ end
+ else if (Event.What = evBroadcast) then
+ if ((Event.Command = cmReleasedFocus) and (Event.InfoPtr = Link))
+ or (Event.Command = cmRecordHistory) then
+ begin
+ if assigned(CurDir) then
+ Rslt:=CurDir^
+ else
+ Rslt:='';
+ Rslt:=Simplify(Rslt,Link^.Data^);
+ RemoveDoubleDirSep(Rslt);
+ If IsWild(Rslt) then
+ RecordHistory(Rslt);
+ end;
+end;
+
+procedure TFileHistory.AdaptHistoryToDir(Dir : string);
+ var S,S2 : String;
+ i,Count : Sw_word;
+begin
+ if assigned(CurDir) then
+ begin
+ S:=CurDir^;
+ if S=Dir then
+ exit;
+ DisposeStr(CurDir);
+ end
+ else
+ S:='';
+ CurDir:=NewStr(Simplify(S,Dir));
+
+ Count:=HistoryCount(HistoryId);
+ for i:=1 to count do
+ begin
+ S2:=HistoryStr(HistoryId,1);
+ HistoryRemove(HistoryId,1);
+ if RelativePath(S2) then
+ if S<>'' then
+ S2:=S+S2
+ else
+ S2:=FExpand(S2);
+ { simply full path
+ we should simplify relative to Dir ! }
+ HistoryAdd(HistoryId,S2);
+ end;
+
+end;
+
+destructor TFileHistory.Done;
+begin
+ If assigned(CurDir) then
+ DisposeStr(CurDir);
+ Inherited Done;
+end;
+
+{****************************************************************************
+ TFileDialog
+****************************************************************************}
+
+constructor TFileDialog.Init(AWildCard: TWildStr; const ATitle,
+ InputName: String; AOptions: Word; HistoryId: Byte);
+var
+ Control: PView;
+ R: TRect;
+ Opt: Word;
+begin
+ R.Assign(15,1,64,20);
+ TDialog.Init(R, ATitle);
+ Options := Options or ofCentered;
+ WildCard := AWildCard;
+
+ R.Assign(3,3,31,4);
+ FileName := New(PFileInputLine, Init(R, 79));
+ FileName^.Data^ := WildCard;
+ Insert(FileName);
+ R.Assign(2,2,3+CStrLen(InputName),3);
+ Control := New(PLabel, Init(R, InputName, FileName));
+ Insert(Control);
+ R.Assign(31,3,34,4);
+ FileHistory := New(PFileHistory, Init(R, FileName, HistoryId));
+ Insert(FileHistory);
+
+ R.Assign(3,14,34,15);
+ Control := New(PScrollBar, Init(R));
+ Insert(Control);
+ R.Assign(3,6,34,14);
+ FileList := New(PFileList, Init(R, PScrollBar(Control)));
+ Insert(FileList);
+ R.Assign(2,5,8,6);
+ Control := New(PLabel, Init(R, slFiles, FileList));
+ Insert(Control);
+
+ R.Assign(35,3,46,5);
+ Opt := bfDefault;
+ if AOptions and fdOpenButton <> 0 then
+ begin
+ Insert(New(PButton, Init(R,slOpen, cmFileOpen, Opt)));
+ Opt := bfNormal;
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ end;
+ if AOptions and fdOkButton <> 0 then
+ begin
+ Insert(New(PButton, Init(R,slOk, cmFileOpen, Opt)));
+ Opt := bfNormal;
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ end;
+ if AOptions and fdReplaceButton <> 0 then
+ begin
+ Insert(New(PButton, Init(R, slReplace,cmFileReplace, Opt)));
+ Opt := bfNormal;
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ end;
+ if AOptions and fdClearButton <> 0 then
+ begin
+ Insert(New(PButton, Init(R, slClear,cmFileClear, Opt)));
+ Opt := bfNormal;
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ end;
+ Insert(New(PButton, Init(R, slCancel, cmCancel, bfNormal)));
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ if AOptions and fdHelpButton <> 0 then
+ begin
+ Insert(New(PButton, Init(R,slHelp,cmHelp, bfNormal)));
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ end;
+
+ R.Assign(1,16,48,18);
+ Control := New(PFileInfoPane, Init(R));
+ Insert(Control);
+
+ SelectNext(False);
+
+ if AOptions and fdNoLoadDir = 0 then ReadDirectory;
+end;
+
+constructor TFileDialog.Load(var S: TStream);
+begin
+ if not TDialog.Load(S) then
+ Fail;
+ S.Read(WildCard, SizeOf(WildCard));
+ if (S.Status <> stOk) then
+ begin
+ TDialog.Done;
+ Fail;
+ end;
+ GetSubViewPtr(S, FileName);
+ GetSubViewPtr(S, FileList);
+ GetSubViewPtr(S, FileHistory);
+ ReadDirectory;
+ if (DosError <> 0) then
+ begin
+ TDialog.Done;
+ Fail;
+ end;
+end;
+
+destructor TFileDialog.Done;
+begin
+ DisposeStr(Directory);
+ TDialog.Done;
+end;
+
+procedure TFileDialog.GetData(var Rec);
+begin
+ GetFilename(PathStr(Rec));
+end;
+
+procedure TFileDialog.GetFileName(var S: PathStr);
+
+var
+ Path: PathStr;
+ Name: NameStr;
+ Ext: ExtStr;
+ TWild : string;
+ TPath: PathStr;
+ TName: NameStr;
+ TExt: NameStr;
+ i : Sw_integer;
+begin
+ S := FileName^.Data^;
+ if RelativePath(S) then
+ begin
+ if (Directory <> nil) then
+ S := FExpand(Directory^ + S);
+ end
+ else
+ S := FExpand(S);
+ if Pos(ListSeparator,S)=0 then
+ begin
+ If FileExists(S) then
+ exit;
+ FSplit(S, Path, Name, Ext);
+ if ((Name = '') or (Ext = '')) and not IsDir(S) then
+ begin
+ TWild:=WildCard;
+ repeat
+ i:=Pos(ListSeparator,TWild);
+ if i=0 then
+ i:=length(TWild)+1;
+ FSplit(Copy(TWild,1,i-1), TPath, TName, TExt);
+ if ((Name = '') and (Ext = '')) then
+ S := Path + TName + TExt
+ else
+ if Name = '' then
+ S := Path + TName + Ext
+ else
+ if Ext = '' then
+ begin
+ if IsWild(Name) then
+ S := Path + Name + TExt
+ else
+ S := Path + Name + NoWildChars(TExt);
+ end;
+ if FileExists(S) then
+ break;
+ System.Delete(TWild,1,i);
+ until TWild='';
+ if TWild='' then
+ S := Path + Name + Ext;
+ end;
+ end;
+end;
+
+procedure TFileDialog.HandleEvent(var Event: TEvent);
+begin
+ if (Event.What and evBroadcast <> 0) and
+ (Event.Command = cmListItemSelected) then
+ begin
+ EndModal(cmFileOpen);
+ ClearEvent(Event);
+ end;
+ TDialog.HandleEvent(Event);
+ if Event.What = evCommand then
+ case Event.Command of
+ cmFileOpen, cmFileReplace, cmFileClear:
+ begin
+ EndModal(Event.Command);
+ ClearEvent(Event);
+ end;
+ end;
+end;
+
+procedure TFileDialog.SetData(var Rec);
+begin
+ TDialog.SetData(Rec);
+ if (PathStr(Rec) <> '') and (IsWild(TWildStr(Rec))) then
+ begin
+ Valid(cmFileInit);
+ FileName^.Select;
+ end;
+end;
+
+procedure TFileDialog.ReadDirectory;
+begin
+ FileList^.ReadDirectory(WildCard);
+ FileHistory^.AdaptHistoryToDir(GetCurDir);
+ Directory := NewStr(GetCurDir);
+end;
+
+procedure TFileDialog.Store(var S: TStream);
+begin
+ TDialog.Store(S);
+ S.Write(WildCard, SizeOf(WildCard));
+ PutSubViewPtr(S, FileName);
+ PutSubViewPtr(S, FileList);
+ PutSubViewPtr(S, FileHistory);
+end;
+
+function TFileDialog.Valid(Command: Word): Boolean;
+var
+ FName: PathStr;
+ Dir: DirStr;
+ Name: NameStr;
+ Ext: ExtStr;
+
+ function CheckDirectory(var S: PathStr): Boolean;
+ begin
+ if not PathValid(S) then
+ begin
+ MessageBox(sInvalidDriveOrDir, nil, mfError + mfOkButton);
+ FileName^.Select;
+ CheckDirectory := False;
+ end else CheckDirectory := True;
+ end;
+
+ function CompleteDir(const Path: string): string;
+ begin
+ { keep c: untouched PM }
+ if (Path<>'') and (Path[Length(Path)]<>DirSeparator) and
+ (Path[Length(Path)]<>':') then
+ CompleteDir:=Path+DirSeparator
+ else
+ CompleteDir:=Path;
+ end;
+
+ function NormalizeDir(const Path: string): string;
+ var Root: boolean;
+ begin
+ Root:=false;
+ {$ifdef Unix}
+ if Path=DirSeparator then Root:=true;
+ {$else}
+ if (length(Path)=3) and (Upcase(Path[1]) in['A'..'Z']) and
+ (Path[2]=':') and (Path[3]=DirSeparator) then
+ Root:=true;
+ {$endif}
+ if (Root=false) and (copy(Path,length(Path),1)=DirSeparator) then
+ NormalizeDir:=copy(Path,1,length(Path)-1)
+ else
+ NormalizeDir:=Path;
+ end;
+function NormalizeDirF(var S: openstring): boolean;
+begin
+ S:=NormalizeDir(S);
+ NormalizeDirF:=true;
+end;
+
+begin
+ if Command = 0 then
+ begin
+ Valid := True;
+ Exit;
+ end
+ else Valid := False;
+ if TDialog.Valid(Command) then
+ begin
+ GetFileName(FName);
+ if (Command <> cmCancel) and (Command <> cmFileClear) then
+ begin
+ if IsWild(FName) or IsList(FName) then
+ begin
+ FSplit(FName, Dir, Name, Ext);
+ if CheckDirectory(Dir) then
+ begin
+ FileHistory^.AdaptHistoryToDir(Dir);
+ DisposeStr(Directory);
+ Directory := NewStr(Dir);
+ if Pos(ListSeparator,FName)>0 then
+ WildCard:=Copy(FName,length(Dir)+1,255)
+ else
+ WildCard := Name+Ext;
+ if Command <> cmFileInit then
+ FileList^.Select;
+ FileList^.ReadDirectory(Directory^+WildCard);
+ end;
+ end
+ else
+ if NormalizeDirF(FName) then
+ { ^^ this is just a dummy if construct (the func always returns true,
+ it's just there, 'coz I don't want to rearrange the following "if"s... }
+ if IsDir(FName) then
+ begin
+ if CheckDirectory(FName) then
+ begin
+ FileHistory^.AdaptHistoryToDir(CompleteDir(FName));
+ DisposeStr(Directory);
+ Directory := NewSTr(CompleteDir(FName));
+ if Command <> cmFileInit then FileList^.Select;
+ FileList^.ReadDirectory(Directory^+WildCard);
+ end
+ end
+ else
+ if ValidFileName(FName) then
+ Valid := True
+ else
+ begin
+ MessageBox(^C + sInvalidFileName, nil, mfError + mfOkButton);
+ Valid := False;
+ end;
+ end
+ else Valid := True;
+ end;
+end;
+
+{ TDirCollection }
+
+function TDirCollection.GetItem(var S: TStream): Pointer;
+var
+ DirItem: PDirEntry;
+begin
+ New(DirItem);
+ DirItem^.DisplayText := S.ReadStr;
+ DirItem^.Directory := S.ReadStr;
+ GetItem := DirItem;
+end;
+
+procedure TDirCollection.FreeItem(Item: Pointer);
+var
+ DirItem: PDirEntry absolute Item;
+begin
+ DisposeStr(DirItem^.DisplayText);
+ DisposeStr(DirItem^.Directory);
+ Dispose(DirItem);
+end;
+
+procedure TDirCollection.PutItem(var S: TStream; Item: Pointer);
+var
+ DirItem: PDirEntry absolute Item;
+begin
+ S.WriteStr(DirItem^.DisplayText);
+ S.WriteStr(DirItem^.Directory);
+end;
+
+{ TDirListBox }
+
+const
+ DrivesS: String = '';
+ Drives: PString = @DrivesS;
+
+constructor TDirListBox.Init(var Bounds: TRect; AScrollBar:
+ PScrollBar);
+begin
+ DrivesS := sDrives;
+ TListBox.Init(Bounds, 1, AScrollBar);
+ Dir := '';
+end;
+
+destructor TDirListBox.Done;
+begin
+ if (List <> nil) then
+ Dispose(List,Done);
+ TListBox.Done;
+end;
+
+function TDirListBox.GetText(Item,MaxLen: Sw_Integer): String;
+begin
+ GetText := PDirEntry(List^.At(Item))^.DisplayText^;
+end;
+
+procedure TDirListBox.HandleEvent(var Event: TEvent);
+begin
+ case Event.What of
+ evMouseDown:
+ if Event.Double then
+ begin
+ Event.What := evCommand;
+ Event.Command := cmChangeDir;
+ PutEvent(Event);
+ ClearEvent(Event);
+ end;
+ evKeyboard:
+ if (Event.CharCode = ' ') and
+ (PSearchRec(List^.At(Focused))^.Name = '..') then
+ NewDirectory(PSearchRec(List^.At(Focused))^.Name);
+ end;
+ TListBox.HandleEvent(Event);
+end;
+
+function TDirListBox.IsSelected(Item: Sw_Integer): Boolean;
+begin
+{ IsSelected := Item = Cur; }
+ IsSelected := Inherited IsSelected(Item);
+end;
+
+procedure TDirListBox.NewDirectory(var ADir: DirStr);
+const
+ PathDir = 'ÀÄÂ';
+ FirstDir = 'ÀÂÄ';
+ MiddleDir = ' ÃÄ';
+ LastDir = ' ÀÄ';
+ IndentSize = ' ';
+var
+ AList: PCollection;
+ NewDir, Dirct: DirStr;
+ C, OldC: Char;
+ S, Indent: String[80];
+ P: PString;
+ NewCur: Word;
+ isFirst: Boolean;
+ SR: SearchRec;
+ I: Sw_Integer;
+
+ function NewDirEntry(const DisplayText, Directory: String): PDirEntry;{$ifdef PPC_BP}near;{$endif}
+ var
+ DirEntry: PDirEntry;
+ begin
+ New(DirEntry);
+ DirEntry^.DisplayText := NewStr(DisplayText);
+ If Directory='' then
+ DirEntry^.Directory := NewStr(DirSeparator)
+ else
+ DirEntry^.Directory := NewStr(Directory);
+ NewDirEntry := DirEntry;
+ end;
+
+begin
+ Dir := ADir;
+ AList := New(PDirCollection, Init(5,5));
+{$ifdef HAS_DOS_DRIVES}
+ AList^.Insert(NewDirEntry(Drives^,Drives^));
+ if Dir = Drives^ then
+ begin
+ isFirst := True;
+ OldC := ' ';
+ for C := 'A' to 'Z' do
+ begin
+ if (C < 'C') or DriveValid(C) then
+ begin
+ if OldC <> ' ' then
+ begin
+ if isFirst then
+ begin
+ S := FirstDir + OldC;
+ isFirst := False;
+ end
+ else S := MiddleDir + OldC;
+ AList^.Insert(NewDirEntry(S, OldC + ':' + DirSeparator));
+ end;
+ if C = GetCurDrive then NewCur := AList^.Count;
+ OldC := C;
+ end;
+ end;
+ if OldC <> ' ' then
+ AList^.Insert(NewDirEntry(LastDir + OldC, OldC + ':' + DirSeparator));
+ end
+ else
+{$endif HAS_DOS_DRIVES}
+ begin
+ Indent := IndentSize;
+ NewDir := Dir;
+{$ifdef HAS_DOS_DRIVES}
+ Dirct := Copy(NewDir,1,3);
+ AList^.Insert(NewDirEntry(PathDir + Dirct, Dirct));
+ NewDir := Copy(NewDir,4,255);
+{$else HAS_DOS_DRIVES}
+ Dirct := '';
+{$endif HAS_DOS_DRIVES}
+ while NewDir <> '' do
+ begin
+ I := Pos(DirSeparator,NewDir);
+ if I <> 0 then
+ begin
+ S := Copy(NewDir,1,I-1);
+ Dirct := Dirct + S;
+ AList^.Insert(NewDirEntry(Indent + PathDir + S, Dirct));
+ NewDir := Copy(NewDir,I+1,255);
+ end
+ else
+ begin
+ Dirct := Dirct + NewDir;
+ AList^.Insert(NewDirEntry(Indent + PathDir + NewDir, Dirct));
+ NewDir := '';
+ end;
+ Indent := Indent + IndentSize;
+ Dirct := Dirct + DirSeparator;
+ end;
+ NewCur := AList^.Count-1;
+ isFirst := True;
+ NewDir := Dirct + AllFiles;
+ FindFirst(NewDir, Directory, SR);
+ while DosError = 0 do
+ begin
+ if (SR.Attr and Directory <> 0) and
+ (SR.Name <> '.') and (SR.Name <> '..') then
+ begin
+ if isFirst then
+ begin
+ S := FirstDir;
+ isFirst := False;
+ end else S := MiddleDir;
+ AList^.Insert(NewDirEntry(Indent + S + SR.Name, Dirct + SR.Name));
+ end;
+ FindNext(SR);
+ end;
+ FindClose(SR);
+ P := PDirEntry(AList^.At(AList^.Count-1))^.DisplayText;
+ I := Pos('À',P^);
+ if I = 0 then
+ begin
+ I := Pos('Ã',P^);
+ if I <> 0 then P^[I] := 'À';
+ end else
+ begin
+ P^[I+1] := 'Ä';
+ P^[I+2] := 'Ä';
+ end;
+ end;
+ NewList(AList);
+ FocusItem(NewCur);
+ Cur:=NewCur;
+end;
+
+procedure TDirListBox.SetState(AState: Word; Enable: Boolean);
+begin
+ TListBox.SetState(AState, Enable);
+ if AState and sfFocused <> 0 then
+ PChDirDialog(Owner)^.ChDirButton^.MakeDefault(Enable);
+end;
+
+{****************************************************************************}
+{ TChDirDialog Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TChDirDialog.Init }
+{****************************************************************************}
+constructor TChDirDialog.Init(AOptions: Word; HistoryId: Sw_Word);
+var
+ R: TRect;
+ Control: PView;
+begin
+ R.Assign(16, 2, 64, 20);
+ TDialog.Init(R,sChangeDirectory);
+
+ Options := Options or ofCentered;
+
+ R.Assign(3, 3, 30, 4);
+ DirInput := New(PInputLine, Init(R, FileNameLen+4));
+ Insert(DirInput);
+ R.Assign(2, 2, 17, 3);
+ Control := New(PLabel, Init(R,slDirectoryName, DirInput));
+ Insert(Control);
+ R.Assign(30, 3, 33, 4);
+ Control := New(PHistory, Init(R, DirInput, HistoryId));
+ Insert(Control);
+
+ R.Assign(32, 6, 33, 16);
+ Control := New(PScrollBar, Init(R));
+ Insert(Control);
+ R.Assign(3, 6, 32, 16);
+ DirList := New(PDirListBox, Init(R, PScrollBar(Control)));
+ Insert(DirList);
+ R.Assign(2, 5, 17, 6);
+ Control := New(PLabel, Init(R, slDirectoryTree, DirList));
+ Insert(Control);
+
+ R.Assign(35, 6, 45, 8);
+ OkButton := New(PButton, Init(R, slOk, cmOK, bfDefault));
+ Insert(OkButton);
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ ChDirButton := New(PButton,Init(R,slChDir,cmChangeDir,
+ bfNormal));
+ Insert(ChDirButton);
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ Insert(New(PButton, Init(R,slRevert, cmRevert, bfNormal)));
+ if AOptions and cdHelpButton <> 0 then
+ begin
+ Inc(R.A.Y,3); Inc(R.B.Y,3);
+ Insert(New(PButton, Init(R,slHelp, cmHelp, bfNormal)));
+ end;
+
+ if AOptions and cdNoLoadDir = 0 then SetUpDialog;
+
+ SelectNext(False);
+end;
+
+{****************************************************************************}
+{ TChDirDialog.Load }
+{****************************************************************************}
+constructor TChDirDialog.Load(var S: TStream);
+begin
+ TDialog.Load(S);
+ GetSubViewPtr(S, DirList);
+ GetSubViewPtr(S, DirInput);
+ GetSubViewPtr(S, OkButton);
+ GetSubViewPtr(S, ChDirbutton);
+ SetUpDialog;
+end;
+
+{****************************************************************************}
+{ TChDirDialog.DataSize }
+{****************************************************************************}
+function TChDirDialog.DataSize: Sw_Word;
+begin
+ DataSize := 0;
+end;
+
+{****************************************************************************}
+{ TChDirDialog.GetData }
+{****************************************************************************}
+procedure TChDirDialog.GetData(var Rec);
+begin
+end;
+
+{****************************************************************************}
+{ TChDirDialog.HandleEvent }
+{****************************************************************************}
+procedure TChDirDialog.HandleEvent(var Event: TEvent);
+var
+ CurDir: DirStr;
+ P: PDirEntry;
+begin
+ TDialog.HandleEvent(Event);
+ case Event.What of
+ evCommand:
+ begin
+ case Event.Command of
+ cmRevert: GetDir(0,CurDir);
+ cmChangeDir:
+ begin
+ P := DirList^.List^.At(DirList^.Focused);
+ if (P^.Directory^ = Drives^)
+ or DriveValid(P^.Directory^[1]) then
+ CurDir := P^.Directory^
+ else Exit;
+ end;
+ else
+ Exit;
+ end;
+ if (Length(CurDir) > 3) and
+ (CurDir[Length(CurDir)] = DirSeparator) then
+ CurDir := Copy(CurDir,1,Length(CurDir)-1);
+ DirList^.NewDirectory(CurDir);
+ DirInput^.Data^ := CurDir;
+ DirInput^.DrawView;
+ DirList^.Select;
+ ClearEvent(Event);
+ end;
+ end;
+end;
+
+{****************************************************************************}
+{ TChDirDialog.SetData }
+{****************************************************************************}
+procedure TChDirDialog.SetData(var Rec);
+begin
+end;
+
+{****************************************************************************}
+{ TChDirDialog.SetUpDialog }
+{****************************************************************************}
+procedure TChDirDialog.SetUpDialog;
+var
+ CurDir: DirStr;
+begin
+ if DirList <> nil then
+ begin
+ CurDir := GetCurDir;
+ DirList^.NewDirectory(CurDir);
+ if (Length(CurDir) > 3) and (CurDir[Length(CurDir)] = DirSeparator) then
+ CurDir := Copy(CurDir,1,Length(CurDir)-1);
+ if DirInput <> nil then
+ begin
+ DirInput^.Data^ := CurDir;
+ DirInput^.DrawView;
+ end;
+ end;
+end;
+
+{****************************************************************************}
+{ TChDirDialog.Store }
+{****************************************************************************}
+procedure TChDirDialog.Store(var S: TStream);
+begin
+ TDialog.Store(S);
+ PutSubViewPtr(S, DirList);
+ PutSubViewPtr(S, DirInput);
+ PutSubViewPtr(S, OkButton);
+ PutSubViewPtr(S, ChDirButton);
+end;
+
+{****************************************************************************}
+{ TChDirDialog.Valid }
+{****************************************************************************}
+function TChDirDialog.Valid(Command: Word): Boolean;
+var
+ P: PathStr;
+begin
+ Valid := True;
+ if Command = cmOk then
+ begin
+ P := FExpand(DirInput^.Data^);
+ if (Length(P) > 3) and (P[Length(P)] = DirSeparator) then
+ Dec(P[0]);
+ {$I-}
+ ChDir(P);
+ if (IOResult <> 0) then
+ begin
+ MessageBox(sInvalidDirectory, nil, mfError + mfOkButton);
+ Valid := False;
+ end;
+ {$I+}
+ end;
+end;
+
+{****************************************************************************}
+{ TEditChDirDialog Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TEditChDirDialog.DataSize }
+{****************************************************************************}
+function TEditChDirDialog.DataSize : Sw_Word;
+begin
+ DataSize := SizeOf(DirStr);
+end;
+
+{****************************************************************************}
+{ TEditChDirDialog.GetData }
+{****************************************************************************}
+procedure TEditChDirDialog.GetData (var Rec);
+var
+ CurDir : DirStr absolute Rec;
+begin
+ if (DirInput = nil) then
+ CurDir := ''
+ else begin
+ CurDir := DirInput^.Data^;
+ if (CurDir[Length(CurDir)] <> DirSeparator) then
+ CurDir := CurDir + DirSeparator;
+ end;
+end;
+
+{****************************************************************************}
+{ TEditChDirDialog.SetData }
+{****************************************************************************}
+procedure TEditChDirDialog.SetData (var Rec);
+var
+ CurDir : DirStr absolute Rec;
+begin
+ if DirList <> nil then
+ begin
+ DirList^.NewDirectory(CurDir);
+ if DirInput <> nil then
+ begin
+ if (Length(CurDir) > 3) and (CurDir[Length(CurDir)] = DirSeparator) then
+ DirInput^.Data^ := Copy(CurDir,1,Length(CurDir)-1)
+ else DirInput^.Data^ := CurDir;
+ DirInput^.DrawView;
+ end;
+ end;
+end;
+
+{****************************************************************************}
+{ TSortedListBox Object }
+{****************************************************************************}
+{****************************************************************************}
+{ TSortedListBox.Init }
+{****************************************************************************}
+constructor TSortedListBox.Init(var Bounds: TRect; ANumCols: Sw_Word;
+ AScrollBar: PScrollBar);
+begin
+ TListBox.Init(Bounds, ANumCols, AScrollBar);
+ SearchPos := 0;
+ ShowCursor;
+ SetCursor(1,0);
+end;
+
+{****************************************************************************}
+{ TSortedListBox.HandleEvent }
+{****************************************************************************}
+procedure TSortedListBox.HandleEvent(var Event: TEvent);
+const
+ SpecialChars: set of Char = [#0,#9,#27];
+var
+ CurString, NewString: String;
+ K: Pointer;
+ Value : Sw_integer;
+ OldPos, OldValue: Sw_Integer;
+ T: Boolean;
+begin
+ OldValue := Focused;
+ TListBox.HandleEvent(Event);
+ if (OldValue <> Focused) or
+ ((Event.What = evBroadcast) and (Event.InfoPtr = @Self) and
+ (Event.Command = cmReleasedFocus)) then
+ SearchPos := 0;
+ if Event.What = evKeyDown then
+ begin
+ { patched to prevent error when no or empty list or Escape pressed }
+ if (not (Event.CharCode in SpecialChars)) and
+ (List <> nil) and (List^.Count > 0) then
+ begin
+ Value := Focused;
+ if Value < Range then
+ CurString := GetText(Value, 255)
+ else
+ CurString := '';
+ OldPos := SearchPos;
+ if Event.KeyCode = kbBack then
+ begin
+ if SearchPos = 0 then Exit;
+ Dec(SearchPos);
+ if SearchPos = 0 then
+ HandleDir:= ((GetShiftState and $3) <> 0) or (Event.CharCode in ['A'..'Z']);
+ CurString[0] := Char(SearchPos);
+ end
+ else if (Event.CharCode = '.') then
+ SearchPos := Pos('.',CurString)
+ else
+ begin
+ Inc(SearchPos);
+ if SearchPos = 1 then
+ HandleDir := ((GetShiftState and 3) <> 0) or (Event.CharCode in ['A'..'Z']);
+ CurString[0] := Char(SearchPos);
+ CurString[SearchPos] := Event.CharCode;
+ end;
+ K := GetKey(CurString);
+ T := PSortedCollection(List)^.Search(K, Value);
+ if Value < Range then
+ begin
+ if Value < Range then
+ NewString := GetText(Value, 255)
+ else
+ NewString := '';
+ if Equal(NewString, CurString, SearchPos) then
+ begin
+ if Value <> OldValue then
+ begin
+ FocusItem(Value);
+ { Assumes ListControl will set the cursor to the first character }
+ { of the sfFocused item }
+ SetCursor(Cursor.X+SearchPos, Cursor.Y);
+ end
+ else
+ SetCursor(Cursor.X+(SearchPos-OldPos), Cursor.Y);
+ end
+ else
+ SearchPos := OldPos;
+ end
+ else SearchPos := OldPos;
+ if (SearchPos <> OldPos) or (Event.CharCode in ['A'..'Z','a'..'z']) then
+ ClearEvent(Event);
+ end;
+ end;
+end;
+
+function TSortedListBox.GetKey(var S: String): Pointer;
+begin
+ GetKey := @S;
+end;
+
+procedure TSortedListBox.NewList(AList: PCollection);
+begin
+ TListBox.NewList(AList);
+ SearchPos := 0;
+end;
+
+{****************************************************************************}
+{ Global Procedures and Functions }
+{****************************************************************************}
+
+{****************************************************************************}
+{ Contains }
+{****************************************************************************}
+function Contains(S1, S2: String): Boolean;
+ { Contains returns true if S1 contains any characters in S2. }
+var
+ i : Byte;
+begin
+ Contains := True;
+ i := 1;
+ while ((i < Length(S2)) and (i < Length(S1))) do
+ if (Upcase(S1[i]) = Upcase(S2[i])) then
+ Exit
+ else Inc(i);
+ Contains := False;
+end;
+
+{****************************************************************************}
+{ StdDeleteFile }
+{****************************************************************************}
+function StdDeleteFile (AFile : FNameStr) : Boolean;
+var
+ Rec : PStringRec;
+begin
+ if CheckOnDelete then
+ begin
+ AFile := ShrinkPath(AFile,33);
+ Rec.AString := PString(@AFile);
+ StdDeleteFile := (MessageBox(^C + sDeleteFile,
+ @Rec,mfConfirmation or mfOkCancel) = cmOk);
+ end
+ else StdDeleteFile := False;
+end;
+
+{****************************************************************************}
+{ DriveValid }
+{****************************************************************************}
+function DriveValid(Drive: Char): Boolean;
+{$ifdef HAS_DOS_DRIVES}
+var
+ D: Char;
+begin
+ D := GetCurDrive;
+ {$I-}
+ ChDir(Drive+':');
+ if (IOResult = 0) then
+ begin
+ DriveValid := True;
+ ChDir(D+':')
+ end
+ else DriveValid := False;
+ {$I+}
+end;
+{$else HAS_DOS_DRIVES}
+begin
+ DriveValid:=true;
+end;
+{$endif HAS_DOS_DRIVES}
+
+{****************************************************************************}
+{ Equal }
+{****************************************************************************}
+function Equal(const S1, S2: String; Count: Sw_word): Boolean;
+var
+ i: Sw_Word;
+begin
+ Equal := False;
+ if (Length(S1) < Count) or (Length(S2) < Count) then
+ Exit;
+ for i := 1 to Count do
+ if UpCase(S1[I]) <> UpCase(S2[I]) then
+ Exit;
+ Equal := True;
+end;
+
+{****************************************************************************}
+{ ExtractDir }
+{****************************************************************************}
+function ExtractDir(AFile: FNameStr): DirStr;
+ { ExtractDir returns the path of AFile terminated with a trailing '\'. If
+ AFile contains no directory information, an empty string is returned. }
+var
+ D: DirStr;
+ N: NameStr;
+ E: ExtStr;
+begin
+ FSplit(AFile,D,N,E);
+ if D = '' then
+ begin
+ ExtractDir := '';
+ Exit;
+ end;
+ if D[Byte(D[0])] <> DirSeparator then
+ D := D + DirSeparator;
+ ExtractDir := D;
+end;
+
+{****************************************************************************}
+{ ExtractFileName }
+{****************************************************************************}
+function ExtractFileName(AFile: FNameStr): NameStr;
+var
+ D: DirStr;
+ N: NameStr;
+ E: ExtStr;
+begin
+ FSplit(AFile,D,N,E);
+ ExtractFileName := N;
+end;
+
+{****************************************************************************}
+{ FileExists }
+{****************************************************************************}
+function FileExists (AFile : FNameStr) : Boolean;
+begin
+ FileExists := (FSearch(AFile,'') <> '');
+end;
+
+{****************************************************************************}
+{ GetCurDir }
+{****************************************************************************}
+function GetCurDir: DirStr;
+var
+ CurDir: DirStr;
+begin
+ GetDir(0, CurDir);
+ if (Length(CurDir) > 3) then
+ begin
+ Inc(CurDir[0]);
+ CurDir[Length(CurDir)] := DirSeparator;
+ end;
+ GetCurDir := CurDir;
+end;
+
+{****************************************************************************}
+{ GetCurDrive }
+{****************************************************************************}
+function GetCurDrive: Char;
+{$ifdef go32v2}
+var
+ Regs : Registers;
+begin
+ Regs.AH := $19;
+ Intr($21,Regs);
+ GetCurDrive := Char(Regs.AL + Byte('A'));
+end;
+{$else not go32v2}
+var
+ D : DirStr;
+begin
+ D:=GetCurDir;
+ if (Length(D)>1) and (D[2]=':') then
+ begin
+ if (D[1]>='a') and (D[1]<='z') then
+ GetCurDrive:=Char(Byte(D[1])+Byte('A')-Byte('a'))
+ else
+ GetCurDrive:=D[1];
+ end
+ else
+ GetCurDrive:='C';
+end;
+{$endif not go32v2}
+
+{****************************************************************************}
+{ IsDir }
+{****************************************************************************}
+function IsDir(const S: String): Boolean;
+var
+ SR: SearchRec;
+ Is: boolean;
+begin
+ Is:=false;
+{$ifdef Unix}
+ Is:=(S=DirSeparator); { handle root }
+{$else}
+ Is:=(length(S)=3) and (Upcase(S[1]) in['A'..'Z']) and (S[2]=':') and (S[3]=DirSeparator);
+ { handle root dirs }
+{$endif}
+ if Is=false then
+ begin
+ FindFirst(S, Directory, SR);
+ if DosError = 0 then
+ Is := (SR.Attr and Directory) <> 0
+ else
+ Is := False;
+ {$ifdef fpc}
+ FindClose(SR);
+ {$endif}
+ end;
+ IsDir:=Is;
+end;
+
+{****************************************************************************}
+{ IsWild }
+{****************************************************************************}
+function IsWild(const S: String): Boolean;
+begin
+ IsWild := (Pos('?',S) > 0) or (Pos('*',S) > 0);
+end;
+
+{****************************************************************************}
+{ IsList }
+{****************************************************************************}
+function IsList(const S: String): Boolean;
+begin
+ IsList := (Pos(ListSeparator,S) > 0);
+end;
+
+{****************************************************************************}
+{ MakeResources }
+{****************************************************************************}
+(*
+procedure MakeResources;
+var
+ Dlg : PDialog;
+ Key : String;
+ i : Word;
+begin
+ for i := 0 to 1 do
+ begin
+ case i of
+ 0 : begin
+ Key := reOpenDlg;
+ Dlg := New(PFileDialog,Init('*.*',sOpen,slName,
+ fdOkButton or fdHelpButton or fdNoLoadDir,0));
+ end;
+ 1 : begin
+ Key := reSaveAsDlg;
+ Dlg := New(PFileDialog,Init('*.*',sSaveAs,slName,
+ fdOkButton or fdHelpButton or fdNoLoadDir,0));
+ end;
+ 2 : begin
+ Key := reEditChDirDialog;
+ Dlg := New(PEditChDirDialog,Init(cdHelpButton,
+ hiCurrentDirectories));
+ end;
+ end;
+ if Dlg = nil then
+ begin
+ PrintStr('Error initializing dialog ' + Key);
+ Halt;
+ end
+ else begin
+ RezFile^.Put(Dlg,Key);
+ if (RezFile^.Stream^.Status <> stOk) then
+ begin
+ PrintStr('Error writing dialog ' + Key + ' to the resource file.');
+ Halt;
+ end;
+ end;
+ end;
+end;
+*)
+{****************************************************************************}
+{ NoWildChars }
+{****************************************************************************}
+function NoWildChars(S: String): String;
+const
+ WildChars : array[0..1] of Char = ('?','*');
+var
+ i : Sw_Word;
+begin
+ repeat
+ i := Pos('?',S);
+ if (i > 0) then
+ System.Delete(S,i,1);
+ until (i = 0);
+ repeat
+ i := Pos('*',S);
+ if (i > 0) then
+ System.Delete(S,i,1);
+ until (i = 0);
+ NoWildChars:=S;
+end;
+
+{****************************************************************************}
+{ OpenFile }
+{****************************************************************************}
+function OpenFile (var AFile : FNameStr; HistoryID : Byte) : Boolean;
+var
+ Dlg : PFileDialog;
+begin
+ {$ifdef cdResource}
+ Dlg := PFileDialog(RezFile^.Get(reOpenDlg));
+ {$else}
+ Dlg := New(PFileDialog,Init('*.*',sOpen,slName,
+ fdOkButton or fdHelpButton,0));
+ {$endif cdResource}
+ { this might not work }
+ PHistory(Dlg^.FileName^.Next^.Next)^.HistoryID := HistoryID;
+ OpenFile := (Application^.ExecuteDialog(Dlg,@AFile) = cmFileOpen);
+end;
+
+{****************************************************************************}
+{ OpenNewFile }
+{****************************************************************************}
+function OpenNewFile (var AFile: FNameStr; HistoryID: Byte): Boolean;
+ { OpenNewFile allows the user to select a directory from disk and enter a
+ new file name. If the file name entered is an existing file the user is
+ optionally prompted for confirmation of replacing the file based on the
+ value in #CheckOnReplace#. If a file name is successfully entered,
+ OpenNewFile returns True. }
+ {#X OpenFile }
+begin
+ OpenNewFile := False;
+ if OpenFile(AFile,HistoryID) then
+ begin
+ if not ValidFileName(AFile) then
+ Exit;
+ if FileExists(AFile) then
+ if (not CheckOnReplace) or (not ReplaceFile(AFile)) then
+ Exit;
+ OpenNewFile := True;
+ end;
+end;
+
+{****************************************************************************}
+{ RegisterStdDlg }
+{****************************************************************************}
+procedure RegisterStdDlg;
+begin
+ RegisterType(RFileInputLine);
+ RegisterType(RFileCollection);
+ RegisterType(RFileList);
+ RegisterType(RFileInfoPane);
+ RegisterType(RFileDialog);
+ RegisterType(RDirCollection);
+ RegisterType(RDirListBox);
+ RegisterType(RSortedListBox);
+ RegisterType(RChDirDialog);
+end;
+
+{****************************************************************************}
+{ StdReplaceFile }
+{****************************************************************************}
+function StdReplaceFile (AFile : FNameStr) : Boolean;
+var
+ Rec : PStringRec;
+begin
+ if CheckOnReplace then
+ begin
+ AFile := ShrinkPath(AFile,33);
+ Rec.AString := PString(@AFile);
+ StdReplaceFile :=
+ (MessageBox(^C + sReplaceFile,
+ @Rec,mfConfirmation or mfOkCancel) = cmOk);
+ end
+ else StdReplaceFile := True;
+end;
+
+{****************************************************************************}
+{ SaveAs }
+{****************************************************************************}
+function SaveAs (var AFile : FNameStr; HistoryID : Word) : Boolean;
+var
+ Dlg : PFileDialog;
+begin
+ SaveAs := False;
+ Dlg := New(PFileDialog,Init('*.*',sSaveAs,slSaveAs,
+ fdOkButton or fdHelpButton,0));
+ { this might not work }
+ PHistory(Dlg^.FileName^.Next^.Next)^.HistoryID := HistoryID;
+ Dlg^.HelpCtx := hcSaveAs;
+ if (Application^.ExecuteDialog(Dlg,@AFile) = cmFileOpen) and
+ ((not FileExists(AFile)) or ReplaceFile(AFile)) then
+ SaveAs := True;
+end;
+
+{****************************************************************************}
+{ SelectDir }
+{****************************************************************************}
+function SelectDir (var ADir : DirStr; HistoryID : Byte) : Boolean;
+var
+ Dir: DirStr;
+ Dlg : PEditChDirDialog;
+ Rec : DirStr;
+begin
+ {$I-}
+ GetDir(0,Dir);
+ {$I+}
+ Rec := FExpand(ADir);
+ Dlg := New(PEditChDirDialog,Init(cdHelpButton,HistoryID));
+ if (Application^.ExecuteDialog(Dlg,@Rec) = cmOk) then
+ begin
+ SelectDir := True;
+ ADir := Rec;
+ end
+ else SelectDir := False;
+ {$I-}
+ ChDir(Dir);
+ {$I+}
+end;
+
+{****************************************************************************}
+{ ShrinkPath }
+{****************************************************************************}
+function ShrinkPath (AFile : FNameStr; MaxLen : Byte) : FNameStr;
+var
+ Filler: string;
+ D1 : DirStr;
+ N1 : NameStr;
+ E1 : ExtStr;
+ i : Sw_Word;
+
+begin
+ if Length(AFile) > MaxLen then
+ begin
+ FSplit(FExpand(AFile),D1,N1,E1);
+ AFile := Copy(D1,1,3) + '..' + DirSeparator;
+ i := Pred(Length(D1));
+ while (i > 0) and (D1[i] <> DirSeparator) do
+ Dec(i);
+ if (i = 0) then
+ AFile := AFile + D1
+ else AFile := AFile + Copy(D1,Succ(i),Length(D1)-i);
+ if AFile[Length(AFile)] <> DirSeparator then
+ AFile := AFile + DirSeparator;
+ if Length(AFile)+Length(N1)+Length(E1) <= MaxLen then
+ AFile := AFile + N1 + E1
+ else
+ begin
+ Filler := '...' + DirSeparator;
+ AFile:=Copy(Afile,1,MaxLen-Length(Filler)-Length(N1)-Length(E1))
+ +Filler+N1+E1;
+ end;
+ end;
+ ShrinkPath := AFile;
+end;
+
+{****************************************************************************}
+{ ValidFileName }
+{****************************************************************************}
+function ValidFileName(var FileName: PathStr): Boolean;
+var
+ IllegalChars: string[12];
+ Dir: DirStr;
+ Name: NameStr;
+ Ext: ExtStr;
+begin
+{$ifdef PPC_FPC}
+{$ifdef go32v2}
+ { spaces are allowed if LFN is supported }
+ if LFNSupport then
+ IllegalChars := ';,=+<>|"[]'+DirSeparator
+ else
+ IllegalChars := ';,=+<>|"[] '+DirSeparator;
+{$else not go32v2}
+{$ifdef win32}
+ IllegalChars := ';,=+<>|"[]'+DirSeparator;
+{$else not go32v2 and not win32 }
+ IllegalChars := ';,=+<>|"[] '+DirSeparator;
+{$endif not win32}
+{$endif not go32v2}
+{$else not PPC_FPC}
+ IllegalChars := ';,=+<>|"[] '+DirSeparator;
+{$endif PPC_FPC}
+ ValidFileName := True;
+ FSplit(FileName, Dir, Name, Ext);
+ if not ((Dir = '') or PathValid(Dir)) or
+ Contains(Name, IllegalChars) or
+ Contains(Dir, IllegalChars) then
+ ValidFileName := False;
+end;
+
+{****************************************************************************}
+{ Unit Initialization Section }
+{****************************************************************************}
+begin
+{$ifdef PPC_BP}
+ ReplaceFile := StdReplaceFile;
+ DeleteFile := StdDeleteFile;
+{$else}
+ ReplaceFile := @StdReplaceFile;
+ DeleteFile := @StdDeleteFile;
+{$endif PPC_BP}
+end.
diff --git a/packages/fv/src/str.inc b/packages/fv/src/str.inc
new file mode 100644
index 0000000000..c833c69155
--- /dev/null
+++ b/packages/fv/src/str.inc
@@ -0,0 +1,190 @@
+{ Strings }
+sVideoFailed = 0; {Video initialization failed.}
+sButtonDefault = 1; { Button default }
+sButtonDisabled = 2; { Button disabled }
+sButtonNormal = 3; { Button normal }
+sButtonSelected = 4; { Button selected }
+sButtonShadow = 5; { Button shadow }
+sButtonShortcut = 6; { Button shortcut }
+sChangeDirectory = 7; { Change Directory }
+sClipboard = 8; { Clipboard }
+sClusterNormal = 9; { Cluster normal }
+sClusterSelected = 10; { Cluster selected }
+sClusterShortcut = 11; { Cluster shortcut }
+sColor = 12; { Color }
+sColors = 13; { Colors }
+sConfirm = 14; { Confirm }
+sDeleteFile = 15; { Delete file?#13#10#13#3%s }
+sDirectory = 16; { Directory }
+sDisabled = 17; { Disabled }
+sDrives = 18; { Drives }
+sError = 19; { Error }
+sFileAlreadyOpen = 20; { #3%s#13#10#13#3is already open in window %d. }
+sFileCreateError = 21; { Error creating file %s }
+sFileReadError = 22; { Error reading file %s }
+sFileUntitled = 23; { Save untitled file? }
+sFileWriteError = 24; { Error writing to file %s }
+sFind = 25; { Find }
+sFrameActive = 26; { Frame active }
+sFrameBackground = 27; { Frame/background }
+sFrameIcons = 28; { Frame icons }
+sFramePassive = 29; { Frame passive }
+sHighlight = 30; { Highlight }
+sHistoryBarIcons = 31; { History bar icons }
+sHistoryBarPage = 32; { History bar page }
+sHistoryButton = 33; { History button }
+sHistorySides = 34; { History sides }
+sInformation = 35; { Information }
+sInformationPane = 36; { Information pane }
+sInputArrow = 37; { Input arrow }
+sInputNormal = 38; { Input normal }
+sInputSelected = 39; { Input selected }
+sInvalidCharacter = 40; { Invalid character in input }
+sInvalidDirectory = 41; { Invalid directory. }
+sInvalidDriveOrDir = 42; { Invalid drive or directory. }
+sInvalidFileName = 43; { Invalid file name. }
+sInvalidPicture = 44; { Input does not conform to picture: %s }
+sInvalidValue = 45; { Value not in the range %d to %d }
+sInverse = 46; { Inverse }
+sJumpTo = 47; { Jump To }
+sLabelNormal = 48; { Label normal }
+sLabelSelected = 49; { Label selected }
+sLabelShortcut = 50; { Label shortcut }
+sListDivider = 51; { List divider }
+sListFocused = 52; { List focused }
+sListNormal = 53; { List normal }
+sListSelected = 54; { List selected }
+sModified = 55; { #3%s#13#10#13#3has been modified. Save? }
+sNoName = 56; { NONAME }
+sNormal = 57; { Normal }
+sNormalText = 58; { Normal text }
+sNotInList = 59; { Input not in valid-list }
+sOpen = 60; { Open }
+sOutOfMemory = 61; { Not enough memory for this operation. }
+sOutOfUnNamedWindows = 62; { Out of unnamed window numbers. Save or discard some unnamed files and try again. }
+sPasteNotPossible = 63; { Wordwrap on: Paste not possible in current margins when at end of line. }
+sReformatDocument = 64; { Reformat Document }
+sReformatNotPossible = 65; { Paragraph reformat not possible while trying to wrap current line with current margins. }
+sReformattingTheDocument = 66; { Reformatting the document: }
+sReplace = 67; { Replace }
+sReplaceFile = 68; { Replace file?#13#10#13#3%s }
+sReplaceNotPossible = 69; { Wordwrap on: Replace not possible in current margins when at end of line. }
+sReplaceThisOccurence = 70; { Replace this occurence? }
+sRightMargin = 71; { Right Margin }
+sSaveAs = 72; { Save As }
+sScrollbarIcons = 73; { Scroll bar icons }
+sScrollbarPage = 74; { Scroll bar page }
+sSearchStringNotFound = 75; { Search string not found. }
+sSelectFormatStart = 76; { Select Format Start }
+sSelectWhereToBegin = 77; { Please select where to begin. }
+sSelected = 78; { Selected }
+sSelectedDisabled = 79; { Selected disabled }
+sSetting = 80; { Setting: }
+sShortcut = 81; { Shortcut }
+sShortcutSelected = 82; { ShortcutSelected }
+sStaticText = 83; { Static text }
+sTabSettings = 84; { Tab Settings }
+sText = 85; { Text }
+sTooManyFiles = 86; { Too many files. }
+sTypeExitOnReturn = 87; { Type EXIT to return... }
+sUnderline = 88; { Underline }
+sUnknownDialog = 89; { Unknown dialog requested! }
+sUntitled = 90; { Untitled }
+sWarning = 91; { Warning }
+sWindowList = 92; { Window List }
+sWordWrapNotPossible = 93; { Wordwrap on: Wordwrap not possible in current margins with continuous line. }
+sWordWrapOff = 94; { You must turn on wordwrap before you can reformat. }
+smApr = 95; { Apr }
+smAug = 96; { Aug }
+smDec = 97; { Dec }
+smFeb = 98; { Feb }
+smJan = 99; { Jan }
+smJul = 100; { Jul }
+smJun = 101; { Jun }
+smMar = 102; { Mar }
+smMay = 103; { May }
+smNov = 104; { Nov }
+smOct = 105; { Oct }
+smSep = 106; { Sep }
+{ Labels }
+slAbout = 107; { ~A~bout }
+slAltF1 = 108; { Alt+F1 }
+slAltF3Close = 109; { ~Alt+F3~ Close }
+slAltXExit = 110; { ~Alt-X~ Exit }
+slBackground = 111; { ~B~ackground }
+slCancel = 112; { Cancel }
+slCascade = 113; { C~a~scade }
+slCaseSensitive = 114; { ~C~ase sensitive }
+slChDir = 115; { ~C~hdir }
+slChangeDir = 116; { ~C~hange dir... }
+slClear = 117; { C~l~ear }
+slClose = 118; { ~C~lose }
+slCloseAll = 119; { Cl~o~se all }
+slColor = 120; { ~C~olor }
+slContents = 121; { ~C~ontents }
+slCopy = 122; { ~C~opy }
+slCtrlF1 = 123; { Ctrl+F1 }
+slCurrentLine = 124; { ~C~urrent line }
+slCut = 125; { Cu~t~ }
+slDOSShell = 126; { ~D~OS shell }
+slDelete = 127; { ~D~elete }
+slDirectoryName = 128; { Directory ~n~ame }
+slDirectoryTree = 129; { Directory ~t~ree }
+slEdit = 130; { ~E~dit }
+slEntireDocument = 131; { ~E~ntire document }
+slExit = 132; { E~x~it }
+slF10Menu = 133; { ~F10~ Menu }
+slF1Help = 134; { ~F1~ Help }
+slF3Open = 135; { ~F3~ Open }
+slFile = 136; { ~F~ile }
+slFiles = 137; { ~F~iles }
+slForeground = 138; { ~F~oreground }
+slGroup = 139; { ~G~roup }
+slHelp = 140; { ~H~elp }
+slIndex = 141; { ~I~ndex }
+slItem = 142; { ~I~tem }
+slLineNumber = 143; { ~L~ine number }
+slName = 144; { ~N~ame }
+slNew = 145; { ~N~ew }
+slNewText = 146; { ~N~ew text }
+slNext = 147; { ~N~ext }
+slNo = 148; { ~N~o }
+slOk = 149; { O~k~ }
+slOpen = 150; { ~O~pen }
+slOpenDots = 151; { ~O~pen... }
+slPaste = 152; { ~P~aste }
+slPrevious = 153; { ~P~revious }
+slPreviousTopic = 154; { ~P~revious topic }
+slPromptOnReplace = 155; { ~P~rompt on replace }
+slReformatDocument = 156; { ~R~eformat document }
+slReplace = 157; { ~R~eplace }
+slReplaceAll = 158; { ~R~eplace all }
+slRevert = 159; { ~R~evert }
+slSave = 160; { ~S~ave }
+slSaveAll = 161; { Save a~l~l }
+slSaveAs = 162; { S~a~ve as... }
+slSaveFileAs = 163; { ~S~ave file as }
+slShiftF1 = 164; { Shift+F1 }
+slSizeMove = 165; { ~S~ize/Move }
+slTextToFind = 166; { ~T~ext to find }
+slTile = 167; { ~T~ile }
+slTopicSearch = 168; { ~T~opic search }
+slUndo = 169; { ~U~ndo }
+slUsingHelp = 170; { ~U~sing help }
+slWholeWordsOnly = 171; { ~W~hole words only }
+slWindow = 172; { ~W~indow }
+slWindows = 173; { ~W~indows }
+slYes = 174; { ~Y~es }
+slZoom = 175; { ~Z~oom }
+slAltF3 = 176; { Alt+F3 }
+slAltX = 177; { Alt+X }
+slF2 = 178; { F2 }
+slF3 = 179; { F3 }
+slF5 = 180; { F5 }
+slF6 = 181; { F6 }
+slCtrlDel = 182; { Ctrl+Del }
+slCtrlF5 = 183; { Ctrl+F5 }
+slCtrlIns = 184; { Ctrl+Ins }
+slShiftDel = 185; { Shift+Del }
+slShiftF6 = 186; { Shift+F6 }
+slShiftIns = 187; { Shift+Ins }
diff --git a/packages/fv/src/strtxt.inc b/packages/fv/src/strtxt.inc
new file mode 100644
index 0000000000..361b1b98b7
--- /dev/null
+++ b/packages/fv/src/strtxt.inc
@@ -0,0 +1,216 @@
+type standard_string=record
+ nr:word;
+ text:Pchar;
+ end;
+
+const standard_string_count=107;
+ standard_strings:array[0..standard_string_count-1] of standard_string=(
+ (nr:sVideoFailed;text:'Video initialization failed.'),
+ (nr:sButtonDefault;text:'Button default'),
+ (nr:sButtonDisabled;text:'Button disabled'),
+ (nr:sButtonNormal;text:'Button normal'),
+ (nr:sButtonSelected;text:'Button selected'),
+ (nr:sButtonShadow;text:'Button shadow'),
+ (nr:sButtonShortcut;text:'Button shortcut'),
+ (nr:sChangeDirectory;text:'Change Directory'),
+ (nr:sClipboard;text:'Clipboard'),
+ (nr:sClusterNormal;text:'Cluster normal'),
+ (nr:sClusterSelected;text:'Cluster selected'),
+ (nr:sClusterShortcut;text:'Cluster shortcut'),
+ (nr:sColor;text:'Color'),
+ (nr:sColors;text:'Colors'),
+ (nr:sConfirm;text:'Confirm'),
+ (nr:sDeleteFile;text:'Delete file?'#13#10#13#3'%s'),
+ (nr:sDirectory;text:'Directory'),
+ (nr:sDisabled;text:'Disabled'),
+ (nr:sDrives;text:'Drives'),
+ (nr:sError;text:'Error'),
+ (nr:sFileAlreadyOpen;text:''#3'%s'#13#10#13#3'is already open in window %d.'),
+ (nr:sFileCreateError;text:'Error creating file %s'),
+ (nr:sFileReadError;text:'Error reading file %s'),
+ (nr:sFileUntitled;text:'Save untitled file?'),
+ (nr:sFileWriteError;text:'Error writing to file %s'),
+ (nr:sFind;text:'Find'),
+ (nr:sFrameActive;text:'Frame active'),
+ (nr:sFrameBackground;text:'Frame/background'),
+ (nr:sFrameIcons;text:'Frame icons'),
+ (nr:sFramePassive;text:'Frame passive'),
+ (nr:sHighlight;text:'Highlight'),
+ (nr:sHistoryBarIcons;text:'History bar icons'),
+ (nr:sHistoryBarPage;text:'History bar page'),
+ (nr:sHistoryButton;text:'History button'),
+ (nr:sHistorySides;text:'History sides'),
+ (nr:sInformation;text:'Information'),
+ (nr:sInformationPane;text:'Information pane'),
+ (nr:sInputArrow;text:'Input arrow'),
+ (nr:sInputNormal;text:'Input normal'),
+ (nr:sInputSelected;text:'Input selected'),
+ (nr:sInvalidCharacter;text:'Invalid character in input'),
+ (nr:sInvalidDirectory;text:'Invalid directory.'),
+ (nr:sInvalidDriveOrDir;text:'Invalid drive or directory.'),
+ (nr:sInvalidFileName;text:'Invalid file name.'),
+ (nr:sInvalidPicture;text:'Input does not conform to picture: %s'),
+ (nr:sInvalidValue;text:'Value not in the range %d to %d'),
+ (nr:sInverse;text:'Inverse'),
+ (nr:sJumpTo;text:'Jump To'),
+ (nr:sLabelNormal;text:'Label normal'),
+ (nr:sLabelSelected;text:'Label selected'),
+ (nr:sLabelShortcut;text:'Label shortcut'),
+ (nr:sListDivider;text:'List divider'),
+ (nr:sListFocused;text:'List focused'),
+ (nr:sListNormal;text:'List normal'),
+ (nr:sListSelected;text:'List selected'),
+ (nr:sModified;text:''#3'%s'#13#10#13#3'has been modified. Save?'),
+ (nr:sNoName;text:'NONAME'),
+ (nr:sNormal;text:'Normal'),
+ (nr:sNormalText;text:'Normal text'),
+ (nr:sNotInList;text:'Input not in valid-list'),
+ (nr:sOpen;text:'Open'),
+ (nr:sOutOfMemory;text:'Not enough memory for this operation.'),
+ (nr:sOutOfUnNamedWindows;text:'Out of unnamed window numbers. Save or discard some unnamed files and try again.'),
+ (nr:sPasteNotPossible;text:'Wordwrap on: Paste not possible in current margins when at end of line.'),
+ (nr:sReformatDocument;text:'Reformat Document'),
+ (nr:sReformatNotPossible;text:'Paragraph reformat not possible while trying to wrap current line with current margins.'),
+ (nr:sReformattingTheDocument;text:'Reformatting the document:'),
+ (nr:sReplace;text:'Replace'),
+ (nr:sReplaceFile;text:'Replace file?'#13#10#13#3'%s'),
+ (nr:sReplaceNotPossible;text:'Wordwrap on: Replace not possible in current margins when at end of line.'),
+ (nr:sReplaceThisOccurence;text:'Replace this occurence?'),
+ (nr:sRightMargin;text:'Right Margin'),
+ (nr:sSaveAs;text:'Save As'),
+ (nr:sScrollbarIcons;text:'Scroll bar icons'),
+ (nr:sScrollbarPage;text:'Scroll bar page'),
+ (nr:sSearchStringNotFound;text:'Search string not found.'),
+ (nr:sSelectFormatStart;text:'Select Format Start'),
+ (nr:sSelectWhereToBegin;text:'Please select where to begin.'),
+ (nr:sSelected;text:'Selected'),
+ (nr:sSelectedDisabled;text:'Selected disabled'),
+ (nr:sSetting;text:'Setting:'),
+ (nr:sShortcut;text:'Shortcut'),
+ (nr:sShortcutSelected;text:'ShortcutSelected'),
+ (nr:sStaticText;text:'Static text'),
+ (nr:sTabSettings;text:'Tab Settings'),
+ (nr:sText;text:'Text'),
+ (nr:sTooManyFiles;text:'Too many files.'),
+ (nr:sTypeExitOnReturn;text:'Type EXIT to return...'),
+ (nr:sUnderline;text:'Underline'),
+ (nr:sUnknownDialog;text:'Unknown dialog requested!'),
+ (nr:sUntitled;text:'Untitled'),
+ (nr:sWarning;text:'Warning'),
+ (nr:sWindowList;text:'Window List'),
+ (nr:sWordWrapNotPossible;text:'Wordwrap on: Wordwrap not possible in current margins with continuous line.'),
+ (nr:sWordWrapOff;text:'You must turn on wordwrap before you can reformat.'),
+ (nr:smApr;text:'Apr'),
+ (nr:smAug;text:'Aug'),
+ (nr:smDec;text:'Dec'),
+ (nr:smFeb;text:'Feb'),
+ (nr:smJan;text:'Jan'),
+ (nr:smJul;text:'Jul'),
+ (nr:smJun;text:'Jun'),
+ (nr:smMar;text:'Mar'),
+ (nr:smMay;text:'May'),
+ (nr:smNov;text:'Nov'),
+ (nr:smOct;text:'Oct'),
+ (nr:smSep;text:'Sep'));
+
+procedure InitResStrings;
+
+var i:word;
+
+begin
+ for i:=0 to standard_string_count-1 do
+ strings^.put(standard_strings[i].nr,strpas(standard_strings[i].text));
+end;
+
+const standard_label_count=81;
+ standard_labels:array[0..standard_label_count-1] of standard_string=(
+ (nr:slAbout;text:'~A~bout'),
+ (nr:slAltF1;text:'Alt+F1'),
+ (nr:slAltF3Close;text:'~Alt+F3~ Close'),
+ (nr:slAltXExit;text:'~Alt-X~ Exit'),
+ (nr:slBackground;text:'~B~ackground'),
+ (nr:slCancel;text:'Cancel'),
+ (nr:slCascade;text:'C~a~scade'),
+ (nr:slCaseSensitive;text:'~C~ase sensitive'),
+ (nr:slChDir;text:'~C~hdir'),
+ (nr:slChangeDir;text:'~C~hange dir...'),
+ (nr:slClear;text:'C~l~ear'),
+ (nr:slClose;text:'~C~lose'),
+ (nr:slCloseAll;text:'Cl~o~se all'),
+ (nr:slColor;text:'~C~olor'),
+ (nr:slContents;text:'~C~ontents'),
+ (nr:slCopy;text:'~C~opy'),
+ (nr:slCtrlF1;text:'Ctrl+F1'),
+ (nr:slCurrentLine;text:'~C~urrent line'),
+ (nr:slCut;text:'Cu~t~'),
+ (nr:slDOSShell;text:'~D~OS shell'),
+ (nr:slDelete;text:'~D~elete'),
+ (nr:slDirectoryName;text:'Directory ~n~ame'),
+ (nr:slDirectoryTree;text:'Directory ~t~ree'),
+ (nr:slEdit;text:'~E~dit'),
+ (nr:slEntireDocument;text:'~E~ntire document'),
+ (nr:slExit;text:'E~x~it'),
+ (nr:slF10Menu;text:'~F10~ Menu'),
+ (nr:slF1Help;text:'~F1~ Help'),
+ (nr:slF3Open;text:'~F3~ Open'),
+ (nr:slFile;text:'~F~ile'),
+ (nr:slFiles;text:'~F~iles'),
+ (nr:slForeground;text:'~F~oreground'),
+ (nr:slGroup;text:'~G~roup'),
+ (nr:slHelp;text:'~H~elp'),
+ (nr:slIndex;text:'~I~ndex'),
+ (nr:slItem;text:'~I~tem'),
+ (nr:slLineNumber;text:'~L~ine number'),
+ (nr:slName;text:'~N~ame'),
+ (nr:slNew;text:'~N~ew'),
+ (nr:slNewText;text:'~N~ew text'),
+ (nr:slNext;text:'~N~ext'),
+ (nr:slNo;text:'~N~o'),
+ (nr:slOk;text:'O~k~'),
+ (nr:slOpen;text:'~O~pen'),
+ (nr:slOpenDots;text:'~O~pen...'),
+ (nr:slPaste;text:'~P~aste'),
+ (nr:slPrevious;text:'~P~revious'),
+ (nr:slPreviousTopic;text:'~P~revious topic'),
+ (nr:slPromptOnReplace;text:'~P~rompt on replace'),
+ (nr:slReformatDocument;text:'~R~eformat document'),
+ (nr:slReplace;text:'~R~eplace'),
+ (nr:slReplaceAll;text:'~R~eplace all'),
+ (nr:slRevert;text:'~R~evert'),
+ (nr:slSave;text:'~S~ave'),
+ (nr:slSaveAll;text:'Save a~l~l'),
+ (nr:slSaveAs;text:'S~a~ve as...'),
+ (nr:slSaveFileAs;text:'~S~ave file as'),
+ (nr:slShiftF1;text:'Shift+F1'),
+ (nr:slSizeMove;text:'~S~ize/Move'),
+ (nr:slTextToFind;text:'~T~ext to find'),
+ (nr:slTile;text:'~T~ile'),
+ (nr:slTopicSearch;text:'~T~opic search'),
+ (nr:slUndo;text:'~U~ndo'),
+ (nr:slUsingHelp;text:'~U~sing help'),
+ (nr:slWholeWordsOnly;text:'~W~hole words only'),
+ (nr:slWindow;text:'~W~indow'),
+ (nr:slWindows;text:'~W~indows'),
+ (nr:slYes;text:'~Y~es'),
+ (nr:slZoom;text:'~Z~oom'),
+ (nr:slAltF3;text:'Alt+F3'),
+ (nr:slAltX;text:'Alt+X'),
+ (nr:slF2;text:'F2'),
+ (nr:slF3;text:'F3'),
+ (nr:slF5;text:'F5'),
+ (nr:slF6;text:'F6'),
+ (nr:slCtrlDel;text:'Ctrl+Del'),
+ (nr:slCtrlF5;text:'Ctrl+F5'),
+ (nr:slCtrlIns;text:'Ctrl+Ins'),
+ (nr:slShiftDel;text:'Shift+Del'),
+ (nr:slShiftF6;text:'Shift+F6'),
+ (nr:slShiftIns;text:'Shift+Ins'));
+
+procedure InitResLabels;
+
+var i:word;
+
+begin
+ for i:=0 to standard_label_count-1 do
+ labels^.put(standard_labels[i].nr,strpas(standard_labels[i].text));
+end;
diff --git a/packages/fv/src/sysmsg.pas b/packages/fv/src/sysmsg.pas
new file mode 100644
index 0000000000..c702dca377
--- /dev/null
+++ b/packages/fv/src/sysmsg.pas
@@ -0,0 +1,127 @@
+{
+
+ Unit to handle system events
+
+ Copyright 2000 by Pierre Muller <muller@ics.u-strasbg.fr>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+Unit sysmsg;
+
+interface
+
+type
+ TSystemMessage = (
+ SysNothing,
+ SysSetFocus,
+ SysReleaseFocus,
+ SysClose,
+ SysResize );
+
+ TSystemEvent = Record
+ case typ : TSystemMessage of
+ SysClose : ( CloseTyp : Longint);
+ SysResize : (X,Y : Longint);
+ end;
+
+ PSystemEvent = ^TSystemEvent;
+
+const
+ SystemEventBufSize = 16;
+
+var
+ PendingSystemEvent : array[0..SystemEventBufSize-1] of TSystemEvent;
+ PendingSystemHead,
+ PendingSystemTail : PSystemEvent;
+ PendingSystemEvents : byte;
+
+ LastSystemEvent : TSystemEvent;
+
+
+procedure InitSystemMsg;
+
+procedure DoneSystemMsg;
+
+procedure GetSystemEvent(var SystemEvent:TSystemEvent);
+{ Returns the last SystemEvent, and waits for one if not available }
+
+procedure PutSystemEvent(const SystemEvent: TSystemEvent);
+{ Adds the given SystemEvent to the input queue. }
+
+function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
+{ Checks if a SystemEvent is available, and returns it if one is found. If no
+ event is pending, it returns 0 }
+
+implementation
+
+{$undef HAS_SYSMSG}
+
+{$ifdef go32v2}
+{$i go32smsg.inc}
+{$define HAS_SYSMSG}
+{$endif go32v2}
+{$ifdef win32}
+{$i w32smsg.inc}
+{$define HAS_SYSMSG}
+{$endif win32}
+{$ifdef unix}
+{$i unixsmsg.inc}
+{$define HAS_SYSMSG}
+{$endif unix}
+
+{$ifdef HAS_SYSMSG}
+
+procedure PutSystemEvent(const SystemEvent: TSystemEvent);
+begin
+ if PendingSystemEvents<SystemEventBufSize then
+ begin
+ PendingSystemTail^:=SystemEvent;
+ inc(PendingSystemTail);
+ if longint(PendingSystemTail)=longint(@PendingSystemEvent)+sizeof(PendingSystemEvent) then
+ PendingSystemTail:=@PendingSystemEvent;
+ inc(PendingSystemEvents);
+ end;
+end;
+
+{$else HAS_SYSMSG}
+
+procedure InitSystemMsg;
+begin
+end;
+
+procedure DoneSystemMsg;
+begin
+end;
+
+procedure GetSystemEvent(var SystemEvent:TSystemEvent);
+begin
+ FillChar(SystemEvent,SizeOf(SystemEvent),#0);
+end;
+
+function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
+begin
+ FillChar(SystemEvent,SizeOf(SystemEvent),#0);
+ PollSystemEvent:=false;
+end;
+
+procedure PutSystemEvent(const SystemEvent: TSystemEvent);
+begin
+end;
+
+{$endif not HAS_SYSMSG}
+
+end.
diff --git a/packages/fv/src/tabs.pas b/packages/fv/src/tabs.pas
new file mode 100644
index 0000000000..d2860b3e8d
--- /dev/null
+++ b/packages/fv/src/tabs.pas
@@ -0,0 +1,774 @@
+{
+
+ Tabbed group for TV/FV dialogs
+
+ Copyright 2000-4 by Free Pascal core team
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+unit tabs;
+
+{$I platform.inc} (* Multi-platform support defines *)
+{$CODEPAGE cp437}
+
+interface
+
+uses
+ objects,
+ drivers,
+ views,
+ fvconsts;
+
+
+type
+ PTabItem = ^TTabItem;
+ TTabItem = record
+ Next : PTabItem;
+ View : PView;
+ Dis : boolean;
+ end;
+
+ PTabDef = ^TTabDef;
+ TTabDef = record
+ Next : PTabDef;
+ Name : PString;
+ Items : PTabItem;
+ DefItem : PView;
+ ShortCut : char;
+ end;
+
+ PTab = ^TTab;
+ TTab = object(TGroup)
+ TabDefs : PTabDef;
+ ActiveDef : integer;
+ DefCount : word;
+ constructor Init(var Bounds: TRect; ATabDef: PTabDef);
+ constructor Load (var S: TStream);
+ function AtTab(Index: integer): PTabDef; virtual;
+ procedure SelectTab(Index: integer); virtual;
+ procedure Store (var S: TStream);
+ function TabCount: integer;
+ function Valid(Command: Word): Boolean; virtual;
+ procedure ChangeBounds(var Bounds: TRect); virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ function GetPalette: PPalette; virtual;
+ procedure Draw; virtual;
+ function DataSize: sw_word;virtual;
+ procedure SetData(var Rec);virtual;
+ procedure GetData(var Rec);virtual;
+ procedure SetState(AState: Word; Enable: Boolean); virtual;
+ destructor Done; virtual;
+ private
+ InDraw: boolean;
+ function FirstSelectable: PView;
+ function LastSelectable: PView;
+ end;
+
+function NewTabItem(AView: PView; ANext: PTabItem): PTabItem;
+procedure DisposeTabItem(P: PTabItem);
+function NewTabDef(AName: string; ADefItem: PView; AItems: PTabItem; ANext: PTabDef): PTabDef;
+procedure DisposeTabDef(P: PTabDef);
+
+procedure RegisterTab;
+
+const
+ RTab: TStreamRec = (
+ ObjType: idTab;
+{$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs (TypeOf (TTab)^);
+{$ELSE BP_VMTLink} { Alt style VMT link }
+ VmtLink: TypeOf (TTab);
+{$ENDIF BP_VMTLink}
+ Load: @TTab.Load;
+ Store: @TTab.Store
+ );
+
+
+implementation
+
+uses
+ FvCommon,
+ dialogs;
+
+constructor TTab.Init(var Bounds: TRect; ATabDef: PTabDef);
+begin
+ inherited Init(Bounds);
+ Options:=Options or ofSelectable or ofFirstClick or ofPreProcess or ofPostProcess;
+ GrowMode:=gfGrowHiX+gfGrowHiY+gfGrowRel;
+ TabDefs:=ATabDef;
+ ActiveDef:=-1;
+ SelectTab(0);
+ ReDraw;
+end;
+
+constructor TTab.Load (var S: TStream);
+
+ function DoLoadTabItems (var XDefItem: PView; ActItem: longint): PTabItem;
+ var
+ Count: longint;
+ Cur, First: PTabItem;
+ Last: ^PTabItem;
+ begin
+ Cur := nil; { Preset nil }
+ Last := @First; { Start on first item }
+ S.Read (Count, SizeOf(Count)); { Read item count }
+ while (Count > 0) do
+ begin
+ New (Cur); { New status item }
+ Last^ := Cur; { First chain part }
+ if (Cur <> nil) then { Check pointer valid }
+ begin
+ Last := @Cur^.Next; { Chain complete }
+ S.Read (Cur^.Dis, SizeOf (Cur^.Dis));
+ Cur^.View := PView (S.Get);
+ if ActItem = 0 then
+ XDefItem := Cur^.View; { Find default view }
+ end;
+ Dec (Count); { One item loaded }
+ Dec (ActItem);
+ end;
+ Last^ := nil; { Now chain end }
+ DoLoadTabItems := First; { Return the list }
+ end;
+
+ function DoLoadTabDefs: PTabDef;
+ var
+ Count: longint;
+ Cur, First: PTabDef;
+ Last: ^PTabDef;
+ ActItem: longint;
+ begin
+ Last := @First; { Start on first }
+ Count := DefCount;
+ while (Count > 0) do
+ begin
+ New (Cur); { New status def }
+ Last^ := Cur; { First part of chain }
+ if (Cur <> nil) then { Check pointer valid }
+ begin
+ Last := @Cur^.Next; { Chain complete }
+ Cur^.Name := S.ReadStr; { Read name }
+ S.Read (Cur^.ShortCut, SizeOf (Cur^.ShortCut));
+ S.Read (ActItem, SizeOf (ActItem));
+ Cur^.Items := DoLoadTabItems (Cur^.DefItem, ActItem); { Set pointer }
+ end;
+ Dec (Count); { One item loaded }
+ end;
+ Last^ := nil; { Now chain ends }
+ DoLoadTabDefs := First; { Return item list }
+ end;
+
+begin
+ inherited Load (S);
+ S.Read (DefCount, SizeOf (DefCount));
+ S.Read (ActiveDef, SizeOf (ActiveDef));
+ TabDefs := DoLoadTabDefs;
+end;
+
+procedure TTab.Store (var S: TStream);
+
+ procedure DoStoreTabItems (Cur: PTabItem; XDefItem: PView);
+ var
+ Count: longint;
+ T: PTabItem;
+ ActItem: longint;
+ begin
+ Count := 0; { Clear count }
+ T := Cur; { Start on current }
+ while (T <> nil) do
+ begin
+ if T^.View = XDefItem then { Current = active? }
+ ActItem := Count; { => set order }
+ Inc (Count); { Count items }
+ T := T^.Next; { Next item }
+ end;
+ S.Write (ActItem, SizeOf (ActItem));
+ S.Write (Count, SizeOf (Count)); { Write item count }
+ while (Cur <> nil) do
+ begin
+ S.Write (Cur^.Dis, SizeOf (Cur^.Dis));
+ S.Put (Cur^.View);
+ end;
+ end;
+
+ procedure DoStoreTabDefs (Cur: PTabDef);
+ begin
+ while (Cur <> nil) do
+ begin
+ with Cur^ do
+ begin
+ S.WriteStr (Cur^.Name); { Write name }
+ S.Write (Cur^.ShortCut, SizeOf (Cur^.ShortCut));
+ DoStoreTabItems (Items, DefItem); { Store the items }
+ end;
+ Cur := Cur^.Next; { Next status item }
+ end;
+ end;
+
+begin
+ inherited Store (S);
+ S.Write (DefCount, SizeOf (DefCount));
+ S.Write (ActiveDef, SizeOf (ActiveDef));
+ DoStoreTabDefs (TabDefs);
+end;
+
+function TTab.TabCount: integer;
+var i: integer;
+ P: PTabDef;
+begin
+ I:=0; P:=TabDefs;
+ while (P<>nil) do
+ begin
+ Inc(I);
+ P:=P^.Next;
+ end;
+ TabCount:=I;
+end;
+
+
+function TTab.AtTab(Index: integer): PTabDef;
+var i: integer;
+ P: PTabDef;
+begin
+ i:=0; P:=TabDefs;
+ while (I<Index) do
+ begin
+ if P=nil then RunError($AA);
+ P:=P^.Next;
+ Inc(i);
+ end;
+ AtTab:=P;
+end;
+
+procedure TTab.SelectTab(Index: integer);
+var P: PTabItem;
+ V: PView;
+begin
+ if ActiveDef<>Index then
+ begin
+ if Owner<>nil then Owner^.Lock;
+ Lock;
+ { --- Update --- }
+ if TabDefs<>nil then
+ begin
+ DefCount:=1;
+ while AtTab(DefCount-1)^.Next<>nil do Inc(DefCount);
+ end
+ else DefCount:=0;
+ if ActiveDef<>-1 then
+ begin
+ P:=AtTab(ActiveDef)^.Items;
+ while P<>nil do
+ begin
+ if P^.View<>nil then Delete(P^.View);
+ P:=P^.Next;
+ end;
+ end;
+ ActiveDef:=Index;
+ P:=AtTab(ActiveDef)^.Items;
+ while P<>nil do
+ begin
+ if P^.View<>nil then Insert(P^.View);
+ P:=P^.Next;
+ end;
+ V:=AtTab(ActiveDef)^.DefItem;
+ if V<>nil then V^.Select;
+ ReDraw;
+ { --- Update --- }
+ UnLock;
+ if Owner<>nil then Owner^.UnLock;
+ DrawView;
+ end;
+end;
+
+procedure TTab.ChangeBounds(var Bounds: TRect);
+var D: TPoint;
+procedure DoCalcChange(P: PView); {$ifndef FPC}far;{$endif}
+var
+ R: TRect;
+begin
+ if P^.Owner=nil then Exit; { it think this is a bug in TV }
+ P^.CalcBounds(R, D);
+ P^.ChangeBounds(R);
+end;
+var
+ P: PTabItem;
+ I: integer;
+begin
+ D.X := Bounds.B.X - Bounds.A.X - Size.X;
+ D.Y := Bounds.B.Y - Bounds.A.Y - Size.Y;
+ inherited ChangeBounds(Bounds);
+ for I:=0 to TabCount-1 do
+ if I<>ActiveDef then
+ begin
+ P:=AtTab(I)^.Items;
+ while P<>nil do
+ begin
+ if P^.View<>nil then DoCalcChange(P^.View);
+ P:=P^.Next;
+ end;
+ end;
+end;
+
+
+function TTab.FirstSelectable: PView;
+var
+ FV : PView;
+begin
+ FV := First;
+ while (FV<>nil) and ((FV^.Options and ofSelectable)=0) and (FV<>Last) do
+ FV:=FV^.Next;
+ if FV<>nil then
+ if (FV^.Options and ofSelectable)=0 then FV:=nil;
+ FirstSelectable:=FV;
+end;
+
+
+function TTab.LastSelectable: PView;
+var
+ LV : PView;
+begin
+ LV := Last;
+ while (LV<>nil) and ((LV^.Options and ofSelectable)=0) and (LV<>First) do
+ LV:=LV^.Prev;
+ if LV<>nil then
+ if (LV^.Options and ofSelectable)=0 then LV:=nil;
+ LastSelectable:=LV;
+end;
+
+procedure TTab.HandleEvent(var Event: TEvent);
+var Index : integer;
+ I : integer;
+ X : integer;
+ Len : byte;
+ P : TPoint;
+ V : PView;
+ CallOrig: boolean;
+ LastV : PView;
+ FirstV: PView;
+begin
+ if (Event.What and evMouseDown)<>0 then
+ begin
+ MakeLocal(Event.Where,P);
+ if P.Y<3 then
+ begin
+ Index:=-1; X:=1;
+ for i:=0 to DefCount-1 do
+ begin
+ Len:=CStrLen(AtTab(i)^.Name^);
+ if (P.X>=X) and (P.X<=X+Len+1) then Index:=i;
+ X:=X+Len+3;
+ end;
+ if Index<>-1 then
+ SelectTab(Index);
+ end;
+ end;
+ if Event.What=evKeyDown then
+ begin
+ Index:=-1;
+ case Event.KeyCode of
+ kbTab,kbShiftTab :
+ if GetState(sfSelected) then
+ begin
+ if Current<>nil then
+ begin
+ LastV:=LastSelectable; FirstV:=FirstSelectable;
+ if ((Current=LastV) or (Current=PLabel(LastV)^.Link)) and (Event.KeyCode=kbShiftTab) then
+ begin
+ if Owner<>nil then Owner^.SelectNext(true);
+ end else
+ if ((Current=FirstV) or (Current=PLabel(FirstV)^.Link)) and (Event.KeyCode=kbTab) then
+ begin
+ Lock;
+ if Owner<>nil then Owner^.SelectNext(false);
+ UnLock;
+ end else
+ SelectNext(Event.KeyCode=kbShiftTab);
+ ClearEvent(Event);
+ end;
+ end;
+ else
+ for I:=0 to DefCount-1 do
+ begin
+ if Upcase(GetAltChar(Event.KeyCode))=AtTab(I)^.ShortCut
+ then begin
+ Index:=I;
+ ClearEvent(Event);
+ Break;
+ end;
+ end;
+ end;
+ if Index<>-1 then
+ begin
+ Select;
+ SelectTab(Index);
+ V:=AtTab(ActiveDef)^.DefItem;
+ if V<>nil then V^.Focus;
+ end;
+ end;
+ CallOrig:=true;
+ if Event.What=evKeyDown then
+ begin
+ if ((Owner<>nil) and (Owner^.Phase=phPostProcess)
+ and (GetAltChar(Event.KeyCode)<>#0)) or GetState(sfFocused)
+ then
+ else CallOrig:=false;
+ end;
+ if CallOrig then inherited HandleEvent(Event);
+end;
+
+function TTab.GetPalette: PPalette;
+begin
+ GetPalette:=nil;
+end;
+
+{$define AVOIDTHREELINES}
+
+procedure TTab.Draw;
+const
+{$ifdef AVOIDTHREELINES}
+ UDL='¿';
+ LUR='Ä';
+ URD='Ú';
+{$else not AVOIDTHREELINES}
+ UDL='´';
+ LUR='Á';
+ URD='Ã';
+{$endif not AVOIDTHREELINES}
+
+
+var B : TDrawBuffer;
+ i : integer;
+ C1,C2,C3,C : word;
+ HeaderLen : integer;
+ X,X2 : integer;
+ Name : PString;
+ ActiveKPos : integer;
+ ActiveVPos : integer;
+ FC : char;
+procedure SWriteBuf(X,Y,W,H: integer; var Buf);
+var i: integer;
+begin
+ if Y+H>Size.Y then H:=Size.Y-Y;
+ if X+W>Size.X then W:=Size.X-X;
+ if Buffer=nil then WriteBuf(X,Y,W,H,Buf)
+ else for i:=1 to H do
+ Move(Buf,Buffer^[X+(Y+i-1)*Size.X],W*2);
+end;
+procedure ClearBuf;
+begin
+ MoveChar(B,' ',C1,Size.X);
+end;
+begin
+ if InDraw then Exit;
+ InDraw:=true;
+ { - Start of TGroup.Draw - }
+{ if Buffer = nil then
+ begin
+ GetBuffer;
+ end; }
+ { - Start of TGroup.Draw - }
+
+ C1:=GetColor(1);
+ C2:=(GetColor(7) and $f0 or $08)+GetColor(9)*256;
+ C3:=GetColor(8)+GetColor({9}8)*256;
+
+ { Calculate the size of the headers }
+ HeaderLen:=0;
+ for i:=0 to DefCount-1 do
+ HeaderLen:=HeaderLen+CStrLen(AtTab(i)^.Name^)+3;
+ Dec(HeaderLen);
+ if HeaderLen>Size.X-2 then HeaderLen:=Size.X-2;
+
+ { --- 1. sor --- }
+ ClearBuf;
+ MoveChar(B[0],'³',C1,1);
+ MoveChar(B[HeaderLen+1],'³',C1,1);
+ X:=1;
+ for i:=0 to DefCount-1 do
+ begin
+ Name:=AtTab(i)^.Name; X2:=CStrLen(Name^);
+ if i=ActiveDef
+ then begin
+ ActiveKPos:=X-1;
+ ActiveVPos:=X+X2+2;
+ if GetState(sfFocused) then C:=C3 else C:=C2;
+ end
+ else C:=C2;
+ MoveCStr(B[X],' '+Name^+' ',C);
+ X:=X+X2+3;
+ MoveChar(B[X-1],'³',C1,1);
+ end;
+ SWriteBuf(0,1,Size.X,1,B);
+
+ { --- 0. sor --- }
+ ClearBuf; MoveChar(B[0],'Ú',C1,1);
+ X:=1;
+ for i:=0 to DefCount-1 do
+ begin
+{$ifdef AVOIDTHREELINES}
+ if I<ActiveDef then
+ FC:='Ú'
+ else
+ FC:='¿';
+{$else not AVOIDTHREELINES}
+ FC:='Â';
+{$endif not AVOIDTHREELINES}
+ X2:=CStrLen(AtTab(i)^.Name^)+2;
+ MoveChar(B[X+X2],FC,C1,1);
+ if i=DefCount-1 then X2:=X2+1;
+ if X2>0 then
+ MoveChar(B[X],'Ä',C1,X2);
+ X:=X+X2+1;
+ end;
+ MoveChar(B[HeaderLen+1],'¿',C1,1);
+ MoveChar(B[ActiveKPos],'Ú',C1,1);
+ MoveChar(B[ActiveVPos],'¿',C1,1);
+ SWriteBuf(0,0,Size.X,1,B);
+
+ { --- 2. sor --- }
+ MoveChar(B[1],'Ä',C1,Max(HeaderLen,0));
+ MoveChar(B[HeaderLen+2],'Ä',C1,Max(Size.X-HeaderLen-3,0));
+ MoveChar(B[HeaderLen+1],LUR,C1,1);
+ MoveChar(B[ActiveKPos],'Ù',C1,1);
+ if ActiveDef=0 then
+ MoveChar(B[0],'³',C1,1)
+ else
+ MoveChar(B[0],URD,C1,1);
+ MoveChar(B[ActiveKPos+1],' ',C1,Max(ActiveVPos-ActiveKPos-1,0));
+ MoveChar(B[ActiveVPos],'À',C1,1);
+ if HeaderLen+1<Size.X-1 then
+ MoveChar(B[Size.X-1],'¿',C1,1)
+ else if (ActiveDef=DefCount-1) then
+ MoveChar(B[Size.X-1],'³',C1,1)
+ else
+ MoveChar(B[Size.X-1],UDL,C1,1);
+ SWriteBuf(0,2,Size.X,1,B);
+
+ { --- marad‚k sor --- }
+ ClearBuf; MoveChar(B[0],'³',C1,1);
+ MoveChar(B[Size.X-1],'³',C1,1);
+ {SWriteBuf(0,3,Size.X,Size.Y-4,B);}
+ for i:=3 to Size.Y-1 do
+ SWriteBuf(0,i,Size.X,1,B);
+
+ { --- Size.X . sor --- }
+ MoveChar(B[0],'À',C1,1);
+ MoveChar(B[1],'Ä',C1,Max(Size.X-2,0));
+ MoveChar(B[Size.X-1],'Ù',C1,1);
+ SWriteBuf(0,Size.Y-1,Size.X,1,B);
+
+ { - End of TGroup.Draw - }
+ if Buffer <> nil then
+ begin
+ Lock;
+ Redraw;
+ UnLock;
+ end;
+ if Buffer <> nil then
+ WriteBuf(0, 0, Size.X, Size.Y, Buffer^)
+ else
+ Redraw;
+ { - End of TGroup.Draw - }
+ InDraw:=false;
+end;
+
+function TTab.Valid(Command: Word): Boolean;
+var PT : PTabDef;
+ PI : PTabItem;
+ OK : boolean;
+begin
+ OK:=true;
+ PT:=TabDefs;
+ while (PT<>nil) and (OK=true) do
+ begin
+ PI:=PT^.Items;
+ while (PI<>nil) and (OK=true) do
+ begin
+ if PI^.View<>nil then OK:=OK and PI^.View^.Valid(Command);
+ PI:=PI^.Next;
+ end;
+ PT:=PT^.Next;
+ end;
+ Valid:=OK;
+end;
+
+
+procedure TTab.SetData(var Rec);
+type
+ Bytes = array[0..65534] of Byte;
+var
+ I: Sw_Word;
+ PT : PTabDef;
+ PI : PTabItem;
+begin
+ I := 0;
+ PT:=TabDefs;
+ while (PT<>nil) do
+ begin
+ PI:=PT^.Items;
+ while (PI<>nil) do
+ begin
+ if PI^.View<>nil then
+ begin
+ PI^.View^.SetData(Bytes(Rec)[I]);
+ Inc(I, PI^.View^.DataSize);
+ end;
+ PI:=PI^.Next;
+ end;
+ PT:=PT^.Next;
+ end;
+end;
+
+
+function TTab.DataSize: sw_word;
+var
+ I: Sw_Word;
+ PT : PTabDef;
+ PI : PTabItem;
+begin
+ I := 0;
+ PT:=TabDefs;
+ while (PT<>nil) do
+ begin
+ PI:=PT^.Items;
+ while (PI<>nil) do
+ begin
+ if PI^.View<>nil then
+ begin
+ Inc(I, PI^.View^.DataSize);
+ end;
+ PI:=PI^.Next;
+ end;
+ PT:=PT^.Next;
+ end;
+ DataSize:=i;
+end;
+
+
+procedure TTab.GetData(var Rec);
+type
+ Bytes = array[0..65534] of Byte;
+var
+ I: Sw_Word;
+ PT : PTabDef;
+ PI : PTabItem;
+begin
+ I := 0;
+ PT:=TabDefs;
+ while (PT<>nil) do
+ begin
+ PI:=PT^.Items;
+ while (PI<>nil) do
+ begin
+ if PI^.View<>nil then
+ begin
+ PI^.View^.GetData(Bytes(Rec)[I]);
+ Inc(I, PI^.View^.DataSize);
+ end;
+ PI:=PI^.Next;
+ end;
+ PT:=PT^.Next;
+ end;
+end;
+
+
+procedure TTab.SetState(AState: Word; Enable: Boolean);
+var
+ LastV : PView;
+begin
+ inherited SetState(AState,Enable);
+ { Select first item }
+ if (AState and sfSelected)<>0 then
+ begin
+ LastV:=LastSelectable;
+ if LastV<>nil then
+ LastV^.Select;
+ end;
+end;
+
+destructor TTab.Done;
+var P,X: PTabDef;
+procedure DeleteViews(P: PView); {$ifndef FPC}far;{$endif}
+begin
+ if P<>nil then Delete(P);
+end;
+begin
+ ForEach(@DeleteViews);
+ inherited Done;
+ P:=TabDefs;
+ while P<>nil do
+ begin
+ X:=P^.Next;
+ DisposeTabDef(P);
+ P:=X;
+ end;
+end;
+
+
+function NewTabItem(AView: PView; ANext: PTabItem): PTabItem;
+var P: PTabItem;
+begin
+ New(P); FillChar(P^,SizeOf(P^),0);
+ P^.Next:=ANext; P^.View:=AView;
+ NewTabItem:=P;
+end;
+
+procedure DisposeTabItem(P: PTabItem);
+begin
+ if P<>nil then
+ begin
+ if P^.View<>nil then Dispose(P^.View, Done);
+ Dispose(P);
+ end;
+end;
+
+function NewTabDef(AName: string; ADefItem: PView; AItems: PTabItem; ANext: PTabDef): PTabDef;
+var P: PTabDef;
+ x: byte;
+begin
+ New(P);
+ P^.Next:=ANext; P^.Name:=NewStr(AName); P^.Items:=AItems;
+ x:=pos('~',AName);
+ if (x<>0) and (x<length(AName)) then P^.ShortCut:=Upcase(AName[x+1])
+ else P^.ShortCut:=#0;
+ P^.DefItem:=ADefItem;
+ NewTabDef:=P;
+end;
+
+procedure DisposeTabDef(P: PTabDef);
+var PI,X: PTabItem;
+begin
+ DisposeStr(P^.Name);
+ PI:=P^.Items;
+ while PI<>nil do
+ begin
+ X:=PI^.Next;
+ DisposeTabItem(PI);
+ PI:=X;
+ end;
+ Dispose(P);
+end;
+
+procedure RegisterTab;
+begin
+ RegisterType (RTab);
+end;
+
+
+begin
+ RegisterTab;
+end.
diff --git a/packages/fv/src/time.pas b/packages/fv/src/time.pas
new file mode 100644
index 0000000000..8d685be458
--- /dev/null
+++ b/packages/fv/src/time.pas
@@ -0,0 +1,465 @@
+{*********************[ TIME UNIT ]************************}
+{ }
+{ System independent TIME unit }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@starwon.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ - Speed Pascal 1.0+ (32 Bit) }
+{ - C'T patch to BP (16 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 06 Dec 96 First multi platform release. }
+{ 1.10 06 Jul 97 New functiions added. }
+{ 1.20 22 Jul 97 FPC pascal compiler added. }
+{ 1.30 29 Aug 97 Platform.inc sort added. }
+{ 1.40 13 Oct 97 Delphi 2/3 32 bit code added. }
+{ 1.50 06 Nov 97 Speed pascal code added. }
+{ 1.60 05 May 98 Virtual pascal 2.0 compiler added. }
+{ 1.61 07 Jul 99 Speedsoft SYBIL 2.0 code added. }
+{**********************************************************}
+
+UNIT Time;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC} { FPC doesn't support these switches }
+ {$F-} { Short calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$E+} { Emulation is on }
+ {$N-} { No 80x87 code generation }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{-CurrentMinuteOfDay-------------------------------------------------
+Returns the number of minutes since midnight of a current system time.
+19Jun97 LdB (Range: 0 - 1439)
+---------------------------------------------------------------------}
+FUNCTION CurrentMinuteOfDay: Word;
+
+{-CurrentSecondOfDay-------------------------------------------------
+Returns the number of seconds since midnight of current system time.
+24Jun97 LdB (Range: 0 - 86399)
+---------------------------------------------------------------------}
+FUNCTION CurrentSecondOfDay: LongInt;
+
+{-CurrentSec100OfDay-------------------------------------------------
+Returns the 1/100ths of a second since midnight of current system time.
+24Jun97 LdB (Range: 0 - 8639999)
+---------------------------------------------------------------------}
+FUNCTION CurrentSec100OfDay: LongInt;
+
+{-MinuteOfDay--------------------------------------------------------
+Returns the number of minutes since midnight of a valid given time.
+19Jun97 LdB (Range: 0 - 1439)
+---------------------------------------------------------------------}
+FUNCTION MinuteOfDay (Hour24, Minute: Word): Word;
+
+{-SecondOfDay--------------------------------------------------------
+Returns the number of seconds since midnight of a valid given time.
+19Jun97 LdB (Range: 0 - 86399)
+---------------------------------------------------------------------}
+FUNCTION SecondOfDay (Hour24, Minute, Second: Word): LongInt;
+
+{-SetTime------------------------------------------------------------
+Set the operating systems time clock to the given values. If values
+are invalid this function will fail without notification.
+06Nov97 LdB
+---------------------------------------------------------------------}
+PROCEDURE SetTime (Hour, Minute, Second, Sec100: Word);
+
+{-GetTime------------------------------------------------------------
+Returns the current time settings of the operating system.
+06Nov97 LdB
+---------------------------------------------------------------------}
+PROCEDURE GetTime (Var Hour, Minute, Second, Sec100: Word);
+
+{-MinutesToTime------------------------------------------------------
+Returns the time in hours and minutes of a given number of minutes.
+19Jun97 LdB
+---------------------------------------------------------------------}
+PROCEDURE MinutesToTime (Md: LongInt; Var Hour24, Minute: Word);
+
+{-SecondsToTime------------------------------------------------------
+Returns the time in hours, mins and secs of a given number of seconds.
+19Jun97 LdB
+---------------------------------------------------------------------}
+PROCEDURE SecondsToTime (Sd: LongInt; Var Hour24, Minute, Second: Word);
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+{$IFDEF OS_WINDOWS} { WIN/NT CODE }
+
+ {$IFNDEF PPC_SPEED} { NON SPEED COMPILER }
+ {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
+ USEs Windows; { Standard unit }
+ {$ELSE} { OTHER COMPILERS }
+ USES WinTypes, WinProcs; { Standard units }
+ {$ENDIF}
+ {$ELSE} { SPEEDSOFT COMPILER }
+ USES WinBase; { Standard unit }
+ TYPE TSystemTime = SystemTime; { Type fix up }
+ {$ENDIF}
+
+{$ENDIF}
+
+{$IFDEF OS_OS2} { OS2 COMPILERS }
+
+ {$IFDEF PPC_VIRTUAL} { VIRTUAL PASCAL }
+ USES OS2Base; { Standard unit }
+ {$ENDIF}
+
+ {$IFDEF PPC_SPEED} { SPEED PASCAL }
+ USES BseDos, Os2Def; { Standard unit }
+ {$ENDIF}
+
+ {$IFDEF PPC_FPC} { FPC }
+ USES Dos, DosCalls; { Standard unit }
+
+ TYPE DateTime = TDateTime; { Type correction }
+ {$ENDIF}
+
+ {$IFDEF PPC_BPOS2} { C'T PATCH TO BP CODE }
+ USES DosTypes, DosProcs; { Standard unit }
+
+ TYPE DateTime = TDateTime; { Type correction }
+ {$ENDIF}
+
+{$ENDIF}
+
+{$ifdef OS_UNIX}
+ USES Dos;
+{$endif OS_UNIX}
+
+{$ifdef OS_GO32}
+ USES Dos;
+{$endif OS_GO32}
+
+{$ifdef OS_NETWARE}
+ USES Dos;
+{$endif OS_GO32}
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ CurrentMinuteOfDay -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Jun97 LdB}
+{---------------------------------------------------------------------------}
+FUNCTION CurrentMinuteOfDay: Word;
+VAR Hour, Minute, Second, Sec100: Word;
+BEGIN
+ GetTime(Hour, Minute, Second, Sec100); { Get current time }
+ CurrentMinuteOfDay := (Hour * 60) + Minute; { Minute from midnight }
+END;
+
+{---------------------------------------------------------------------------}
+{ CurrentSecondOfDay -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Jun97 LdB}
+{---------------------------------------------------------------------------}
+FUNCTION CurrentSecondOfDay: LongInt;
+VAR Hour, Minute, Second, Sec100: Word;
+BEGIN
+ GetTime(Hour, Minute, Second, Sec100); { Get current time }
+ CurrentSecondOfDay := (LongInt(Hour) * 3600) +
+ (Minute * 60) + Second; { Second from midnight }
+END;
+
+{---------------------------------------------------------------------------}
+{ CurrentSec100OfDay -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Jun97 LdB}
+{---------------------------------------------------------------------------}
+FUNCTION CurrentSec100OfDay: LongInt;
+VAR Hour, Minute, Second, Sec100: Word;
+BEGIN
+ GetTime(Hour, Minute, Second, Sec100); { Get current time }
+ CurrentSec100OfDay := (LongInt(Hour) * 360000) +
+ (LongInt(Minute) * 6000) + (Second*100)+ Sec100; { Sec100 from midnight }
+END;
+
+{---------------------------------------------------------------------------}
+{ MinuteOfDay -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Jun97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION MinuteOfDay (Hour24, Minute: Word): Word;
+BEGIN
+ MinuteOfDay := (Hour24 * 60) + Minute; { Minute from midnight }
+END;
+
+{---------------------------------------------------------------------------}
+{ SecondOfDay -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Jun97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION SecondOfDay (Hour24, Minute, Second: Word): LongInt;
+BEGIN
+ SecondOfDay := (LongInt(Hour24) * 3600) +
+ (Minute * 60) + Second; { Second from midnight }
+END;
+
+{---------------------------------------------------------------------------}
+{ SetTime -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Nov97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SetTime (Hour, Minute, Second, Sec100: Word);
+{$IFDEF OS_DOS} { DOS/DPMI CODE }
+ {$IFDEF ASM_BP} { BP COMPATABLE ASM }
+ ASSEMBLER;
+ ASM
+ MOV CH, BYTE PTR Hour; { Fetch hour }
+ MOV CL, BYTE PTR Minute; { Fetch minute }
+ MOV DH, BYTE PTR Second; { Fetch second }
+ MOV DL, BYTE PTR Sec100; { Fetch hundredths }
+ MOV AX, $2D00; { Set function id }
+ PUSH BP; { Safety save register }
+ INT $21; { Set the time }
+ POP BP; { Restore register }
+ END;
+ {$ENDIF}
+ {$IFDEF ASM_FPC} { FPC COMPATABLE ASM }
+ BEGIN
+ ASM
+ MOVB Hour, %CH; { Fetch hour }
+ MOVB Minute, %CL; { Fetch minute }
+ MOVB Second, %DH; { Fetch second }
+ MOVB Sec100, %DL; { Fetch hundredths }
+ MOVW $0x2D00, %AX; { Set function id }
+ PUSHL %EBP; { Save register }
+ INT $0x21; { BIOS set time }
+ POPL %EBP; { Restore register }
+ END;
+ END;
+ {$ENDIF}
+{$ENDIF}
+{$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ {$IFDEF BIT_16} { 16 BIT WINDOWS CODE }
+ ASSEMBLER;
+ ASM
+ MOV CH, BYTE PTR Hour; { Fetch hour }
+ MOV CL, BYTE PTR Minute; { Fetch minute }
+ MOV DH, BYTE PTR Second; { Fetch second }
+ MOV DL, BYTE PTR Sec100; { Fetch hundredths }
+ MOV AX, $2D00; { Set function id }
+ PUSH BP; { Safety save register }
+ INT $21; { Set the time }
+ POP BP; { Restore register }
+ END;
+ {$ENDIF}
+ {$IFDEF BIT_32} { 32 BIT WINDOWS CODE }
+ VAR DT: TSystemTime;
+ BEGIN
+ {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
+ GetLocalTime(@DT); { Get the date/time }
+ {$ELSE} { OTHER COMPILERS }
+ GetLocalTime(DT); { Get the date/time }
+ {$ENDIF}
+ DT.wHour := Hour; { Transfer hour }
+ DT.wMinute := Minute; { Transfer minute }
+ DT.wSecond := Second; { Transfer seconds }
+ DT.wMilliseconds := Sec100 * 10; { Transfer millisecs }
+ SetLocalTime(DT); { Set the date/time }
+ END;
+ {$ENDIF}
+{$ENDIF}
+{$IFDEF OS_OS2} { OS2 CODE }
+VAR DT: DateTime;
+BEGIN
+ DosGetDateTime(DT); { Get the date/time }
+ DT.Hours := Hour; { Transfer hour }
+ DT.Minutes := Minute; { Transfer minute }
+ DT.Seconds := Second; { Transfer seconds }
+ DT.Hundredths := Sec100; { Transfer hundredths }
+ DosSetDateTime(DT); { Set the time }
+END;
+{$ENDIF}
+{$ifdef OS_UNIX}
+BEGIN
+ {settime is dummy in Linux}
+END;
+{$endif OS_UNIX}
+{$IFDEF OS_NETWARE}
+BEGIN
+ {settime is dummy in Netware (Libc and Clib) }
+END;
+{$ENDIF OS_NETWARE}
+
+{---------------------------------------------------------------------------}
+{ GetTime -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Nov97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE GetTime (Var Hour, Minute, Second, Sec100: Word);
+{$IFDEF OS_DOS} { DOS/DPMI CODE }
+ {$IFDEF ASM_BP} { BP COMPATABLE ASM }
+ ASSEMBLER;
+ ASM
+ MOV AX, $2C00; { Set function id }
+ PUSH BP; { Safety save register }
+ INT $21; { System get time }
+ POP BP; { Restore register }
+ XOR AH, AH; { Clear register }
+ CLD; { Strings go forward }
+ MOV AL, DL; { Transfer register }
+ LES DI, Sec100; { ES:DI -> hundredths }
+ STOSW; { Return hundredths }
+ MOV AL, DH; { Transfer register }
+ LES DI, Second; { ES:DI -> seconds }
+ STOSW; { Return seconds }
+ MOV AL, CL; { Transfer register }
+ LES DI, Minute; { ES:DI -> minutes }
+ STOSW; { Return minutes }
+ MOV AL, CH; { Transfer register }
+ LES DI, Hour; { ES:DI -> hours }
+ STOSW; { Return hours }
+ END;
+ {$ENDIF}
+ {$IFDEF OS_GO32} { FPC COMPATABLE ASM }
+ BEGIN
+ (* ASM
+ MOVW $0x2C00, %AX; { Set function id }
+ PUSHL %EBP; { Save register }
+ INT $0x21; { System get time }
+ POPL %EBP; { Restore register }
+ XORB %AH, %AH; { Clear register }
+ MOVB %DL, %AL; { Transfer register }
+ MOVL Sec100, %EDI; { EDI -> Sec100 }
+ MOVW %AX, (%EDI); { Return Sec100 }
+ MOVB %DH, %AL; { Transfer register }
+ MOVL Second, %EDI; { EDI -> Second }
+ MOVW %AX, (%EDI); { Return Second }
+ MOVB %CL, %AL; { Transfer register }
+ MOVL Minute, %EDI; { EDI -> Minute }
+ MOVW %AX, (%EDI); { Return minute }
+ MOVB %CH, %AL; { Transfer register }
+ MOVL Hour, %EDI; { EDI -> Hour }
+ MOVW %AX, (%EDI); { Return hour }
+ END; *)
+ { direct call of real interrupt seems to render the system
+ unstable on Win2000 because some registers are not properly
+ restored if a mouse interrupt is generated while the Dos
+ interrupt is called... PM }
+ Dos.GetTime(Hour,Minute,Second,Sec100);
+ END;
+ {$ENDIF}
+{$ENDIF}
+{$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ {$IFDEF BIT_16} { 16 BIT WINDOWS CODE }
+ ASSEMBLER;
+ ASM
+ MOV AX, $2C00; { Set function id }
+ PUSH BP; { Safety save register }
+ INT $21; { System get time }
+ POP BP; { Restore register }
+ XOR AH, AH; { Clear register }
+ CLD; { Strings go forward }
+ MOV AL, DL; { Transfer register }
+ LES DI, Sec100; { ES:DI -> hundredths }
+ STOSW; { Return hundredths }
+ MOV AL, DH; { Transfer register }
+ LES DI, Second; { ES:DI -> seconds }
+ STOSW; { Return seconds }
+ MOV AL, CL; { Transfer register }
+ LES DI, Minute; { ES:DI -> minutes }
+ STOSW; { Return minutes }
+ MOV AL, CH; { Transfer register }
+ LES DI, Hour; { ES:DI -> hours }
+ STOSW; { Return hours }
+ END;
+ {$ENDIF}
+ {$IFDEF BIT_32} { 32 BIT WINDOWS CODE }
+ VAR DT: TSystemTime;
+ BEGIN
+ {$IFDEF PPC_FPC} { FPC WINDOWS COMPILER }
+ GetLocalTime(@DT); { Get the date/time }
+ {$ELSE} { OTHER COMPILERS }
+ GetLocalTime(DT); { Get the date/time }
+ {$ENDIF}
+ Hour := DT.wHour; { Transfer hour }
+ Minute := DT.wMinute; { Transfer minute }
+ Second := DT.wSecond; { Transfer seconds }
+ Sec100 := DT.wMilliseconds DIV 10; { Transfer hundredths }
+ END;
+ {$ENDIF}
+{$ENDIF}
+{$IFDEF OS_OS2} { OS2 CODE }
+VAR DT: DateTime;
+BEGIN
+ DosGetDateTime(DT); { Get the date/time }
+ Hour := DT.Hours; { Transfer hour }
+ Minute := DT.Minutes; { Transfer minute }
+ Second := DT.Seconds; { Transfer seconds }
+ Sec100 := DT.Hundredths; { Transfer hundredths }
+END;
+{$ENDIF}
+{$ifdef OS_UNIX}
+BEGIN
+ Dos.GetTime(Hour,Minute,Second,Sec100);
+END;
+{$endif OS_UNIX}
+{$IFDEF OS_NETWARE}
+BEGIN
+ Dos.GetTime(Hour,Minute,Second,Sec100);
+END;
+{$ENDIF OS_NETWARE}
+
+{---------------------------------------------------------------------------}
+{ MinutesToTime -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Jun97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE MinutesToTime (Md: LongInt; Var Hour24, Minute: Word);
+BEGIN
+ Hour24 := Md DIV 60; { Hours of time }
+ Minute := Md MOD 60; { Minutes of time }
+END;
+
+{---------------------------------------------------------------------------}
+{ SecondsToTime -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Jun97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SecondsToTime (Sd: LongInt; Var Hour24, Minute, Second: Word);
+BEGIN
+ Hour24 := Sd DIV 3600; { Hours of time }
+ Minute := Sd MOD 3600 DIV 60; { Minutes of time }
+ Second := Sd MOD 60; { Seconds of time }
+END;
+
+END.
diff --git a/packages/fv/src/timeddlg.pas b/packages/fv/src/timeddlg.pas
new file mode 100644
index 0000000000..9a24ee9cd9
--- /dev/null
+++ b/packages/fv/src/timeddlg.pas
@@ -0,0 +1,254 @@
+{
+
+ Timed dialogs for Free Vision
+
+ Copyright (c) 2004 by Free Pascal core team
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************}
+UNIT timeddlg;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Near calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES objects, dialogs, fvconsts, drivers, views; { Standard GFV unit }
+
+type
+ TTimedDialog = object (TDialog)
+ Secs: longint;
+ constructor Init (var Bounds: TRect; ATitle: TTitleStr; ASecs: word);
+ constructor Load (var S: TStream);
+ procedure GetEvent (var Event: TEvent); virtual;
+ procedure Store (var S: TStream); virtual;
+ private
+ Secs0: longint;
+ Secs2: longint;
+ DayWrap: boolean;
+ end;
+ PTimedDialog = ^TTimedDialog;
+
+(* Must be always included in TTimeDialog! *)
+ TTimedDialogText = object (TStaticText)
+ constructor Init (var Bounds: TRect);
+ procedure GetText (var S: string); virtual;
+ end;
+ PTimedDialogText = ^TTimedDialogText;
+
+const
+ RTimedDialog: TStreamRec = (
+ ObjType: idTimedDialog;
+{$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs (TypeOf (TTimedDialog)^);
+{$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf (TTimedDialog);
+{$ENDIF BP_VMTLink}
+ Load: @TTimedDialog.Load;
+ Store: @TTimedDialog.Store
+ );
+
+ RTimedDialogText: TStreamRec = (
+ ObjType: idTimedDialogText;
+{$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs (TypeOf (TTimedDialogText)^);
+{$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf (TTimedDialogText);
+{$ENDIF BP_VMTLink}
+ Load: @TTimedDialogText.Load;
+ Store: @TTimedDialogText.Store
+ );
+
+procedure RegisterTimedDialog;
+
+FUNCTION TimedMessageBox (Const Msg: String; Params: Pointer;
+ AOptions: Word; ASecs: Word): Word;
+
+{-TimedMessageBoxRect------------------------------------------------
+TimedMessageBoxRect allows the specification of a TRect for the message box
+to occupy.
+---------------------------------------------------------------------}
+FUNCTION TimedMessageBoxRect (Var R: TRect; Const Msg: String; Params: Pointer;
+ AOptions: Word; ASecs: Word): Word;
+
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+USES
+ dos,
+ app, {resource,} msgbox; { Standard GFV units }
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+constructor TTimedDialogText.Init (var Bounds: TRect);
+begin
+ inherited Init (Bounds, '');
+end;
+
+
+procedure TTimedDialogText.GetText (var S: string);
+begin
+ if Owner <> nil
+(* and (TypeOf (Owner^) = TypeOf (TTimedDialog)) *)
+ then
+ begin
+ Str (PTimedDialog (Owner)^.Secs, S);
+ S := #3 + S;
+ end
+ else
+ S := '';
+end;
+
+
+
+constructor TTimedDialog.Init (var Bounds: TRect; ATitle: TTitleStr;
+ ASecs: word);
+var
+ H, M, S, S100: word;
+begin
+ inherited Init (Bounds, ATitle);
+ GetTime (H, M, S, S100);
+ Secs0 := H * 3600 + M * 60 + S;
+ Secs2 := Secs0 + ASecs;
+ Secs := ASecs;
+ DayWrap := Secs2 > 24 * 3600;
+end;
+
+
+procedure TTimedDialog.GetEvent (var Event: TEvent);
+var
+ H, M, S, S100: word;
+ Secs1: longint;
+begin
+ inherited GetEvent (Event);
+ GetTime (H, M, S, S100);
+ Secs1 := H * 3600 + M * 60 + S;
+ if DayWrap then Inc (Secs1, 24 * 3600);
+ if Secs2 - Secs1 <> Secs then
+ begin
+ Secs := Secs2 - Secs1;
+ if Secs < 0 then
+ Secs := 0;
+(* If remaining seconds are displayed in one of included views, update them. *)
+ Redraw;
+ end;
+ with Event do
+ if (Secs = 0) and (What = evNothing) then
+ begin
+ What := evCommand;
+ Command := cmCancel;
+ end;
+end;
+
+
+constructor TTimedDialog.Load (var S: TStream);
+begin
+ inherited Load (S);
+ S.Read (Secs, SizeOf (Secs));
+ S.Read (Secs0, SizeOf (Secs0));
+ S.Read (Secs2, SizeOf (Secs2));
+ S.Read (DayWrap, SizeOf (DayWrap));
+end;
+
+
+procedure TTimedDialog.Store (var S: TStream);
+begin
+ inherited Store (S);
+ S.Write (Secs, SizeOf (Secs));
+ S.Write (Secs0, SizeOf (Secs0));
+ S.Write (Secs2, SizeOf (Secs2));
+ S.Write (DayWrap, SizeOf (DayWrap));
+end;
+
+
+
+function TimedMessageBox (const Msg: string; Params: pointer;
+ AOptions: word; ASecs: word): word;
+var
+ R: TRect;
+begin
+ R.Assign(0, 0, 40, 10); { Assign area }
+ if (AOptions AND mfInsertInApp = 0) then { Non app insert }
+ R.Move((Desktop^.Size.X - R.B.X) div 2,
+ (Desktop^.Size.Y - R.B.Y) div 2) { Calculate position }
+ else
+ R.Move((Application^.Size.X - R.B.X) div 2,
+ (Application^.Size.Y - R.B.Y) div 2); { Calculate position }
+ TimedMessageBox := TimedMessageBoxRect (R, Msg, Params,
+ AOptions, ASecs); { Create message box }
+end;
+
+
+function TimedMessageBoxRect (var R: TRect; const Msg: string; Params: pointer;
+ AOptions: word; ASecs: word): word;
+var
+ Dlg: PTimedDialog;
+ TimedText: PTimedDialogText;
+begin
+ Dlg := New (PTimedDialog, Init (R, MsgBoxTitles [AOptions
+ and $3], ASecs)); { Create dialog }
+ with Dlg^ do
+ begin
+ R.Assign (3, Size.Y - 5, Size.X - 2, Size.Y - 4);
+ New (TimedText, Init (R));
+ Insert (TimedText);
+ R.Assign (3, 2, Size.X - 2, Size.Y - 5); { Assign area for text }
+ end;
+ TimedMessageBoxRect := MessageBoxRectDlg (Dlg, R, Msg, Params, AOptions);
+ Dispose (Dlg, Done); { Dispose of dialog }
+end;
+
+
+
+procedure RegisterTimedDialog;
+begin
+ RegisterType (RTimedDialog);
+ RegisterType (RTimedDialogText);
+end;
+
+
+begin
+ RegisterTimedDialog;
+end.
diff --git a/packages/fv/src/unixsmsg.inc b/packages/fv/src/unixsmsg.inc
new file mode 100644
index 0000000000..7872ebafe8
--- /dev/null
+++ b/packages/fv/src/unixsmsg.inc
@@ -0,0 +1,126 @@
+{
+ System dependent system messages for unix
+
+ Copyright (c) 2002 by Pierre Muller
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+
+{ This file is still a dummy,
+ it should use ioctl to get information about resizing of windows }
+
+uses
+{$ifdef VER1_0}
+ linux;
+{$else}
+ BaseUnix,termio;
+{$endif}
+
+Const
+ SystemEventActive : Boolean = false;
+
+var
+ lastxsize,lastysize : longint;
+
+procedure InitSystemMsg;
+var
+ WinSize : TWinSize;
+begin
+ If SystemEventActive then
+ exit;
+ { Code to enable size tracking should go here }
+ PendingSystemHead:=@PendingSystemEvent;
+ PendingSystemTail:=@PendingSystemEvent;
+ PendingSystemEvents:=0;
+ FillChar(LastSystemEvent,sizeof(TSystemEvent),0);
+ FillChar(WinSize,sizeof(WinSize),0);
+{$ifdef VER1_0}
+ ioctl(stdinputhandle,TIOCGWINSZ,@winsize);
+{$else}
+ fpioctl(stdinputhandle,TIOCGWINSZ,@winsize);
+{$endif}
+ LastXSize:=WinSize.ws_row;
+ LastYSize:=WinSize.ws_col;
+ If LastXSize=0 then
+ LastXSize:=80;
+ If LastYSize=0 then
+ LastYSize:=25;
+
+ SystemEventActive:=true;
+end;
+
+
+procedure DoneSystemMsg;
+begin
+ if not SystemEventActive then
+ exit;
+ { Code to disable size tracking should go here }
+ SystemEventActive:=false;
+end;
+
+procedure GetSystemEvent(var SystemEvent: TSystemEvent);
+begin
+ if PendingSystemEvents=0 then
+ PollSystemEvent(SystemEvent);
+ if PendingSystemEvents=0 then
+ exit;
+ SystemEvent:=PendingSystemHead^;
+ inc(PendingSystemHead);
+ if longint(PendingSystemHead)=longint(@PendingSystemEvent)+sizeof(PendingSystemEvent) then
+ PendingSystemHead:=@PendingSystemEvent;
+ dec(PendingSystemEvents);
+ LastSystemEvent:=SystemEvent;
+end;
+
+
+function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
+var
+ CloseState : word;
+ WinSize : TWinSize;
+begin
+ SystemEvent.typ:=SysNothing;
+ if not SystemEventActive then
+ exit(false);
+ if PendingSystemEvents>0 then
+ begin
+ SystemEvent:=PendingSystemHead^;
+ PollSystemEvent:=true;
+ end
+ else
+ begin
+ FillChar(WinSize,sizeof(WinSize),0);
+{$ifdef VER1_0}
+ ioctl(stdinputhandle,TIOCGWINSZ,@winsize);
+{$else}
+ fpioctl(stdinputhandle,TIOCGWINSZ,@winsize);
+{$endif}
+ if (winsize.ws_col<>0) and (winsize.ws_row<>0) and
+ ((winsize.ws_row<>lastxsize) or (winsize.ws_col<>lastysize)) then
+ begin
+ SystemEvent.typ:=SysResize;
+ SystemEvent.x:=WinSize.ws_col;
+ SystemEvent.y:=WinSize.ws_row;
+ PutSystemEvent(SystemEvent);
+ LastXSize:=WinSize.ws_row;
+ LastYSize:=WinSize.ws_col;
+ PollSystemEvent:=true;
+ end
+ else
+ PollSystemEvent:=false;
+ end;
+end;
+
diff --git a/packages/fv/src/validate.pas b/packages/fv/src/validate.pas
new file mode 100644
index 0000000000..e4ed9a5be3
--- /dev/null
+++ b/packages/fv/src/validate.pas
@@ -0,0 +1,1048 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of VALIDATE.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@ibm.net }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ 16 and 32 Bit compilers }
+{ DOS - Turbo Pascal 7.0 + (16 Bit) }
+{ DPMI - Turbo Pascal 7.0 + (16 Bit) }
+{ - FPC 0.9912+ (GO32V2) (32 Bit) }
+{ WINDOWS - Turbo Pascal 7.0 + (16 Bit) }
+{ - Delphi 1.0+ (16 Bit) }
+{ WIN95/NT - Delphi 2.0+ (32 Bit) }
+{ - Virtual Pascal 2.0+ (32 Bit) }
+{ - Speedsoft Sybil 2.0+ (32 Bit) }
+{ - FPC 0.9912+ (32 Bit) }
+{ OS2 - Virtual Pascal 1.0+ (32 Bit) }
+{ }
+{******************[ REVISION HISTORY ]********************}
+{ Version Date Fix }
+{ ------- --------- --------------------------------- }
+{ 1.00 12 Jun 96 Initial DOS/DPMI code released. }
+{ 1.10 29 Aug 97 Platform.inc sort added. }
+{ 1.20 13 Oct 97 Delphi3 32 bit code added. }
+{ 1.30 11 May 98 Virtual pascal 2.0 code added. }
+{ 1.40 10 Jul 99 Sybil 2.0 code added }
+{ 1.41 03 Nov 99 FPC windows code added }
+{**********************************************************}
+
+UNIT Validate;
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$IFNDEF PPC_FPC}{ FPC doesn't support these switches }
+ {$F-} { Short calls are okay }
+ {$A+} { Word Align Data }
+ {$B-} { Allow short circuit boolean evaluations }
+ {$O+} { This unit may be overlaid }
+ {$G+} { 286 Code optimization - if you're on an 8088 get a real computer }
+ {$P-} { Normal string variables }
+ {$N-} { No 80x87 code generation }
+ {$E+} { Emulation is on }
+{$ENDIF}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES FVCommon, Objects, fvconsts; { GFV standard units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ VALIDATOR STATUS CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ vsOk = 0; { Validator ok }
+ vsSyntax = 1; { Validator sytax err }
+
+{---------------------------------------------------------------------------}
+{ VALIDATOR OPTION MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ voFill = $0001; { Validator fill }
+ voTransfer = $0002; { Validator transfer }
+ voOnAppend = $0004; { Validator append }
+ voReserved = $00F8; { Clear above flags }
+
+{***************************************************************************}
+{ RECORD DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ VALIDATOR TRANSFER CONSTANTS }
+{---------------------------------------------------------------------------}
+TYPE
+ TVTransfer = (vtDataSize, vtSetData, vtGetData); { Transfer states }
+
+{---------------------------------------------------------------------------}
+{ PICTURE VALIDATOR RESULT CONSTANTS }
+{---------------------------------------------------------------------------}
+TYPE
+ TPicResult = (prComplete, prIncomplete, prEmpty, prError, prSyntax,
+ prAmbiguous, prIncompNoFill);
+
+{***************************************************************************}
+{ OBJECT DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TValidator OBJECT - VALIDATOR ANCESTOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TValidator = OBJECT (TObject)
+ Status : Word; { Validator status }
+ Options: Word; { Validator options }
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION Valid(CONST S: String): Boolean;
+ FUNCTION IsValid (CONST S: String): Boolean; Virtual;
+ FUNCTION IsValidInput (Var S: String;
+ SuppressFill: Boolean): Boolean; Virtual;
+ FUNCTION Transfer (Var S: String; Buffer: Pointer;
+ Flag: TVTransfer): Word; Virtual;
+ PROCEDURE Error; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PValidator = ^TValidator;
+
+{---------------------------------------------------------------------------}
+{ TPictureValidator OBJECT - PICTURE VALIDATOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TPXPictureValidator = OBJECT (TValidator)
+ Pic: PString; { Picture filename }
+ CONSTRUCTOR Init (Const APic: String; AutoFill: Boolean);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION IsValid (Const S: String): Boolean; Virtual;
+ FUNCTION IsValidInput (Var S: String;
+ SuppressFill: Boolean): Boolean; Virtual;
+ FUNCTION Picture (Var Input: String;
+ AutoFill: Boolean): TPicResult; Virtual;
+ PROCEDURE Error; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PPXPictureValidator = ^TPXPictureValidator;
+
+TYPE CharSet = TCharSet;
+
+{---------------------------------------------------------------------------}
+{ TFilterValidator OBJECT - FILTER VALIDATOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TFilterValidator = OBJECT (TValidator)
+ ValidChars: CharSet; { Valid char set }
+ CONSTRUCTOR Init (AValidChars: CharSet);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION IsValid (CONST S: String): Boolean; Virtual;
+ FUNCTION IsValidInput (Var S: String;
+ SuppressFill: Boolean): Boolean; Virtual;
+ PROCEDURE Error; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PFilterValidator = ^TFilterValidator;
+
+{---------------------------------------------------------------------------}
+{ TRangeValidator OBJECT - RANGE VALIDATOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TRangeValidator = OBJECT (TFilterValidator)
+ Min: LongInt; { Min valid value }
+ Max: LongInt; { Max valid value }
+ CONSTRUCTOR Init(AMin, AMax: LongInt);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION IsValid (Const S: String): Boolean; Virtual;
+ FUNCTION Transfer (Var S: String; Buffer: Pointer;
+ Flag: TVTransfer): Word; Virtual;
+ PROCEDURE Error; Virtual;
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PRangeValidator = ^TRangeValidator;
+
+{---------------------------------------------------------------------------}
+{ TLookUpValidator OBJECT - LOOKUP VALIDATOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TLookupValidator = OBJECT (TValidator)
+ FUNCTION IsValid (Const S: String): Boolean; Virtual;
+ FUNCTION Lookup (Const S: String): Boolean; Virtual;
+ END;
+ PLookupValidator = ^TLookupValidator;
+
+{---------------------------------------------------------------------------}
+{ TStringLookUpValidator OBJECT - STRING LOOKUP VALIDATOR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TStringLookupValidator = OBJECT (TLookupValidator)
+ Strings: PStringCollection;
+ CONSTRUCTOR Init (AStrings: PStringCollection);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION Lookup (Const S: String): Boolean; Virtual;
+ PROCEDURE Error; Virtual;
+ PROCEDURE NewStringList (AStrings: PStringCollection);
+ PROCEDURE Store (Var S: TStream);
+ END;
+ PStringLookupValidator = ^TStringLookupValidator;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{-RegisterValidate---------------------------------------------------
+Calls RegisterType for each of the object types defined in this unit.
+18May98 LdB
+---------------------------------------------------------------------}
+PROCEDURE RegisterValidate;
+
+{***************************************************************************}
+{ OBJECT REGISTRATION }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TPXPictureValidator STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RPXPictureValidator: TStreamRec = (
+ ObjType: idPXPictureValidator; { Register id = 80 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TPXPictureValidator)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TPXPictureValidator);
+ {$ENDIF}
+ Load: @TPXPictureValidator.Load; { Object load method }
+ Store: @TPXPictureValidator.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TFilterValidator STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RFilterValidator: TStreamRec = (
+ ObjType: idFilterValidator; { Register id = 81 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TFilterValidator)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TFilterValidator);
+ {$ENDIF}
+ Load: @TFilterValidator.Load; { Object load method }
+ Store: @TFilterValidator.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TRangeValidator STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RRangeValidator: TStreamRec = (
+ ObjType: idRangeValidator; { Register id = 82 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TRangeValidator)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TRangeValidator);
+ {$ENDIF}
+ Load: @TRangeValidator.Load; { Object load method }
+ Store: @TRangeValidator.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TStringLookupValidator STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RStringLookupValidator: TStreamRec = (
+ ObjType: idStringLookupValidator; { Register id = 83 }
+ {$IFDEF BP_VMTLink} { BP style VMT link }
+ VmtLink: Ofs(TypeOf(TStringLookupValidator)^);
+ {$ELSE} { Alt style VMT link }
+ VmtLink: TypeOf(TStringLookupValidator);
+ {$ENDIF}
+ Load: @TStringLookupValidator.Load; { Object load method }
+ Store: @TStringLookupValidator.Store { Object store method }
+ );
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+USES MsgBox; { GFV standard unit }
+
+{***************************************************************************}
+{ PRIVATE ROUTINES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ IsLetter -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION IsLetter (Chr: Char): Boolean;
+BEGIN
+ Chr := Char(Ord(Chr) AND $DF); { Lower to upper case }
+ If (Chr >= 'A') AND (Chr <='Z') Then { Check if A..Z }
+ IsLetter := True Else IsLetter := False; { Return result }
+END;
+
+{---------------------------------------------------------------------------}
+{ IsComplete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION IsComplete (Rslt: TPicResult): Boolean;
+BEGIN
+ IsComplete := Rslt IN [prComplete, prAmbiguous]; { Return if complete }
+END;
+
+{---------------------------------------------------------------------------}
+{ IsInComplete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION IsIncomplete (Rslt: TPicResult): Boolean;
+BEGIN
+ IsIncomplete := Rslt IN
+ [prIncomplete, prIncompNoFill]; { Return if incomplete }
+END;
+
+{---------------------------------------------------------------------------}
+{ NumChar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NumChar (Chr: Char; Const S: String): Byte;
+VAR I, Total: Byte;
+BEGIN
+ Total := 0; { Zero total }
+ For I := 1 To Length(S) Do { For entire string }
+ If (S[I] = Chr) Then Inc(Total); { Count matches of Chr }
+ NumChar := Total; { Return char count }
+END;
+
+{---------------------------------------------------------------------------}
+{ IsSpecial -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION IsSpecial (Chr: Char; Const Special: String): Boolean;
+VAR Rslt: Boolean; I: Byte;
+BEGIN
+ Rslt := False; { Preset false result }
+ For I := 1 To Length(Special) Do
+ If (Special[I] = Chr) Then Rslt := True; { Character found }
+ IsSpecial := Rslt; { Return result }
+END;
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TValidator---------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TValidator.Load (Var S:TStream);
+BEGIN
+ Inherited Init; { Call ancestor }
+ S.Read(Options, SizeOf(Options)); { Read option masks }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TValidator.Valid (Const S: String): Boolean;
+BEGIN
+ Valid := False; { Preset false result }
+ If Not IsValid(S) Then Error { Check for error }
+ Else Valid := True; { Return valid result }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ IsValid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TValidator.IsValid (Const S: String): Boolean;
+BEGIN
+ IsValid := True; { Default return valid }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ IsValidInput -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TValidator.IsValidInput (Var S: String; SuppressFill: Boolean): Boolean;
+BEGIN
+ IsValidInput := True; { Default return true }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ Transfer -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TValidator.Transfer (Var S: String; Buffer: Pointer;
+ Flag: TVTransfer): Word;
+BEGIN
+ Transfer := 0; { Default return zero }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TValidator.Error;
+BEGIN { Abstract method }
+END;
+
+{--TValidator---------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TValidator.Store (Var S: TStream);
+BEGIN
+ S.Write(Options, SizeOf(Options)); { Write options }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TPXPictureValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TPXPictureValidator.Init (Const APic: String; AutoFill: Boolean);
+VAR S: String;
+BEGIN
+ Inherited Init; { Call ancestor }
+ Pic := NewStr(APic); { Hold filename }
+ Options := voOnAppend; { Preset option mask }
+ If AutoFill Then Options := Options OR voFill; { Check/set fill mask }
+ S := ''; { Create empty string }
+ If (Picture(S, False) <> prEmpty) Then { Check for empty }
+ Status := vsSyntax; { Set error mask }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TPXPictureValidator.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Pic := S.ReadStr; { Read filename }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TPXPictureValidator.Done;
+BEGIN
+ If (Pic <> Nil) Then DisposeStr(Pic); { Dispose of filename }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ IsValid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TPXPictureValidator.IsValid (Const S: String): Boolean;
+VAR Str: String; Rslt: TPicResult;
+BEGIN
+ Str := S; { Transfer string }
+ Rslt := Picture(Str, False); { Check for picture }
+ IsValid := (Pic = nil) OR (Rslt = prComplete) OR
+ (Rslt = prEmpty); { Return result }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ IsValidInput -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TPXPictureValidator.IsValidInput (Var S: String;
+ SuppressFill: Boolean): Boolean;
+BEGIN
+ IsValidInput := (Pic = Nil) OR (Picture(S,
+ (Options AND voFill <> 0) AND NOT SuppressFill)
+ <> prError); { Return input result }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Picture -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TPXPictureValidator.Picture (Var Input: String; AutoFill: Boolean): TPicResult;
+VAR I, J: Byte; Rslt: TPicResult; Reprocess: Boolean;
+
+ FUNCTION Process (TermCh: Byte): TPicResult;
+ VAR Rslt: TPicResult; Incomp: Boolean; OldI, OldJ, IncompJ, IncompI: Byte;
+
+ PROCEDURE Consume (Ch: Char);
+ BEGIN
+ Input[J] := Ch; { Return character }
+ Inc(J); { Inc count J }
+ Inc(I); { Inc count I }
+ END;
+
+ PROCEDURE ToGroupEnd (Var I: Byte);
+ VAR BrkLevel, BrcLevel: Integer;
+ BEGIN
+ BrkLevel := 0; { Zero bracket level }
+ BrcLevel := 0; { Zero bracket level }
+ Repeat
+ If (I <> TermCh) Then Begin { Not end }
+ Case Pic^[I] Of
+ '[': Inc(BrkLevel); { Inc bracket level }
+ ']': Dec(BrkLevel); { Dec bracket level }
+ '{': Inc(BrcLevel); { Inc bracket level }
+ '}': Dec(BrcLevel); { Dec bracket level }
+ ';': Inc(I); { Next character }
+ '*': Begin
+ Inc(I); { Next character }
+ While Pic^[I] in ['0'..'9'] Do Inc(I); { Search for text }
+ ToGroupEnd(I); { Move to group end }
+ Continue; { Now continue }
+ End;
+ End;
+ Inc(I); { Next character }
+ End;
+ Until ((BrkLevel = 0) AND (BrcLevel = 0)) OR { Both levels must be 0 }
+ (I = TermCh); { Terminal character }
+ END;
+
+ FUNCTION SkipToComma: Boolean;
+ BEGIN
+ Repeat
+ ToGroupEnd(I); { Find group end }
+ Until (I = TermCh) OR (Pic^[I] = ','); { Terminator found }
+ If (Pic^[I] = ',') Then Inc(I); { Comma so continue }
+ SkipToComma := (I < TermCh); { Return result }
+ END;
+
+ FUNCTION CalcTerm: Byte;
+ VAR K: Byte;
+ BEGIN
+ K := I; { Hold count }
+ ToGroupEnd(K); { Find group end }
+ CalcTerm := K; { Return count }
+ END;
+
+ FUNCTION Iteration: TPicResult;
+ VAR Itr, K, L: Byte; Rslt: TPicResult; NewTermCh: Byte;
+ BEGIN
+ Itr := 0; { Zero iteration }
+ Iteration := prError; { Preset error result }
+ Inc(I); { Skip '*' character }
+ While Pic^[I] in ['0'..'9'] Do Begin { Entry is a number }
+ Itr := Itr * 10 + Byte(Pic^[I]) - Byte('0'); { Convert to number }
+ Inc(I); { Next character }
+ End;
+ If (I <= TermCh) Then Begin { Not end of name }
+ K := I; { Hold count }
+ NewTermCh := CalcTerm; { Calc next terminator }
+ If (Itr <> 0) Then Begin
+ For L := 1 To Itr Do Begin { For each character }
+ I := K; { Reset count }
+ Rslt := Process(NewTermCh); { Process new entry }
+ If (NOT IsComplete(Rslt)) Then Begin { Not empty }
+ If (Rslt = prEmpty) Then { Check result }
+ Rslt := prIncomplete; { Return incomplete }
+ Iteration := Rslt; { Return result }
+ Exit; { Now exit }
+ End;
+ End;
+ End Else Begin
+ Repeat
+ I := K; { Hold count }
+ Rslt := Process(NewTermCh); { Process new entry }
+ Until (NOT IsComplete(Rslt)); { Until complete }
+ If (Rslt = prEmpty) OR (Rslt = prError) { Check for any error }
+ Then Begin
+ Inc(I); { Next character }
+ Rslt := prAmbiguous; { Return result }
+ End;
+ End;
+ I := NewTermCh; { Find next name }
+ End Else Rslt := prSyntax; { Completed }
+ Iteration := Rslt; { Return result }
+ END;
+
+ FUNCTION Group: TPicResult;
+ VAR Rslt: TPicResult; TermCh: Byte;
+ BEGIN
+ TermCh := CalcTerm; { Calc new term }
+ Inc(I); { Next character }
+ Rslt := Process(TermCh - 1); { Process the name }
+ If (NOT IsIncomplete(Rslt)) Then I := TermCh; { Did not complete }
+ Group := Rslt; { Return result }
+ END;
+
+ FUNCTION CheckComplete (Rslt: TPicResult): TPicResult;
+ VAR J: Byte;
+ BEGIN
+ J := I; { Hold count }
+ If IsIncomplete(Rslt) Then Begin { Check if complete }
+ While True Do
+ Case Pic^[J] Of
+ '[': ToGroupEnd(J); { Find name end }
+ '*': If not(Pic^[J + 1] in ['0'..'9'])
+ Then Begin
+ Inc(J); { Next name }
+ ToGroupEnd(J); { Find name end }
+ End Else Break;
+ Else Break;
+ End;
+ If (J = TermCh) Then Rslt := prAmbiguous; { End of name }
+ End;
+ CheckComplete := Rslt; { Return result }
+ END;
+
+ FUNCTION Scan: TPicResult;
+ VAR Ch: Char; Rslt: TPicResult;
+ BEGIN
+ Scan := prError; { Preset return error }
+ Rslt := prEmpty; { Preset empty result }
+ While (I <> TermCh) AND (Pic^[I] <> ',') { For each entry }
+ Do Begin
+ If (J > Length(Input)) Then Begin { Move beyond length }
+ Scan := CheckComplete(Rslt); { Return result }
+ Exit; { Now exit }
+ End;
+ Ch := Input[J]; { Fetch character }
+ Case Pic^[I] of
+ '#': If NOT (Ch in ['0'..'9']) Then Exit { Check is a number }
+ Else Consume(Ch); { Transfer number }
+ '?': If (NOT IsLetter(Ch)) Then Exit { Check is a letter }
+ Else Consume(Ch); { Transfer character }
+ '&': If (NOT IsLetter(Ch)) Then Exit { Check is a letter }
+ Else Consume(UpCase(Ch)); { Transfer character }
+ '!': Consume(UpCase(Ch)); { Transfer character }
+ '@': Consume(Ch); { Transfer character }
+ '*': Begin
+ Rslt := Iteration; { Now re-iterate }
+ If (NOT IsComplete(Rslt)) Then Begin { Check not complete }
+ Scan := Rslt; { Return result }
+ Exit; { Now exit }
+ End;
+ If (Rslt = prError) Then { Check for error }
+ Rslt := prAmbiguous; { Return ambiguous }
+ End;
+ '{': Begin
+ Rslt := Group; { Return group }
+ If (NOT IsComplete(Rslt)) Then Begin { Not incomplete check }
+ Scan := Rslt; { Return result }
+ Exit; { Now exit }
+ End;
+ End;
+ '[': Begin
+ Rslt := Group; { Return group }
+ If IsIncomplete(Rslt) Then Begin { Incomplete check }
+ Scan := Rslt; { Return result }
+ Exit; { Now exit }
+ End;
+ If (Rslt = prError) Then { Check for error }
+ Rslt := prAmbiguous; { Return ambiguous }
+ End;
+ Else If Pic^[I] = ';' Then Inc(I); { Move fwd for follow }
+ If (UpCase(Pic^[I]) <> UpCase(Ch)) Then { Characters differ }
+ If (Ch = ' ') Then Ch := Pic^[I] { Ignore space }
+ Else Exit;
+ Consume(Pic^[I]); { Consume character }
+ End; { Case }
+ If (Rslt = prAmbiguous) Then { If ambiguous result }
+ Rslt := prIncompNoFill { Set incomplete fill }
+ Else Rslt := prIncomplete; { Set incomplete }
+ End;{ While}
+ If (Rslt = prIncompNoFill) Then { Check incomp fill }
+ Scan := prAmbiguous Else { Return ambiguous }
+ Scan := prComplete; { Return completed }
+ END;
+
+ BEGIN
+ Incomp := False; { Clear incomplete }
+ InCompJ:=0; { set to avoid a warning }
+ OldI := I; { Hold I count }
+ OldJ := J; { Hold J count }
+ Repeat
+ Rslt := Scan; { Scan names }
+ If (Rslt IN [prComplete, prAmbiguous]) AND
+ Incomp AND (J < IncompJ) Then Begin { Check if complete }
+ Rslt := prIncomplete; { Return result }
+ J := IncompJ; { Return position }
+ End;
+ If ((Rslt = prError) OR (Rslt = prIncomplete)) { Check no errors }
+ Then Begin
+ Process := Rslt; { Hold result }
+ If ((NOT Incomp) AND (Rslt = prIncomplete)) { Check complete }
+ Then Begin
+ Incomp := True; { Set incomplete }
+ IncompI := I; { Set current position }
+ IncompJ := J; { Set current position }
+ End;
+ I := OldI; { Restore held value }
+ J := OldJ; { Restore held value }
+ If (NOT SkipToComma) Then Begin { Check not comma }
+ If Incomp Then Begin { Check incomplete }
+ Process := prIncomplete; { Set incomplete mask }
+ I := IncompI; { Hold incomp position }
+ J := IncompJ; { Hold incomp position }
+ End;
+ Exit; { Now exit }
+ End;
+ OldI := I; { Hold position }
+ End;
+ Until (Rslt <> prError) AND { Check for error }
+ (Rslt <> prIncomplete); { Incomplete load }
+ If (Rslt = prComplete) AND Incomp Then { Complete load }
+ Process := prAmbiguous Else { Return completed }
+ Process := Rslt; { Return result }
+ END;
+
+ FUNCTION SyntaxCheck: Boolean;
+ VAR I, BrkLevel, BrcLevel: Integer;
+ Begin
+ SyntaxCheck := False; { Preset false result }
+ If (Pic^ <> '') AND (Pic^[Length(Pic^)] <> ';') { Name is valid }
+ AND ((Pic^[Length(Pic^)] = '*') AND
+ (Pic^[Length(Pic^) - 1] <> ';') = False) { Not wildcard list }
+ Then Begin
+ I := 1; { Set count to 1 }
+ BrkLevel := 0; { Zero bracket level }
+ BrcLevel := 0; { Zero bracket level }
+ While (I <= Length(Pic^)) Do Begin { For each character }
+ Case Pic^[I] Of
+ '[': Inc(BrkLevel); { Inc bracket level }
+ ']': Dec(BrkLevel); { Dec bracket level }
+ '{': Inc(BrcLevel); { Inc bracket level }
+ '}': Dec(BrcLevel); { Dec bracket level }
+ ';': Inc(I); { Next character }
+ End;
+ Inc(I); { Next character }
+ End;
+ If (BrkLevel = 0) AND (BrcLevel = 0) Then { Check both levels 0 }
+ SyntaxCheck := True; { Return true syntax }
+ End;
+ End;
+
+BEGIN
+ Picture := prSyntax; { Preset error default }
+ If SyntaxCheck Then Begin { Check syntax }
+ Picture := prEmpty; { Preset picture empty }
+ If (Input <> '') Then Begin { We have an input }
+ J := 1; { Set J count to 1 }
+ I := 1; { Set I count to 1 }
+ Rslt := Process(Length(Pic^) + 1); { Set end of name }
+ If (Rslt <> prError) AND (Rslt <> prSyntax) AND
+ (J <= Length(Input)) Then Rslt := prError; { Check for any error }
+ If (Rslt = prIncomplete) AND AutoFill { Check autofill flags }
+ Then Begin
+ Reprocess := False; { Set reprocess false }
+ while (I <= Length(Pic^)) AND (NOT { Not at end of name }
+ IsSpecial(Pic^[I], '#?&!@*{}[],'#0)) { No special chars }
+ DO Begin
+ If Pic^[I] = ';' Then Inc(I); { Check for next mark }
+ Input := Input + Pic^[I]; { Move to that name }
+ Inc(I); { Inc count }
+ Reprocess := True; { Set reprocess flag }
+ End;
+ J := 1; { Set J count to 1 }
+ I := 1; { Set I count to 1 }
+ If Reprocess Then { Check for reprocess }
+ Rslt := Process(Length(Pic^) + 1); { Move to next name }
+ End;
+ If (Rslt = prAmbiguous) Then { Result ambiguous }
+ Picture := prComplete Else { Return completed }
+ If (Rslt = prInCompNoFill) Then { Result incomplete }
+ Picture := prIncomplete Else { Return incomplete }
+ Picture := Rslt; { Return result }
+ End;
+ End;
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TPXPictureValidator.Error;
+CONST PXErrMsg = 'Input does not conform to picture:';
+VAR S: String;
+BEGIN
+ If (Pic <> Nil) Then S := Pic^ Else S := 'No name';{ Transfer filename }
+ MessageBox(PxErrMsg + #13' %s', @S, mfError OR
+ mfOKButton); { Message box }
+END;
+
+{--TPXPictureValidator------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TPXPictureValidator.Store (Var S: TStream);
+BEGIN
+ TValidator.Store(S); { TValidator.store call }
+ S.WriteStr(Pic); { Write filename }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TFilterValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TFilterValidator---------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TFilterValidator.Init (AValidChars: CharSet);
+BEGIN
+ Inherited Init; { Call ancestor }
+ ValidChars := AValidChars; { Hold valid char set }
+END;
+
+{--TFilterValidator---------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TFilterValidator.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(ValidChars, SizeOf(ValidChars)); { Read valid char set }
+END;
+
+{--TFilterValidator---------------------------------------------------------}
+{ IsValid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TFilterValidator.IsValid (Const S: String): Boolean;
+VAR I: Integer;
+BEGIN
+ I := 1; { Start at position 1 }
+ While S[I] In ValidChars Do Inc(I); { Check each char }
+ If (I > Length(S)) Then IsValid := True Else { All characters valid }
+ IsValid := False; { Invalid characters }
+END;
+
+{--TFilterValidator---------------------------------------------------------}
+{ IsValidInput -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TFilterValidator.IsValidInput (Var S: String; SuppressFill: Boolean): Boolean;
+VAR I: Integer;
+BEGIN
+ I := 1; { Start at position 1 }
+ While S[I] In ValidChars Do Inc(I); { Check each char }
+ If (I > Length(S)) Then IsValidInput := True { All characters valid }
+ Else IsValidInput := False; { Invalid characters }
+END;
+
+{--TFilterValidator---------------------------------------------------------}
+{ Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TFilterValidator.Error;
+CONST PXErrMsg = 'Invalid character in input';
+BEGIN
+ MessageBox(PXErrMsg, Nil, mfError OR mfOKButton); { Show error message }
+END;
+
+{--TFilterValidator---------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TFilterValidator.Store (Var S: TStream);
+BEGIN
+ TValidator.Store(S); { TValidator.Store call }
+ S.Write(ValidChars, SizeOf(ValidChars)); { Write valid char set }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TRangeValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TRangeValidator----------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TRangeValidator.Init (AMin, AMax: LongInt);
+BEGIN
+ Inherited Init(['0'..'9','+','-']); { Call ancestor }
+ If (AMin >= 0) Then { Check min value > 0 }
+ ValidChars := ValidChars - ['-']; { Is so no negatives }
+ Min := AMin; { Hold min value }
+ Max := AMax; { Hold max value }
+END;
+
+{--TRangeValidator----------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TRangeValidator.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(Min, SizeOf(Min)); { Read min value }
+ S.Read(Max, SizeOf(Max)); { Read max value }
+END;
+
+{--TRangeValidator----------------------------------------------------------}
+{ IsValid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TRangeValidator.IsValid (Const S: String): Boolean;
+VAR Value: LongInt; Code: Sw_Integer;
+BEGIN
+ IsValid := False; { Preset false result }
+ If Inherited IsValid(S) Then Begin { Call ancestor }
+ Val(S, Value, Code); { Convert to number }
+ If (Value >= Min) AND (Value <= Max) { With valid range }
+ AND (Code = 0) Then IsValid := True; { No illegal chars }
+ End;
+END;
+
+{--TRangeValidator----------------------------------------------------------}
+{ Transfer -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TRangeValidator.Transfer (Var S: String; Buffer: Pointer; Flag: TVTransfer): Word;
+VAR Value: LongInt; Code: Sw_Integer;
+BEGIN
+ If (Options AND voTransfer <> 0) Then Begin { Tranfer mask set }
+ Transfer := SizeOf(Value); { Transfer a longint }
+ Case Flag Of
+ vtGetData: Begin
+ Val(S, Value, Code); { Convert s to number }
+ LongInt(Buffer^) := Value; { Transfer result }
+ End;
+ vtSetData: Str(LongInt(Buffer^), S); { Convert to string s }
+ End;
+ End Else Transfer := 0; { No transfer = zero }
+END;
+
+{--TRangeValidator----------------------------------------------------------}
+{ Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRangeValidator.Error;
+CONST PXErrMsg = 'Value not in the range';
+VAR Params: Array[0..1] Of Longint;
+BEGIN
+ Params[0] := Min; { Transfer min value }
+ Params[1] := Max; { Transfer max value }
+ MessageBox(PXErrMsg+' %d to %d', @Params,
+ mfError OR mfOKButton); { Display message }
+END;
+
+{--TRangeValidator----------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TRangeValidator.Store (Var S: TStream);
+BEGIN
+ TFilterValidator.Store(S); { TFilterValidator.Store }
+ S.Write(Min, SizeOf(Min)); { Write min value }
+ S.Write(Max, SizeOf(Max)); { Write max value }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TLookUpValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TLookUpValidator---------------------------------------------------------}
+{ IsValid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TLookUpValidator.IsValid (Const S: String): Boolean;
+BEGIN
+ IsValid := LookUp(S); { Check for string }
+END;
+
+{--TLookUpValidator---------------------------------------------------------}
+{ LookUp -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TLookupValidator.Lookup (Const S: String): Boolean;
+BEGIN
+ Lookup := True; { Default return true }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TStringLookUpValidator OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStringLookUpValidator.Init (AStrings: PStringCollection);
+BEGIN
+ Inherited Init; { Call ancestor }
+ Strings := AStrings; { Hold string list }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TStringLookUpValidator.Load (Var S: TStream);
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ Strings := PStringCollection(S.Get); { Fecth string list }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TStringLookUpValidator.Done;
+BEGIN
+ NewStringList(Nil); { Dispsoe string list }
+ Inherited Done; { Call ancestor }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Lookup -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TStringLookUpValidator.Lookup (Const S: String): Boolean;
+{$IFDEF PPC_VIRTUAL} VAR Index: LongInt; {$ELSE} VAR Index: sw_Integer; {$ENDIF}
+BEGIN
+ Lookup := False; { Preset false return }
+ If (Strings <> Nil) Then
+ Lookup := Strings^.Search(@S, Index); { Search for string }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Error -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStringLookUpValidator.Error;
+CONST PXErrMsg = 'Input not in valid-list';
+BEGIN
+ MessageBox(PXErrMsg, Nil, mfError OR mfOKButton); { Display message }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ NewStringList -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStringLookUpValidator.NewStringList (AStrings: PStringCollection);
+BEGIN
+ If (Strings <> Nil) Then Dispose(Strings, Done); { Free old string list }
+ Strings := AStrings; { Hold new string list }
+END;
+
+{--TStringLookUpValidator---------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TStringLookUpValidator.Store (Var S: TStream);
+BEGIN
+ TLookupValidator.Store(S); { TlookupValidator call }
+ S.Put(Strings); { Now store strings }
+END;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTER ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ RegisterValidate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 18May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE RegisterValidate;
+BEGIN
+ RegisterType(RPXPictureValidator); { Register viewer }
+ RegisterType(RFilterValidator); { Register filter }
+ RegisterType(RRangeValidator); { Register validator }
+ RegisterType(RStringLookupValidator); { Register str lookup }
+END;
+
+END.
diff --git a/packages/fv/src/views.pas b/packages/fv/src/views.pas
new file mode 100644
index 0000000000..f29b31e7fc
--- /dev/null
+++ b/packages/fv/src/views.pas
@@ -0,0 +1,4673 @@
+{********[ SOURCE FILE OF GRAPHICAL FREE VISION ]**********}
+{ }
+{ System independent GRAPHICAL clone of VIEWS.PAS }
+{ }
+{ Interface Copyright (c) 1992 Borland International }
+{ }
+{ Copyright (c) 1996, 1997, 1998, 1999 by Leon de Boer }
+{ ldeboer@attglobal.net - primary e-mail address }
+{ ldeboer@starwon.com.au - backup e-mail address }
+{ }
+{****************[ THIS CODE IS FREEWARE ]*****************}
+{ }
+{ This sourcecode is released for the purpose to }
+{ promote the pascal language on all platforms. You may }
+{ redistribute it and/or modify with the following }
+{ DISCLAIMER. }
+{ }
+{ This SOURCE CODE is distributed "AS IS" WITHOUT }
+{ WARRANTIES AS TO PERFORMANCE OF MERCHANTABILITY OR }
+{ ANY OTHER WARRANTIES WHETHER EXPRESSED OR IMPLIED. }
+{ }
+{*****************[ SUPPORTED PLATFORMS ]******************}
+{ }
+{ Only Free Pascal Compiler supported }
+{ }
+{**********************************************************}
+
+UNIT Views;
+
+{$CODEPAGE cp437}
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ INTERFACE
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+{====Include file to sort compiler platform out =====================}
+{$I Platform.inc}
+{====================================================================}
+
+{==== Compiler directives ===========================================}
+
+{$X+} { Extended syntax is ok }
+{$R-} { Disable range checking }
+{$S-} { Disable Stack Checking }
+{$I-} { Disable IO Checking }
+{$Q-} { Disable Overflow Checking }
+{$V-} { Turn off strict VAR strings }
+{====================================================================}
+
+USES
+ {$IFDEF OS_WINDOWS} { WIN/NT CODE }
+ Windows, { Standard unit }
+ {$ENDIF}
+
+ {$IFDEF OS_OS2} { OS2 CODE }
+ Os2Def, DosCalls, PmWin,
+ {$ENDIF}
+
+ Objects, FVCommon, Drivers, fvconsts; { GFV standard units }
+
+{***************************************************************************}
+{ PUBLIC CONSTANTS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TView STATE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ sfVisible = $0001; { View visible mask }
+ sfCursorVis = $0002; { Cursor visible }
+ sfCursorIns = $0004; { Cursor insert mode }
+ sfShadow = $0008; { View has shadow }
+ sfActive = $0010; { View is active }
+ sfSelected = $0020; { View is selected }
+ sfFocused = $0040; { View is focused }
+ sfDragging = $0080; { View is dragging }
+ sfDisabled = $0100; { View is disabled }
+ sfModal = $0200; { View is modal }
+ sfDefault = $0400; { View is default }
+ sfExposed = $0800; { View is exposed }
+ sfIconised = $1000; { View is iconised }
+
+{---------------------------------------------------------------------------}
+{ TView OPTION MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ ofSelectable = $0001; { View selectable }
+ ofTopSelect = $0002; { Top selectable }
+ ofFirstClick = $0004; { First click react }
+ ofFramed = $0008; { View is framed }
+ ofPreProcess = $0010; { Pre processes }
+ ofPostProcess = $0020; { Post processes }
+ ofBuffered = $0040; { View is buffered }
+ ofTileable = $0080; { View is tileable }
+ ofCenterX = $0100; { View centred on x }
+ ofCenterY = $0200; { View centred on y }
+ ofCentered = $0300; { View x,y centred }
+ ofValidate = $0400; { View validates }
+ ofVersion = $3000; { View TV version }
+ ofVersion10 = $0000; { TV version 1 view }
+ ofVersion20 = $1000; { TV version 2 view }
+
+{---------------------------------------------------------------------------}
+{ TView GROW MODE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ gfGrowLoX = $01; { Left side grow }
+ gfGrowLoY = $02; { Top side grow }
+ gfGrowHiX = $04; { Right side grow }
+ gfGrowHiY = $08; { Bottom side grow }
+ gfGrowAll = $0F; { Grow on all sides }
+ gfGrowRel = $10; { Grow relative }
+
+{---------------------------------------------------------------------------}
+{ TView DRAG MODE MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ dmDragMove = $01; { Move view }
+ dmDragGrow = $02; { Grow view }
+ dmLimitLoX = $10; { Limit left side }
+ dmLimitLoY = $20; { Limit top side }
+ dmLimitHiX = $40; { Limit right side }
+ dmLimitHiY = $80; { Limit bottom side }
+ dmLimitAll = $F0; { Limit all sides }
+
+{---------------------------------------------------------------------------}
+{ >> NEW << TAB OPTION MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ tmTab = $01; { Tab move mask }
+ tmShiftTab = $02; { Shift+tab move mask }
+ tmEnter = $04; { Enter move mask }
+ tmLeft = $08; { Left arrow move mask }
+ tmRight = $10; { Right arrow move mask }
+ tmUp = $20; { Up arrow move mask }
+ tmDown = $40; { Down arrow move mask }
+
+{---------------------------------------------------------------------------}
+{ >> NEW << VIEW DRAW MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ vdBackGnd = $01; { Draw backgound }
+ vdInner = $02; { Draw inner detail }
+ vdCursor = $04; { Draw cursor }
+ vdBorder = $08; { Draw view border }
+ vdFocus = $10; { Draw focus state }
+ vdNoChild = $20; { Draw no children }
+ vdShadow = $40;
+ vdAll = vdBackGnd + vdInner + vdCursor + vdBorder + vdFocus + vdShadow;
+
+{---------------------------------------------------------------------------}
+{ TView HELP CONTEXTS }
+{---------------------------------------------------------------------------}
+CONST
+ hcNoContext = 0; { No view context }
+ hcDragging = 1; { No drag context }
+
+{---------------------------------------------------------------------------}
+{ TWindow FLAG MASKS }
+{---------------------------------------------------------------------------}
+CONST
+ wfMove = $01; { Window can move }
+ wfGrow = $02; { Window can grow }
+ wfClose = $04; { Window can close }
+ wfZoom = $08; { Window can zoom }
+
+{---------------------------------------------------------------------------}
+{ TWindow PALETTES }
+{---------------------------------------------------------------------------}
+CONST
+ wpBlueWindow = 0; { Blue palette }
+ wpCyanWindow = 1; { Cyan palette }
+ wpGrayWindow = 2; { Gray palette }
+
+{---------------------------------------------------------------------------}
+{ COLOUR PALETTES }
+{---------------------------------------------------------------------------}
+CONST
+ CFrame = #1#1#2#2#3; { Frame palette }
+ CScrollBar = #4#5#5; { Scrollbar palette }
+ CScroller = #6#7; { Scroller palette }
+ CListViewer = #26#26#27#28#29; { Listviewer palette }
+
+ CBlueWindow = #8#9#10#11#12#13#14#15; { Blue window palette }
+ CCyanWindow = #16#17#18#19#20#21#22#23; { Cyan window palette }
+ CGrayWindow = #24#25#26#27#28#29#30#31; { Grey window palette }
+
+{---------------------------------------------------------------------------}
+{ TScrollBar PART CODES }
+{---------------------------------------------------------------------------}
+CONST
+ sbLeftArrow = 0; { Left arrow part }
+ sbRightArrow = 1; { Right arrow part }
+ sbPageLeft = 2; { Page left part }
+ sbPageRight = 3; { Page right part }
+ sbUpArrow = 4; { Up arrow part }
+ sbDownArrow = 5; { Down arrow part }
+ sbPageUp = 6; { Page up part }
+ sbPageDown = 7; { Page down part }
+ sbIndicator = 8; { Indicator part }
+
+{---------------------------------------------------------------------------}
+{ TScrollBar OPTIONS FOR TWindow.StandardScrollBar }
+{---------------------------------------------------------------------------}
+CONST
+ sbHorizontal = $0000; { Horz scrollbar }
+ sbVertical = $0001; { Vert scrollbar }
+ sbHandleKeyboard = $0002; { Handle keyboard }
+
+{---------------------------------------------------------------------------}
+{ STANDARD COMMAND CODES }
+{---------------------------------------------------------------------------}
+CONST
+ cmValid = 0; { Valid command }
+ cmQuit = 1; { Quit command }
+ cmError = 2; { Error command }
+ cmMenu = 3; { Menu command }
+ cmClose = 4; { Close command }
+ cmZoom = 5; { Zoom command }
+ cmResize = 6; { Resize command }
+ cmNext = 7; { Next view command }
+ cmPrev = 8; { Prev view command }
+ cmHelp = 9; { Help command }
+ cmOK = 10; { Okay command }
+ cmCancel = 11; { Cancel command }
+ cmYes = 12; { Yes command }
+ cmNo = 13; { No command }
+ cmDefault = 14; { Default command }
+ cmCut = 20; { Clipboard cut cmd }
+ cmCopy = 21; { Clipboard copy cmd }
+ cmPaste = 22; { Clipboard paste cmd }
+ cmUndo = 23; { Clipboard undo cmd }
+ cmClear = 24; { Clipboard clear cmd }
+ cmTile = 25; { Tile subviews cmd }
+ cmCascade = 26; { Cascade subviews cmd }
+ cmReceivedFocus = 50; { Received focus }
+ cmReleasedFocus = 51; { Released focus }
+ cmCommandSetChanged = 52; { Commands changed }
+ cmScrollBarChanged = 53; { Scrollbar changed }
+ cmScrollBarClicked = 54; { Scrollbar clicked on }
+ cmSelectWindowNum = 55; { Select window }
+ cmListItemSelected = 56; { Listview item select }
+
+ cmNotify = 27;
+ cmIdCommunicate = 28; { Communicate via id }
+ cmIdSelect = 29; { Select via id }
+
+{---------------------------------------------------------------------------}
+{ TWindow NUMBER CONSTANTS }
+{---------------------------------------------------------------------------}
+CONST
+ wnNoNumber = 0; { Window has no num }
+ MaxViewWidth = 255; { Max view width }
+
+
+{***************************************************************************}
+{ PUBLIC TYPE DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TWindow Title string }
+{---------------------------------------------------------------------------}
+TYPE
+ TTitleStr = String[80]; { Window title string }
+
+{---------------------------------------------------------------------------}
+{ COMMAND SET RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ TCommandSet = SET OF Byte; { Command set record }
+ PCommandSet = ^TCommandSet; { Ptr to command set }
+
+{---------------------------------------------------------------------------}
+{ PALETTE RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ TPalette = String; { Palette record }
+ PPalette = ^TPalette; { Pointer to palette }
+
+{---------------------------------------------------------------------------}
+{ TDrawBuffer RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ TDrawBuffer = Array [0..MaxViewWidth - 1] Of Word; { Draw buffer record }
+ PDrawBuffer = ^TDrawBuffer; { Ptr to draw buffer }
+
+{---------------------------------------------------------------------------}
+{ TVideoBuffer RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ TVideoBuf = ARRAY [0..3999] of Word; { Video buffer }
+ PVideoBuf = ^TVideoBuf; { Pointer to buffer }
+
+{---------------------------------------------------------------------------}
+{ TComplexArea RECORD }
+{---------------------------------------------------------------------------}
+TYPE
+ PComplexArea = ^TComplexArea; { Complex area }
+ TComplexArea =
+{$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
+ PACKED
+{$endif FPC_REQUIRES_PROPER_ALIGNMENT}
+ RECORD
+ X1, Y1 : Sw_Integer; { Top left corner }
+ X2, Y2 : Sw_Integer; { Lower right corner }
+ NextArea: PComplexArea; { Next area pointer }
+ END;
+
+{***************************************************************************}
+{ PUBLIC OBJECT DEFINITIONS }
+{***************************************************************************}
+
+TYPE
+ PGroup = ^TGroup; { Pointer to group }
+
+{---------------------------------------------------------------------------}
+{ TView OBJECT - ANCESTOR VIEW OBJECT }
+{---------------------------------------------------------------------------}
+ PView = ^TView;
+ TView = OBJECT (TObject)
+ GrowMode : Byte; { View grow mode }
+ DragMode : Byte; { View drag mode }
+ TabMask : Byte; { Tab move masks }
+ ColourOfs: Sw_Integer; { View palette offset }
+ HelpCtx : Word; { View help context }
+ State : Word; { View state masks }
+ Options : Word; { View options masks }
+ EventMask: Word; { View event masks }
+ Origin : TPoint; { View origin }
+ Size : TPoint; { View size }
+ Cursor : TPoint; { Cursor position }
+ Next : PView; { Next peerview }
+ Owner : PGroup; { Owner group }
+ HoldLimit: PComplexArea; { Hold limit values }
+
+ RevCol : Boolean;
+ BackgroundChar : Char;
+
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION Prev: PView;
+ FUNCTION Execute: Word; Virtual;
+ FUNCTION Focus: Boolean;
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION TopView: PView;
+ FUNCTION PrevView: PView;
+ FUNCTION NextView: PView;
+ FUNCTION GetHelpCtx: Word; Virtual;
+ FUNCTION EventAvail: Boolean;
+ FUNCTION GetPalette: PPalette; Virtual;
+ function MapColor (color:byte):byte;
+ FUNCTION GetColor (Color: Word): Word;
+ FUNCTION Valid (Command: Word): Boolean; Virtual;
+ FUNCTION GetState (AState: Word): Boolean;
+ FUNCTION TextWidth (const Txt: String): Sw_Integer;
+ FUNCTION CTextWidth (const Txt: String): Sw_Integer;
+ FUNCTION MouseInView (Point: TPoint): Boolean;
+ FUNCTION CommandEnabled (Command: Word): Boolean;
+ FUNCTION OverLapsArea (X1, Y1, X2, Y2: Sw_Integer): Boolean;
+ FUNCTION MouseEvent (Var Event: TEvent; Mask: Word): Boolean;
+ PROCEDURE Hide;
+ PROCEDURE Show;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE ResetCursor; Virtual;
+ PROCEDURE Select;
+ PROCEDURE Awaken; Virtual;
+ PROCEDURE DrawView;
+ PROCEDURE MakeFirst;
+ PROCEDURE DrawCursor; Virtual;
+ PROCEDURE HideCursor;
+ PROCEDURE ShowCursor;
+ PROCEDURE BlockCursor;
+ PROCEDURE NormalCursor;
+ PROCEDURE FocusFromTop; Virtual;
+ PROCEDURE MoveTo (X, Y: Sw_Integer);
+ PROCEDURE GrowTo (X, Y: Sw_Integer);
+ PROCEDURE EndModal (Command: Word); Virtual;
+ PROCEDURE SetCursor (X, Y: Sw_Integer);
+ PROCEDURE PutInFrontOf (Target: PView);
+ PROCEDURE SetCommands (Commands: TCommandSet);
+ PROCEDURE EnableCommands (Commands: TCommandSet);
+ PROCEDURE DisableCommands (Commands: TCommandSet);
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE SetCmdState (Commands: TCommandSet; Enable: Boolean);
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE Locate (Var Bounds: TRect);
+ PROCEDURE KeyEvent (Var Event: TEvent);
+ PROCEDURE GetEvent (Var Event: TEvent); Virtual;
+ PROCEDURE PutEvent (Var Event: TEvent); Virtual;
+ PROCEDURE GetExtent (Var Extent: TRect);
+ PROCEDURE GetBounds (Var Bounds: TRect);
+ PROCEDURE SetBounds (Var Bounds: TRect);
+ PROCEDURE GetClipRect (Var Clip: TRect);
+ PROCEDURE ClearEvent (Var Event: TEvent);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
+ PROCEDURE SizeLimits (Var Min, Max: TPoint); Virtual;
+ PROCEDURE GetCommands (Var Commands: TCommandSet);
+ PROCEDURE GetPeerViewPtr (Var S: TStream; Var P);
+ PROCEDURE PutPeerViewPtr (Var S: TStream; P: PView);
+ PROCEDURE CalcBounds (Var Bounds: TRect; Delta: TPoint); Virtual;
+
+ FUNCTION Exposed: Boolean; { This needs help!!!!! }
+ PROCEDURE WriteBuf (X, Y, W, H: Sw_Integer; Var Buf);
+ PROCEDURE WriteLine (X, Y, W, H: Sw_Integer; Var Buf);
+ PROCEDURE MakeLocal (Source: TPoint; Var Dest: TPoint);
+ PROCEDURE MakeGlobal (Source: TPoint; Var Dest: TPoint);
+ PROCEDURE WriteStr (X, Y: Sw_Integer; Str: String; Color: Byte);
+ PROCEDURE WriteChar (X, Y: Sw_Integer; C: Char; Color: Byte;
+ Count: Sw_Integer);
+ PROCEDURE DragView (Event: TEvent; Mode: Byte; Var Limits: TRect;
+ MinSize, MaxSize: TPoint);
+ private
+ procedure CursorChanged;
+ procedure DrawHide(LastView: PView);
+ procedure DrawShow(LastView: PView);
+ procedure DrawUnderRect(var R: TRect; LastView: PView);
+ procedure DrawUnderView(DoShadow: Boolean; LastView: PView);
+ procedure do_WriteView(x1,x2,y:Sw_Integer; var Buf);
+ procedure do_WriteViewRec1(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer);
+ procedure do_WriteViewRec2(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer);
+ function do_ExposedRec1(x1,x2:Sw_integer; p:PView):boolean;
+ function do_ExposedRec2(x1,x2:Sw_integer; p:PView):boolean;
+ END;
+
+ SelectMode = (NormalSelect, EnterSelect, LeaveSelect);
+
+{---------------------------------------------------------------------------}
+{ TGroup OBJECT - GROUP OBJECT ANCESTOR }
+{---------------------------------------------------------------------------}
+ TGroup = OBJECT (TView)
+ Phase : (phFocused, phPreProcess, phPostProcess);
+ EndState: Word; { Modal result }
+ Current : PView; { Selected subview }
+ Last : PView; { 1st view inserted }
+ Buffer : PVideoBuf; { Speed up buffer }
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION First: PView;
+ FUNCTION Execute: Word; Virtual;
+ FUNCTION GetHelpCtx: Word; Virtual;
+ FUNCTION DataSize: Sw_Word; Virtual;
+ FUNCTION ExecView (P: PView): Word; Virtual;
+ FUNCTION FirstThat (P: Pointer): PView;
+ FUNCTION Valid (Command: Word): Boolean; Virtual;
+ FUNCTION FocusNext (Forwards: Boolean): Boolean;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE Lock;
+ PROCEDURE UnLock;
+ PROCEDURE ResetCursor; Virtual;
+ PROCEDURE Awaken; Virtual;
+ PROCEDURE ReDraw;
+ PROCEDURE SelectDefaultView;
+ PROCEDURE Insert (P: PView);
+ PROCEDURE Delete (P: PView);
+ PROCEDURE ForEach (P: Pointer);
+ { ForEach can't be virtual because it generates SIGSEGV }
+ PROCEDURE EndModal (Command: Word); Virtual;
+ PROCEDURE SelectNext (Forwards: Boolean);
+ PROCEDURE InsertBefore (P, Target: PView);
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE GetData (Var Rec); Virtual;
+ PROCEDURE SetData (Var Rec); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE EventError (Var Event: TEvent); Virtual;
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
+ PROCEDURE GetSubViewPtr (Var S: TStream; Var P);
+ PROCEDURE PutSubViewPtr (Var S: TStream; P: PView);
+ function ClipChilds: boolean; virtual;
+ procedure BeforeInsert(P: PView); virtual;
+ procedure AfterInsert(P: PView); virtual;
+ procedure BeforeDelete(P: PView); virtual;
+ procedure AfterDelete(P: PView); virtual;
+
+ PRIVATE
+ LockFlag: Byte;
+ Clip : TRect;
+ FUNCTION IndexOf (P: PView): Sw_Integer;
+ FUNCTION FindNext (Forwards: Boolean): PView;
+ FUNCTION FirstMatch (AState: Word; AOptions: Word): PView;
+ PROCEDURE ResetCurrent;
+ PROCEDURE RemoveView (P: PView);
+ PROCEDURE InsertView (P, Target: PView);
+ PROCEDURE SetCurrent (P: PView; Mode: SelectMode);
+ procedure DrawSubViews(P, Bottom: PView);
+ END;
+
+{---------------------------------------------------------------------------}
+{ TFrame OBJECT - FRAME VIEW OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TFrame = OBJECT (TView)
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ FUNCTION GetPalette: PPalette; Virtual;
+ procedure Draw; virtual;
+ procedure HandleEvent(var Event: TEvent); virtual;
+ procedure SetState(AState: Word; Enable: Boolean); virtual;
+ private
+ FrameMode: Word;
+ procedure FrameLine(var FrameBuf; Y, N: Sw_Integer; Color: Byte);
+ END;
+ PFrame = ^TFrame;
+
+{---------------------------------------------------------------------------}
+{ TScrollBar OBJECT - SCROLL BAR OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TScrollChars = Array [0..4] of Char;
+
+ TScrollBar = OBJECT (TView)
+ Value : Sw_Integer; { Scrollbar value }
+ Min : Sw_Integer; { Scrollbar minimum }
+ Max : Sw_Integer; { Scrollbar maximum }
+ PgStep: Sw_Integer; { One page step }
+ ArStep: Sw_Integer; { One range step }
+ Id : Sw_Integer; { Scrollbar ID }
+ CONSTRUCTOR Init (Var Bounds: TRect);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION ScrollStep (Part: Sw_Integer): Sw_Integer; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE ScrollDraw; Virtual;
+ PROCEDURE SetValue (AValue: Sw_Integer);
+ PROCEDURE SetRange (AMin, AMax: Sw_Integer);
+ PROCEDURE SetStep (APgStep, AArStep: Sw_Integer);
+ PROCEDURE SetParams (AValue, AMin, AMax, APgStep, AArStep: Sw_Integer);
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PRIVATE
+ Chars: TScrollChars; { Scrollbar chars }
+ FUNCTION GetPos: Sw_Integer;
+ FUNCTION GetSize: Sw_Integer;
+ PROCEDURE DrawPos (Pos: Sw_Integer);
+ END;
+ PScrollBar = ^TScrollBar;
+
+{---------------------------------------------------------------------------}
+{ TScroller OBJECT - SCROLLING VIEW ANCESTOR }
+{---------------------------------------------------------------------------}
+TYPE
+ TScroller = OBJECT (TView)
+ Delta : TPoint;
+ Limit : TPoint;
+ HScrollBar: PScrollBar; { Horz scroll bar }
+ VScrollBar: PScrollBar; { Vert scroll bar }
+ CONSTRUCTOR Init (Var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ PROCEDURE ScrollDraw; Virtual;
+ PROCEDURE SetLimit (X, Y: Sw_Integer);
+ PROCEDURE ScrollTo (X, Y: Sw_Integer);
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
+ PRIVATE
+ DrawFlag: Boolean;
+ DrawLock: Byte;
+ PROCEDURE CheckDraw;
+ END;
+ PScroller = ^TScroller;
+
+{---------------------------------------------------------------------------}
+{ TListViewer OBJECT - LIST VIEWER OBJECT }
+{---------------------------------------------------------------------------}
+TYPE
+ TListViewer = OBJECT (TView)
+ NumCols : Sw_Integer; { Number of columns }
+ TopItem : Sw_Integer; { Top most item }
+ Focused : Sw_Integer; { Focused item }
+ Range : Sw_Integer; { Range of listview }
+ HScrollBar: PScrollBar; { Horz scrollbar }
+ VScrollBar: PScrollBar; { Vert scrollbar }
+ CONSTRUCTOR Init (Var Bounds: TRect; ANumCols: Sw_Word; AHScrollBar,
+ AVScrollBar: PScrollBar);
+ CONSTRUCTOR Load (Var S: TStream);
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION IsSelected (Item: Sw_Integer): Boolean; Virtual;
+ FUNCTION GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String; Virtual;
+ PROCEDURE Draw; Virtual;
+ PROCEDURE FocusItem (Item: Sw_Integer); Virtual;
+ PROCEDURE SetTopItem (Item: Sw_Integer);
+ PROCEDURE SetRange (ARange: Sw_Integer);
+ PROCEDURE SelectItem (Item: Sw_Integer); Virtual;
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE ChangeBounds (Var Bounds: TRect); Virtual;
+ PROCEDURE FocusItemNum (Item: Sw_Integer); Virtual;
+ END;
+ PListViewer = ^TListViewer;
+
+{---------------------------------------------------------------------------}
+{ TWindow OBJECT - WINDOW OBJECT ANCESTOR }
+{---------------------------------------------------------------------------}
+TYPE
+ TWindow = OBJECT (TGroup)
+ Flags : Byte; { Window flags }
+ Number : Sw_Integer; { Window number }
+ Palette : Sw_Integer; { Window palette }
+ ZoomRect: TRect; { Zoom rectangle }
+ Frame : PFrame; { Frame view object }
+ Title : PString; { Title string }
+ CONSTRUCTOR Init (Var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
+ CONSTRUCTOR Load (Var S: TStream);
+ DESTRUCTOR Done; Virtual;
+ FUNCTION GetPalette: PPalette; Virtual;
+ FUNCTION GetTitle (MaxSize: Sw_Integer): TTitleStr; Virtual;
+ FUNCTION StandardScrollBar (AOptions: Word): PScrollBar;
+ PROCEDURE Zoom; Virtual;
+ PROCEDURE Close; Virtual;
+ PROCEDURE InitFrame; Virtual;
+ PROCEDURE SetState (AState: Word; Enable: Boolean); Virtual;
+ PROCEDURE Store (Var S: TStream);
+ PROCEDURE HandleEvent (Var Event: TEvent); Virtual;
+ PROCEDURE SizeLimits (Var Min, Max: TPoint); Virtual;
+ END;
+ PWindow = ^TWindow;
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ WINDOW MESSAGE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-Message------------------------------------------------------------
+Message sets up an event record and calls Receiver^.HandleEvent to
+handle the event. Message returns nil if Receiver is nil, or if
+the event is not handled successfully.
+12Sep97 LdB
+---------------------------------------------------------------------}
+FUNCTION Message (Receiver: PView; What, Command: Word;
+ InfoPtr: Pointer): Pointer;
+
+{-NewMessage---------------------------------------------------------
+NewMessage sets up an event record including the new fields and calls
+Receiver^.HandleEvent to handle the event. Message returns nil if
+Receiver is nil, or if the event is not handled successfully.
+19Sep97 LdB
+---------------------------------------------------------------------}
+FUNCTION NewMessage (P: PView; What, Command: Word; Id: Sw_Integer; Data: Real;
+ InfoPtr: Pointer): Pointer;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ VIEW OBJECT REGISTRATION ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{-RegisterViews------------------------------------------------------
+This registers all the view type objects used in this unit.
+11Aug99 LdB
+---------------------------------------------------------------------}
+PROCEDURE RegisterViews;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ NEW VIEW ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{-CreateIdScrollBar--------------------------------------------------
+Creates and scrollbar object of the given size and direction and sets
+the scrollbar id number.
+22Sep97 LdB
+---------------------------------------------------------------------}
+FUNCTION CreateIdScrollBar (X, Y, Size, Id: Sw_Integer; Horz: Boolean): PScrollBar;
+
+{***************************************************************************}
+{ INITIALIZED PUBLIC VARIABLES }
+{***************************************************************************}
+
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED DOS/DPMI/WIN/NT/OS2 VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ UseNativeClasses: Boolean = True; { Native class modes }
+ CommandSetChanged: Boolean = False; { Command change flag }
+ ShowMarkers: Boolean = False; { Show marker state }
+ ErrorAttr: Byte = $CF; { Error colours }
+ PositionalEvents: Word = evMouse; { Positional defined }
+ FocusedEvents: Word = evKeyboard + evCommand; { Focus defined }
+ MinWinSize: TPoint = (X: 16; Y: 6); { Minimum window size }
+ ShadowSize: TPoint = (X: 2; Y: 1); { Shadow sizes }
+ ShadowAttr: Byte = $08; { Shadow attribute }
+
+{ Characters used for drawing selected and default items in }
+{ monochrome color sets }
+ SpecialChars: Array [0..5] Of Char = (#175, #174, #26, #27, ' ', ' ');
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ STREAM REGISTRATION RECORDS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ TView STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RView: TStreamRec = (
+ ObjType: idView; { Register id = 1 }
+ VmtLink: TypeOf(TView); { Alt style VMT link }
+ Load: @TView.Load; { Object load method }
+ Store: @TView.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TFrame STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RFrame: TStreamRec = (
+ ObjType: idFrame; { Register id = 2 }
+ VmtLink: TypeOf(TFrame); { Alt style VMT link }
+ Load: @TFrame.Load; { Frame load method }
+ Store: @TFrame.Store { Frame store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TScrollBar STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RScrollBar: TStreamRec = (
+ ObjType: idScrollBar; { Register id = 3 }
+ VmtLink: TypeOf(TScrollBar); { Alt style VMT link }
+ Load: @TScrollBar.Load; { Object load method }
+ Store: @TScrollBar.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TScroller STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RScroller: TStreamRec = (
+ ObjType: idScroller; { Register id = 4 }
+ VmtLink: TypeOf(TScroller); { Alt style VMT link }
+ Load: @TScroller.Load; { Object load method }
+ Store: @TScroller.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TListViewer STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RListViewer: TStreamRec = (
+ ObjType: idListViewer; { Register id = 5 }
+ VmtLink: TypeOf(TListViewer); { Alt style VMT link }
+ Load: @TListViewer.Load; { Object load method }
+ Store: @TLIstViewer.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TGroup STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RGroup: TStreamRec = (
+ ObjType: idGroup; { Register id = 6 }
+ VmtLink: TypeOf(TGroup); { Alt style VMT link }
+ Load: @TGroup.Load; { Object load method }
+ Store: @TGroup.Store { Object store method }
+ );
+
+{---------------------------------------------------------------------------}
+{ TWindow STREAM REGISTRATION }
+{---------------------------------------------------------------------------}
+CONST
+ RWindow: TStreamRec = (
+ ObjType: idWindow; { Register id = 7 }
+ VmtLink: TypeOf(TWindow); { Alt style VMT link }
+ Load: @TWindow.Load; { Object load method }
+ Store: @TWindow.Store { Object store method }
+ );
+
+
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+ IMPLEMENTATION
+{<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
+
+USES
+ Video;
+
+{***************************************************************************}
+{ PRIVATE TYPE DEFINITIONS }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ TFixupList DEFINITION }
+{---------------------------------------------------------------------------}
+TYPE
+ TFixupList = ARRAY [1..4096] Of Pointer; { Fix up ptr array }
+ PFixupList = ^TFixupList; { Ptr to fix up list }
+
+{***************************************************************************}
+{ PRIVATE INITIALIZED VARIABLES }
+{***************************************************************************}
+
+{---------------------------------------------------------------------------}
+{ INITIALIZED DOS/DPMI/WIN/NT/OS2 PRIVATE VARIABLES }
+{---------------------------------------------------------------------------}
+CONST
+ TheTopView : PView = Nil; { Top focused view }
+ LimitsLocked: PView = Nil; { View locking limits }
+ OwnerGroup : PGroup = Nil; { Used for loading }
+ FixupList : PFixupList = Nil; { Used for loading }
+ CurCommandSet: TCommandSet = ([0..255] -
+ [cmZoom, cmClose, cmResize, cmNext, cmPrev]); { All active but these }
+
+ vdInSetCursor = $80; { AVOID RECURSION IN SetCursor }
+
+ { Flags for TFrame }
+ fmCloseClicked = $01;
+ fmZoomClicked = $02;
+
+
+type
+ TstatVar2 = record
+ target : PView;
+ offset,y : integer;
+ end;
+
+var
+ staticVar1 : PDrawBuffer;
+ staticVar2 : TstatVar2;
+
+
+{***************************************************************************}
+{ PRIVATE INTERNAL ROUTINES }
+{***************************************************************************}
+
+ function posidx(const substr,s : string;idx:sw_integer):sw_integer;
+ var
+ i,j : sw_integer;
+ e : boolean;
+ begin
+ i:=idx;
+ j:=0;
+ e:=(length(SubStr)>0);
+ while e and (i<=Length(s)-Length(SubStr)) do
+ begin
+ if (SubStr[1]=s[i]) and (Substr=Copy(s,i,Length(SubStr))) then
+ begin
+ j:=i;
+ e:=false;
+ end;
+ inc(i);
+ end;
+ PosIdx:=j;
+ end;
+
+
+{$ifdef UNIX}
+const
+ MouseUsesVideoBuf = true;
+{$else not UNIX}
+const
+ MouseUsesVideoBuf = false;
+{$endif not UNIX}
+
+procedure DrawScreenBuf(force:boolean);
+begin
+ if (GetLockScreenCount=0) then
+ begin
+{ If MouseUsesVideoBuf then
+ begin
+ LockScreenUpdate;
+ HideMouse;
+ ShowMouse;
+ UnlockScreenUpdate;
+ end
+ else
+ HideMouse;}
+ UpdateScreen(force);
+{ If not MouseUsesVideoBuf then
+ ShowMouse;}
+ end;
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ VIEW PORT CONTROL ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+TYPE
+ ViewPortType = RECORD
+ X1, Y1, X2, Y2: Integer; { Corners of viewport }
+ Clip : Boolean; { Clip status }
+ END;
+
+var
+ ViewPort : ViewPortType;
+
+{---------------------------------------------------------------------------}
+{ GetViewSettings -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Dec2000 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE GetViewSettings (Var CurrentViewPort: ViewPortType);
+BEGIN
+ CurrentViewPort := ViewPort; { Textmode viewport }
+END;
+
+{---------------------------------------------------------------------------}
+{ SetViewPort -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05Dec2000 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE SetViewPort (X1, Y1, X2, Y2: Integer; Clip: Boolean);
+BEGIN
+ If (X1 < 0) Then X1 := 0; { X1 negative fix }
+ If (X1 >ScreenWidth) Then
+ X1 := ScreenWidth; { X1 off screen fix }
+ If (Y1 < 0) Then Y1 := 0; { Y1 negative fix }
+ If (Y1 > ScreenHeight) Then
+ Y1 := ScreenHeight; { Y1 off screen fix }
+ If (X2 < 0) Then X2 := 0; { X2 negative fix }
+ If (X2 > ScreenWidth) Then
+ X2 := ScreenWidth; { X2 off screen fix }
+ If (Y2 < 0) Then Y2 := 0; { Y2 negative fix }
+ If (Y2 > ScreenHeight) Then
+ Y2 := ScreenHeight; { Y2 off screen fix }
+ ViewPort.X1 := X1; { Set X1 port value }
+ ViewPort.Y1 := Y1; { Set Y1 port value }
+ ViewPort.X2 := X2; { Set X2 port value }
+ ViewPort.Y2 := Y2; { Set Y2 port value }
+ ViewPort.Clip := Clip; { Set port clip value }
+{ $ifdef DEBUG
+ If WriteDebugInfo then
+ Writeln(stderr,'New ViewPort(',X1,',',Y1,',',X2,',',Y2,')');
+ $endif DEBUG}
+END;
+
+{***************************************************************************}
+{ OBJECT METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TView OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TView--------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20Jun96 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TView.Init (Var Bounds: TRect);
+BEGIN
+ Inherited Init; { Call ancestor }
+ DragMode := dmLimitLoY; { Default drag mode }
+ HelpCtx := hcNoContext; { Clear help context }
+ State := sfVisible; { Default state }
+ EventMask := evMouseDown + evKeyDown + evCommand; { Default event masks }
+ BackgroundChar := ' ';
+ SetBounds(Bounds); { Set view bounds }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
+{---------------------------------------------------------------------------}
+{ This load method will read old original TV data from a stream but the }
+{ new options and tabmasks are not set so some NEW functionality is not }
+{ supported but it should work as per original TV code. }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TView.Load (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ Inherited Init; { Call ancestor }
+ S.Read(i, SizeOf(i)); Origin.X:=i; { Read origin x value }
+ S.Read(i, SizeOf(i)); Origin.Y:=i; { Read origin y value }
+ S.Read(i, SizeOf(i)); Size.X:=i; { Read view x size }
+ S.Read(i, SizeOf(i)); Size.Y:=i; { Read view y size }
+ S.Read(i, SizeOf(i)); Cursor.X:=i; { Read cursor x size }
+ S.Read(i, SizeOf(i)); Cursor.Y:=i; { Read cursor y size }
+ S.Read(GrowMode, SizeOf(GrowMode)); { Read growmode flags }
+ S.Read(DragMode, SizeOf(DragMode)); { Read dragmode flags }
+ S.Read(HelpCtx, SizeOf(HelpCtx)); { Read help context }
+ S.Read(State, SizeOf(State)); { Read state masks }
+ S.Read(Options, SizeOf(Options)); { Read options masks }
+ S.Read(Eventmask, SizeOf(Eventmask)); { Read event masks }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Nov99 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TView.Done;
+VAR P: PComplexArea;
+BEGIN
+ Hide; { Hide the view }
+ If (Owner <> Nil) Then Owner^.Delete(@Self); { Delete from owner }
+ While (HoldLimit <> Nil) Do Begin { Free limit memory }
+ P := HoldLimit^.NextArea; { Hold next pointer }
+ FreeMem(HoldLimit, SizeOf(TComplexArea)); { Release memory }
+ HoldLimit := P; { Shuffle to next }
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Prev -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.Prev: PView;
+VAR NP : PView;
+BEGIN
+ Prev := @Self;
+ NP := Next;
+ While (NP <> Nil) AND (NP <> @Self) Do
+ Begin
+ Prev := NP; { Locate next view }
+ NP := NP^.Next;
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Execute -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.Execute: Word;
+BEGIN
+ Execute := cmCancel; { Return cancel }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Focus -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.Focus: Boolean;
+VAR Res: Boolean;
+BEGIN
+ Res := True; { Preset result }
+ If (State AND (sfSelected + sfModal)=0) Then Begin { Not modal/selected }
+ If (Owner <> Nil) Then Begin { View has an owner }
+ Res := Owner^.Focus; { Return focus state }
+ If Res Then { Owner has focus }
+ If ((Owner^.Current = Nil) OR { No current view }
+ (Owner^.Current^.Options AND ofValidate = 0) { Non validating view }
+ OR (Owner^.Current^.Valid(cmReleasedFocus))) { Okay to drop focus }
+ Then Select Else Res := False; { Then select us }
+ End;
+ End;
+ Focus := Res; { Return focus result }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.DataSize: Sw_Word;
+BEGIN
+ DataSize := 0; { Transfer size }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ TopView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.TopView: PView;
+VAR P: PView;
+BEGIN
+ If (TheTopView = Nil) Then Begin { Check topmost view }
+ P := @Self; { Start with us }
+ While (P <> Nil) AND (P^.State AND sfModal = 0) { Check if modal }
+ Do P := P^.Owner; { Search each owner }
+ TopView := P; { Return result }
+ End Else TopView := TheTopView; { Return topview }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ PrevView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.PrevView: PView;
+BEGIN
+ If (@Self = Owner^.First) Then PrevView := Nil { We are first view }
+ Else PrevView := Prev; { Return our prior }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ NextView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.NextView: PView;
+BEGIN
+ If (@Self = Owner^.Last) Then NextView := Nil { This is last view }
+ Else NextView := Next; { Return our next }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.GetHelpCtx: Word;
+BEGIN
+ If (State AND sfDragging <> 0) Then { Dragging state check }
+ GetHelpCtx := hcDragging Else { Return dragging }
+ GetHelpCtx := HelpCtx; { Return help context }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ EventAvail -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.EventAvail: Boolean;
+VAR Event: TEvent;
+BEGIN
+ GetEvent(Event); { Get next event }
+ If (Event.What <> evNothing) Then PutEvent(Event); { Put it back }
+ EventAvail := (Event.What <> evNothing); { Return result }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.GetPalette: PPalette;
+BEGIN
+ GetPalette := Nil; { Return nil ptr }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ MapColor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
+{---------------------------------------------------------------------------}
+function TView.MapColor(color:byte):byte;
+var
+ cur : PView;
+ p : PPalette;
+begin
+ if color=0 then
+ MapColor:=errorAttr
+ else
+ begin
+ cur:=@Self;
+ repeat
+ p:=cur^.GetPalette;
+ if (p<>Nil) then
+ if ord(p^[0])<>0 then
+ begin
+ if color>ord(p^[0]) then
+ begin
+ MapColor:=errorAttr;
+ Exit;
+ end;
+ color:=ord(p^[color]);
+ if color=0 then
+ begin
+ MapColor:=errorAttr;
+ Exit;
+ end;
+ end;
+ cur:=cur^.Owner;
+ until (cur=Nil);
+ MapColor:=color;
+ end;
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ GetColor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.GetColor (Color: Word): Word;
+VAR Col: Byte; W: Word; P: PPalette; Q: PView;
+BEGIN
+ W := 0; { Clear colour Sw_Word }
+ If (Hi(Color) > 0) Then Begin { High colour req }
+ Col := Hi(Color) + ColourOfs; { Initial offset }
+ Q := @Self; { Pointer to self }
+ Repeat
+ P := Q^.GetPalette; { Get our palette }
+ If (P <> Nil) Then Begin { Palette is valid }
+ If (Col <= Length(P^)) Then
+ Col := Ord(P^[Col]) Else { Return colour }
+ Col := ErrorAttr; { Error attribute }
+ End;
+ Q := Q^.Owner; { Move up to owner }
+ Until (Q = Nil); { Until no owner }
+ W := Col SHL 8; { Translate colour }
+ End;
+ If (Lo(Color) > 0) Then Begin
+ Col := Lo(Color) + ColourOfs; { Initial offset }
+ Q := @Self; { Pointer to self }
+ Repeat
+ P := Q^.GetPalette; { Get our palette }
+ If (P <> Nil) Then Begin { Palette is valid }
+ If (Col <= Length(P^)) Then
+ Col := Ord(P^[Col]) Else { Return colour }
+ Col := ErrorAttr; { Error attribute }
+ End;
+ Q := Q^.Owner; { Move up to owner }
+ Until (Q = Nil); { Until no owner }
+ End Else Col := ErrorAttr; { No colour found }
+ GetColor := W OR Col; { Return color }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.Valid (Command: Word): Boolean;
+BEGIN
+ Valid := True; { Simply return true }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.GetState (AState: Word): Boolean;
+BEGIN
+ GetState := State AND AState = AState; { Check states equal }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ TextWidth -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 25Nov99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.TextWidth (const Txt: String): Sw_Integer;
+BEGIN
+ TextWidth := Length(Txt); { Calc text length }
+END;
+
+FUNCTION TView.CTextWidth (const Txt: String): Sw_Integer;
+VAR I: Sw_Integer; S: String;
+BEGIN
+ S := Txt; { Transfer text }
+ Repeat
+ I := Pos('~', S); { Check for tilde }
+ If (I <> 0) Then System.Delete(S, I, 1); { Remove the tilde }
+ Until (I = 0); { Remove all tildes }
+ CTextWidth := Length(S); { Calc text length }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ MouseInView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.MouseInView (Point: TPoint): Boolean;
+BEGIN
+ MakeLocal(Point,Point);
+ MouseInView := (Point.X >= 0) and
+ (Point.Y >= 0) and
+ (Point.X < Size.X) and
+ (Point.Y < Size.Y);
+END;
+
+{--TView--------------------------------------------------------------------}
+{ CommandEnabled -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.CommandEnabled(Command: Word): Boolean;
+BEGIN
+ CommandEnabled := (Command > 255) OR
+ (Command IN CurCommandSet); { Check command }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ OverLapsArea -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.OverlapsArea (X1, Y1, X2, Y2: Sw_Integer): Boolean;
+BEGIN
+ OverLapsArea := False; { Preset false }
+ If (Origin.X > X2) Then Exit; { Area to the left }
+ If ((Origin.X + Size.X) < X1) Then Exit; { Area to the right }
+ If (Origin.Y > Y2) Then Exit; { Area is above }
+ If ((Origin.Y + Size.Y) < Y1) Then Exit; { Area is below }
+ OverLapsArea := True; { Return true }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ MouseEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TView.MouseEvent (Var Event: TEvent; Mask: Word): Boolean;
+BEGIN
+ Repeat
+ GetEvent(Event); { Get next event }
+ Until (Event.What AND (Mask OR evMouseUp) <> 0); { Wait till valid }
+ MouseEvent := Event.What <> evMouseUp; { Return result }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Hide -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Hide;
+BEGIN
+ If (State AND sfVisible <> 0) Then { View is visible }
+ SetState(sfVisible, False); { Hide the view }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Show -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Show;
+BEGIN
+ If (State AND sfVisible = 0) Then { View not visible }
+ SetState(sfVisible, True); { Show the view }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Draw;
+VAR B : TDrawBuffer;
+BEGIN
+ MoveChar(B, ' ', GetColor(1), Size.X);
+ WriteLine(0, 0, Size.X, Size.Y, B);
+END;
+
+
+procedure TView.ResetCursor;
+const
+ sfV_CV_F:word = sfVisible + sfCursorVis + sfFocused;
+var
+ p,p2 : PView;
+ G : PGroup;
+ cur : TPoint;
+
+ function Check0:boolean;
+ var
+ res : byte;
+ begin
+ res:=0;
+ while res=0 do
+ begin
+ p:=p^.next;
+ if p=p2 then
+ begin
+ p:=P^.owner;
+ res:=1
+ end
+ else
+ if ((p^.state and sfVisible)<>0) and
+ (cur.x>=p^.origin.x) and
+ (cur.x<p^.size.x+p^.origin.x) and
+ (cur.y>=p^.origin.y) and
+ (cur.y<p^.size.y+p^.origin.y) then
+ res:=2;
+ end;
+ Check0:=res=2;
+ end;
+
+begin
+ if ((state and sfV_CV_F) = sfV_CV_F) then
+ begin
+ p:=@Self;
+ cur:=cursor;
+ while true do
+ begin
+ if (cur.x<0) or (cur.x>=p^.size.x) or
+ (cur.y<0) or (cur.y>=p^.size.y) then
+ break;
+ inc(cur.X,p^.origin.X);
+ inc(cur.Y,p^.origin.Y);
+ p2:=p;
+ G:=p^.owner;
+ if G=Nil then { top view }
+ begin
+ Video.SetCursorPos(cur.x,cur.y);
+ if (state and sfCursorIns)<>0 then
+ Video.SetCursorType(crBlock)
+ else
+ Video.SetCursorType(crUnderline);
+ exit;
+ end;
+ if (G^.state and sfVisible)=0 then
+ break;
+ p:=G^.Last;
+ if Check0 then
+ break;
+ end; { while }
+ end; { if }
+ Video.SetCursorType(crHidden);
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ Select -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 05May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Select;
+BEGIN
+ If (Options AND ofSelectable <> 0) Then { View is selectable }
+ If (Options AND ofTopSelect <> 0) Then MakeFirst { Top selectable }
+ Else If (Owner <> Nil) Then { Valid owner }
+ Owner^.SetCurrent(@Self, NormalSelect); { Make owners current }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Awaken -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Awaken;
+BEGIN { Abstract method }
+END;
+
+
+{--TView--------------------------------------------------------------------}
+{ MakeFirst -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.MakeFirst;
+BEGIN
+ If (Owner <> Nil) Then Begin { Must have owner }
+ PutInFrontOf(Owner^.First); { Float to the top }
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ DrawCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.DrawCursor;
+BEGIN { Abstract method }
+ if State and sfFocused <> 0 then
+ ResetCursor;
+END;
+
+
+procedure TView.DrawHide(LastView: PView);
+begin
+ TView.DrawCursor;
+ DrawUnderView(State and sfShadow <> 0, LastView);
+end;
+
+
+procedure TView.DrawShow(LastView: PView);
+begin
+ DrawView;
+ if State and sfShadow <> 0 then
+ DrawUnderView(True, LastView);
+end;
+
+
+procedure TView.DrawUnderRect(var R: TRect; LastView: PView);
+begin
+ Owner^.Clip.Intersect(R);
+ Owner^.DrawSubViews(NextView, LastView);
+ Owner^.GetExtent(Owner^.Clip);
+end;
+
+
+procedure TView.DrawUnderView(DoShadow: Boolean; LastView: PView);
+var
+ R: TRect;
+begin
+ GetBounds(R);
+ if DoShadow then
+ begin
+ inc(R.B.X,ShadowSize.X);
+ inc(R.B.Y,ShadowSize.Y);
+ end;
+ DrawUnderRect(R, LastView);
+end;
+
+
+procedure TView.DrawView;
+begin
+ if Exposed then
+ begin
+ LockScreenUpdate; { don't update the screen yet }
+ Draw;
+ UnLockScreenUpdate;
+ DrawScreenBuf(false);
+ TView.DrawCursor;
+ end;
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ HideCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.HideCursor;
+BEGIN
+ SetState(sfCursorVis , False); { Hide the cursor }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ ShowCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.ShowCursor;
+BEGIN
+ SetState(sfCursorVis , True); { Show the cursor }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ BlockCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.BlockCursor;
+BEGIN
+ SetState(sfCursorIns, True); { Set insert mode }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ NormalCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.NormalCursor;
+BEGIN
+ SetState(sfCursorIns, False); { Clear insert mode }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ FocusFromTop -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11Aug99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.FocusFromTop;
+BEGIN
+ If (Owner <> Nil) AND
+ (Owner^.State AND sfSelected = 0)
+ Then Owner^.Select;
+ If (State AND sfFocused = 0) Then Focus;
+ If (State AND sfSelected = 0) Then Select;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ MoveTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.MoveTo (X, Y: Sw_Integer);
+VAR R: TRect;
+BEGIN
+ R.Assign(X, Y, X + Size.X, Y + Size.Y); { Assign area }
+ Locate(R); { Locate the view }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GrowTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GrowTo (X, Y: Sw_Integer);
+VAR R: TRect;
+BEGIN
+ R.Assign(Origin.X, Origin.Y, Origin.X + X,
+ Origin.Y + Y); { Assign area }
+ Locate(R); { Locate the view }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ EndModal -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.EndModal (Command: Word);
+VAR P: PView;
+BEGIN
+ P := TopView; { Get top view }
+ If (P <> Nil) Then P^.EndModal(Command); { End modal operation }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SetCursor -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SetCursor (X, Y: Sw_Integer);
+BEGIN
+ if (Cursor.X<>X) or (Cursor.Y<>Y) then
+ begin
+ Cursor.X := X;
+ Cursor.Y := Y;
+ CursorChanged;
+ end;
+ TView.DrawCursor;
+END;
+
+
+procedure TView.CursorChanged;
+begin
+ Message(Owner,evBroadcast,cmCursorChanged,@Self);
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ PutInFrontOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.PutInFrontOf (Target: PView);
+VAR P, LastView: PView;
+BEGIN
+ If (Owner <> Nil) AND (Target <> @Self) AND
+ (Target <> NextView) AND ((Target = Nil) OR
+ (Target^.Owner = Owner)) Then { Check validity }
+ If (State AND sfVisible = 0) Then Begin { View not visible }
+ Owner^.RemoveView(@Self); { Remove from list }
+ Owner^.InsertView(@Self, Target); { Insert into list }
+ End Else Begin
+ LastView := NextView; { Hold next view }
+ If (LastView <> Nil) Then Begin { Lastview is valid }
+ P := Target; { P is target }
+ While (P <> Nil) AND (P <> LastView)
+ Do P := P^.NextView; { Find our next view }
+ If (P = Nil) Then LastView := Target; { Lastview is target }
+ End;
+ State := State AND NOT sfVisible; { Temp stop drawing }
+ If (LastView = Target) Then
+ DrawHide(LastView);
+ Owner^.Lock;
+ Owner^.RemoveView(@Self); { Remove from list }
+ Owner^.InsertView(@Self, Target); { Insert into list }
+ State := State OR sfVisible; { Allow drawing again }
+ If (LastView <> Target) Then
+ DrawShow(LastView);
+ If (Options AND ofSelectable <> 0) Then { View is selectable }
+ begin
+ Owner^.ResetCurrent; { Reset current }
+ Owner^.ResetCursor;
+ end;
+ Owner^.Unlock;
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SetCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SetCommands (Commands: TCommandSet);
+BEGIN
+ CommandSetChanged := CommandSetChanged OR
+ (CurCommandSet <> Commands); { Set change flag }
+ CurCommandSet := Commands; { Set command set }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ EnableCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.EnableCommands (Commands: TCommandSet);
+BEGIN
+ CommandSetChanged := CommandSetChanged OR
+ (CurCommandSet * Commands <> Commands); { Set changed flag }
+ CurCommandSet := CurCommandSet + Commands; { Update command set }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ DisableCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.DisableCommands (Commands: TCommandSet);
+BEGIN
+ CommandSetChanged := CommandSetChanged OR
+ (CurCommandSet * Commands <> []); { Set changed flag }
+ CurCommandSet := CurCommandSet - Commands; { Update command set }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SetState (AState: Word; Enable: Boolean);
+var
+ Command: Word;
+ OState : Word;
+begin
+ OState:=State;
+ if Enable then
+ State := State or AState
+ else
+ State := State and not AState;
+ if Owner <> nil then
+ case AState of
+ sfVisible:
+ begin
+ if Owner^.State and sfExposed <> 0 then
+ SetState(sfExposed, Enable);
+ if Enable then
+ DrawShow(nil)
+ else
+ DrawHide(nil);
+ if Options and ofSelectable <> 0 then
+ Owner^.ResetCurrent;
+ end;
+ sfCursorVis,
+ sfCursorIns:
+ TView.DrawCursor;
+ sfShadow:
+ DrawUnderView(True, nil);
+ sfFocused:
+ begin
+ ResetCursor;
+ if Enable then
+ Command := cmReceivedFocus
+ else
+ Command := cmReleasedFocus;
+ Message(Owner, evBroadcast, Command, @Self);
+ end;
+ end;
+ if ((OState xor State) and (sfCursorVis+sfCursorIns+sfFocused))<>0 then
+ CursorChanged;
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ SetCmdState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SetCmdState (Commands: TCommandSet; Enable: Boolean);
+BEGIN
+ If Enable Then EnableCommands(Commands) { Enable commands }
+ Else DisableCommands(Commands); { Disable commands }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetData (Var Rec);
+BEGIN { Abstract method }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SetData (Var Rec);
+BEGIN { Abstract method }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Store (Var S: TStream);
+VAR SaveState: Word;
+ i: integer;
+BEGIN
+ SaveState := State; { Hold current state }
+ State := State AND NOT (sfActive OR sfSelected OR
+ sfFocused OR sfExposed); { Clear flags }
+ i:=Origin.X;S.Write(i, SizeOf(i)); { Write view x origin }
+ i:=Origin.Y;S.Write(i, SizeOf(i)); { Write view y origin }
+ i:=Size.X;S.Write(i, SizeOf(i)); { Write view x size }
+ i:=Size.Y;S.Write(i, SizeOf(i)); { Write view y size }
+ i:=Cursor.X;S.Write(i, SizeOf(i)); { Write cursor x size }
+ i:=Cursor.Y;S.Write(i, SizeOf(i)); { Write cursor y size }
+ S.Write(GrowMode, SizeOf(GrowMode)); { Write growmode flags }
+ S.Write(DragMode, SizeOf(DragMode)); { Write dragmode flags }
+ S.Write(HelpCtx, SizeOf(HelpCtx)); { Write help context }
+ S.Write(State, SizeOf(State)); { Write state masks }
+ S.Write(Options, SizeOf(Options)); { Write options masks }
+ S.Write(Eventmask, SizeOf(Eventmask)); { Write event masks }
+ State := SaveState; { Reset state masks }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ Locate -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.Locate (Var Bounds: TRect);
+VAR
+ Min, Max: TPoint; R: TRect;
+
+ FUNCTION Range(Val, Min, Max: Sw_Integer): Sw_Integer;
+ BEGIN
+ If (Val < Min) Then Range := Min Else { Value to small }
+ If (Val > Max) Then Range := Max Else { Value to large }
+ Range := Val; { Value is okay }
+ END;
+
+BEGIN
+ SizeLimits(Min, Max); { Get size limits }
+ Bounds.B.X := Bounds.A.X + Range(Bounds.B.X -
+ Bounds.A.X, Min.X, Max.X); { X bound limit }
+ Bounds.B.Y := Bounds.A.Y + Range(Bounds.B.Y
+ - Bounds.A.Y, Min.Y, Max.Y); { Y bound limit }
+ GetBounds(R); { Current bounds }
+ If NOT Bounds.Equals(R) Then Begin { Size has changed }
+ ChangeBounds(Bounds); { Change bounds }
+ If (State AND sfVisible <> 0) AND { View is visible }
+ (State AND sfExposed <> 0) AND (Owner <> Nil) { Check view exposed }
+ Then
+ begin
+ if State and sfShadow <> 0 then
+ begin
+ R.Union(Bounds);
+ Inc(R.B.X, ShadowSize.X);
+ Inc(R.B.Y, ShadowSize.Y);
+ end;
+ DrawUnderRect(R, nil);
+ end;
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ KeyEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.KeyEvent (Var Event: TEvent);
+BEGIN
+ Repeat
+ GetEvent(Event); { Get next event }
+ Until (Event.What = evKeyDown); { Wait till keydown }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetEvent (Var Event: TEvent);
+BEGIN
+ If (Owner <> Nil) Then Owner^.GetEvent(Event); { Event from owner }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ PutEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.PutEvent (Var Event: TEvent);
+BEGIN
+ If (Owner <> Nil) Then Owner^.PutEvent(Event); { Put in owner }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetExtent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetExtent (Var Extent: TRect);
+BEGIN
+ Extent.A.X := 0; { Zero x field }
+ Extent.A.Y := 0; { Zero y field }
+ Extent.B.X := Size.X; { Return x size }
+ Extent.B.Y := Size.Y; { Return y size }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetBounds (Var Bounds: TRect);
+BEGIN
+ Bounds.A := Origin; { Get first corner }
+ Bounds.B.X := Origin.X + Size.X; { Calc corner x value }
+ Bounds.B.Y := Origin.Y + Size.Y; { Calc corner y value }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SetBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 24Sep99 LdB }
+{---------------------------------------------------------------------------}
+procedure TView.SetBounds(var Bounds: TRect);
+begin
+ Origin := Bounds.A; { Get first corner }
+ Size := Bounds.B; { Get second corner }
+ Dec(Size.X,Origin.X);
+ Dec(Size.Y,Origin.Y);
+end;
+
+{--TView--------------------------------------------------------------------}
+{ GetClipRect -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetClipRect (Var Clip: TRect);
+BEGIN
+ GetBounds(Clip); { Get current bounds }
+ If (Owner <> Nil) Then Clip.Intersect(Owner^.Clip);{ Intersect with owner }
+ Clip.Move(-Origin.X, -Origin.Y); { Sub owner origin }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ ClearEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.ClearEvent (Var Event: TEvent);
+BEGIN
+ Event.What := evNothing; { Clear the event }
+ Event.InfoPtr := @Self; { Set us as handler }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.HandleEvent (Var Event: TEvent);
+BEGIN
+ If (Event.What = evMouseDown) Then { Mouse down event }
+ If (State AND (sfSelected OR sfDisabled) = 0) { Not selected/disabled }
+ AND (Options AND ofSelectable <> 0) Then { View is selectable }
+ If (Focus = False) OR { Not view with focus }
+ (Options AND ofFirstClick = 0) { Not 1st click select }
+ Then ClearEvent(Event); { Handle the event }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.ChangeBounds (Var Bounds: TRect);
+BEGIN
+ SetBounds(Bounds); { Set new bounds }
+ DrawView; { Draw the view }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ SizeLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.SizeLimits (Var Min, Max: TPoint);
+BEGIN
+ Min.X := 0; { Zero x minimum }
+ Min.Y := 0; { Zero y minimum }
+ If (Owner <> Nil) and(Owner^.ClipChilds) Then
+ Max := Owner^.Size
+ else { Max owner size }
+ Begin
+ Max.X := high(sw_integer); { Max possible x size }
+ Max.Y := high(sw_integer); { Max possible y size }
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetCommands -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetCommands (Var Commands: TCommandSet);
+BEGIN
+ Commands := CurCommandSet; { Return command set }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ GetPeerViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.GetPeerViewPtr (Var S: TStream; Var P);
+VAR Index: Integer;
+BEGIN
+ Index := 0; { Zero index value }
+ S.Read(Index, SizeOf(Index)); { Read view index }
+ If (Index = 0) OR (OwnerGroup = Nil) Then { Check for peer views }
+ Pointer(P) := Nil Else Begin { Return nil }
+ Pointer(P) := FixupList^[Index]; { New view ptr }
+ FixupList^[Index] := @P; { Patch this pointer }
+ End;
+END;
+
+{--TView--------------------------------------------------------------------}
+{ PutPeerViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.PutPeerViewPtr (Var S: TStream; P: PView);
+VAR Index: Integer;
+BEGIN
+ If (P = Nil) OR (OwnerGroup = Nil) Then Index := 0 { Return zero index }
+ Else Index := OwnerGroup^.IndexOf(P); { Return view index }
+ S.Write(Index, SizeOf(Index)); { Write the index }
+END;
+
+{--TView--------------------------------------------------------------------}
+{ CalcBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.CalcBounds (Var Bounds: Objects.TRect; Delta: TPoint);
+VAR S, D: Sw_Integer; Min, Max: TPoint;
+
+ FUNCTION Range (Val, Min, Max: Sw_Integer): Sw_Integer;
+ BEGIN
+ If (Val < Min) Then Range := Min Else { Value below min }
+ If (Val > Max) Then Range := Max Else { Value above max }
+ Range := Val; { Accept value }
+ END;
+
+ PROCEDURE GrowI (Var I: Sw_Integer);
+ BEGIN
+ If (GrowMode AND gfGrowRel = 0) Then Inc(I, D)
+ Else I := (I * S + (S - D) SHR 1) DIV (S - D); { Calc grow value }
+ END;
+
+BEGIN
+ GetBounds(Bounds); { Get bounds }
+ If (GrowMode = 0) Then Exit; { No grow flags exits }
+ S := Owner^.Size.X; { Set initial size }
+ D := Delta.X; { Set initial delta }
+ If (GrowMode AND gfGrowLoX <> 0) Then
+ GrowI(Bounds.A.X); { Grow left side }
+ If (GrowMode AND gfGrowHiX <> 0) Then
+ GrowI(Bounds.B.X); { Grow right side }
+ If (Bounds.B.X - Bounds.A.X > MaxViewWidth) Then
+ Bounds.B.X := Bounds.A.X + MaxViewWidth; { Check values }
+ S := Owner^.Size.Y; D := Delta.Y; { set initial values }
+ If (GrowMode AND gfGrowLoY <> 0) Then
+ GrowI(Bounds.A.Y); { Grow top side }
+ If (GrowMode AND gfGrowHiY <> 0) Then
+ GrowI(Bounds.B.Y); { grow lower side }
+ SizeLimits(Min, Max); { Check sizes }
+ Bounds.B.X := Bounds.A.X + Range(Bounds.B.X -
+ Bounds.A.X, Min.X, Max.X); { Set right side }
+ Bounds.B.Y := Bounds.A.Y + Range(Bounds.B.Y -
+ Bounds.A.Y, Min.Y, Max.Y); { Set lower side }
+END;
+
+{***************************************************************************}
+{ TView OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TGroup OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TGroup-------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TGroup.Init (Var Bounds: TRect);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR (ofSelectable + ofBuffered); { Set options }
+ GetExtent(Clip); { Get clip extents }
+ EventMask := $FFFF; { See all events }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TGroup.Load (Var S: TStream);
+VAR I: Sw_Word;
+ Count: Word;
+ P, Q: ^Pointer; V: PView; OwnerSave: PGroup;
+ FixupSave: PFixupList;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetExtent(Clip); { Get view extents }
+ OwnerSave := OwnerGroup; { Save current group }
+ OwnerGroup := @Self; { We are current group }
+ FixupSave := FixupList; { Save current list }
+ Count := 0; { Zero count value }
+ S.Read(Count, SizeOf(Count)); { Read entry count }
+ If (MaxAvail >= Count*SizeOf(Pointer)) Then Begin { Memory available }
+ GetMem(FixupList, Count*SizeOf(Pointer)); { List size needed }
+ FillChar(FixUpList^, Count*SizeOf(Pointer), #0); { Zero all entries }
+ For I := 1 To Count Do Begin
+ V := PView(S.Get); { Get view off stream }
+ If (V <> Nil) Then InsertView(V, Nil); { Insert valid views }
+ End;
+ V := Last; { Start on last view }
+ For I := 1 To Count Do Begin
+ V := V^.Next; { Fetch next view }
+ P := FixupList^[I]; { Transfer pointer }
+ While (P <> Nil) Do Begin { If valid view }
+ Q := P; { Copy pointer }
+ P := P^; { Fetch pointer }
+ Q^ := V; { Transfer view ptr }
+ End;
+ End;
+ FreeMem(FixupList, Count*SizeOf(Pointer)); { Release fixup list }
+ End;
+ OwnerGroup := OwnerSave; { Reload current group }
+ FixupList := FixupSave; { Reload current list }
+ GetSubViewPtr(S, V); { Load any subviews }
+ SetCurrent(V, NormalSelect); { Select current view }
+ If (OwnerGroup = Nil) Then Awaken; { If topview activate }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TGroup.Done;
+VAR P, T: PView;
+BEGIN
+ Hide; { Hide the view }
+ P := Last; { Start on last }
+ If (P <> Nil) Then Begin { Subviews exist }
+ Repeat
+ P^.Hide; { Hide each view }
+ P := P^.Prev; { Prior view }
+ Until (P = Last); { Loop complete }
+ Repeat
+ T := P^.Prev; { Hold prior pointer }
+ Dispose(P, Done); { Dispose subview }
+ P := T; { Transfer pointer }
+ Until (Last = Nil); { Loop complete }
+ End;
+ Inherited Done; { Call ancestor }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ First -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.First: PView;
+BEGIN
+ If (Last = Nil) Then First := Nil { No first view }
+ Else First := Last^.Next; { Return first view }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Execute -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.Execute: Word;
+VAR Event: TEvent;
+BEGIN
+ Repeat
+ EndState := 0; { Clear end state }
+ Repeat
+ GetEvent(Event); { Get next event }
+ HandleEvent(Event); { Handle the event }
+ If (Event.What <> evNothing) Then
+ EventError(Event); { Event not handled }
+ Until (EndState <> 0); { Until command set }
+ Until Valid(EndState); { Repeat until valid }
+ Execute := EndState; { Return result }
+ EndState := 0; { Clear end state }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ GetHelpCtx -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.GetHelpCtx: Word;
+VAR H: Word;
+BEGIN
+ H := hcNoContext; { Preset no context }
+ If (Current <> Nil) Then H := Current^.GetHelpCtx; { Current context }
+ If (H=hcNoContext) Then H := Inherited GetHelpCtx; { Call ancestor }
+ GetHelpCtx := H; { Return result }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ DataSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.DataSize: Sw_Word;
+VAR Total: Word; P: PView;
+BEGIN
+ Total := 0; { Zero totals count }
+ P := Last; { Start on last view }
+ If (P <> Nil) Then Begin { Subviews exist }
+ Repeat
+ P := P^.Next; { Move to next view }
+ Total := Total + P^.DataSize; { Add view size }
+ Until (P = Last); { Until last view }
+ End;
+ DataSize := Total; { Return data size }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ ExecView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Jul99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.ExecView (P: PView): Word;
+VAR SaveOptions: Word; SaveTopView, SaveCurrent: PView; SaveOwner: PGroup;
+ SaveCommands: TCommandSet;
+BEGIN
+ If (P<>Nil) Then Begin
+ SaveOptions := P^.Options; { Hold options }
+ SaveOwner := P^.Owner; { Hold owner }
+ SaveTopView := TheTopView; { Save topmost view }
+ SaveCurrent := Current; { Save current view }
+ GetCommands(SaveCommands); { Save commands }
+ TheTopView := P; { Set top view }
+ P^.Options := P^.Options AND NOT ofSelectable; { Not selectable }
+ P^.SetState(sfModal, True); { Make modal }
+ SetCurrent(P, EnterSelect); { Select next }
+ If (SaveOwner = Nil) Then Insert(P); { Insert view }
+ ExecView := P^.Execute; { Execute view }
+ If (SaveOwner = Nil) Then Delete(P); { Remove view }
+ SetCurrent(SaveCurrent, LeaveSelect); { Unselect current }
+ P^.SetState(sfModal, False); { Clear modal state }
+ P^.Options := SaveOptions; { Restore options }
+ TheTopView := SaveTopView; { Restore topview }
+ SetCommands(SaveCommands); { Restore commands }
+ End Else ExecView := cmCancel; { Return cancel }
+END;
+
+{ ********************************* REMARK ******************************** }
+{ This call really is very COMPILER SPECIFIC and really can't be done }
+{ effectively any other way but assembler code as SELF & FRAMES need }
+{ to be put down in exact order and OPTIMIZERS make a mess of it. }
+{ ******************************** END REMARK *** Leon de Boer, 17Jul99 *** }
+
+{--TGroup-------------------------------------------------------------------}
+{ FirstThat -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.FirstThat (P: Pointer): PView;
+VAR
+ Tp : PView;
+BEGIN
+ If (Last<>Nil) Then
+ Begin
+ Tp := Last; { Set temporary ptr }
+ Repeat
+ Tp := Tp^.Next; { Get next view }
+ IF Byte(Longint(CallPointerMethodLocal(P,get_caller_frame(get_frame),@self,Tp)))<>0 THEN
+ Begin { Test each view }
+ FirstThat := Tp; { View returned true }
+ Exit; { Now exit }
+ End;
+ Until (Tp=Last); { Until last }
+ FirstThat := Nil; { None passed test }
+ End
+ Else
+ FirstThat := Nil; { Return nil }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Valid -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.Valid (Command: Word): Boolean;
+
+ FUNCTION IsInvalid (P: PView): Boolean;
+ BEGIN
+ IsInvalid := NOT P^.Valid(Command); { Check if valid }
+ END;
+
+BEGIN
+ Valid := True; { Preset valid }
+ If (Command = cmReleasedFocus) Then Begin { Release focus cmd }
+ If (Current <> Nil) AND { Current view exists }
+ (Current^.Options AND ofValidate <> 0) Then { Validating view }
+ Valid := Current^.Valid(Command); { Validate command }
+ End Else Valid := FirstThat(@IsInvalid) = Nil; { Check first valid }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ FocusNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.FocusNext (Forwards: Boolean): Boolean;
+VAR P: PView;
+BEGIN
+ P := FindNext(Forwards); { Find next view }
+ FocusNext := True; { Preset true }
+ If (P <> Nil) Then FocusNext := P^.Focus; { Check next focus }
+END;
+
+
+procedure TGroup.DrawSubViews(P, Bottom: PView);
+begin
+ if P <> nil then
+ while P <> Bottom do
+ begin
+ P^.DrawView;
+ P := P^.NextView;
+ end;
+end;
+
+
+{--TGroup-------------------------------------------------------------------}
+{ ReDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 2Jun06 DM }
+{---------------------------------------------------------------------------}
+procedure TGroup.Redraw;
+begin
+ {Lock to prevent screen update.}
+ lockscreenupdate;
+ DrawSubViews(First, nil);
+ unlockscreenupdate;
+ {Draw all views at once, forced update.}
+ drawscreenbuf(true);
+end;
+
+
+PROCEDURE TGroup.ResetCursor;
+BEGIN
+ if (Current<>nil) then
+ Current^.ResetCursor;
+END;
+
+
+{--TGroup-------------------------------------------------------------------}
+{ Awaken -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Awaken;
+
+ PROCEDURE DoAwaken (P: PView);
+ BEGIN
+ If (P <> Nil) Then P^.Awaken; { Awaken view }
+ END;
+
+BEGIN
+ ForEach(@DoAwaken); { Awaken each view }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Draw;
+BEGIN
+ If Buffer=Nil then
+ DrawSubViews(First, nil)
+ else
+ WriteBuf(0,0,Size.X,Size.Y,Buffer);
+END;
+
+
+{--TGroup-------------------------------------------------------------------}
+{ SelectDefaultView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.SelectDefaultView;
+VAR P: PView;
+BEGIN
+ P := Last; { Start at last }
+ While (P <> Nil) Do Begin
+ If P^.GetState(sfDefault) Then Begin { Search 1st default }
+ P^.Select; { Select default view }
+ P := Nil; { Force kick out }
+ End Else P := P^.PrevView; { Prior subview }
+ End;
+END;
+
+
+function TGroup.ClipChilds: boolean;
+begin
+ ClipChilds:=true;
+end;
+
+
+procedure TGroup.BeforeInsert(P: PView);
+begin
+ { abstract }
+end;
+
+procedure TGroup.AfterInsert(P: PView);
+begin
+ { abstract }
+end;
+
+procedure TGroup.BeforeDelete(P: PView);
+begin
+ { abstract }
+end;
+
+procedure TGroup.AfterDelete(P: PView);
+begin
+ { abstract }
+end;
+
+{--TGroup-------------------------------------------------------------------}
+{ Insert -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Insert (P: PView);
+BEGIN
+ BeforeInsert(P);
+ InsertBefore(P, First);
+ AfterInsert(P);
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Delete -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Delete (P: PView);
+VAR SaveState: Word;
+BEGIN
+ BeforeDelete(P);
+ SaveState := P^.State; { Save state }
+ P^.Hide; { Hide the view }
+ RemoveView(P); { Remove the view }
+ P^.Owner := Nil; { Clear owner ptr }
+ P^.Next := Nil; { Clear next ptr }
+ if SaveState and sfVisible <> 0 then
+ P^.Show;
+ AfterDelete(P);
+END;
+
+{ ********************************* REMARK ******************************** }
+{ This call really is very COMPILER SPECIFIC and really can't be done }
+{ effectively any other way but assembler code as SELF & FRAMES need }
+{ to be put down in exact order and OPTIMIZERS make a mess of it. }
+{ ******************************** END REMARK *** Leon de Boer, 17Jul99 *** }
+
+{--TGroup-------------------------------------------------------------------}
+{ ForEach -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 17Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.ForEach (P: Pointer);
+VAR
+ Tp,Hp,L0 : PView;
+{ Vars Hp and L0 are necessary to hold original pointers in case }
+{ when some view closes himself as a result of broadcast message ! }
+BEGIN
+ If (Last<>Nil) Then
+ Begin
+ Tp:=Last;
+ Hp:=Tp^.Next;
+ L0:=Last; { Set temporary ptr }
+ Repeat
+ Tp:=Hp;
+ if tp=nil then
+ exit;
+ Hp:=Tp^.Next; { Get next view }
+ CallPointerMethodLocal(P,get_caller_frame(get_frame),@self,Tp);
+ Until (Tp=L0); { Until last }
+ End;
+END;
+
+
+
+{--TGroup-------------------------------------------------------------------}
+{ EndModal -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.EndModal (Command: Word);
+BEGIN
+ If (State AND sfModal <> 0) Then { This view is modal }
+ EndState := Command Else { Set endstate }
+ Inherited EndModal(Command); { Call ancestor }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ SelectNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.SelectNext (Forwards: Boolean);
+VAR P: PView;
+BEGIN
+ P := FindNext(Forwards); { Find next view }
+ If (P <> Nil) Then P^.Select; { Select view }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ InsertBefore -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.InsertBefore (P, Target: PView);
+VAR SaveState : Word;
+BEGIN
+ If (P <> Nil) AND (P^.Owner = Nil) AND { View valid }
+ ((Target = Nil) OR (Target^.Owner = @Self)) { Target valid }
+ Then Begin
+ If (P^.Options AND ofCenterX <> 0) Then { Centre on x axis }
+ P^.Origin.X := (Size.X - P^.Size.X) div 2;
+ If (P^.Options AND ofCenterY <> 0) Then { Centre on y axis }
+ P^.Origin.Y := (Size.Y - P^.Size.Y) div 2;
+ SaveState := P^.State; { Save view state }
+ P^.Hide; { Make sure hidden }
+ InsertView(P, Target); { Insert into list }
+ If (SaveState AND sfVisible <> 0) Then P^.Show; { Show the view }
+ If (State AND sfActive <> 0) Then { Was active before }
+ P^.SetState(sfActive , True); { Make active again }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.SetState (AState: Word; Enable: Boolean);
+
+ PROCEDURE DoSetState (P: PView);
+ BEGIN
+ If (P <> Nil) Then P^.SetState(AState, Enable); { Set subview state }
+ END;
+
+ PROCEDURE DoExpose (P: PView);
+ BEGIN
+ If (P <> Nil) Then Begin
+ If (P^.State AND sfVisible <> 0) Then { Check view visible }
+ P^.SetState(sfExposed, Enable); { Set exposed flag }
+ End;
+ END;
+
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ Case AState Of
+ sfActive, sfDragging: Begin
+ Lock; { Lock the view }
+ ForEach(@DoSetState); { Set each subview }
+ UnLock; { Unlock the view }
+ End;
+ sfFocused: Begin
+ If (Current <> Nil) Then
+ Current^.SetState(sfFocused, Enable); { Focus current view }
+ End;
+ sfExposed: Begin
+ ForEach(@DoExpose); { Expose each subview }
+ End;
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ GetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Mar98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.GetData (Var Rec);
+VAR Total: Sw_Word; P: PView;
+BEGIN
+ Total := 0; { Clear total }
+ P := Last; { Start at last }
+ While (P <> Nil) Do Begin { Subviews exist }
+ P^.GetData(TByteArray(Rec)[Total]); { Get data }
+ Inc(Total, P^.DataSize); { Increase total }
+ P := P^.PrevView; { Previous view }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ SetData -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 29Mar98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.SetData (Var Rec);
+VAR Total: Sw_Word; P: PView;
+BEGIN
+ Total := 0; { Clear total }
+ P := Last; { Start at last }
+ While (P <> Nil) Do Begin { Subviews exist }
+ P^.SetData(TByteArray(Rec)[Total]); { Get data }
+ Inc(Total, P^.DataSize); { Increase total }
+ P := P^.PrevView; { Previous view }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Store (Var S: TStream);
+VAR Count: Word; OwnerSave: PGroup;
+
+ PROCEDURE DoPut (P: PView);
+ BEGIN
+ S.Put(P); { Put view on stream }
+ END;
+
+BEGIN
+ TView.Store(S); { Call view store }
+ OwnerSave := OwnerGroup; { Save ownergroup }
+ OwnerGroup := @Self; { Set as owner group }
+ Count := IndexOf(Last); { Subview count }
+ S.Write(Count, SizeOf(Count)); { Write the count }
+ ForEach(@DoPut); { Put each in stream }
+ PutSubViewPtr(S, Current); { Current on stream }
+ OwnerGroup := OwnerSave; { Restore ownergroup }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ EventError -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.EventError (Var Event: TEvent);
+BEGIN
+ If (Owner <> Nil) Then Owner^.EventError(Event); { Event error }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.HandleEvent (Var Event: TEvent);
+
+ FUNCTION ContainsMouse (P: PView): Boolean;
+ BEGIN
+ ContainsMouse := (P^.State AND sfVisible <> 0) { Is view visible }
+ AND P^.MouseInView(Event.Where); { Is point in view }
+ END;
+
+ PROCEDURE DoHandleEvent (P: PView);
+ BEGIN
+ If (P = Nil) OR ((P^.State AND sfDisabled <> 0) AND
+ (Event.What AND(PositionalEvents OR FocusedEvents) <>0 ))
+ Then Exit; { Invalid/disabled }
+ Case Phase Of
+ phPreProcess: If (P^.Options AND ofPreProcess = 0)
+ Then Exit; { Not pre processing }
+ phPostProcess: If (P^.Options AND ofPostProcess = 0)
+ Then Exit; { Not post processing }
+ End;
+ If (Event.What AND P^.EventMask <> 0) Then { View handles event }
+ P^.HandleEvent(Event); { Pass to view }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evNothing) Then Exit; { No valid event exit }
+ If (Event.What AND FocusedEvents <> 0) Then Begin { Focused event }
+ Phase := phPreProcess; { Set pre process }
+ ForEach(@DoHandleEvent); { Pass to each view }
+ Phase := phFocused; { Set focused }
+ DoHandleEvent(Current); { Pass to current }
+ Phase := phPostProcess; { Set post process }
+ ForEach(@DoHandleEvent); { Pass to each }
+ End Else Begin
+ Phase := phFocused; { Set focused }
+ If (Event.What AND PositionalEvents <> 0) Then { Positional event }
+ DoHandleEvent(FirstThat(@ContainsMouse)) { Pass to first }
+ Else ForEach(@DoHandleEvent); { Pass to all }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.ChangeBounds (Var Bounds: TRect);
+VAR D: TPoint;
+
+ PROCEDURE DoCalcChange (P: PView);
+ VAR R: TRect;
+ BEGIN
+ P^.CalcBounds(R, D); { Calc view bounds }
+ P^.ChangeBounds(R); { Change view bounds }
+ END;
+
+BEGIN
+ D.X := Bounds.B.X - Bounds.A.X - Size.X; { Delta x value }
+ D.Y := Bounds.B.Y - Bounds.A.Y - Size.Y; { Delta y value }
+ If ((D.X=0) AND (D.Y=0)) Then Begin
+ SetBounds(Bounds); { Set new bounds }
+ { Force redraw }
+ ReDraw; { Draw the view }
+ End Else Begin
+ SetBounds(Bounds); { Set new bounds }
+ GetExtent(Clip); { Get new clip extents }
+ Lock; { Lock drawing }
+ ForEach(@DoCalcChange); { Change each view }
+ UnLock; { Unlock drawing }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ GetSubViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.GetSubViewPtr (Var S: TStream; Var P);
+VAR Index, I: Sw_Word; Q: PView;
+BEGIN
+ Index := 0; { Zero index value }
+ S.Read(Index, SizeOf(Index)); { Read view index }
+ If (Index > 0) Then Begin { Valid index }
+ Q := Last; { Start on last }
+ For I := 1 To Index Do Q := Q^.Next; { Loop for count }
+ Pointer(P) := Q; { Return the view }
+ End Else Pointer(P) := Nil; { Return nil }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ PutSubViewPtr -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 20May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.PutSubViewPtr (Var S: TStream; P: PView);
+VAR Index: Sw_Word;
+BEGIN
+ If (P = Nil) Then Index := 0 Else { Nil view, Index = 0 }
+ Index := IndexOf(P); { Calc view index }
+ S.Write(Index, SizeOf(Index)); { Write the index }
+END;
+
+
+{***************************************************************************}
+{ TGroup OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{--TGroup-------------------------------------------------------------------}
+{ IndexOf -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.IndexOf (P: PView): Sw_Integer;
+VAR I: Sw_Integer; Q: PView;
+BEGIN
+ Q := Last; { Start on last view }
+ If (Q <> Nil) Then Begin { Subviews exist }
+ I := 1; { Preset value }
+ While (Q <> P) AND (Q^.Next <> Last) Do Begin
+ Q := Q^.Next; { Load next view }
+ Inc(I); { Increment count }
+ End;
+ If (Q <> P) Then IndexOf := 0 Else IndexOf := I; { Return index }
+ End Else IndexOf := 0; { Return zero }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ FindNext -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.FindNext (Forwards: Boolean): PView;
+VAR P: PView;
+BEGIN
+ FindNext := Nil; { Preset nil return }
+ If (Current <> Nil) Then Begin { Has current view }
+ P := Current; { Start on current }
+ Repeat
+ If Forwards Then P := P^.Next { Get next view }
+ Else P := P^.Prev; { Get prev view }
+ Until ((P^.State AND (sfVisible+sfDisabled) = sfVisible) AND
+ (P^.Options AND ofSelectable <> 0)) OR { Tab selectable }
+ (P = Current); { Not singular select }
+ If (P <> Current) Then FindNext := P; { Return result }
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ FirstMatch -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TGroup.FirstMatch (AState: Word; AOptions: Word): PView;
+
+ FUNCTION Matches (P: PView): Boolean;
+ BEGIN
+ Matches := (P^.State AND AState = AState) AND
+ (P^.Options AND AOptions = AOptions); { Return match state }
+ END;
+
+BEGIN
+ FirstMatch := FirstThat(@Matches); { Return first match }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ ResetCurrent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.ResetCurrent;
+BEGIN
+ SetCurrent(FirstMatch(sfVisible, ofSelectable),
+ NormalSelect); { Reset current view }
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ RemoveView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.RemoveView (P: PView);
+VAR Q: PView;
+BEGIN
+ If (P <> Nil) AND (Last <> Nil) Then Begin { Check view is valid }
+ Q := Last; { Start on last view }
+ While (Q^.Next <> P) AND (Q^.Next <> Last) Do
+ Q := Q^.Next; { Find prior view }
+ If (Q^.Next = P) Then Begin { View found }
+ If (Q^.Next <> Q) Then Begin { Not only view }
+ Q^.Next := P^.Next; { Rechain views }
+ If (P = Last) Then Last := P^.Next; { Fix if last removed }
+ End Else Last := Nil; { Only view }
+ End;
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ InsertView -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.InsertView (P, Target: PView);
+BEGIN
+ If (P <> Nil) Then Begin { Check view is valid }
+ P^.Owner := @Self; { Views owner is us }
+ If (Target <> Nil) Then Begin { Valid target }
+ Target := Target^.Prev; { 1st part of chain }
+ P^.Next := Target^.Next; { 2nd part of chain }
+ Target^.Next := P; { Chain completed }
+ End Else Begin
+ If (Last <> Nil) Then Begin { Not first view }
+ P^.Next := Last^.Next; { 1st part of chain }
+ Last^.Next := P; { Completed chain }
+ End Else P^.Next := P; { 1st chain to self }
+ Last := P; { P is now last }
+ End;
+ End;
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ SetCurrent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.SetCurrent (P: PView; Mode: SelectMode);
+
+ PROCEDURE SelectView (P: PView; Enable: Boolean);
+ BEGIN
+ If (P <> Nil) Then { View is valid }
+ P^.SetState(sfSelected, Enable); { Select the view }
+ END;
+
+ PROCEDURE FocusView (P: PView; Enable: Boolean);
+ BEGIN
+ If (State AND sfFocused <> 0) AND (P <> Nil) { Check not focused }
+ Then P^.SetState(sfFocused, Enable); { Focus the view }
+ END;
+
+BEGIN
+ If (Current<>P) Then Begin { Not already current }
+ Lock; { Stop drawing }
+ FocusView(Current, False); { Defocus current }
+ If (Mode <> EnterSelect) Then
+ SelectView(Current, False); { Deselect current }
+ If (Mode<>LeaveSelect) Then SelectView(P, True); { Select view P }
+ FocusView(P, True); { Focus view P }
+ Current := P; { Set as current view }
+ UnLock; { Redraw now }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TFrame OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TFrame-------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TFrame.Init (Var Bounds: TRect);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ GrowMode := gfGrowHiX + gfGrowHiY; { Set grow modes }
+ EventMask := EventMask OR evBroadcast; { See broadcasts }
+END;
+
+procedure TFrame.FrameLine(var FrameBuf; Y, N: Sw_Integer; Color: Byte);
+const
+ InitFrame: array[0..17] of Byte =
+ ($06, $0A, $0C, $05, $00, $05, $03, $0A, $09,
+ $16, $1A, $1C, $15, $00, $15, $13, $1A, $19);
+ FrameChars_437: array[0..31] of Char =
+ ' À ³Úà ÙÄÁ¿´ÂÅ È ºÉÇ ¼ÍÏ»¶ÑÎ';
+ FrameChars_850: array[0..31] of Char =
+ ' À ³Úà ÙÄÁ¿´ÂÅ È ºÉº ¼ÍÍ»ºÍÎ';
+var
+ FrameMask : array[0..MaxViewWidth-1] of Byte;
+ ColorMask : word;
+ i,j,k : {Sw_ lo and hi are used !! }integer;
+ CurrView : PView;
+ p : Pchar;
+begin
+ FrameMask[0]:=InitFrame[n];
+ FillChar(FrameMask[1],Size.X-2,InitFrame[n+1]);
+ FrameMask[Size.X-1]:=InitFrame[n+2];
+ CurrView:=Owner^.Last^.Next;
+ while (CurrView<>PView(@Self)) do
+ begin
+ if ((CurrView^.Options and ofFramed)<>0) and
+ ((CurrView^.State and sfVisible)<>0) then
+ begin
+ i:=Y-CurrView^.Origin.Y;
+ if (i<0) then
+ begin
+ inc(i);
+ if i=0 then
+ i:=$0a06
+ else
+ i:=0;
+ end
+ else
+ begin
+ if i<CurrView^.Size.Y then
+ i:=$0005
+ else
+ if i=CurrView^.Size.Y then
+ i:=$0a03
+ else
+ i:=0;
+ end;
+ if (i<>0) then
+ begin
+ j:=CurrView^.Origin.X;
+ k:=CurrView^.Size.X+j;
+ if j<1 then
+ j:=1;
+ if k>Size.X then
+ k:=Size.X;
+ if (k>j) then
+ begin
+ FrameMask[j-1]:=FrameMask[j-1] or lo(i);
+ i:=(lo(i) xor hi(i)) or (i and $ff00);
+ FrameMask[k]:=FrameMask[k] or lo(i);
+ if hi(i)<>0 then
+ begin
+ dec(k,j);
+ repeat
+ FrameMask[j]:=FrameMask[j] or hi(i);
+ inc(j);
+ dec(k);
+ until k=0;
+ end;
+ end;
+ end;
+ end;
+ CurrView:=CurrView^.Next;
+ end;
+ ColorMask:=Color shl 8;
+ p:=framechars_437;
+ {$ifdef unix}
+ {Codepage variables are currently Unix only.}
+ if internal_codepage<>cp437 then
+ p:=framechars_850;
+ {$endif}
+ for i:=0 to Size.X-1 do
+ TVideoBuf(FrameBuf)[i]:=ord(p[FrameMask[i]]) or ColorMask;
+end;
+
+
+procedure TFrame.Draw;
+const
+ LargeC:array[boolean] of char=('^',#24);
+ RestoreC:array[boolean] of char=('|',#18);
+ ClickC:array[boolean] of char=('*',#15);
+var
+ CFrame, CTitle: Word;
+ F, I, L, Width: Sw_Integer;
+ B: TDrawBuffer;
+ Title: TTitleStr;
+ Min, Max: TPoint;
+begin
+ if State and sfDragging <> 0 then
+ begin
+ CFrame := $0505;
+ CTitle := $0005;
+ F := 0;
+ end
+ else if State and sfActive = 0 then
+ begin
+ CFrame := $0101;
+ CTitle := $0002;
+ F := 0;
+ end
+ else
+ begin
+ CFrame := $0503;
+ CTitle := $0004;
+ F := 9;
+ end;
+ CFrame := GetColor(CFrame);
+ CTitle := GetColor(CTitle);
+ Width := Size.X;
+ L := Width - 10;
+ if PWindow(Owner)^.Flags and (wfClose+wfZoom) <> 0 then
+ Dec(L,6);
+ FrameLine(B, 0, F, Byte(CFrame));
+ if (PWindow(Owner)^.Number <> wnNoNumber) and
+ (PWindow(Owner)^.Number < 10) then
+ begin
+ Dec(L,4);
+ if PWindow(Owner)^.Flags and wfZoom <> 0 then
+ I := 7
+ else
+ I := 3;
+ WordRec(B[Width - I]).Lo := PWindow(Owner)^.Number + $30;
+ end;
+ if Owner <> nil then
+ Title := PWindow(Owner)^.GetTitle(L)
+ else
+ Title := '';
+ if Title <> '' then
+ begin
+ L := Length(Title);
+ if L > Width - 10 then
+ L := Width - 10;
+ if L < 0 then
+ L := 0;
+ I := (Width - L) shr 1;
+ MoveChar(B[I - 1], ' ', CTitle, 1);
+ MoveBuf(B[I], Title[1], CTitle, L);
+ MoveChar(B[I + L], ' ', CTitle, 1);
+ end;
+ if State and sfActive <> 0 then
+ begin
+ if PWindow(Owner)^.Flags and wfClose <> 0 then
+ if FrameMode and fmCloseClicked = 0 then
+ MoveCStr(B[2], '[~þ~]', CFrame)
+ else
+ MoveCStr(B[2], '[~'+ClickC[LowAscii]+'~]', CFrame);
+ if PWindow(Owner)^.Flags and wfZoom <> 0 then
+ begin
+ MoveCStr(B[Width - 5], '[~'+LargeC[LowAscii]+'~]', CFrame);
+ Owner^.SizeLimits(Min, Max);
+ if FrameMode and fmZoomClicked <> 0 then
+ WordRec(B[Width - 4]).Lo := ord(ClickC[LowAscii])
+ else
+ if (Owner^.Size.X=Max.X) and (Owner^.Size.Y=Max.Y) then
+ WordRec(B[Width - 4]).Lo := ord(RestoreC[LowAscii]);
+ end;
+ end;
+ WriteLine(0, 0, Size.X, 1, B);
+ for I := 1 to Size.Y - 2 do
+ begin
+ FrameLine(B, I, F + 3, Byte(CFrame));
+ WriteLine(0, I, Size.X, 1, B);
+ end;
+ FrameLine(B, Size.Y - 1, F + 6, Byte(CFrame));
+ if State and sfActive <> 0 then
+ if PWindow(Owner)^.Flags and wfGrow <> 0 then
+ MoveCStr(B[Width - 2], '~ÄÙ~', CFrame);
+ WriteLine(0, Size.Y - 1, Size.X, 1, B);
+end;
+
+{--TFrame-------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TFrame.GetPalette: PPalette;
+CONST P: String[Length(CFrame)] = CFrame; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+procedure TFrame.HandleEvent(var Event: TEvent);
+var
+ Mouse: TPoint;
+
+ procedure DragWindow(Mode: Byte);
+ var
+ Limits: TRect;
+ Min, Max: TPoint;
+ begin
+ Owner^.Owner^.GetExtent(Limits);
+ Owner^.SizeLimits(Min, Max);
+ Owner^.DragView(Event, Owner^.DragMode or Mode, Limits, Min, Max);
+ ClearEvent(Event);
+ end;
+
+begin
+ TView.HandleEvent(Event);
+ if Event.What = evMouseDown then
+ begin
+ MakeLocal(Event.Where, Mouse);
+ if Mouse.Y = 0 then
+ begin
+ if (PWindow(Owner)^.Flags and wfClose <> 0) and
+ (State and sfActive <> 0) and (Mouse.X >= 2) and (Mouse.X <= 4) then
+ begin
+ {Close button clicked.}
+ repeat
+ MakeLocal(Event.Where, Mouse);
+ if (Mouse.X >= 2) and (Mouse.X <= 4) and (Mouse.Y = 0) then
+ FrameMode := fmCloseClicked
+ else FrameMode := 0;
+ DrawView;
+ until not MouseEvent(Event, evMouseMove + evMouseAuto);
+ FrameMode := 0;
+ if (Mouse.X >= 2) and (Mouse.X <= 4) and (Mouse.Y = 0) then
+ begin
+ Event.What := evCommand;
+ Event.Command := cmClose;
+ Event.InfoPtr := Owner;
+ PutEvent(Event);
+ end;
+ ClearEvent(Event);
+ DrawView;
+ end else
+ if (PWindow(Owner)^.Flags and wfZoom <> 0) and
+ (State and sfActive <> 0) and (Event.Double or
+ (Mouse.X >= Size.X - 5) and
+ (Mouse.X <= Size.X - 3)) then
+ begin
+ {Zoom button clicked.}
+ if not Event.Double then
+ repeat
+ MakeLocal(Event.Where, Mouse);
+ if (Mouse.X >= Size.X - 5) and (Mouse.X <= Size.X - 3) and
+ (Mouse.Y = 0) then
+ FrameMode := fmZoomClicked
+ else FrameMode := 0;
+ DrawView;
+ until not MouseEvent(Event, evMouseMove + evMouseAuto);
+ FrameMode := 0;
+ if ((Mouse.X >= Size.X - 5) and (Mouse.X <= Size.X - 3) and
+ (Mouse.Y = 0)) or Event.Double then
+ begin
+ Event.What := evCommand;
+ Event.Command := cmZoom;
+ Event.InfoPtr := Owner;
+ PutEvent(Event);
+ end;
+ ClearEvent(Event);
+ DrawView;
+ end else
+ if PWindow(Owner)^.Flags and wfMove <> 0 then
+ DragWindow(dmDragMove);
+ end else
+ if (State and sfActive <> 0) and (Mouse.X >= Size.X - 2) and
+ (Mouse.Y >= Size.Y - 1) then
+ if PWindow(Owner)^.Flags and wfGrow <> 0 then
+ DragWindow(dmDragGrow);
+ end;
+end;
+
+
+procedure TFrame.SetState(AState: Word; Enable: Boolean);
+begin
+ TView.SetState(AState, Enable);
+ if AState and (sfActive + sfDragging) <> 0 then
+ DrawView;
+end;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TScrollBar OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+
+{--TScrollBar---------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TScrollBar.Init (Var Bounds: TRect);
+const
+ VChars: array[boolean] of TScrollChars =
+ (('^','V', #177, #254, #178),(#30, #31, #177, #254, #178));
+ HChars: array[boolean] of TScrollChars =
+ (('<','>', #177, #254, #178),(#17, #16, #177, #254, #178));
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ PgStep := 1; { Page step size = 1 }
+ ArStep := 1; { Arrow step sizes = 1 }
+ If (Size.X = 1) Then Begin { Vertical scrollbar }
+ GrowMode := gfGrowLoX + gfGrowHiX + gfGrowHiY; { Grow vertically }
+ Chars := VChars[LowAscii]; { Vertical chars }
+ End Else Begin { Horizontal scrollbar }
+ GrowMode := gfGrowLoY + gfGrowHiX + gfGrowHiY; { Grow horizontal }
+ Chars := HChars[LowAscii]; { Horizontal chars }
+ End;
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+{ This load method will read old original TV data from a stream with the }
+{ scrollbar id set to zero. }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TScrollBar.Load (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(i, SizeOf(i)); Value:=i; { Read current value }
+ S.Read(i, SizeOf(i)); Min:=i; { Read min value }
+ S.Read(i, SizeOf(i)); Max:=i; { Read max value }
+ S.Read(i, SizeOf(i)); PgStep:=i; { Read page step size }
+ S.Read(i, SizeOf(i)); ArStep:=i; { Read arrow step size }
+ S.Read(Chars, SizeOf(Chars)); { Read scroll chars }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TScrollBar.GetPalette: PPalette;
+CONST P: String[Length(CScrollBar)] = CScrollBar; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ ScrollStep -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TScrollBar.ScrollStep (Part: Sw_Integer): Sw_Integer;
+VAR Step: Sw_Integer;
+BEGIN
+ If (Part AND $0002 = 0) Then Step := ArStep { Range step size }
+ Else Step := PgStep; { Page step size }
+ If (Part AND $0001 = 0) Then ScrollStep := -Step { Upwards move }
+ Else ScrollStep := Step; { Downwards move }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ ScrollDraw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.ScrollDraw;
+VAR P: PView;
+BEGIN
+ If (Id <> 0) Then Begin
+ P := TopView; { Get topmost view }
+ NewMessage(P, evCommand, cmIdCommunicate, Id,
+ Value, @Self); { New Id style message }
+ End;
+ NewMessage(Owner, evBroadcast, cmScrollBarChanged,
+ Id, Value, @Self); { Old TV style message }
+END;
+
+
+{--TScrollBar---------------------------------------------------------------}
+{ SetValue -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.SetValue (AValue: Sw_Integer);
+BEGIN
+ SetParams(AValue, Min, Max, PgStep, ArStep); { Set value }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ SetRange -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.SetRange (AMin, AMax: Sw_Integer);
+BEGIN
+ SetParams(Value, AMin, AMax, PgStep, ArStep); { Set range }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ SetStep -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.SetStep (APgStep, AArStep: Sw_Integer);
+BEGIN
+ SetParams(Value, Min, Max, APgStep, AArStep); { Set step sizes }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ SetParams -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 21Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.SetParams (AValue, AMin, AMax, APgStep, AArStep: Sw_Integer);
+var
+ OldValue : Sw_Integer;
+BEGIN
+ If (AMax < AMin) Then AMax := AMin; { Max below min fix up }
+ If (AValue < AMin) Then AValue := AMin; { Value below min fix }
+ If (AValue > AMax) Then AValue := AMax; { Value above max fix }
+ OldValue:=Value;
+ If (Value <> AValue) OR (Min <> AMin) OR
+ (Max <> AMax) Then Begin { Something changed }
+ Min := AMin; { Set new minimum }
+ Max := AMax; { Set new maximum }
+ Value := AValue; { Set new value }
+ DrawView;
+ if OldValue <> AValue then
+ ScrollDraw;
+ End;
+ PgStep := APgStep; { Hold page step }
+ ArStep := AArStep; { Hold arrow step }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+{ You can save data to the stream compatable with the old original TV by }
+{ temporarily turning off the ofGrafVersion making the call to this store }
+{ routine and resetting the ofGrafVersion flag after the call. }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.Store (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ TView.Store(S); { TView.Store called }
+ i:=Value;S.Write(i, SizeOf(i)); { Write current value }
+ i:=Min;S.Write(i, SizeOf(i)); { Write min value }
+ i:=Max;S.Write(i, SizeOf(i)); { Write max value }
+ i:=PgStep;S.Write(i, SizeOf(i)); { Write page step size }
+ i:=ArStep;S.Write(i, SizeOf(i)); { Write arrow step size }
+ S.Write(Chars, SizeOf(Chars)); { Write scroll chars }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 22May98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.HandleEvent (Var Event: TEvent);
+VAR Tracking: Boolean; I, P, S, ClickPart, Iv: Sw_Integer;
+ Mouse: TPoint; Extent: TRect;
+
+ FUNCTION GetPartCode: Sw_Integer;
+ VAR Mark, Part : Sw_Integer;
+ BEGIN
+ Part := -1; { Preset failure }
+ If Extent.Contains(Mouse) Then Begin { Contains mouse }
+ If (Size.X = 1) Then Begin { Vertical scrollbar }
+ Mark := Mouse.Y - 1; { Calc position }
+ End Else Begin { Horizontal bar }
+ Mark := Mouse.X - 1; { Calc position }
+ End;
+ If (Mark >= P) AND (Mark < P+1) Then { Within thumbnail }
+ Part := sbIndicator; { Indicator part }
+ If (Part <> sbIndicator) Then Begin { Not indicator part }
+ If (Mark < 1) Then Part := sbLeftArrow Else { Left arrow part }
+ If (Mark < P) Then Part := sbPageLeft Else { Page left part }
+ If (Mark < S) Then Part := sbPageRight Else { Page right part }
+ Part := sbRightArrow; { Right arrow part }
+ If (Size.X = 1) Then Inc(Part, 4); { Correct for vertical }
+ End;
+ End;
+ GetPartCode := Part; { Return part code }
+ END;
+
+ PROCEDURE Clicked;
+ BEGIN
+ NewMessage(Owner, evBroadcast, cmScrollBarClicked,
+ Id, Value, @Self); { Old TV style message }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evCommand: Begin { Command event }
+ If (Event.Command = cmIdCommunicate) AND { Id communication }
+ (Event.Id = Id) AND (Event.InfoPtr <> @Self) { Targeted to us }
+ Then Begin
+ SetValue(Round(Event.Data)); { Set scrollbar value }
+ ClearEvent(Event); { Event was handled }
+ End;
+ End;
+ evKeyDown:
+ If (State AND sfVisible <> 0) Then Begin { Scrollbar visible }
+ ClickPart := sbIndicator; { Preset result }
+ If (Size.Y = 1) Then { Horizontal bar }
+ Case CtrlToArrow(Event.KeyCode) Of
+ kbLeft: ClickPart := sbLeftArrow; { Left one item }
+ kbRight: ClickPart := sbRightArrow; { Right one item }
+ kbCtrlLeft: ClickPart := sbPageLeft; { One page left }
+ kbCtrlRight: ClickPart := sbPageRight; { One page right }
+ kbHome: I := Min; { Move to start }
+ kbEnd: I := Max; { Move to end }
+ Else Exit; { Not a valid key }
+ End
+ Else { Vertical bar }
+ Case CtrlToArrow(Event.KeyCode) Of
+ kbUp: ClickPart := sbUpArrow; { One item up }
+ kbDown: ClickPart := sbDownArrow; { On item down }
+ kbPgUp: ClickPart := sbPageUp; { One page up }
+ kbPgDn: ClickPart := sbPageDown; { One page down }
+ kbCtrlPgUp: I := Min; { Move to top }
+ kbCtrlPgDn: I := Max; { Move to bottom }
+ Else Exit; { Not a valid key }
+ End;
+ Clicked; { Send out message }
+ If (ClickPart <> sbIndicator) Then
+ I := Value + ScrollStep(ClickPart); { Calculate position }
+ SetValue(I); { Set new item }
+ ClearEvent(Event); { Event now handled }
+ End;
+ evMouseDown: Begin { Mouse press event }
+ Clicked; { Scrollbar clicked }
+ MakeLocal(Event.Where, Mouse); { Localize mouse }
+ Extent.A.X := 0; { Zero x extent value }
+ Extent.A.Y := 0; { Zero y extent value }
+ Extent.B.X := Size.X; { Set extent x value }
+ Extent.B.Y := Size.Y; { set extent y value }
+ P := GetPos; { Current position }
+ S := GetSize; { Initial size }
+ ClickPart := GetPartCode; { Get part code }
+ If (ClickPart <> sbIndicator) Then Begin { Not thumb nail }
+ Repeat
+ MakeLocal(Event.Where, Mouse); { Localize mouse }
+ If GetPartCode = ClickPart Then
+ SetValue(Value+ScrollStep(ClickPart)); { Same part repeat }
+ Until NOT MouseEvent(Event, evMouseAuto); { Until auto done }
+ Clicked; { Scrollbar clicked }
+ End Else Begin { Thumb nail move }
+ Iv := Value; { Initial value }
+ Repeat
+ MakeLocal(Event.Where, Mouse); { Localize mouse }
+ Tracking := Extent.Contains(Mouse); { Check contains }
+ If Tracking Then Begin { Tracking mouse }
+ If (Size.X=1) Then
+ I := Mouse.Y-1 Else { Calc vert position }
+ I := Mouse.X-1; { Calc horz position }
+ If (I < 0) Then I := 0; { Check underflow }
+ If (I > S) Then I := S; { Check overflow }
+ End Else I := GetPos; { Get position }
+ If (I <> P) Then Begin
+ SetValue(LongInt((LongInt(I)*(Max-Min))
+ +(S SHR 1)) DIV S + Min); { Set new value }
+ P := I; { Hold new position }
+ End;
+ Until NOT MouseEvent(Event, evMouseMove); { Until not moving }
+ If Tracking AND (S > 0) Then { Tracking mouse }
+ SetValue(LongInt((LongInt(P)*(Max-Min))+
+ (S SHR 1)) DIV S + Min); { Set new value }
+ If (Iv <> Value) Then Clicked; { Scroll has moved }
+ End;
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+END;
+
+{***************************************************************************}
+{ TScrollBar OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{--TScrollBar---------------------------------------------------------------}
+{ GetPos -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TScrollBar.GetPos: Sw_Integer;
+VAR R: Sw_Integer;
+BEGIN
+ R := Max - Min; { Get full range }
+ If (R = 0) Then GetPos := 1 Else { Return zero }
+ GetPos := LongInt((LongInt(Value-Min) * (GetSize -3))
+ + (R SHR 1)) DIV R + 1; { Calc position }
+END;
+
+{--TScrollBar---------------------------------------------------------------}
+{ GetSize -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TScrollBar.GetSize: Sw_Integer;
+VAR S: Sw_Integer;
+BEGIN
+ If Size.X = 1 Then
+ S:= Size.Y
+ else
+ S:= Size.X;
+ If (S < 3) Then S := 3; { Fix minimum size }
+ GetSize := S; { Return size }
+END;
+
+
+{--TScrollBar---------------------------------------------------------------}
+{ Draw -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScrollBar.Draw;
+BEGIN
+ DrawPos(GetPos); { Draw position }
+END;
+
+
+procedure TScrollBar.DrawPos(Pos: Sw_Integer);
+var
+ S: Sw_Integer;
+ B: TDrawBuffer;
+begin
+ S := GetSize - 1;
+ MoveChar(B[0], Chars[0], GetColor(2), 1);
+ if Max = Min then
+ MoveChar(B[1], Chars[4], GetColor(1), S - 1)
+ else
+ begin
+ MoveChar(B[1], Chars[2], GetColor(1), S - 1);
+ MoveChar(B[Pos], Chars[3], GetColor(3), 1);
+ end;
+ MoveChar(B[S], Chars[1], GetColor(2), 1);
+ WriteBuf(0, 0, Size.X, Size.Y, B);
+end;
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TScroller OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TScroller----------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TScroller.Init (Var Bounds: TRect; AHScrollBar, AVScrollBar: PScrollBar);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR ofSelectable; { View is selectable }
+ EventMask := EventMask OR evBroadcast; { See broadcasts }
+ HScrollBar := AHScrollBar; { Hold horz scrollbar }
+ VScrollBar := AVScrollBar; { Hold vert scrollbar }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+{ This load method will read old original TV data from a stream as well }
+{ as the new graphical scroller views. }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TScroller.Load (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetPeerViewPtr(S, HScrollBar); { Load horz scrollbar }
+ GetPeerViewPtr(S, VScrollBar); { Load vert scrollbar }
+ S.Read(i, SizeOf(i)); Delta.X:=i; { Read delta x value }
+ S.Read(i, SizeOf(i)); Delta.Y:=i; { Read delta y value }
+ S.Read(i, SizeOf(i)); Limit.X:=i; { Read limit x value }
+ S.Read(i, SizeOf(i)); Limit.Y:=i; { Read limit y value }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TScroller.GetPalette: PPalette;
+CONST P: String[Length(CScroller)] = CScroller; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Scroller palette }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ ScrollTo -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScroller.ScrollTo (X, Y: Sw_Integer);
+BEGIN
+ Inc(DrawLock); { Set draw lock }
+ If (HScrollBar<>Nil) Then HScrollBar^.SetValue(X); { Set horz scrollbar }
+ If (VScrollBar<>Nil) Then VScrollBar^.SetValue(Y); { Set vert scrollbar }
+ Dec(DrawLock); { Release draw lock }
+ CheckDraw; { Check need to draw }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScroller.SetState (AState: Word; Enable: Boolean);
+
+ PROCEDURE ShowSBar (SBar: PScrollBar);
+ BEGIN
+ If (SBar <> Nil) Then { Scroll bar valid }
+ If GetState(sfActive + sfSelected) Then { Check state masks }
+ SBar^.Show Else SBar^.Hide; { Draw appropriately }
+ END;
+
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState AND (sfActive + sfSelected) <> 0) { Active/select change }
+ Then Begin
+ ShowSBar(HScrollBar); { Redraw horz scrollbar }
+ ShowSBar(VScrollBar); { Redraw vert scrollbar }
+ End;
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+{ The scroller is saved to the stream compatable with the old TV object. }
+{---------------------------------------------------------------------------}
+PROCEDURE TScroller.Store (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ TView.Store(S); { Call TView explicitly }
+ PutPeerViewPtr(S, HScrollBar); { Store horz bar }
+ PutPeerViewPtr(S, VScrollBar); { Store vert bar }
+ i:=Delta.X;S.Write(i, SizeOf(i)); { Write delta x value }
+ i:=Delta.Y;S.Write(i, SizeOf(i)); { Write delta y value }
+ i:=Limit.X;S.Write(i, SizeOf(i)); { Write limit x value }
+ i:=Limit.Y;S.Write(i, SizeOf(i)); { Write limit y value }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScroller.HandleEvent (Var Event: TEvent);
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ If (Event.What = evBroadcast) AND
+ (Event.Command = cmScrollBarChanged) AND { Scroll bar change }
+ ((Event.InfoPtr = HScrollBar) OR { Our scrollbar? }
+ (Event.InfoPtr = VScrollBar)) Then ScrollDraw; { Redraw scroller }
+END;
+
+{--TScroller----------------------------------------------------------------}
+{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TScroller.ChangeBounds (Var Bounds: TRect);
+BEGIN
+ SetBounds(Bounds); { Set new bounds }
+ Inc(DrawLock); { Set draw lock }
+ SetLimit(Limit.X, Limit.Y); { Adjust limits }
+ Dec(DrawLock); { Release draw lock }
+ DrawFlag := False; { Clear draw flag }
+ DrawView; { Redraw now }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TListViewer OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+CONST TvListViewerName = 'LISTBOX'; { Native name }
+
+{--TListViewer--------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TListViewer.Init (Var Bounds: TRect; ANumCols: Sw_Word; AHScrollBar,
+ AVScrollBar: PScrollBar);
+VAR ArStep, PgStep: Sw_Integer;
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ Options := Options OR (ofFirstClick+ofSelectable); { Set options }
+ EventMask := EventMask OR evBroadcast; { Set event mask }
+ NumCols := ANumCols; { Hold column number }
+ If (AVScrollBar <> Nil) Then Begin { Chk vert scrollbar }
+ If (NumCols = 1) Then Begin { Only one column }
+ PgStep := Size.Y -1; { Set page size }
+ ArStep := 1; { Set step size }
+ End Else Begin { Multiple columns }
+ PgStep := Size.Y * NumCols; { Set page size }
+ ArStep := Size.Y; { Set step size }
+ End;
+ AVScrollBar^.SetStep(PgStep, ArStep); { Set scroll values }
+ End;
+ If (AHScrollBar <> Nil) Then
+ AHScrollBar^.SetStep(Size.X DIV NumCols, 1); { Set step size }
+ HScrollBar := AHScrollBar; { Horz scrollbar held }
+ VScrollBar := AVScrollBar; { Vert scrollbar held }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TListViewer.Load (Var S: TStream);
+VAR w: Word;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ GetPeerViewPtr(S, HScrollBar); { Get horz scrollbar }
+ GetPeerViewPtr(S, VScrollBar); { Get vert scrollbar }
+ S.Read(w, SizeOf(w)); NumCols:=w; { Read column number }
+ S.Read(w, SizeOf(w)); TopItem:=w; { Read top most item }
+ S.Read(w, SizeOf(w)); Focused:=w; { Read focused item }
+ S.Read(w, SizeOf(w)); Range:=w; { Read listview range }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TListViewer.GetPalette: PPalette;
+CONST P: String[Length(CListViewer)] = CListViewer; { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P); { Return palette }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ IsSelected -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TListViewer.IsSelected (Item: Sw_Integer): Boolean;
+BEGIN
+ If (Item = Focused) Then IsSelected := True Else
+ IsSelected := False; { Selected item }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ GetText -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May98 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TListViewer.GetText (Item: Sw_Integer; MaxLen: Sw_Integer): String;
+BEGIN { Abstract method }
+ GetText := ''; { Return empty }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ DrawBackGround -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.Draw;
+VAR I, J, ColWidth, Item, Indent, CurCol: Sw_Integer;
+ Color: Word; SCOff: Byte;
+ Text: String; B: TDrawBuffer;
+BEGIN
+ ColWidth := Size.X DIV NumCols + 1; { Calc column width }
+ If (HScrollBar = Nil) Then Indent := 0 Else { Set indent to zero }
+ Indent := HScrollBar^.Value; { Fetch any indent }
+ For I := 0 To Size.Y - 1 Do Begin { For each line }
+ For J := 0 To NumCols-1 Do Begin { For each column }
+ Item := J*Size.Y + I + TopItem; { Process this item }
+ CurCol := J*ColWidth; { Current column }
+ If (State AND (sfSelected + sfActive) =
+ (sfSelected + sfActive)) AND (Focused = Item) { Focused item }
+ AND (Range > 0) Then Begin
+ Color := GetColor(3); { Focused colour }
+ SetCursor(CurCol+1,I); { Set the cursor }
+ SCOff := 0; { Zero colour offset }
+ End Else If (Item < Range) AND IsSelected(Item){ Selected item }
+ Then Begin
+ Color := GetColor(4); { Selected color }
+ SCOff := 2; { Colour offset=2 }
+ End Else Begin
+ Color := GetColor(2); { Normal Color }
+ SCOff := 4; { Colour offset=4 }
+ End;
+ MoveChar(B[CurCol], ' ', Color, ColWidth); { Clear buffer }
+ If (Item < Range) Then Begin { Within text range }
+ Text := GetText(Item, ColWidth + Indent); { Fetch text }
+ Text := Copy(Text, Indent, ColWidth); { Select right bit }
+ MoveStr(B[CurCol+1], Text, Color); { Transfer to buffer }
+ If ShowMarkers Then Begin
+ WordRec(B[CurCol]).Lo := Byte(
+ SpecialChars[SCOff]); { Set marker character }
+ WordRec(B[CurCol+ColWidth-2]).Lo := Byte(
+ SpecialChars[SCOff+1]); { Set marker character }
+ End;
+ End;
+ MoveChar(B[CurCol+ColWidth-1], #179,
+ GetColor(5), 1); { Put centre line marker }
+ End;
+ WriteLine(0, I, Size.X, 1, B); { Write line to screen }
+ End;
+END;
+
+
+{--TListViewer--------------------------------------------------------------}
+{ FocusItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.FocusItem (Item: Sw_Integer);
+BEGIN
+ Focused := Item; { Set focus to item }
+ If (VScrollBar <> Nil) Then
+ VScrollBar^.SetValue(Item); { Scrollbar to value }
+ If (Item < TopItem) Then { Item above top item }
+ If (NumCols = 1) Then TopItem := Item { Set top item }
+ Else TopItem := Item - Item MOD Size.Y { Set top item }
+ Else If (Item >= TopItem + (Size.Y*NumCols)) Then { Item below bottom }
+ If (NumCols = 1) Then TopItem := Item-Size.Y+1 { Set new top item }
+ Else TopItem := Item - Item MOD Size.Y -
+ (Size.Y*(NumCols-1)); { Set new top item }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ SetTopItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 06Aug99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.SetTopItem (Item: Sw_Integer);
+BEGIN
+ TopItem := Item; { Set the top item }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ SetRange -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.SetRange (ARange: Sw_Integer);
+BEGIN
+ Range := ARange; { Set new range }
+ If (VScrollBar <> Nil) Then Begin { Vertical scrollbar }
+ If (Focused > ARange) Then Focused := 0; { Clear focused }
+ VScrollBar^.SetParams(Focused, 0, ARange - 1,
+ VScrollBar^.PgStep, VScrollBar^.ArStep); { Set parameters }
+ End;
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ SelectItem -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.SelectItem (Item: Sw_Integer);
+BEGIN
+ Message(Owner, evBroadcast, cmListItemSelected,
+ @Self); { Send message }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.SetState (AState: Word; Enable: Boolean);
+
+ PROCEDURE ShowSBar(SBar: PScrollBar);
+ BEGIN
+ If (SBar <> Nil) Then { Valid scrollbar }
+ If GetState(sfActive) AND GetState(sfVisible) { Check states }
+ Then SBar^.Show Else SBar^.Hide; { Show or hide }
+ END;
+
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState AND (sfSelected + sfActive + sfVisible) <> 0)
+ Then Begin { Check states }
+ DrawView; { Draw the view }
+ ShowSBar(HScrollBar); { Show horz scrollbar }
+ ShowSBar(VScrollBar); { Show vert scrollbar }
+ End;
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.Store (Var S: TStream);
+VAR w: Word;
+BEGIN
+ TView.Store(S); { Call TView explicitly }
+ PutPeerViewPtr(S, HScrollBar); { Put horz scrollbar }
+ PutPeerViewPtr(S, VScrollBar); { Put vert scrollbar }
+ w:=NumCols;S.Write(w, SizeOf(w)); { Write column number }
+ w:=TopItem;S.Write(w, SizeOf(w)); { Write top most item }
+ w:=Focused;S.Write(w, SizeOf(w)); { Write focused item }
+ w:=Range;S.Write(w, SizeOf(w)); { Write listview range }
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 27Oct99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.HandleEvent (Var Event: TEvent);
+CONST MouseAutosToSkip = 4;
+VAR Oi, Ni: Sw_Integer; Ct, Cw: Word; Mouse: TPoint;
+
+ PROCEDURE MoveFocus (Req: Sw_Integer);
+ BEGIN
+ FocusItemNum(Req); { Focus req item }
+ DrawView; { Redraw focus box }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speed up exit }
+ evKeyDown: Begin { Key down event }
+ If (Event.CharCode = ' ') AND (Focused < Range){ Spacebar select }
+ Then Begin
+ SelectItem(Focused); { Select focused item }
+ Ni := Focused; { Hold new item }
+ End Else Case CtrlToArrow(Event.KeyCode) Of
+ kbUp: Ni := Focused - 1; { One item up }
+ kbDown: Ni := Focused + 1; { One item down }
+ kbRight: If (NumCols > 1) Then
+ Ni := Focused + Size.Y Else Exit; { One column right }
+ kbLeft: If (NumCols > 1) Then
+ Ni := Focused - Size.Y Else Exit; { One column left }
+ kbPgDn: Ni := Focused + Size.Y * NumCols; { One page down }
+ kbPgUp: Ni := Focused - Size.Y * NumCols; { One page up }
+ kbHome: Ni := TopItem; { Move to top }
+ kbEnd: Ni := TopItem + (Size.Y*NumCols)-1; { Move to bottom }
+ kbCtrlPgDn: Ni := Range - 1; { Move to last item }
+ kbCtrlPgUp: Ni := 0; { Move to first item }
+ Else Exit;
+ End;
+ MoveFocus(Ni); { Move the focus }
+ ClearEvent(Event); { Event was handled }
+ End;
+ evBroadcast: Begin { Broadcast event }
+ If (Options AND ofSelectable <> 0) Then { View is selectable }
+ If (Event.Command = cmScrollBarClicked) AND { Scrollbar click }
+ ((Event.InfoPtr = HScrollBar) OR
+ (Event.InfoPtr = VScrollBar)) Then Select { Scrollbar selects us }
+ Else If (Event.Command = cmScrollBarChanged) { Scrollbar changed }
+ Then Begin
+ If (VScrollBar = Event.InfoPtr) Then Begin
+ MoveFocus(VScrollBar^.Value); { Focus us to item }
+ End Else If (HScrollBar = Event.InfoPtr)
+ Then DrawView; { Redraw the view }
+ End;
+ End;
+ evMouseDown: Begin { Mouse down event }
+ Cw := Size.X DIV NumCols + 1; { Column width }
+ Oi := Focused; { Hold focused item }
+ MakeLocal(Event.Where, Mouse); { Localize mouse }
+ If MouseInView(Event.Where) Then Ni := Mouse.Y
+ + (Size.Y*(Mouse.X DIV Cw))+TopItem { Calc item to focus }
+ Else Ni := Oi; { Focus old item }
+ Ct := 0; { Clear count value }
+ Repeat
+ If (Ni <> Oi) Then Begin { Item is different }
+ MoveFocus(Ni); { Move the focus }
+ Oi := Focused; { Hold as focused item }
+ End;
+ MakeLocal(Event.Where, Mouse); { Localize mouse }
+ If NOT MouseInView(Event.Where) Then Begin
+ If (Event.What = evMouseAuto) Then Inc(Ct);{ Inc auto count }
+ If (Ct = MouseAutosToSkip) Then Begin
+ Ct := 0; { Reset count }
+ If (NumCols = 1) Then Begin { Only one column }
+ If (Mouse.Y < 0) Then Ni := Focused-1; { Move up one item }
+ If (Mouse.Y >= Size.Y) Then
+ Ni := Focused+1; { Move down one item }
+ End Else Begin { Multiple columns }
+ If (Mouse.X < 0) Then { Mouse x below zero }
+ Ni := Focused-Size.Y; { Move down 1 column }
+ If (Mouse.X >= Size.X) Then { Mouse x above width }
+ Ni := Focused+Size.Y; { Move up 1 column }
+ If (Mouse.Y < 0) Then { Mouse y below zero }
+ Ni := Focused-Focused MOD Size.Y; { Move up one item }
+ If (Mouse.Y > Size.Y) Then { Mouse y above height }
+ Ni := Focused-Focused MOD
+ Size.Y+Size.Y-1; { Move down one item }
+ End;
+ End;
+ End Else Ni := Mouse.Y + (Size.Y*(Mouse.X
+ DIV Cw))+TopItem; { New item to focus }
+ Until NOT MouseEvent(Event, evMouseMove +
+ evMouseAuto); { Mouse stopped }
+ If (Oi <> Ni) Then MoveFocus(Ni); { Focus moved again }
+ If (Event.Double AND (Range > Focused)) Then
+ SelectItem(Focused); { Select the item }
+ ClearEvent(Event); { Event was handled }
+ End;
+ End;
+END;
+
+{--TListViewer--------------------------------------------------------------}
+{ ChangeBounds -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.ChangeBounds (Var Bounds: TRect);
+BEGIN
+ Inherited ChangeBounds(Bounds); { Call ancestor }
+ If (HScrollBar <> Nil) Then { Valid horz scrollbar }
+ HScrollBar^.SetStep(Size.X DIV NumCols,
+ HScrollBar^.ArStep); { Update horz bar }
+ If (VScrollBar <> Nil) Then { Valid vert scrollbar }
+ VScrollBar^.SetStep(Size.Y * NumCols,
+ VScrollBar^.ArStep); { Update vert bar }
+END;
+
+{***************************************************************************}
+{ TListViewer OBJECT PRIVATE METHODS }
+{***************************************************************************}
+
+{--TListViewer--------------------------------------------------------------}
+{ FocusItemNum -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 26Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TListViewer.FocusItemNum (Item: Sw_Integer);
+BEGIN
+ If (Item < 0) Then Item := 0 Else { Restrain underflow }
+ If (Item >= Range) AND (Range > 0) Then
+ Item := Range-1; { Restrain overflow }
+ If (Range <> 0) Then FocusItem(Item); { Set focus value }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TWindow OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{--TWindow------------------------------------------------------------------}
+{ Init -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TWindow.Init (Var Bounds: TRect; ATitle: TTitleStr; ANumber: Sw_Integer);
+BEGIN
+ Inherited Init(Bounds); { Call ancestor }
+ State := State OR sfShadow; { View is shadowed }
+ Options := Options OR (ofSelectable+ofTopSelect); { Select options set }
+ GrowMode := gfGrowAll + gfGrowRel; { Set growmodes }
+ Flags := wfMove + wfGrow + wfClose + wfZoom; { Set flags }
+ Title := NewStr(ATitle); { Hold title }
+ Number := ANumber; { Hold number }
+ Palette := wpBlueWindow; { Default palette }
+ InitFrame; { Initialize frame }
+ If (Frame <> Nil) Then Insert(Frame); { Insert any frame }
+ GetBounds(ZoomRect); { Default zoom rect }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ Load -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+{ This load method will read old original TV data from a stream however }
+{ although a frame view is read for compatability it is disposed of. }
+{---------------------------------------------------------------------------}
+CONSTRUCTOR TWindow.Load (Var S: TStream);
+VAR I: Integer;
+BEGIN
+ Inherited Load(S); { Call ancestor }
+ S.Read(Flags, SizeOf(Flags)); { Read window flags }
+ S.Read(i, SizeOf(i)); Number:=i; { Read window number }
+ S.Read(i, SizeOf(i)); Palette:=i; { Read window palette }
+ S.Read(i, SizeOf(i)); ZoomRect.A.X:=i; { Read zoom area x1 }
+ S.Read(i, SizeOf(i)); ZoomRect.A.Y:=i; { Read zoom area y1 }
+ S.Read(i, SizeOf(i)); ZoomRect.B.X:=i; { Read zoom area x2 }
+ S.Read(i, SizeOf(i)); ZoomRect.B.Y:=i; { Read zoom area y2 }
+ GetSubViewPtr(S, Frame); { Now read frame object }
+ Title := S.ReadStr; { Read title }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ Done -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+DESTRUCTOR TWindow.Done;
+BEGIN
+ Inherited Done; { Call ancestor }
+ If (Title <> Nil) Then DisposeStr(Title); { Dispose title }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ GetPalette -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TWindow.GetPalette: PPalette;
+CONST P: ARRAY [wpBlueWindow..wpGrayWindow] Of String[Length(CBlueWindow)] =
+ (CBlueWindow, CCyanWindow, CGrayWindow); { Always normal string }
+BEGIN
+ GetPalette := PPalette(@P[Palette]); { Return palette }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ GetTitle -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{ Modified 31may2002 PM (No number included anymore) }
+{---------------------------------------------------------------------------}
+FUNCTION TWindow.GetTitle (MaxSize: Sw_Integer): TTitleStr;
+VAR S: String;
+BEGIN
+ If (Title <> Nil) Then S:=Title^
+ Else S := '';
+ if Length(S)>MaxSize then
+ GetTitle:=Copy(S,1,MaxSize)
+ else
+ GetTitle:=S;
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ StandardScrollBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION TWindow.StandardScrollBar (AOptions: Word): PScrollBar;
+VAR R: TRect; S: PScrollBar;
+BEGIN
+ GetExtent(R); { View extents }
+ If (AOptions AND sbVertical = 0) Then
+ R.Assign(R.A.X+2, R.B.Y-1, R.B.X-2, R.B.Y) { Horizontal scrollbar }
+ Else R.Assign(R.B.X-1, R.A.Y+1, R.B.X, R.B.Y-1); { Vertical scrollbar }
+ S := New(PScrollBar, Init(R)); { Create scrollbar }
+ Insert(S); { Insert scrollbar }
+ If (AOptions AND sbHandleKeyboard <> 0) Then
+ S^.Options := S^.Options or ofPostProcess; { Post process }
+ StandardScrollBar := S; { Return scrollbar }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ Zoom -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.Zoom;
+VAR R: TRect; Max, Min: TPoint;
+BEGIN
+ SizeLimits(Min, Max); { Return size limits }
+ If ((Size.X <> Max.X) OR (Size.Y <> Max.Y)) { Larger size possible }
+ Then Begin
+ GetBounds(ZoomRect); { Get zoom bounds }
+ R.A.X := 0; { Zero x origin }
+ R.A.Y := 0; { Zero y origin }
+ R.B := Max; { Bounds to max size }
+ Locate(R); { Locate the view }
+ End Else Locate(ZoomRect); { Move to zoom rect }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ Close -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 23Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.Close;
+BEGIN
+ If Valid(cmClose) Then Free; { Dispose of self }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ InitFrame -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Jul99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.InitFrame;
+VAR
+ R: TRect;
+BEGIN
+ GetExtent(R);
+ Frame := New(PFrame, Init(R));
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ SetState -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.SetState (AState: Word; Enable: Boolean);
+VAR WindowCommands: TCommandSet;
+BEGIN
+ Inherited SetState(AState, Enable); { Call ancestor }
+ If (AState = sfSelected) Then
+ SetState(sfActive, Enable); { Set active state }
+ If (AState = sfSelected) OR ((AState = sfExposed)
+ AND (State AND sfSelected <> 0)) Then Begin { View is selected }
+ WindowCommands := [cmNext, cmPrev]; { Set window commands }
+ If (Flags AND (wfGrow + wfMove) <> 0) Then
+ WindowCommands := WindowCommands + [cmResize]; { Add resize command }
+ If (Flags AND wfClose <> 0) Then
+ WindowCommands := WindowCommands + [cmClose]; { Add close command }
+ If (Flags AND wfZoom <> 0) Then
+ WindowCommands := WindowCommands + [cmZoom]; { Add zoom command }
+ If Enable Then EnableCommands(WindowCommands) { Enable commands }
+ Else DisableCommands(WindowCommands); { Disable commands }
+ End;
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ Store -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 30Mar98 LdB }
+{---------------------------------------------------------------------------}
+{ You can save data to the stream compatable with the old original TV by }
+{ temporarily turning off the ofGrafVersion making the call to this store }
+{ routine and resetting the ofGrafVersion flag after the call. }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.Store (Var S: TStream);
+VAR i: Integer;
+BEGIN
+ TGroup.Store(S); { Call group store }
+ S.Write(Flags, SizeOf(Flags)); { Write window flags }
+ i:=Number;S.Write(i, SizeOf(i)); { Write window number }
+ i:=Palette;S.Write(i, SizeOf(i)); { Write window palette }
+ i:=ZoomRect.A.X;S.Write(i, SizeOf(i)); { Write zoom area x1 }
+ i:=ZoomRect.A.Y;S.Write(i, SizeOf(i)); { Write zoom area y1 }
+ i:=ZoomRect.B.X;S.Write(i, SizeOf(i)); { Write zoom area x2 }
+ i:=ZoomRect.B.Y;S.Write(i, SizeOf(i)); { Write zoom area y2 }
+ PutSubViewPtr(S, Frame); { Write any frame }
+ S.WriteStr(Title); { Write title string }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ HandleEvent -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 11Aug99 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.HandleEvent (Var Event: TEvent);
+VAR
+ Min, Max: TPoint; Limits: TRect;
+
+ PROCEDURE DragWindow (Mode: Byte);
+ VAR Limits: TRect; Min, Max: TPoint;
+ BEGIN
+ Owner^.GetExtent(Limits); { Get owner extents }
+ SizeLimits(Min, Max); { Restrict size }
+ DragView(Event, DragMode OR Mode, Limits, Min,
+ Max); { Drag the view }
+ ClearEvent(Event); { Clear the event }
+ END;
+
+BEGIN
+ Inherited HandleEvent(Event); { Call ancestor }
+ Case Event.What Of
+ evNothing: Exit; { Speeds up exit }
+ evCommand: { COMMAND EVENT }
+ Case Event.Command Of { Command type case }
+ cmResize: { RESIZE COMMAND }
+ If (Flags AND (wfMove + wfGrow) <> 0) { Window can resize }
+ AND (Owner <> Nil) Then Begin { Valid owner }
+ Owner^.GetExtent(Limits); { Owners extents }
+ SizeLimits(Min, Max); { Check size limits }
+ DragView(Event, DragMode OR (Flags AND
+ (wfMove + wfGrow)), Limits, Min, Max); { Drag the view }
+ ClearEvent(Event); { Clear the event }
+ End;
+ cmClose: { CLOSE COMMAND }
+ If (Flags AND wfClose <> 0) AND { Close flag set }
+ ((Event.InfoPtr = Nil) OR { None specific close }
+ (Event.InfoPtr = @Self)) Then Begin { Close to us }
+ ClearEvent(Event); { Clear the event }
+ If (State AND sfModal = 0) Then Close { Non modal so close }
+ Else Begin { Modal window }
+ Event.What := evCommand; { Command event }
+ Event.Command := cmCancel; { Cancel command }
+ PutEvent(Event); { Place on queue }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ cmZoom: { ZOOM COMMAND }
+ If (Flags AND wfZoom <> 0) AND { Zoom flag set }
+ ((Event.InfoPtr = Nil) OR { No specific zoom }
+ (Event.InfoPtr = @Self)) Then Begin
+ Zoom; { Zoom our window }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ evBroadcast: { BROADCAST EVENT }
+ If (Event.Command = cmSelectWindowNum) AND
+ (Event.InfoInt = Number) AND { Select our number }
+ (Options AND ofSelectable <> 0) Then Begin { Is view selectable }
+ Select; { Select our view }
+ ClearEvent(Event); { Clear the event }
+ End;
+ evKeyDown: Begin { KEYDOWN EVENT }
+ Case Event.KeyCode Of
+ kbTab: Begin { TAB KEY }
+ FocusNext(False); { Select next view }
+ ClearEvent(Event); { Clear the event }
+ End;
+ kbShiftTab: Begin { SHIFT TAB KEY }
+ FocusNext(True); { Select prior view }
+ ClearEvent(Event); { Clear the event }
+ End;
+ End;
+ End;
+ End; { Event.What case end }
+END;
+
+{--TWindow------------------------------------------------------------------}
+{ SizeLimits -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 15Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TWindow.SizeLimits (Var Min, Max: TPoint);
+BEGIN
+ Inherited SizeLimits(Min, Max); { View size limits }
+ Min.X := MinWinSize.X; { Set min x size }
+ Min.Y := MinWinSize.Y; { Set min y size }
+END;
+
+
+
+{--TView--------------------------------------------------------------------}
+{ Exposed -> Platforms DOS/DPMI/WIN/OS2 - Checked 17Sep97 LdB }
+{---------------------------------------------------------------------------}
+function TView.do_ExposedRec1(x1,x2:sw_integer; p:PView):boolean;
+var
+ G : PGroup;
+ dy,dx : sw_integer;
+begin
+ while true do
+ begin
+ p:=p^.Next;
+ G:=p^.Owner;
+ if p=staticVar2.target then
+ begin
+ do_exposedRec1:=do_exposedRec2(x1,x2,G);
+ Exit;
+ end;
+ dy:=p^.origin.y;
+ dx:=p^.origin.x;
+ if ((p^.state and sfVisible)<>0) and (staticVar2.y>=dy) then
+ begin
+ if staticVar2.y<dy+p^.size.y then
+ begin
+ if x1<dx then
+ begin
+ if x2<=dx then
+ continue;
+ if x2>dx+p^.size.x then
+ begin
+ if do_exposedRec1(x1,dx,p) then
+ begin
+ do_exposedRec1:=True;
+ Exit;
+ end;
+ x1:=dx+p^.size.x;
+ end
+ else
+ x2:=dx;
+ end
+ else
+ begin
+ if x1<dx+p^.size.x then
+ x1:=dx+p^.size.x;
+ if x1>=x2 then
+ begin
+ do_exposedRec1:=False;
+ Exit;
+ end;
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+function TView.do_ExposedRec2(x1,x2:Sw_integer; p:PView):boolean;
+var
+ G : PGroup;
+ savedStat : TStatVar2;
+begin
+ if (p^.state and sfVisible)=0 then
+ do_ExposedRec2:=false
+ else
+ begin
+ G:=p^.Owner;
+ if (G=Nil) or (G^.Buffer<>Nil) then
+ do_ExposedRec2:=true
+ else
+ begin
+ savedStat:=staticVar2;
+ inc(staticVar2.y,p^.origin.y);
+ inc(x1,p^.origin.x);
+ inc(x2,p^.origin.x);
+ staticVar2.target:=p;
+ if (staticVar2.y<G^.clip.a.y) or (staticVar2.y>=G^.clip.b.y) then
+ do_ExposedRec2:=false
+ else
+ begin
+ if (x1<G^.clip.a.x) then
+ x1:=G^.clip.a.x;
+ if (x2>G^.clip.b.x) then
+ x2:=G^.clip.b.x;
+ if (x1>=x2) then
+ do_ExposedRec2:=false
+ else
+ do_ExposedRec2:=do_exposedRec1(x1,x2,G^.Last);
+ end;
+ staticVar2 := savedStat;
+ end;
+ end;
+end;
+
+
+function TView.Exposed: Boolean;
+var
+ OK : boolean;
+ y : sw_integer;
+begin
+ if ((State and sfExposed)<>0) and (Size.X>0) and (Size.Y>0) then
+ begin
+ OK:=false;
+ y:=0;
+ while (y<Size.Y) and (not OK) do
+ begin
+ staticVar2.y:=y;
+ OK:=do_ExposedRec2(0,Size.X,@Self);
+ inc(y);
+ end;
+ Exposed:=OK;
+ end
+ else
+ Exposed:=False
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ MakeLocal -> Platforms DOS/DPMI/WIN/OS2 - Checked 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.MakeLocal (Source: TPoint; Var Dest: TPoint);
+var
+ cur : PView;
+begin
+ cur:=@Self;
+ Dest:=Source;
+ repeat
+ dec(Dest.X,cur^.Origin.X);
+ if dest.x<0 then
+ break;
+ dec(Dest.Y,cur^.Origin.Y);
+ if dest.y<0 then
+ break;
+ cur:=cur^.Owner;
+ until cur=nil;
+end;
+
+
+{--TView--------------------------------------------------------------------}
+{ MakeGlobal -> Platforms DOS/DPMI/WIN/OS2 - Checked 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TView.MakeGlobal (Source: TPoint; Var Dest: TPoint);
+var
+ cur : PView;
+begin
+ cur:=@Self;
+ Dest:=Source;
+ repeat
+ inc(Dest.X,cur^.Origin.X);
+ inc(Dest.Y,cur^.Origin.Y);
+ cur:=cur^.Owner;
+ until cur=nil;
+end;
+
+
+procedure TView.do_writeViewRec1(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer);
+var
+ G : PGroup;
+ c : Word;
+ BufPos,
+ SrcPos,
+ l,dx : Sw_integer;
+begin
+ repeat
+ p:=p^.Next;
+ if (p=staticVar2.target) then
+ begin
+ G:=p^.Owner;
+ if (G^.buffer<>Nil) then
+ begin
+ BufPos:=G^.size.x * staticVar2.y + x1;
+ SrcPos:=x1 - staticVar2.offset;
+ l:=x2-x1;
+ if (shadowCounter=0) then
+ move(staticVar1^[SrcPos],PVideoBuf(G^.buffer)^[BufPos],l shl 1)
+ else
+ begin { paint with shadowAttr }
+ while (l>0) do
+ begin
+ c:=staticVar1^[SrcPos];
+ WordRec(c).hi:=shadowAttr;
+ PVideoBuf(G^.buffer)^[BufPos]:=c;
+ inc(BufPos);
+ inc(SrcPos);
+ dec(l);
+ end;
+ end;
+ end;
+ if G^.lockFlag=0 then
+ do_writeViewRec2(x1,x2,G,shadowCounter);
+ exit;
+ end; { p=staticVar2.target }
+
+ if ((p^.state and sfVisible)<>0) and (staticVar2.y>=p^.Origin.Y) then
+ begin
+ if staticVar2.y<p^.Origin.Y+p^.size.Y then
+ begin
+ if x1<p^.origin.x then
+ begin
+ if x2<=p^.origin.x then
+ continue;
+ do_writeViewRec1(x1,p^.origin.x,p,shadowCounter);
+ x1:=p^.origin.x;
+ end;
+ dx:=p^.origin.x+p^.size.x;
+ if (x2<=dx) then
+ exit;
+ if (x1<dx) then
+ x1:=dx;
+ inc(dx,shadowSize.x);
+ if ((p^.state and sfShadow)<>0) and (staticVar2.y>=p^.origin.y+shadowSize.y) then
+ if (x1>dx) then
+ continue
+ else
+ begin
+ inc(shadowCounter);
+ if (x2<=dx) then
+ continue
+ else
+ begin
+ do_writeViewRec1(x1,dx,p,shadowCounter);
+ x1:=dx;
+ dec(shadowCounter);
+ continue;
+ end;
+ end
+ else
+ continue;
+ end;
+
+ if ((p^.state and sfShadow)<>0) and (staticVar2.y<p^.origin.y+p^.size.y+shadowSize.y) then
+ begin
+ dx:=p^.origin.x+shadowSize.x;
+ if x1<dx then
+ begin
+ if x2<=dx then
+ continue;
+ do_writeViewRec1(x1,dx,p,shadowCounter);
+ x1:=dx;
+ end;
+ inc(dx,p^.size.x);
+ if x1>=dx then
+ continue;
+ inc(shadowCounter);
+ if x2<=dx then
+ continue
+ else
+ begin
+ do_writeViewRec1(x1,dx,p,shadowCounter);
+ x1:=dx;
+ dec(shadowCounter);
+ end;
+ end;
+ end;
+ until false;
+end;
+
+
+procedure TView.do_writeViewRec2(x1,x2:Sw_integer; p:PView; shadowCounter:Sw_integer);
+var
+ savedStatics : TstatVar2;
+ dx : Sw_integer;
+ G : PGroup;
+begin
+ G:=P^.Owner;
+ if ((p^.State and sfVisible) <> 0) and (G<>Nil) then
+ begin
+ savedStatics:=staticVar2;
+ inc(staticVar2.y,p^.Origin.Y);
+ dx:=p^.Origin.X;
+ inc(x1,dx);
+ inc(x2,dx);
+ inc(staticVar2.offset,dx);
+ staticVar2.target:=p;
+ if (staticVar2.y >= G^.clip.a.y) and (staticVar2.y < G^.clip.b.y) then
+ begin
+ if (x1<g^.clip.a.x) then
+ x1 := g^.clip.a.x;
+ if (x2>g^.clip.b.x) then
+ x2 := g^.clip.b.x;
+ if x1<x2 then
+ do_writeViewRec1(x1,x2,G^.Last,shadowCounter);
+ end;
+ staticVar2 := savedStatics;
+ end;
+end;
+
+
+procedure TView.do_WriteView(x1,x2,y:Sw_integer; var Buf);
+begin
+ if (y>=0) and (y<Size.Y) then
+ begin
+ if x1<0 then
+ x1:=0;
+ if x2>Size.X then
+ x2:=Size.X;
+ if x1<x2 then
+ begin
+ staticVar2.offset:=x1;
+ staticVar2.y:=y;
+ staticVar1:=@Buf;
+ do_writeViewRec2( x1, x2, @Self, 0 );
+ end;
+ end;
+end;
+
+
+procedure TView.WriteBuf(X, Y, W, H: Sw_Integer; var Buf);
+var
+ i : Sw_integer;
+begin
+ if h>0 then
+ for i:= 0 to h-1 do
+ do_writeView(X,X+W,Y+i,TVideoBuf(Buf)[W*i]);
+end;
+
+
+procedure TView.WriteChar(X,Y:Sw_Integer; C:Char; Color:Byte; Count:Sw_Integer);
+var
+ B : TDrawBuffer;
+ myChar : word;
+ i : Sw_integer;
+begin
+ myChar:=MapColor(Color);
+ myChar:=(myChar shl 8) + ord(C);
+ if Count>0 then
+ begin
+ if Count>maxViewWidth then
+ Count:=maxViewWidth;
+ for i:=0 to Count-1 do
+ B[i]:=myChar;
+ do_writeView(X,X+Count,Y,B);
+ end;
+ DrawScreenBuf(false);
+end;
+
+
+procedure TView.WriteLine(X, Y, W, H: Sw_Integer; var Buf);
+var
+ i:Sw_integer;
+begin
+ if h>0 then
+ for i:=0 to h-1 do
+ do_writeView(x,x+w,y+i,buf);
+ DrawScreenBuf(false);
+end;
+
+
+procedure TView.WriteStr(X, Y: Sw_Integer; Str: String; Color: Byte);
+var
+ l,i : Sw_word;
+ B : TDrawBuffer;
+ myColor : word;
+begin
+ l:=length(Str);
+ if l>0 then
+ begin
+ if l>maxViewWidth then
+ l:=maxViewWidth;
+ MyColor:=MapColor(Color);
+ MyColor:=MyColor shl 8;
+ for i:=0 to l-1 do
+ B[i]:=MyColor+ord(Str[i+1]);
+ do_writeView(x,x+l,y,b);
+ end;
+ DrawScreenBuf(false);
+end;
+
+
+procedure TView.DragView(Event: TEvent; Mode: Byte;
+ var Limits: TRect; MinSize, MaxSize: TPoint);
+var
+ P, S: TPoint;
+ SaveBounds: TRect;
+
+ procedure MoveGrow(P, S: TPoint);
+ var
+ R: TRect;
+ begin
+ S.X := Min(Max(S.X, MinSize.X), MaxSize.X);
+ S.Y := Min(Max(S.Y, MinSize.Y), MaxSize.Y);
+ P.X := Min(Max(P.X, Limits.A.X - S.X + 1), Limits.B.X - 1);
+ P.Y := Min(Max(P.Y, Limits.A.Y - S.Y + 1), Limits.B.Y - 1);
+ if Mode and dmLimitLoX <> 0 then P.X := Max(P.X, Limits.A.X);
+ if Mode and dmLimitLoY <> 0 then P.Y := Max(P.Y, Limits.A.Y);
+ if Mode and dmLimitHiX <> 0 then P.X := Min(P.X, Limits.B.X - S.X);
+ if Mode and dmLimitHiY <> 0 then P.Y := Min(P.Y, Limits.B.Y - S.Y);
+ R.Assign(P.X, P.Y, P.X + S.X, P.Y + S.Y);
+ Locate(R);
+ end;
+
+ procedure Change(DX, DY: Sw_Integer);
+ begin
+ if (Mode and dmDragMove <> 0) and (Event.KeyShift{GetShiftState} and $03 = 0) then
+ begin
+ Inc(P.X, DX);
+ Inc(P.Y, DY);
+ end else
+ if (Mode and dmDragGrow <> 0) and (Event.KeyShift{GetShiftState} and $03 <> 0) then
+ begin
+ Inc(S.X, DX);
+ Inc(S.Y, DY);
+ end;
+ end;
+
+ procedure Update(X, Y: Sw_Integer);
+ begin
+ if Mode and dmDragMove <> 0 then
+ begin
+ P.X := X;
+ P.Y := Y;
+ end;
+ end;
+
+begin
+ SetState(sfDragging, True);
+ if Event.What = evMouseDown then
+ begin
+ if Mode and dmDragMove <> 0 then
+ begin
+ P.X := Origin.X - Event.Where.X;
+ P.Y := Origin.Y - Event.Where.Y;
+ repeat
+ Inc(Event.Where.X, P.X);
+ Inc(Event.Where.Y, P.Y);
+ MoveGrow(Event.Where, Size);
+ until not MouseEvent(Event, evMouseMove);
+ {We need to process the mouse-up event, since not all terminals
+ send drag events.}
+ Inc(Event.Where.X, P.X);
+ Inc(Event.Where.Y, P.Y);
+ MoveGrow(Event.Where, Size);
+ end else
+ begin
+ P.X := Size.X - Event.Where.X;
+ P.Y := Size.Y - Event.Where.Y;
+ repeat
+ Inc(Event.Where.X, P.X);
+ Inc(Event.Where.Y, P.Y);
+ MoveGrow(Origin, Event.Where);
+ until not MouseEvent(Event, evMouseMove);
+ {We need to process the mouse-up event, since not all terminals
+ send drag events.}
+ Inc(Event.Where.X, P.X);
+ Inc(Event.Where.Y, P.Y);
+ MoveGrow(Origin, Event.Where);
+ end;
+ end else
+ begin
+ GetBounds(SaveBounds);
+ repeat
+ P := Origin;
+ S := Size;
+ KeyEvent(Event);
+ case Event.KeyCode and $FF00 of
+ kbLeft: Change(-1, 0);
+ kbRight: Change(1, 0);
+ kbUp: Change(0, -1);
+ kbDown: Change(0, 1);
+ kbCtrlLeft: Change(-8, 0);
+ kbCtrlRight: Change(8, 0);
+ kbHome: Update(Limits.A.X, P.Y);
+ kbEnd: Update(Limits.B.X - S.X, P.Y);
+ kbPgUp: Update(P.X, Limits.A.Y);
+ kbPgDn: Update(P.X, Limits.B.Y - S.Y);
+ end;
+ MoveGrow(P, S);
+ until (Event.KeyCode = kbEnter) or (Event.KeyCode = kbEsc);
+ if Event.KeyCode = kbEsc then
+ Locate(SaveBounds);
+ end;
+ SetState(sfDragging, False);
+end;
+
+
+{***************************************************************************}
+{ TScroller OBJECT METHODS }
+{***************************************************************************}
+
+PROCEDURE TScroller.ScrollDraw;
+VAR D: TPoint;
+BEGIN
+ If (HScrollBar<>Nil) Then D.X := HScrollBar^.Value
+ Else D.X := 0; { Horz scroll value }
+ If (VScrollBar<>Nil) Then D.Y := VScrollBar^.Value
+ Else D.Y := 0; { Vert scroll value }
+ If (D.X<>Delta.X) OR (D.Y<>Delta.Y) Then Begin { View has moved }
+ SetCursor(Cursor.X+Delta.X-D.X,
+ Cursor.Y+Delta.Y-D.Y); { Move the cursor }
+ Delta := D; { Set new delta }
+ If (DrawLock<>0) Then DrawFlag := True { Draw will need draw }
+ Else DrawView; { Redraw the view }
+ End;
+END;
+
+PROCEDURE TScroller.SetLimit (X, Y: Sw_Integer);
+VAR PState: Word;
+BEGIN
+ Limit.X := X; { Hold x limit }
+ Limit.Y := Y; { Hold y limit }
+ Inc(DrawLock); { Set draw lock }
+ If (HScrollBar<>Nil) Then Begin
+ PState := HScrollBar^.State; { Hold bar state }
+ HScrollBar^.State := PState AND NOT sfVisible; { Temp not visible }
+ HScrollBar^.SetParams(HScrollBar^.Value, 0,
+ X-Size.X, Size.X-1, HScrollBar^.ArStep); { Set horz scrollbar }
+ HScrollBar^.State := PState; { Restore bar state }
+ End;
+ If (VScrollBar<>Nil) Then Begin
+ PState := VScrollBar^.State; { Hold bar state }
+ VScrollBar^.State := PState AND NOT sfVisible; { Temp not visible }
+ VScrollBar^.SetParams(VScrollBar^.Value, 0,
+ Y-Size.Y, Size.Y-1, VScrollBar^.ArStep); { Set vert scrollbar }
+ VScrollBar^.State := PState; { Restore bar state }
+ End;
+ Dec(DrawLock); { Release draw lock }
+ CheckDraw; { Check need to draw }
+END;
+
+{***************************************************************************}
+{ TScroller OBJECT PRIVATE METHODS }
+{***************************************************************************}
+PROCEDURE TScroller.CheckDraw;
+BEGIN
+ If (DrawLock = 0) AND DrawFlag Then Begin { Clear & draw needed }
+ DrawFlag := False; { Clear draw flag }
+ DrawView; { Draw now }
+ End;
+END;
+
+
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ TGroup OBJECT METHODS }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+
+
+
+{--TGroup-------------------------------------------------------------------}
+{ Lock -> Platforms DOS/DPMI/WIN/OS2 - Checked 23Sep97 LdB }
+{---------------------------------------------------------------------------}
+{$ifndef NoLock}
+{$define UseLock}
+{$endif ndef NoLock}
+PROCEDURE TGroup.Lock;
+BEGIN
+{$ifdef UseLock}
+ {If (Buffer <> Nil) OR (LockFlag <> 0)
+ Then} Inc(LockFlag); { Increment count }
+{$endif UseLock}
+END;
+
+{--TGroup-------------------------------------------------------------------}
+{ UnLock -> Platforms DOS/DPMI/WIN/OS2 - Checked 23Sep97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE TGroup.Unlock;
+BEGIN
+{$ifdef UseLock}
+ If (LockFlag <> 0) Then Begin
+ Dec(LockFlag); { Decrement count }
+ If (LockFlag = 0) Then DrawView; { Lock release draw }
+ End;
+{$endif UseLock}
+END;
+
+
+{***************************************************************************}
+{ INTERFACE ROUTINES }
+{***************************************************************************}
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ WINDOW MESSAGE ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ Message -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 12Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION Message (Receiver: PView; What, Command: Word;
+ InfoPtr: Pointer): Pointer;
+VAR Event: TEvent;
+BEGIN
+ Message := Nil; { Preset nil }
+ If (Receiver <> Nil) Then Begin { Valid receiver }
+ Event.What := What; { Set what }
+ Event.Command := Command; { Set command }
+ Event.Id := 0; { Zero id field }
+ Event.Data := 0; { Zero data field }
+ Event.InfoPtr := InfoPtr; { Set info ptr }
+ Receiver^.HandleEvent(Event); { Pass to handler }
+ If (Event.What = evNothing) Then
+ Message := Event.InfoPtr; { Return handler }
+ End;
+END;
+
+{---------------------------------------------------------------------------}
+{ NewMessage -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 19Sep97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION NewMessage (P: PView; What, Command: Word; Id: Sw_Integer;
+ Data: Real; InfoPtr: Pointer): Pointer;
+VAR Event: TEvent;
+BEGIN
+ NewMessage := Nil; { Preset failure }
+ If (P <> Nil) Then Begin
+ Event.What := What; { Set what }
+ Event.Command := Command; { Set event command }
+ Event.Id := Id; { Set up Id }
+ Event.Data := Data; { Set up data }
+ Event.InfoPtr := InfoPtr; { Set up event ptr }
+ P^.HandleEvent(Event); { Send to view }
+ If (Event.What = evNothing) Then
+ NewMessage := Event.InfoPtr; { Return handler }
+ End;
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ NEW VIEW ROUTINES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ CreateIdScrollBar -> Platforms DOS/DPMI/WIN/NT/OS2 - Checked 22May97 LdB }
+{---------------------------------------------------------------------------}
+FUNCTION CreateIdScrollBar (X, Y, Size, Id: Sw_Integer; Horz: Boolean): PScrollBar;
+VAR R: TRect; P: PScrollBar;
+BEGIN
+ If Horz Then R.Assign(X, Y, X+Size, Y+1) Else { Horizontal bar }
+ R.Assign(X, Y, X+1, Y+Size); { Vertical bar }
+ P := New(PScrollBar, Init(R)); { Create scrollbar }
+ If (P <> Nil) Then Begin
+ P^.Id := Id; { Set scrollbar id }
+ P^.Options := P^.Options OR ofPostProcess; { Set post processing }
+ End;
+ CreateIdScrollBar := P; { Return scrollbar }
+END;
+
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+{ OBJECT REGISTRATION PROCEDURES }
+{+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
+
+{---------------------------------------------------------------------------}
+{ RegisterViews -> Platforms DOS/DPMI/WIN/NT/OS2 - Updated 28May97 LdB }
+{---------------------------------------------------------------------------}
+PROCEDURE RegisterViews;
+BEGIN
+ RegisterType(RView); { Register views }
+ RegisterType(RFrame); { Register frame }
+ RegisterType(RScrollBar); { Register scrollbar }
+ RegisterType(RScroller); { Register scroller }
+ RegisterType(RListViewer); { Register listview }
+ RegisterType(RGroup); { Register group }
+ RegisterType(RWindow); { Register window }
+END;
+
+END.
diff --git a/packages/fv/src/w32smsg.inc b/packages/fv/src/w32smsg.inc
new file mode 100644
index 0000000000..b557d60dd8
--- /dev/null
+++ b/packages/fv/src/w32smsg.inc
@@ -0,0 +1,190 @@
+{
+ System independent system interface for win32
+
+ Copyright (c) 2000 by Pierre Muller
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+}
+
+uses
+ windows,dos,winevent;
+
+var
+ ChangeSystemEvents : TCriticalSection;
+Const
+ SystemEventActive : Boolean = false;
+
+procedure SystemEventHandler(var ir:INPUT_RECORD);
+
+ var
+ e : TSystemEvent;
+
+ begin
+ { WINDOW_BUFFER_SIZE_EVENT is triggered by buffer size changes
+ but we are interested in console size changes, thus its handled below
+ in PollSystemEvent }
+ if (ir.EventType in [FOCUS_EVENT{,WINDOW_BUFFER_SIZE_EVENT}]) then
+ begin
+ EnterCriticalSection(ChangeSystemEvents);
+ if (ir.EventType=FOCUS_EVENT) then
+ begin
+ if ir.Event.FocusEvent.bSetFocus then
+ e.typ:=SysSetFocus
+ else
+ e.typ:=SysReleaseFocus;
+ end
+ else
+ begin
+ e.typ:=SysResize;
+ e.x:=ir.Event.WindowBufferSizeEvent.dwSize.x;
+ e.y:=ir.Event.WindowBufferSizeEvent.dwSize.y;
+ end;
+ PutSystemEvent(e);
+ LeaveCriticalSection(ChangeSystemEvents);
+ end;
+ end;
+
+
+var
+ Xsize, YSize : longint;
+
+function HandleConsoleCtrl(typ : dword) : BOOL; stdcall;
+var
+ SE : TSystemEvent;
+begin
+ HandleConsoleCtrl:=false;
+ case typ of
+ CTRL_CLOSE_EVENT,
+ CTRL_LOGOFF_EVENT,
+ CTRL_SHUTDOWN_EVENT :
+ begin
+ SE.typ:=SysClose;
+ SE.CloseTyp:=typ;
+ PutSystemEvent(SE);
+ HandleConsoleCtrl:=true;
+ end;
+ end;
+end;
+
+
+procedure InitSystemMsg;
+
+var
+ mode : dword;
+ ConsoleScreenBufferInfo : Console_screen_buffer_info;
+
+begin
+ if SystemEventActive then
+ exit;
+ // enable Window events
+ GetConsoleMode(TextRec(Input).Handle,@mode);
+ mode:=mode or ENABLE_WINDOW_INPUT;
+ SetConsoleMode(TextRec(Input).Handle,mode);
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
+ @ConsoleScreenBufferInfo);
+ XSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
+ YSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
+ PendingSystemHead:=@PendingSystemEvent;
+ PendingSystemTail:=@PendingSystemEvent;
+ PendingSystemEvents:=0;
+ FillChar(LastSystemEvent,sizeof(TSystemEvent),0);
+ InitializeCriticalSection(ChangeSystemEvents);
+ SetResizeEventHandler(@SystemEventHandler);
+ SetFocusEventHandler(@SystemEventHandler);
+ SetConsoleCtrlHandler(@HandleConsoleCtrl,true);
+ SystemEventActive:=true;
+end;
+
+
+procedure DoneSystemMsg;
+var
+ mode : dword;
+begin
+ if not SystemEventActive then
+ exit;
+ // disable System events
+ GetConsoleMode(TextRec(Input).Handle,@mode);
+ mode:=mode and (not ENABLE_WINDOW_INPUT);
+ SetConsoleMode(TextRec(Input).Handle,mode);
+
+ SetResizeEventHandler(nil);
+ SetFocusEventHandler(nil);
+ DeleteCriticalSection(ChangeSystemEvents);
+ SetConsoleCtrlHandler(@HandleConsoleCtrl,false);
+ SystemEventActive:=false;
+end;
+
+
+
+procedure GetSystemEvent(var SystemEvent: TSystemEvent);
+
+var
+ b : byte;
+
+begin
+ repeat
+ EnterCriticalSection(ChangeSystemEvents);
+ b:=PendingSystemEvents;
+ LeaveCriticalSection(ChangeSystemEvents);
+ if b>0 then
+ break
+ else
+ sleep(50);
+ until false;
+ EnterCriticalSection(ChangeSystemEvents);
+ SystemEvent:=PendingSystemHead^;
+ inc(PendingSystemHead);
+ if longint(PendingSystemHead)=longint(@PendingSystemEvent)+sizeof(PendingSystemEvent) then
+ PendingSystemHead:=@PendingSystemEvent;
+ dec(PendingSystemEvents);
+ LastSystemEvent:=SystemEvent;
+ LeaveCriticalSection(ChangeSystemEvents);
+end;
+
+
+function PollSystemEvent(var SystemEvent: TSystemEvent):boolean;
+var
+ ConsoleScreenBufferInfo : Console_screen_buffer_info;
+ NewXSize, NewYSize : longint;
+begin
+ EnterCriticalSection(ChangeSystemEvents);
+ if PendingSystemEvents>0 then
+ begin
+ SystemEvent:=PendingSystemHead^;
+ PollSystemEvent:=true;
+ end
+ else
+ begin
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
+ @ConsoleScreenBufferInfo);
+ NewXSize:=ConsoleScreenBufferInfo.srWindow.right-ConsoleScreenBufferInfo.srWindow.left+1;
+ NewYSize:=ConsoleScreenBufferInfo.srWindow.bottom-ConsoleScreenBufferInfo.srWindow.top+1;
+ if (XSize<>NewXSize) or (YSize<>NewYSize) then
+ begin
+ SystemEvent.typ:=SysResize;
+ SystemEvent.x:=NewXSize;
+ SystemEvent.y:=NewYSize;
+ PutSystemEvent(SystemEvent);
+ XSize:=NewXSize;
+ YSize:=NewYSize;
+ PollSystemEvent:=true;
+ end
+ else
+ PollSystemEvent:=false;
+ end;
+ LeaveCriticalSection(ChangeSystemEvents);
+end;
+