home *** CD-ROM | disk | FTP | other *** search
- {$D+,F+,O+,R+,S-}
- {$DEFINE VBROWSER} {If activated, descend from VBrowser instead of FBrowser.}
-
-
- UNIT DBrowse;
-
-
- {
- Version 1.00 released on 14 February 1991
- Version 1.01 released on 4 July 1991
- Version 1.02 released on 11 December 1992
-
- Written by a guy named Rob Rosenberger (who?)
- Barn Owl Software
- P.O. Box 1115
- O'Fallon, IL 62269
-
- CompuServe userID 74017,1344
-
- An OOP descendent unit for TurboPower Software FBROWSE.TPU users who want
- to offer an incremental-key positioning capability by overriding the default
- CharHook() method in FBrowse objects.
-
- DBrowse offers one descendent object called DataDefBrowser for overriding
- the FBrowser CharHook() method.
-
- DataDefBrowser implements a SetCurrentRecordAndPos() method used by the
- replacement CharHook() to display the incremental record in the center of the
- screen or to move the highlight bar if already on the screen.
-
- By default, DataDefBrowser uses header index zero, the first AddHeader()
- command you issue, to display the current incremental key string. You can
- make DataDefBrowser use a different header index by issuing the following
- commands:
-
- MyDBrowser.wFrame.AddHeader(...);
- MyDBrowser.dbrHdrIndex := MyDBrowser.wFrame.GetLastHeaderIndex;
-
- You can disable header updates by setting dbrHdrIndex to a value of 255 or
- by simply not adding any headers to the frame.
-
- DBrowse's initialization code modifies the FBrowserCommands object so it
- recognizes the backspace key as a ccChar command. This lets DBrowse intercept
- it via the CharHook() method so the user can correct any typing mistakes. If
- you Load() FBrowserCommands from disk (like I do) or use an alternate command
- processor, you must issue an appropriate call to AddCommand() to change the
- backspace to a ccChar.
-
-
- Version 1.01 changes:
- Corrected occasional tendency to leave frame droppings behind.
- Renamed InitCustom()'s "ValidKeys" variable to "IncrKeys" for readability.
- Has no effect on anyone who uses InitCustom().
-
- Version 1.02 changes:
- Upgraded the source code to compile under BP7 and BTREE 5.4x. Also, the
- new 5.4x docs claim MaxNrOfKeys now goes up only to 254, meaning we can
- service the entire range. (Previous BTREE versions let you use up to
- 750 keys at once. I assume TurboPower switched it to a byte variable in
- order to achieve memory savings somewhere. Besides, I can't conceive of
- a situation where you'd need >254 keys!)}
-
-
- INTERFACE {section}
-
-
- USES
- OpKey,
- OpString,
- OpCRT,
- OpCmd,
-
- Filer,
- FBrowse;
-
-
- TYPE
- KeySeriesSet = SET OF 1..MaxNrOfKeys;
-
- DataDefBrowserPtr = ^DataDefBrowser;
- DataDefBrowser
- {$IFDEF VBROWSER}
- = OBJECT(VBrowser)
- {$ELSE}
- = OBJECT(FBrowser)
- {$ENDIF}
- dbrHdrIndex : BYTE;
- IncrementalKey : IsamKeyStr;
- MaxIncKeyLen : BYTE;
- ValidIncKeys : KeySeriesSet;
-
- CONSTRUCTOR InitCustom(X1 : BYTE;
- Y1 : BYTE;
- X2 : BYTE;
- Y2 : BYTE;
- VAR Colors : ColorSet;
- Options : LONGINT;
- IFBPtr : IsamFileBlockPtr;
- KeyNum : INTEGER;
- VAR DatS;
- MaxRows : BYTE;
- RowsPerItem : BYTE;
- MaxCols : WORD;
- MaxIncLen : BYTE;
- IncrKeys : KeySeriesSet);
-
- PROCEDURE Process; VIRTUAL;
- PROCEDURE SetCurrentRecordAndPos(Key : IsamKeyStr;
- Ref : LONGINT;
- ItemPos : BYTE);
-
- {Following public methods not for application programs.}
- PROCEDURE CharHook; VIRTUAL;
- PROCEDURE UpdateHeaders; VIRTUAL;
- END;
-
-
- IMPLEMENTATION {section}
-
-
- CONST
- NullChar = #0;
- NullString = '';
- SpaceChar = ' ';
-
-
- {============================================================================}
- CONSTRUCTOR DataDefBrowser.InitCustom(X1 : BYTE;
- Y1 : BYTE;
- X2 : BYTE;
- Y2 : BYTE;
- VAR Colors : ColorSet;
- Options : LONGINT;
- IFBPtr : IsamFileBlockPtr;
- KeyNum : INTEGER;
- VAR DatS;
- MaxRows : BYTE;
- RowsPerItem : BYTE;
- MaxCols : WORD;
- MaxIncLen : BYTE;
- IncrKeys : KeySeriesSet);
-
- BEGIN {DataDefBrowser.InitCustom}
- IF INHERITED InitCustom(X1,Y1,X2,Y2,
- Colors,
- Options,
- IFBPtr,
- KeyNum,
- {VAR} DatS,
- MaxRows,
- RowsPerItem,
- MaxCols)
- THEN
- BEGIN
- dbrHdrIndex := 0;
- IncrementalKey := NullString;
- IF (MaxIncLen = 0)
- THEN MaxIncKeyLen := MaxKeyLen
- ELSE MaxIncKeyLen := MaxIncLen;
- ValidIncKeys := IncrKeys
- END
- ELSE
- FAIL
- END; {DataDefBrowser.InitCustom}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE DataDefBrowser.Process;
-
- BEGIN {DataDefBrowser.Process}
- IncrementalKey := NullString;
- UpdateHeaders;
- INHERITED Process;
- UpdateHeaders
- END; {DataDefBrowser.Process}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE DataDefBrowser.SetCurrentRecordAndPos(Key : IsamKeyStr;
- Ref : LONGINT;
- ItemPos : BYTE);
-
- {Set the current record to a specific position on the screen. NOTE: this
- does no repositioning if a given record is on the screen at a different spot.
- This helps avoid needless screen repositioning.}
-
- VAR
- DI : WORD;
- Index : WORD;
-
- BEGIN {DataDefBrowser.SetCurrentRecordAndPos}
- {Initialize.}
- IF (ItemPos < 1)
- THEN ItemPos := 1;
- IF (ItemPos > (Height DIV fbRowsPerItem))
- THEN ItemPos := (Height DIV fbRowsPerItem);
-
- {Is record already displayed?}
- DI := fbDisplayItems;
- IF (fbItemRecs^[1].irRef <> 0)
- THEN
- FOR Index := 1 TO DI
- DO WITH fbItemRecs^[Index]
- DO IF ((irRef = Ref) AND (Key = irKey))
- THEN
- BEGIN
- IF (Index <> fbCurItem)
- THEN fbGotoItem(Index);
- EXIT {no need to hang around here, eh?}
- END;
-
- {Set current item, etc.}
- IF (Ref <> fbCurRef)
- THEN fbCurItem := ItemPos;
- fbCurKey := Key;
- fbCurRef := Ref;
-
- {Mark the screen as empty.}
- fbEmptyBrowScreen;
-
- {Update the screen if the window is current.}
- IF IsCurrent
- THEN UpdateContents
- END; {DataDefBrowser.SetCurrentRecordAndPos}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE DataDefBrowser.CharHook;
-
- {Translate keyboard chars into incremental key searches. Notice how we
- first convert a space to a null char, and convert it back to a space only if
- we don't find a match?
- Suppose the user searches for "xxxx<null>yyy" and it happens to exist as
- the very last key. If we searched for "xxxx<space>" first, we'd get error
- 10210 telling us no key exists AND NO GREATER KEY EXISTED as a substitute! A
- rather obscure condition, of course, but it pays to convert to a null first
- and convert back to the original space only if necessary. Otherwise people
- might call you with bug reports.}
-
- VAR
- TempKeyStr : IsamKeyStr;
- TempRecord : LONGINT;
-
- BEGIN {DataDefBrowser.CharHook}
- {Is this a valid key for incremental searching?}
- IF NOT (GetKeyNumber IN ValidIncKeys)
- THEN EXIT; {no need to hang around here, eh?}
-
- {Deal with incremental keystroke.}
- CASE GetLastKey OF
- BkSp :
- IF (LENGTH(IncrementalKey) >= 1)
- THEN DEC(IncrementalKey[0]);
- Space :
- IncrementalKey := (IncrementalKey + NullChar)
- ELSE
- IncrementalKey := (IncrementalKey + UPCASE(CHAR(LO(GetLastKey))))
- END; {CASE}
-
- {Trim the incremental key if it's too long.}
- IF (LENGTH(IncrementalKey) > MaxIncKeyLen)
- THEN BYTE(IncrementalKey[0]) := MaxIncKeyLen;
-
- UpdateHeaders;
-
- {Move to closest match if we have an incremental key.}
- IF (IncrementalKey > NullString)
- THEN
- BEGIN
- TempKeyStr := IncrementalKey;
- BTSearchKey(fbIFB,GetKeyNumber,{VAR} TempRecord,{VAR} TempKeyStr);
- IF IsamOK
- THEN
- IF (POS(StUpCase(IncrementalKey),StUpCase(TempKeyStr)) = 1)
- THEN
- SetCurrentRecordAndPos(TempKeyStr,TempRecord,(Height DIV 2))
- ELSE
- BEGIN
- DEC(IncrementalKey[0]);
-
- {Maybe they typed a space and really meant a space char?}
- IF (CHAR(LO(GetLastKey)) = SpaceChar)
- THEN
- BEGIN
- IncrementalKey := (IncrementalKey + SpaceChar);
- {Trim the incremental key if it's too long.}
- IF (LENGTH(IncrementalKey) > MaxIncKeyLen)
- THEN BYTE(IncrementalKey[0]) := MaxIncKeyLen;
-
- {Move to closest match.}
- TempKeyStr := IncrementalKey;
- BTSearchKey(fbIFB,
- GetKeyNumber,
- {VAR} TempRecord,
- {VAR} TempKeyStr);
- IF IsamOK
- THEN
- IF (POS(StUpCase(IncrementalKey),
- StUpCase(TempKeyStr)) = 1)
- THEN
- SetCurrentRecordAndPos(TempKeyStr,
- TempRecord,
- (Height DIV 2))
- ELSE
- BEGIN
- DEC(IncrementalKey[0]);
- RingBell
- END
- END
- ELSE
- RingBell;
-
- UpdateHeaders
- END
- ELSE
- BEGIN
- {Probably error 10210, no matching key & no greater key.}
- DEC(IncrementalKey[0]);
- RingBell;
- UpdateHeaders
- END
- END
- {ELSE don't move anywhere}
- END; {DataDefBrowser.CharHook}
- {============================================================================}
-
- {============================================================================}
- PROCEDURE DataDefBrowser.UpdateHeaders;
-
- VAR
- Redraw : BOOLEAN;
-
- BEGIN {DataDefBrowser.UpdateHeaders}
- WITH wFrame
- DO IF ((dbrHdrIndex < 255)
- AND (GetLastHeaderIndex < 255)
- AND IsCurrent)
- THEN
- BEGIN
- {Modify dbrHdrIndex'th string to show the incremental key.}
- IF (IncrementalKey = NullString)
- THEN
- IF ((GetKeyNumber IN ValidIncKeys) AND IsCurrent)
- THEN ChangeHeaderString(dbrHdrIndex,'╡INCR KEY╞',{VAR} Redraw)
- ELSE ChangeHeaderString(dbrHdrIndex,NullString,{VAR} Redraw)
- ELSE
- ChangeHeaderString(dbrHdrIndex,
- ('╡KEY "' + IncrementalKey + '"╞'),
- {VAR} Redraw);
-
- IF Redraw
- THEN UpdateFrame
- ELSE DrawHeader(dbrHdrIndex)
- END
- END; {DataDefBrowser.UpdateHeaders}
- {============================================================================}
-
-
- BEGIN
- FBrowserCommands.AddCommand(ccChar,1,BkSp,0)
- END. {DBrowse}
-