| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- IMPLEMENTATION MODULE DBScreen;
- (*
- * ModBase
- * Release 3.0
- * By Don Fletcher & John McMonagle
- * (c) Copyright 1986 - 1991 PMI
- * P.O. Box 8402
- * Green Bay Wi 53308
- * All Rights Reserved
- *
- *)
- IMPORT SYSTEM;
- (*Repertoire modules*)
- IMPORT BigSets;
- IMPORT LowLevel;
- IMPORT KbdInput;
- IMPORT SmartScreen;
- IMPORT StrEdit;
- IMPORT StrInput;
- IMPORT StrConv;
- IMPORT M2Strings;
- IMPORT VWindows;
- IMPORT WindowPrims;
- IMPORT ModBase3;
- IMPORT ErrorManager;
- FROM MiscFunctions IMPORT FieldName, FieldNameChar,
- Alph, Trim, Upper;
- CONST Blank = ' ';
- MaxGets = 80;
- MaxField = 128;
- MaxLength = 256;
- MaxNLength = 18;
- CRnum = 13;
- TABnum = 9;
- BSPnum = 8;
- ESCnum = 27;
- BTBnum = 15 + KbdInput.Extended;
- (*back tab numeric code for extended scan code*)
- LARWnum = 75 + KbdInput.Extended;
- (*left arrow numeric code*)
- RARWnum = 77 + KbdInput.Extended;
- (*right arrow*)
- UARWnum = 72 + KbdInput.Extended;
- (*up arrow*)
- DARWnum = 80 + KbdInput.Extended;
- TYPE
- String = ARRAY [0..MaxField] OF CHAR;
- StrPtr = POINTER TO String;
- GetType = RECORD
- row: CARDINAL;
- col: CARDINAL;
- len: CARDINAL;
- val: StrPtr;
- END;
- InputArray = ARRAY [1..MaxGets] OF GetType;
- VAR input: InputArray;
- lastget: CARDINAL;
- PROCEDURE ValidType(ch: CHAR): BOOLEAN;
- BEGIN
- RETURN (CAP(ch)='C') OR (CAP(ch)='N') OR (CAP(ch)='L') OR
- (CAP(ch)='D') OR (CAP(ch)='M');
- END ValidType;
- PROCEDURE ValidSize(size: CARDINAL; fieldtype: CHAR): BOOLEAN;
- (* Checks to see whether size is valid for the given fieldtype*)
- BEGIN
- CASE CAP(fieldtype) OF
- 'C': RETURN (size >= 1) AND (size <= MaxLength);
- | 'N': RETURN (size >= 1) AND (size <= MaxNLength);
- | 'L': RETURN (size = 1);
- | 'D': RETURN (size = 8);
- | 'M': RETURN (size = 10);
- END;
- RETURN FALSE;
- END ValidSize;
- PROCEDURE ValidDec(size, decimalplaces: CARDINAL): BOOLEAN;
- BEGIN
- RETURN (decimalplaces <= size);
- END ValidDec;
- PROCEDURE GetDescriptors(VAR fields: ARRAY OF ModBase3.DBFieldDescriptor);
- VAR
- i, j, crow, ccol, lastfield, pagebottom, pagetop: CARDINAL;
- sizestring: ARRAY [0..2] OF CHAR;
- decstr: ARRAY [0..1] OF CHAR;
- confirmed: CHAR;
- ok: BOOLEAN;
- PROCEDURE UniqueName(testname: ARRAY OF CHAR): BOOLEAN;
- VAR i, matches: CARDINAL;
- BEGIN
- i := 0;
- matches := 0;
- WHILE (i <= lastfield) DO
- IF (M2Strings.CompareStr(fields[i].name, testname) = 0) THEN
- INC(matches)
- END;
- INC(i)
- END;
- RETURN matches = 1;
- END UniqueName;
- BEGIN
- WindowPrims.PushColors();
- SmartScreen.ClearScreen();
- i := 0;
- pagetop := i;
- pagebottom := i+29;
- confirmed := 'N';
- Say(2, 5, 'NAME------ TYPE SIZE DEC');
- SmartScreen.SetAttribOrColor( SmartScreen.red,
- SmartScreen.blue, SmartScreen.ReverseVideo );
- REPEAT
- crow := (i MOD 15) + 4;
- ccol := 5+((i DIV 15) * 35);
- Say(crow, ccol, fields[i].name);
- Say(crow, ccol+12, fields[i].fldtype);
- StrConv.CardinalToStr(fields[i].size, 3, sizestring);
- Say(crow, ccol+18, sizestring);
- StrConv.CardinalToStr(fields[i].decplaces, 3, decstr);
- Say(crow, ccol+24, decstr);
- INC(i);
- UNTIL (NOT FieldName(fields[i].name)) OR (i >= pagebottom);
- lastfield := i-1;
- REPEAT
- i := 0;
- REPEAT
- REPEAT
- crow := (i MOD 15) + 4;
- ccol := 5+((i DIV 15) * 35);
- Get(crow, ccol, fields[i].name);
- Get(crow, ccol + 12, fields[i].fldtype);
- ReadGets;
- fields[i].fldtype := CAP(fields[i].fldtype);
- Upper(fields[i].name);
- Say(crow, ccol, fields[i].name);
- Say(crow, ccol + 12, fields[i].fldtype);
- UNTIL (FieldName(fields[i].name) AND UniqueName(fields[i].name))
- AND (ValidType(fields[i].fldtype))
- OR (fields[i].name[0] = ' ')
- OR (lastdirection = Escape);
- IF ((fields[i].name[0]) # ' ') AND (lastdirection # Back) THEN
- CASE fields[i].fldtype OF
- 'D' : fields[i].size := 8 |
- 'M' : fields[i].size := 10 |
- 'L' : fields[i].size := 1
- ELSE
- StrConv.CardinalToStr(fields[i].size, 3, sizestring);
- StrConv.CardinalToStr(fields[i].decplaces, 3, decstr);
- REPEAT
- Get(crow, ccol + 18, sizestring);
- ReadGets;
- Trim(sizestring);
- ok := StrConv.StrToCardinal(sizestring, 0, fields[i].size);
- UNTIL ok AND ValidSize(fields[i].size, fields[i].fldtype);
- IF fields[i].fldtype = 'N' THEN
- REPEAT
- Get(crow, ccol + 24, decstr);
- ReadGets;
- Trim(decstr);
- ok := StrConv.StrToCardinal(decstr, 0, fields[i].decplaces);
- UNTIL ok AND ValidDec(fields[i].size, fields[i].decplaces);
- END;
- END; (* case *)
- END;
- IF (i < lastfield) AND (fields[i].name[0] = ' ') THEN
- (* the user has deleted a field in mid-record so the subsequent
- fields must be 'sucked up' *)
- FOR j := i TO lastfield DO
- fields[j] := fields[j+1]
- END (* for *);
- END;
- IF lastdirection = Ahead THEN
- IF i < MaxField-1 THEN
- IF i >= lastfield THEN INC(lastfield) END;
- INC(i)
- END;
- ELSIF lastdirection = Back THEN
- IF i > 0 THEN
- DEC(i)
- END;
- END;
- UNTIL (lastdirection = Escape)
- OR (fields[i-1].name[0] = ' ')
- OR (i < pagetop)
- OR (i > pagebottom);
- (* CONFIRM *)
- Say(24,5, 'Enter "Y" to confirm - ');
- Get(24, 28, confirmed);
- ReadGets;
- UNTIL CAP(confirmed) = 'Y';
- WindowPrims.PopColors();
- END GetDescriptors;
- PROCEDURE ModifyDBStruc(VAR alias: ModBase3.DBFile);
- VAR displayoffset: CARDINAL;
- new: ModBase3.DBFile;
- BEGIN
- (* new = alias;
- ChangeExt(alias.name, 'BAK');
- (* Rename alias to *.bak *)
- Rename(alias.fileID, alias.name);
- CloseDBF(alias);
- (* Rename alias to *.bak *)
- GetDescriptors(new.fieldlist);
- BuildDBF(new.name, new.fieldlist, alias);
- CloseDBF(alias);
- (* UpDate from *.bak *)
- *)
- END ModifyDBStruc;
- (*
- PROCEDURE ChangeExt(VAR filename: ARRAY OF CHAR; ext: ARRAY OF CHAR);
- (* add the ext after the last period in the filename *)
- VAR i, j: CARDINAL;
- BEGIN
- i := M2Strings.Length(filename)-1;
- WHILE (i > 0) AND (filename[i] # '.') DO
- DEC(i)
- END;
- IF i = 0 THEN
- i := M2Strings.Length(filename)-1;
- END;
- FOR j := i+1 TO i+M2Strings.Length(ext)+1 DO
- filename[j] := ext[j-(i+1)]
- END;
- IF HIGH(filename) > (i+M2Strings.Length(ext)+1) THEN
- filename[i+M2Strings.Length(ext)] := 0C;
- END;
- END ChangeExt;
- *)
- PROCEDURE CreateDBF(dbfilename: ARRAY OF CHAR; VAR alias: ModBase3.DBFile);
- VAR descarray: ARRAY [0..MaxField-1] OF ModBase3.DBFieldDescriptor;
- i: CARDINAL;
- BEGIN
- (* initialize field descriptor array *)
- FOR i := 0 TO MaxField-1 DO
- WITH descarray[i] DO
- name := ' ';
- size := 0;
- fldtype := ' ';
- decplaces := 0;
- offset := 0;
- END;
- END;
- GetDescriptors(descarray);
- IF ModBase3.BuildDBF(descarray,MaxField, alias) # 0 THEN
- ErrorManager.WARN('Unable to create DataBase File')
- END;
- END CreateDBF;
- PROCEDURE Row(): CARDINAL;
- VAR row, col: CARDINAL;
- BEGIN
- WindowPrims.GetCursorCoords( col, row );
- RETURN row;
- END Row;
- PROCEDURE Col(): CARDINAL;
- VAR row, col: CARDINAL;
- BEGIN
- WindowPrims.GetCursorCoords( col, row );
- RETURN col;
- END Col;
- PROCEDURE Say(row, col: CARDINAL; s: ARRAY OF CHAR);
- BEGIN
- WindowPrims.PushColors();
- (* Note that we don't push and pop the cursor size or
- position here or in Get, and we don't turn it off,
- because we don't want it to flash between fields as they
- are initially written. Means you ought to turn it off
- before doing a series of Say and Get statements. *)
- SmartScreen.SetAttribOrColor( writeattr.fore, writeattr.back,
- writeattr.MonoAttr );
- SmartScreen.WriteAt( col, row, s );
- SmartScreen.GotoXY( SmartScreen.NominalCol,
- SmartScreen.NominalRow );
- (* The GotoXY guarantees consistent cursor placement between
- VideoMethods; in DMA mode, WriteAt doesn't move the
- cursor. See documentation for SmartScreen in the
- Repertoire manual. *)
- WindowPrims.PopColors();
- END Say;
- PROCEDURE Get(row, col: CARDINAL; VAR s: ARRAY OF CHAR);
- BEGIN
- WindowPrims.PushColors();
- (* pad the string with trailing blanks *)
- WHILE M2Strings.Length(s) <= HIGH(s) DO
- StrEdit.Append( s, Blank );
- END;
- INC(lastget);
- input[lastget].row := row;
- input[lastget].col := col;
- input[lastget].len := HIGH(s)+1;
- input[lastget].val := SYSTEM.ADR(s);
- SmartScreen.SetAttribOrColor( readattr.fore, readattr.back,
- readattr.MonoAttr );
- SmartScreen.GotoXY( col, row );
- SmartScreen.WriteAt( col, row, s );
- SmartScreen.GotoXY( SmartScreen.NominalCol,
- SmartScreen.NominalRow );
- WindowPrims.PopColors();
- END Get;
- PROCEDURE ReadGets;
- VAR
- tmpLen, currentget, CursorPos, LastKey : CARDINAL;
- ExitKeys: KbdInput.KeyNumSet;
- InsertMode: BOOLEAN;
- TmpStr: ARRAY [0..128] OF CHAR;
- tmpStrPtr: StrPtr;
- LocalInput: InputArray;
- BEGIN
- LocalInput := input;
- (* We do this to make the routine easier to follow in the
- runtime debugger. The global input variable isn't
- normally visible there because it's global to a module
- outside the calling chain. *)
- WindowPrims.PushColors();
- WindowPrims.PushCursorCoords();
- (* Insulates calling procedures from the color choices and
- cursor-position changes we make here. We don't need to
- push and pop the cursor size or turn it off because
- ReadWithEdits handles that internally. *)
- SmartScreen.SetAttribOrColor( readattr.fore, readattr.back,
- readattr.MonoAttr );
- InsertMode := TRUE;
- BigSets.InitSet( ExitKeys );
- BigSets.AppendSet( ExitKeys, '{8, 9, 13, 27, 271, 328, 329, 336, 337}' );
- (* Means BackSpace, TAB, BackTab, CR, ESC, and the arrow
- keys let you out of a field. *)
- IF lastget > 0 THEN
- currentget:= 1;
- lastdirection := Nowhere;
- WHILE (lastdirection # Escape) AND
- (currentget > 0) AND
- (currentget <= lastget) DO
- CursorPos := 0;
- tmpStrPtr := LocalInput[currentget].val;
- (* Break out the steps because otherwise Stony Brook
- generates code that causes a protection fault
- when the pointer is dereferenced. *)
- tmpLen := LocalInput[currentget].len;
- LowLevel.Move(tmpStrPtr, SYSTEM.ADR(TmpStr), tmpLen);
- (* We have to do this to prevent overflows; since val
- points to an area of memory larger than what we are
- really considering the variable here, ReadWithEdits
- can't reliably tell whether it should put a length
- byte at the end of the string. Notice that we can't
- use M2Strings.Copy because it will begin by trying to
- make a copy of all HIGH+1 bytes of the first argument
- on the stack. In this case, they aren't all there.*)
- StrInput.ReadWithEdits( VWindows.CurrentWindow, TmpStr,
- LocalInput[currentget].col, LocalInput[currentget].row,
- LocalInput[currentget].len, CursorPos, InsertMode, FALSE,
- LastKey, KbdInput.AnyKeyNum, ExitKeys );
- LowLevel.Move( SYSTEM.ADR(TmpStr), LocalInput[currentget].val,
- LocalInput[currentget].len );
- CASE LastKey OF
- BSPnum, BTBnum, LARWnum, UARWnum:
- DEC( currentget );
- lastdirection := Back;
- | CRnum, TABnum, RARWnum, DARWnum:
- INC(currentget);
- lastdirection := Ahead;
- | ESCnum:
- lastdirection := Escape
- ELSE (* nothing *)
- END;
- END; (*WHILE*)
- FOR currentget := 1 TO lastget DO
- tmpStrPtr := LocalInput[currentget].val;
- tmpLen := LocalInput[currentget].len;
- LowLevel.Move(tmpStrPtr, SYSTEM.ADR(TmpStr), tmpLen);
- (* Same problem here; the procedure that strips the
- blanks can't reliably determine where the end of the
- string is because we are trying to pass it only a
- part of the string. So we copy into a local
- variable. *)
- StrEdit.CutTrailingChars( Blank, TmpStr );
- LowLevel.Move( SYSTEM.ADR(TmpStr), LocalInput[currentget].val,
- LocalInput[currentget].len );
- END;
- lastget := 0;
- END; (* if *)
- WindowPrims.PopCursorCoords();
- WindowPrims.PopColors();
- input := LocalInput;
- END ReadGets;
- BEGIN (* main *)
- WITH readattr DO
- MonoAttr := SmartScreen.ReverseVideo;
- fore := SmartScreen.blue;
- back := SmartScreen.lightgrey;
- END;
- WITH writeattr DO
- MonoAttr := SmartScreen.plain;
- fore := SmartScreen.lightgrey;
- back := SmartScreen.blue;
- END;
- lastget := 0;
- END DBScreen.
|