Copyright (C) 1993, Digital Equipment Corporation
All rights reserved.
See the file COPYRIGHT for a full description.
Last modified on Tue Jan 16 13:08:17 PST 1996 by heydon
modified on Wed Feb 1 09:40:44 PST 1995 by kalsow
modified on Wed Sep 7 18:48:22 PDT 1994 by bharat
modified on Fri Jul 2 16:33:31 PDT 1993 by mhb
<* PRAGMA LL *>
MODULE Browser;
IMPORT Attributes, FormsVBT,Fmt, ListVBT, NodeVBT, Split, Text, TSplit, VBT,
Rd, Wr, RW;
REVEAL
BrowserNode = NodeVBT.Widget BRANDED "VO-BrowserNode" OBJECT END;
Browser = BrowserNode BRANDED "VO-Browser" OBJECT
Quick : BOOLEAN := FALSE;
Multiplicity: BOOLEAN := FALSE;
Contents: REF ARRAY OF TEXT := NIL;
Cix : CARDINAL := 0;
(* multibrowser *)
Selections: REF ARRAY OF CARDINAL := NIL;
Six : CARDINAL := 0;
(* unibrowser *)
Selection: INTEGER := -1; (* not selected *)
OVERRIDES
loadAttributes := BroLoadAttributes;
applyAttributes := BroApplyAttributes;
computeSX := BroComputeSX;
save := BroSave;
load := BroLoad;
initObliqAttrs := BroObAttrs;
END;
FileBrowser = BrowserNode BRANDED "VO-FileBrowser" OBJECT
LabelFont: TEXT := "-*-helvetica-bold-*R-*120-*";
ReadOnly: BOOLEAN := FALSE;
Value : TEXT := ".";
Suffixes: REF ARRAY OF TEXT := NIL;
ActionLabel : TEXT := "Open";
OVERRIDES
loadAttributes := FbLoadAttributes;
applyAttributes := FbApplyAttributes;
generateAttachments := FbGenerateAttachments;
computeSX := FbComputeSX;
save := FbSave;
load := FbLoad;
initObliqAttrs := FbObAttrs;
END;
<* FATAL FormsVBT.Error,FormsVBT.Unimplemented, Split.NotAChild *>
PROCEDURE BrowserConstructor (): NodeVBT.T =
BEGIN
RETURN NEW(Browser, BgColor := "SlightlyYellowishGrey90",
FgColor := "Black",
Rim := 0,
Border := 0, Font := "-*-helvetica-bold-*R-*120-*",
width := 100, height := 100, Embellishment := "Lowered" );
END BrowserConstructor;
PROCEDURE FileBrowserConstructor (): NodeVBT.T =
BEGIN
RETURN NEW(FileBrowser, BgColor := "PaleGray", FgColor := "Black",
Rim := 0,
Border := 0, Font := "-*-helvetica-bold-*R-*120-*",
width := 150, height := 150, Embellishment := "Lowered");
END FileBrowserConstructor;
PROCEDURE BroComputeSX (nv: Browser; Final: BOOLEAN := FALSE): TEXT =
VAR
items : TEXT := "";
values: TEXT := "";
BEGIN
IF nv.Multiplicity THEN
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "typeOfBrowser", "MultiBrowser");
IF nv.Six = 0 THEN
nv.DialogSX :=
NodeVBT.FindAndReplace(nv.DialogSX, "ValueList", "");
ELSE
FOR i := FIRST(nv.Selections^)
TO FIRST(nv.Selections^) + nv.Six - 1 DO
values := values & Fmt.Int(nv.Selections[i]) & " ";
END;
nv.DialogSX :=
NodeVBT.FindAndReplace(nv.DialogSX, "ValueList",
"(Value " & values & " )" );
END
ELSE
nv.DialogSX :=
NodeVBT.FindAndReplace(nv.DialogSX, "typeOfBrowser", "Browser");
IF nv.Selection = -1 THEN
nv.DialogSX :=
NodeVBT.FindAndReplace(nv.DialogSX, "ValueList", "");
ELSE
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "ValueList",
"(Value " & Fmt.Int(nv.Selection) & " )");
END
END;
IF nv.Quick THEN
nv.DialogSX := NodeVBT.FindAndReplace(nv.DialogSX, "quick", "Quick")
ELSE
nv.DialogSX := NodeVBT.FindAndReplace(nv.DialogSX, "quick", "")
END;
IF nv.Cix = 0 THEN
nv.DialogSX := NodeVBT.FindAndReplace(nv.DialogSX, "Items", "")
ELSE
FOR i := FIRST(nv.Contents^) TO LAST(nv.Contents^) DO
items := items & "\"" & nv.Contents[i] & "\" ";
END;
nv.DialogSX := NodeVBT.FindAndReplace(nv.DialogSX, "Items", items);
END;
RETURN NodeVBT.T.computeSX(nv, Final);
END BroComputeSX;
Browser Support Procs
PROCEDURE BroLoadAttributes (nv: Browser; as: FormsVBT.T) =
BEGIN
FormsVBT.PutBoolean(as, "brQuick", nv.Quick);
FormsVBT.PutBoolean(as, "brMultiplicity", nv.Multiplicity);
FormsVBT.PutChoice(as, "brModes", "brEditMode"); (* always start in
edit mode *)
WITH (* set all the t-splits *)
tsp1 = NARROW(FormsVBT.GetVBT(as, "brSelectionMode"), TSplit.T),
tsp2 = NARROW(FormsVBT.GetVBT(as, "brBrowsers"), TSplit.T),
tsp3 = NARROW(FormsVBT.GetVBT(as, "brNestedTS"), TSplit.T) DO
TSplit.SetCurrent(tsp1, FormsVBT.GetVBT(as, "page1"));
TSplit.SetCurrent(tsp2, FormsVBT.GetVBT(as, "brEdit"));
IF nv.Multiplicity THEN
TSplit.SetCurrent(tsp3, FormsVBT.GetVBT(as, "brMulti"))
ELSE
TSplit.SetCurrent(tsp3, FormsVBT.GetVBT(as, "brUni"))
END
END;
(* load contents into browsers *)
WITH editBrowser = NARROW(FormsVBT.GetVBT(as, "brInitial"), ListVBT.T),
uniBrowser = NARROW(FormsVBT.GetVBT(as, "brSingle"), ListVBT.T),
multiBrowser = NARROW(
FormsVBT.GetVBT(as, "brMultiple"), ListVBT.T) DO
Attributes.LVFlush(editBrowser);
Attributes.LVFlush(uniBrowser);
Attributes.LVFlush(multiBrowser);
IF nv.Cix = 0 THEN (* no contents yet so disable "add next"
"delete" *)
FormsVBT.MakeDormant(as, "brFilter")
ELSE
FormsVBT.MakeActive(as, "brFilter");
FOR i := FIRST(nv.Contents^) TO LAST(nv.Contents^) DO
Attributes.LVAppendText(editBrowser, nv.Contents[i] & "\n");
Attributes.LVAppendText(uniBrowser, nv.Contents[i] & "\n");
Attributes.LVAppendText(multiBrowser, nv.Contents[i] & "\n");
END;
IF nv.Selection # -1 THEN uniBrowser.selectOnly(nv.Selection) END;
multiBrowser.selectNone();
IF nv.Six # 0 THEN
FOR i := FIRST(nv.Selections^)
TO FIRST(nv.Selections^) + nv.Six - 1 DO
multiBrowser.select(nv.Selections[i], TRUE);
END
END
END;
END;
NodeVBT.T.loadAttributes(nv, as);
END BroLoadAttributes;
PROCEDURE BroObAttrs (nv : Browser): TEXT =
VAR code : TEXT;
BEGIN
code := NodeVBT.BoolAttr("Quick", nv.Quick) &
NodeVBT.BoolAttr("Multiplicity", nv.Multiplicity);
IF nv.Cix > 0 THEN
code := code & "\ttemp.Contents := [";
FOR i:= 0 TO nv.Cix - 1 DO
code := code & "\"" & nv.Contents[FIRST(nv.Contents^) + i] &
"\",";
END;
code := code & "];\n";
END;
IF nv.Six > 0 THEN
code := code & "\ttemp.Selections := [";
FOR i:= 0 TO nv.Six - 1 DO
code := code & Fmt.Int(nv.Selections[FIRST(nv.Selections^) + i]) &
",";
END;
code := code & "];\n";
END;
code := code & NodeVBT.IntAttr("Selection", nv.Selection);
RETURN NodeVBT.T.initObliqAttrs(nv) & code ;
END BroObAttrs;
PROCEDURE BroApplyAttributes (nv: Browser; as: FormsVBT.T) =
VAR
ctr : CARDINAL;
index: INTEGER;
BEGIN
NodeVBT.T.applyAttributes(nv, as);
nv.Quick := FormsVBT.GetBoolean(as, "brQuick");
nv.Multiplicity := FormsVBT.GetBoolean(as, "brMultiplicity");
WITH uniBrowser = NARROW(FormsVBT.GetVBT(as, "brSingle"), ListVBT.T),
multiBrowser = NARROW(
FormsVBT.GetVBT(as, "brMultiple"), ListVBT.T) DO
nv.Cix := uniBrowser.count();
nv.Contents := NEW(REF ARRAY OF TEXT, nv.Cix);
nv.Selections := NEW(REF ARRAY OF CARDINAL, nv.Cix);
nv.Six := 0;
ctr := 0;
index := FIRST(nv.Selections^);
FOR i := FIRST(nv.Contents^) TO LAST(nv.Contents^) DO
nv.Contents[i] := uniBrowser.getValue(ctr);
IF multiBrowser.isSelected(ctr) THEN
INC(nv.Six);
nv.Selections[index] := ctr;
INC(index);
END;
INC(ctr);
END;
IF NOT uniBrowser.getFirstSelected(nv.Selection) THEN
nv.Selection := -1
END;
END
END BroApplyAttributes;
PROCEDURE addProc (<* UNUSED *> cl : FormsVBT.Closure;
afv : FormsVBT.T;
name: TEXT;
<* UNUSED *> time: VBT.TimeStamp ) =
VAR
editBrowser := NARROW(FormsVBT.GetVBT(afv, "brInitial"), ListVBT.T);
uniBrowser := NARROW(FormsVBT.GetVBT(afv, "brSingle"), ListVBT.T);
multiBrowser := NARROW(FormsVBT.GetVBT(afv, "brMultiple"), ListVBT.T);
item := FormsVBT.GetText(afv, "brItem");
pos: INTEGER;
PROCEDURE insertAt (n: CARDINAL) =
BEGIN
editBrowser.insertCells(n, 1);
editBrowser.setValue(n, item);
uniBrowser.insertCells(n, 1);
uniBrowser.setValue(n, item);
multiBrowser.insertCells(n, 1);
multiBrowser.setValue(n, item);
editBrowser.selectOnly(n);
END insertAt;
BEGIN
IF Text.Equal(name, "brAddFirst") THEN
insertAt(0);
ELSIF editBrowser.getFirstSelected(pos) THEN
insertAt(pos + 1);
ELSE
insertAt(0)
END;
FormsVBT.MakeActive(afv, "brFilter");
END addProc;
PROCEDURE delProc (<* UNUSED *> cl : FormsVBT.Closure;
afv : FormsVBT.T;
<* UNUSED *> name: TEXT;
<* UNUSED *> time: VBT.TimeStamp ) =
VAR
editBrowser := NARROW(FormsVBT.GetVBT(afv, "brInitial"), ListVBT.T);
uniBrowser := NARROW(FormsVBT.GetVBT(afv, "brSingle"), ListVBT.T);
multiBrowser := NARROW(FormsVBT.GetVBT(afv, "brMultiple"), ListVBT.T);
pos: INTEGER;
BEGIN
IF editBrowser.getFirstSelected(pos) THEN
editBrowser.removeCells(pos, 1);
uniBrowser.removeCells(pos, 1);
multiBrowser.removeCells(pos, 1);
editBrowser.selectOnly(pos);
END;
IF editBrowser.count() = 0 THEN
FormsVBT.MakeDormant(afv, "brFilter");
END
END delProc;
PROCEDURE selProc (<* UNUSED *> cl : FormsVBT.Closure;
afv : FormsVBT.T;
<* UNUSED *> name: TEXT;
<* UNUSED *> time: VBT.TimeStamp ) =
BEGIN
(* load the currently selected item into the typein for copy-editing*)
WITH z = FormsVBT.GetTextProperty(afv, "brInitial", "Select") DO
FormsVBT.PutText(afv, "brItem", z, FALSE);
END
END selProc;
FileBrowser Support Procs *****************************************
PROCEDURE FbLoadAttributes (nv: FileBrowser; as: FormsVBT.T) =
BEGIN
FormsVBT.PutText(as, "fbLFtypein", nv.LabelFont, FALSE);
FormsVBT.PutBoolean(as, "fbReadOnly", nv.ReadOnly);
FormsVBT.PutText(as, "fbVal", nv.Value, FALSE);
FormsVBT.PutText(as, "fbActionLabel", nv.ActionLabel, FALSE);
WITH (* set all the t-split & the browser *)
tsp2 = NARROW(FormsVBT.GetVBT(as, "fbEditSuffixes"), TSplit.T),
tsp3 = NARROW(FormsVBT.GetVBT(as, "fbSuffixesToolkit"), TSplit.T),
suffixBrowser = NARROW(FormsVBT.GetVBT(as, "fbSuffixes"), ListVBT.T) DO
Attributes.LVFlush(suffixBrowser);
IF nv.Suffixes = NIL THEN
FormsVBT.PutChoice(as, "fbModes", "fbNoSuffixes");
TSplit.SetCurrent(tsp2, FormsVBT.GetVBT(as, "fbBlank"));
TSplit.SetCurrent(tsp3, FormsVBT.GetVBT(as, "fbPage2"));
FormsVBT.MakeDormant(as, "fbFilter");
ELSE
FormsVBT.PutChoice(as, "fbModes", "fbAddSuffixes");
TSplit.SetCurrent(tsp2, FormsVBT.GetVBT(as, "fbEdit"));
TSplit.SetCurrent(tsp3, FormsVBT.GetVBT(as, "fbPage1"));
FormsVBT.MakeActive(as, "fbFilter");
FOR i := FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
Attributes.LVAppendText(suffixBrowser, nv.Suffixes[i] & "\n")
END;
END;
END;
NodeVBT.T.loadAttributes(nv, as);
END FbLoadAttributes;
PROCEDURE FbApplyAttributes (nv: FileBrowser; as: FormsVBT.T) =
VAR ctr := 0;
BEGIN
NodeVBT.T.applyAttributes(nv, as);
nv.LabelFont := FormsVBT.GetText(as, "fbLFtypein");
nv.ReadOnly := FormsVBT.GetBoolean(as, "fbReadOnly");
nv.Value := FormsVBT.GetText(as, "fbVal");
nv.ActionLabel := FormsVBT.GetText(as, "fbActionLabel");
WITH suffixBrowser = NARROW(
FormsVBT.GetVBT(as, "fbSuffixes"), ListVBT.T),
ct = suffixBrowser.count(),
currentMode = FormsVBT.GetChoice(as, "fbModes") DO
IF ct = 0 OR Text.Equal(currentMode, "fbNoSuffixes") THEN
nv.Suffixes := NIL
ELSE
nv.Suffixes := NEW(REF ARRAY OF TEXT, ct);
FOR i := FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
nv.Suffixes[i] := suffixBrowser.getValue(ctr);
INC(ctr);
END;
END;
END
END FbApplyAttributes;
PROCEDURE fbAddProc (<* UNUSED *> cl : FormsVBT.Closure;
afv : FormsVBT.T;
name: TEXT;
<* UNUSED *> time: VBT.TimeStamp ) =
VAR
suffixBrowser := NARROW(FormsVBT.GetVBT(afv, "fbSuffixes"), ListVBT.T);
item := FormsVBT.GetText(afv, "fbItem");
pos: INTEGER;
BEGIN
IF Text.Equal(name, "fbAddFirst") THEN
suffixBrowser.insertCells(0, 1);
suffixBrowser.setValue(0, item);
suffixBrowser.selectOnly(0);
ELSIF suffixBrowser.getFirstSelected(pos) THEN
suffixBrowser.insertCells(pos + 1, 1);
suffixBrowser.setValue(pos + 1, item);
suffixBrowser.selectOnly(pos + 1);
ELSE
suffixBrowser.insertCells(0, 1);
suffixBrowser.setValue(0, item);
suffixBrowser.selectOnly(0);
END;
FormsVBT.MakeActive(afv, "fbFilter");
END fbAddProc;
PROCEDURE fbDelProc (<* UNUSED *> cl : FormsVBT.Closure;
afv : FormsVBT.T;
<* UNUSED *> name: TEXT;
<* UNUSED *> time: VBT.TimeStamp ) =
VAR
suffixBrowser := NARROW(FormsVBT.GetVBT(afv, "fbSuffixes"), ListVBT.T);
pos: INTEGER;
BEGIN
IF suffixBrowser.getFirstSelected(pos) THEN
suffixBrowser.removeCells(pos, 1);
IF suffixBrowser.count() > pos THEN
suffixBrowser.selectOnly(pos)
ELSIF pos > 0 THEN
suffixBrowser.selectOnly(pos - 1)
END
END;
IF suffixBrowser.count() = 0 THEN
FormsVBT.MakeDormant(afv, "fbFilter");
END
END fbDelProc;
PROCEDURE FbGenerateAttachments (nv: FileBrowser): TEXT =
BEGIN
IF NodeVBT.AllWhitespace(nv.Code) THEN RETURN ""; END;
RETURN "form_attach(SELF.FORM, SELF." & nv.name & ".name & \"action\", SELF." & nv.name
& "Proc);\n" & NodeVBT.T.generateAttachments(nv);
END FbGenerateAttachments;
PROCEDURE FbComputeSX (nv: FileBrowser; Final: BOOLEAN := FALSE): TEXT =
VAR
suffixList := "";
BEGIN
IF nv.ReadOnly THEN
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "ReadOnly", "ReadOnly")
ELSE
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "ReadOnly", "")
END;
(* two occurrences *)
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "LabelFont", nv.LabelFont);
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "LabelFont", nv.LabelFont);
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "Initial", nv.Value);
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "fbName1", nv.name);
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "fbName2", nv.name);
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "ActionLabel", nv.ActionLabel);
IF nv.Suffixes = NIL THEN
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "Suffixes", "\"\"")
ELSE
FOR i:= FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
suffixList := suffixList & " \"" & nv.Suffixes[i] &
"\" "
END;
nv.DialogSX := NodeVBT.FindAndReplace(
nv.DialogSX, "Suffixes", suffixList)
END;
RETURN NodeVBT.T.computeSX(nv, Final);
END FbComputeSX;
PROCEDURE FbObAttrs (nv : FileBrowser): TEXT =
VAR code : TEXT;
BEGIN
code := NodeVBT.TextAttr("LabelFont", nv.LabelFont) &
NodeVBT.BoolAttr("ReadOnly", nv.ReadOnly) &
NodeVBT.TextAttr("Value", nv.Value);
IF nv.Suffixes # NIL THEN
code := code & "\ttemp.Suffixes := [";
FOR i := FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
code := code & "\"" & nv.Suffixes[i] & "\",";
END;
code := code & "];\n";
END;
code := code & NodeVBT.TextAttr("ActionLabel", nv.ActionLabel);
RETURN NodeVBT.T.initObliqAttrs(nv) & code ;
END FbObAttrs;
PROCEDURE BroSave (nv: Browser; fv: FormsVBT.T; s: Wr.T) =
BEGIN
NodeVBT.T.save(nv, fv, s);
RW.wbool(s, nv.Quick);
RW.wbool(s, nv.Multiplicity);
RW.wcard(s, nv.Cix);
IF nv.Cix > 0 THEN
FOR i:= 0 TO nv.Cix - 1 DO
RW.wtext(s, nv.Contents[FIRST(nv.Contents^) + i]);
END
END;
RW.wcard(s, nv.Six);
IF nv.Six > 0 THEN
FOR i:= 0 TO nv.Six - 1 DO
RW.wcard(s, nv.Selections[FIRST(nv.Selections^) + i]);
END
END;
RW.wint(s, nv.Selection);
END BroSave;
PROCEDURE BroLoad (nv: Browser ; fv: FormsVBT.T; s: Rd.T) =
BEGIN
NodeVBT.T.load(nv, fv, s);
RW.rbool(s, nv.Quick);
RW.rbool(s, nv.Multiplicity);
RW.rcard(s, nv.Cix);
IF nv.Cix > 0 THEN
nv.Contents := NEW(REF ARRAY OF TEXT, nv.Cix);
FOR i:= 0 TO nv.Cix - 1 DO
RW.rtext(s, nv.Contents[FIRST(nv.Contents^) + i]);
END
ELSE
nv.Contents := NIL
END;
RW.rcard(s, nv.Six);
IF nv.Six > 0 THEN
nv.Selections := NEW(REF ARRAY OF CARDINAL, nv.Six);
FOR i:= 0 TO nv.Six - 1 DO
RW.rcard(s, nv.Selections[FIRST(nv.Selections^) + i]);
END
ELSE
nv.Selections := NIL
END;
RW.rint(s, nv.Selection);
END BroLoad;
PROCEDURE FbSave (nv: FileBrowser ; fv: FormsVBT.T; s: Wr.T) =
BEGIN
NodeVBT.T.save(nv, fv, s);
RW.wtext(s, nv.LabelFont);
RW.wbool(s, nv.ReadOnly);
RW.wtext(s, nv.Value);
IF nv.Suffixes # NIL THEN
RW.wcard(s, NUMBER(nv.Suffixes^));
FOR i := FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
RW.wtext(s, nv.Suffixes[i]);
END
ELSE
RW.wcard(s, 0)
END;
RW.wtext(s, nv.ActionLabel);
END FbSave;
PROCEDURE FbLoad (nv: FileBrowser ; fv: FormsVBT.T; s: Rd.T) =
VAR size : CARDINAL;
BEGIN
NodeVBT.T.load(nv, fv, s);
RW.rtext(s, nv.LabelFont);
RW.rbool(s, nv.ReadOnly);
RW.rtext(s, nv.Value);
RW.rcard(s, size);
IF size > 0 THEN
nv.Suffixes := NEW(REF ARRAY OF TEXT, size);
FOR i := FIRST(nv.Suffixes^) TO LAST(nv.Suffixes^) DO
RW.rtext(s, nv.Suffixes[i]);
END
ELSE
nv.Suffixes := NIL;
END;
RW.rtext(s, nv.ActionLabel);
END FbLoad;
PROCEDURE Initialize () =
BEGIN
EVAL NodeVBT.Register("browser", BrowserConstructor);
EVAL NodeVBT.Register("filebrowser", FileBrowserConstructor);
WITH addclosure = NEW(FormsVBT.Closure, apply := addProc),
delclosure = NEW(FormsVBT.Closure, apply := delProc),
selclosure = NEW(FormsVBT.Closure, apply := selProc) DO
FormsVBT.Attach(Attributes.afv, "brAddFirst", addclosure);
FormsVBT.Attach(Attributes.afv, "brAddAfter", addclosure);
FormsVBT.Attach(Attributes.afv, "brDelete", delclosure);
FormsVBT.Attach(Attributes.afv, "brItem", addclosure);
FormsVBT.Attach(Attributes.afv, "brInitial", selclosure);
END;
WITH addclosure = NEW(FormsVBT.Closure, apply := fbAddProc),
delclosure = NEW(FormsVBT.Closure, apply := fbDelProc)
DO
FormsVBT.Attach(Attributes.afv, "fbLF", addclosure);
FormsVBT.Attach(Attributes.afv, "fbAddFirst", addclosure);
FormsVBT.Attach(Attributes.afv, "fbAddAfter", addclosure);
FormsVBT.Attach(Attributes.afv, "fbDelete", delclosure);
FormsVBT.Attach(Attributes.afv, "fbItem", addclosure);
END;
END Initialize;
BEGIN
END Browser.