home *** CD-ROM | disk | FTP | other *** search
- $R-,S-,D+,T+,F-,V+,B-
-
- Unit FeltEdit;
-
- Interface
-
- Uses Crt;
-
- CONST
- ToUpper = 1;
- ToLower = 2;
- NoInput = 4;
-
- TYPE
- CharSet = SET OF CHAR;
- CharSetPtr = ^CharSet;
- JustType = (LeftJ,CenterJ,RightJ);
- FeltStr = STRING[12];
- PromptStr = STRING[30];
- FeltStrArray = ARRAY [0..255] OF FeltStr;
- FeltType = (CharT, StrT, EnumT, BoolT, ByteT, IntT, WordT, LongT);
- EditPtr = ^EditRecord;
- EditRecord = RECORD
- x, y, len, xpos : BYTE;
- just : JustType;
- prompt : PromptStr;
- CASE ftype : FeltType OF
- CharT : (CharP : ^CHAR;
- oksetC : CharSetPtr;
- modeC : BYTE);
- StrT : (StrP : ^STRING;
- oksetS : CharSetPtr;
- modeS : BYTE);
- EnumT,
- BoolT : (EnumP : ^BYTE;
- EnumAntall : BYTE;
- EnumStr : ^FeltStrArray);
- ByteT : (ByteP : ^BYTE;
- ByteMin, ByteMax : LongInt);
- IntT : (IntP : ^INTEGER;
- IntMin, IntMax : LongInt);
- WordT : (WordP : ^WORD;
- WordMin, WordMax : LongInt);
- LongT : (LongP : ^LongInt;
- LongMin, LongMax : LongInt);
- END;
-
- CONST
- Eantall : WORD = 0;
- BoolStr : ARRAY [0..1] OF FeltStr = ('FALSE','TRUE');
- NumericSet : CharSet = ['0'..'9','.','+','-'];
- InsertMode : BOOLEAN = FALSE;
- LastRecord : WORD = 0;
- FeltAttr : BYTE = 14;
- EditAttr : BYTE = 112;
-
- CONST
- EditChar : CHAR = #255;
-
- FUNCTION EditStr(VAR str: String; VAR xpos: BYTE;
- len, mode : BYTE; ok : CharSetPtr;just : JustType): BOOLEAN;
-
- FUNCTION Pad(st:String;len : INTEGER): String;
-
- FUNCTION Tstr(l : LongInt; len : INTEGER): String;
-
- PROCEDURE ShowOne(VAR e : EditRecord);
-
- PROCEDURE ShowAll;
-
- PROCEDURE EditOne(VAR e : EditRecord);
-
- PROCEDURE EditARecord(n : WORD);
-
- FUNCTION UpCase(ch : CHAR): CHAR;
-
- FUNCTION LoCase(ch : CHAR): CHAR;
-
- PROCEDURE MakeStr(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : String; okp : Pointer; mode : BYTE);
-
- PROCEDURE MakeChar(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : CHAR; okp : Pointer; mode : BYTE);
-
- PROCEDURE MakeEnum(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v ; antall : BYTE; VAR enum_ar);
-
- PROCEDURE MakeBool(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : BOOLEAN);
-
- PROCEDURE MakeByte(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : BYTE; min, max : BYTE);
-
- PROCEDURE MakeInt(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : INTEGER; min, max : INTEGER);
-
- PROCEDURE MakeWord(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : WORD; min, max : WORD);
-
- PROCEDURE MakeLong(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : LongInt; min, max : LongInt);
-
- PROCEDURE EditAllRecords;
-
- PROCEDURE EditVar(VAR v);
-
- (**************************************************************************)
-
- Implementation
-
- VAR
- ERec : ARRAY [0..255] OF EditPtr;
-
- CONST No_Upper : String[3] = '';
- No_Lower : String[3] = '';
-
- FUNCTION UpCase(ch : CHAR): CHAR;
- VAR p : INTEGER;
- BEGIN
- IF (ch >= 'a') AND (ch <= 'z') THEN ch := CHAR(BYTE(ch)-32)
- ELSE BEGIN
- p := Pos(ch,No_Lower);
- IF p > 0 THEN ch := No_Upper[p];
- END;
- UpCase := ch;
- END;
-
- FUNCTION LoCase(ch : CHAR): CHAR;
- VAR p : INTEGER;
- BEGIN
- IF (ch >= 'A') AND (ch <= 'Z') THEN ch := CHAR(BYTE(ch)+32)
- ELSE BEGIN
- p := Pos(ch,No_Upper);
- IF p > 0 THEN ch := No_Lower[p];
- END;
- LoCase := ch;
- END;
-
- PROCEDURE MakeStr(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : String; okp : Pointer; mode : BYTE);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := StrT; xpos := 1; just := pjust;
- StrP := Addr(v);
- oksetS := okp;
- modeS := mode;
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeChar(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : CHAR; okp : Pointer; mode : BYTE);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := CharT; xpos := 1; just := pjust;
- CharP := Addr(v);
- oksetC := okp;
- modeC := mode;
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeEnum(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v ; antall : BYTE; VAR enum_ar);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := EnumT; xpos := 1; just := pjust;
- EnumP := Addr(v);
- EnumAntall := antall;
- EnumStr := Addr(enum_ar);
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeBool(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : BOOLEAN);
- BEGIN
- MakeEnum(px,py,plen,pjust,prstr,v,2,BoolStr);
- END;
-
- PROCEDURE MakeByte(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : BYTE; min, max : BYTE);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := ByteT; xpos := 1; just := pjust;
- ByteP := Addr(v);
- ByteMin := min;
- ByteMax := max;
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeInt(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : INTEGER; min, max : INTEGER);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := IntT; xpos := 1; just := pjust;
- IntP := Addr(v);
- IntMin := min;
- IntMax := max;
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeWord(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : WORD; min, max : WORD);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := WordT; xpos := 1; just := pjust;
- WordP := Addr(v);
- WordMin := min;
- WordMax := max;
- END;
- Inc(EAntall);
- END;
-
- PROCEDURE MakeLong(px, py, plen : BYTE; pjust : JustType;
- prstr : PromptStr; VAR v : LongInt; min, max : LongInt);
- BEGIN
- New(ERec[EAntall]);
-
- WITH ERec[Eantall]^ DO BEGIN
- x := px; y := py; len := plen; prompt := prstr;
- ftype := LongT; xpos := 1; just := pjust;
- LongP := Addr(v);
- LongMin := min;
- LongMax := max;
- END;
- Inc(EAntall);
- END;
-
- FUNCTION Pad(st:String;len : INTEGER): String;
- BEGIN
- IF len < 0 THEN BEGIN
- len := Lo(-len);
- WHILE len > Length(st) DO st := ' ' + st;
- END
- ELSE IF len > 0 THEN BEGIN
- len := Lo(len);
- WHILE len > Length(st) DO st := st + ' ';
- END;
- Pad := st;
- END;
-
- (*
- FUNCTION Justify(st : String; len : BYTE; just : JustType): String;
- VAR front : BOOLEAN;
- BEGIN
- CASE just OF
- LeftJ : Justify := Pad(st,len);
- CenterJ : BEGIN
- front := FALSE;
- WHILE Length(st) < len DO BEGIN
- IF front THEN st := ' ' + st
- ELSE st := st + ' ';
- front := NOT front;
- END;
- Justify := st;
- END;
- RightJ : Justify := Pad(st,-len);
- END;
- END;
- *)
-
- FUNCTION Tstr(l : LongInt; len : INTEGER): String;
- VAR st : String;
- BEGIN
- Str(l:len,st);
- Tstr := st;
- END;
-
- FUNCTION Refresh(len: BYTE; just : JustType; st : String): INTEGER;
- VAR front, back, offs : INTEGER;
- BEGIN
- front := len - Length(st); IF front < 0 THEN front := 0;
- CASE just OF
- LeftJ : BEGIN back := front; front := 0; END;
- RightJ : back := 0;
- CenterJ : BEGIN back := (front+1) DIV 2; Dec(front,back); END;
- END;
- IF front > 0 THEN Write('':front);
- Write(st);
- IF back > 0 THEN Write('':back);
- Refresh := front;
- END;
-
- PROCEDURE ShowOne(VAR e : EditRecord);
- VAR i : WORD;
- l : LongInt;
- attr : BYTE;
- BEGIN
- attr := TextAttr;
- GotoXY(e.x,e.y);
- Write(e.prompt);
- TextAttr := FeltAttr;
- CASE e.ftype OF
- CharT : IF Refresh(e.len,e.just,e.CharP^) = 0 THEN ;
- StrT : IF Refresh(e.len,e.just,e.StrP^) = 0 THEN ;
- BoolT,
- EnumT : IF Refresh(e.len,e.just,e.EnumStr^[e.EnumP^]) = 0 THEN ;
- ByteT : IF Refresh(e.len,e.just,Tstr(e.ByteP^,1)) = 0 THEN ;
- IntT : IF Refresh(e.len,e.just,Tstr(e.IntP^,1)) = 0 THEN ;
- WordT : IF Refresh(e.len,e.just,Tstr(e.WordP^,1)) = 0 THEN ;
- LongT : IF Refresh(e.len,e.just,Tstr(e.LongP^,1)) = 0 THEN ;
- END;
- TextAttr := attr;
- END;
-
- PROCEDURE ShowAll;
- VAR i : WORD;
- BEGIN
- FOR i := 0 TO Eantall-1 DO
- ShowOne(ERec[i]^);
- END;
-
- FUNCTION EditStr(VAR str: String; VAR xpos: BYTE;
- len, mode : BYTE; ok : CharSetPtr;just : JustType): BOOLEAN;
- VAR sx, sy : BYTE;
- st : String;
- cok, ferdig, change, dirty : BOOLEAN;
-
- PROCEDURE Del1; BEGIN Delete(st,xpos,1); Dirty := TRUE; END;
-
- PROCEDURE RefreshStr;
- BEGIN
- GotoXY(sx,sy);
- GotoXY(sx+xpos+Refresh(len,just,st)-1,sy);
- Dirty := FALSE;
- END;
-
- BEGIN
- EditStr := FALSE;
- sx := WhereX; sy := WhereY;
- st := str;
- dirty := TRUE;
- ferdig := FALSE;
- IF xpos > Length(str)+1 THEN xpos := 1;
- REPEAT
- IF len <= 1 THEN xpos := 1;
- {IF Dirty THEN }RefreshStr;
-
- EditChar := ReadKey;
- CASE EditChar OF
- #0 : BEGIN
- EditChar := ReadKey;
- CASE Ord(EditChar) OF
- 68 : BEGIN
- st := str; RefreshStr; Exit;
- END;
- 71 : BEGIN xpos := 1; END;
- 72,
- 80 : ferdig := TRUE;
- 75 : IF xpos > 1 THEN Dec(xpos);
- 77 : IF xpos <= Length(st) THEN Inc(xpos);
- 79 : BEGIN xpos := Length(st)+1; END;
- 82 : InsertMode := NOT InsertMode;
- 83 : Del1;
- $75 : st[0] := Chr(xpos-1); {Ctrl-End}
- ELSE
- Exit;
- END;
- END;
- ^H : IF xpos > 1 THEN BEGIN
- Dec(xpos);
- Del1;
- END;
- ^M : ferdig := TRUE;
- ^[ : BEGIN
- change := st <> str;
- IF change THEN BEGIN st := str; xpos := 1; END;
- RefreshStr;
- IF NOT change THEN Exit;
- END;
- #0..#255 :
- BEGIN
- IF mode AND ToUpper <> 0 THEN EditChar := UpCase(EditChar)
- ELSE IF mode AND ToLower <> 0 THEN EditChar := LoCase(EditChar);
-
- cok := mode AND NoInput = 0;
- IF (ok <> NIL) AND cok THEN cok := EditChar IN ok^;
-
- IF cok THEN BEGIN
- IF InsertMode THEN BEGIN
- IF Length(st) < len THEN BEGIN
- Insert(EditChar,st,xpos);
- Inc(xpos);
- END;
- END
- ELSE BEGIN
- IF xpos <= len THEN BEGIN
- IF xpos > Length(st) THEN
- st := st + EditChar
- ELSE
- st[xpos] := EditChar;
- Inc(xpos);
- END;
- END;
- Dirty := TRUE;
- END;
- END;
- END;
- UNTIL ferdig;
- str := st;
- EditStr := TRUE;
- END;
-
- FUNCTION EditNum(VAR e : EditRecord): BOOLEAN;
- VAR feil, sx, sy : WORD;
- st : String;
- num : LongInt;
- BEGIN
- EditNum:= FALSE;
- sx := WhereX; sy := WhereY;
- CASE e.ftype OF
- ByteT : num := e.ByteP^;
- IntT : num := e.IntP^;
- WordT : num := e.WordP^;
- LongT : num := e.LongP^;
- END;
-
- REPEAT
- GotoXY(sx,sy);
- Str(num:1,st);
- e.xpos := 1;
- IF NOT EditStr(st,e.xpos,e.len,0,Addr(NumericSet),e.just) THEN Exit;
- Val(st,num,feil);
- IF feil = 0 THEN BEGIN
- feil := 1;
- IF num < e.LongMin THEN
- num := e.LongMin
- ELSE IF num > e.LongMax THEN
- num := e.LongMax
- ELSE
- feil := 0;
- END;
- UNTIL feil = 0;
- EditNum := TRUE;
- CASE e.ftype OF
- ByteT : e.ByteP^ := num;
- IntT : e.IntP^ := num;
- WordT : e.WordP^ := num;
- LongT : e.LongP^ := num;
- END;
- END;
-
- FUNCTION EditEnum(VAR en; max : WORD; len : BYTE; just : JustType;
- VAR enstr : FeltStrArray): BOOLEAN;
- VAR e : BYTE ABSOLUTE en;
- b : BYTE;
- sx, sy : WORD;
- BEGIN
- b := e;
- sx := WhereX; sy := WhereY;
- EditEnum := TRUE;
-
- REPEAT
- GotoXY(sx,sy);
- IF Refresh(len,just,enstr[b]) = 0 THEN ;
- GotoXY(sx,sy);
- EditChar := ReadKey;
- CASE EditChar OF
- #0 :
- BEGIN
- EditChar := ReadKey;
- CASE Ord(EditChar) OF
- 68 : BEGIN EditEnum := FALSE; Exit; END;
- 71 : b := 0;
- 72,
- 80 : BEGIN e := b; Exit; END;
- 75 : b := Succ(b) MOD max;
- 77 : b := Pred(b+max) MOD max;
- 79 : b := max-1;
- ELSE BEGIN
- e := b;
- Exit;
- END;
- END;
- END;
- ^M : BEGIN e := b; Exit; END;
- ^[ : IF e <> b THEN b := e
- ELSE BEGIN EditEnum := FALSE; Exit; END;
- ' ': b := Succ(b) MOD max;
- END;
- UNTIL FALSE;
- END;
-
- PROCEDURE EditOne(VAR e : EditRecord);
- VAR res : BOOLEAN;
- attr : BYTE;
- st : String;
- BEGIN
- attr := TextAttr;
- WITH e DO BEGIN
- GotoXY(x,y); Write(prompt);
- TextAttr := EditAttr;
- CASE ftype OF
- CharT : BEGIN
- st := CharP^;
- res := EditStr(st,xpos,len,modeC,oksetC,just);
- IF res AND (Length(st) = 1) THEN CharP^ := st[1];
- END;
- StrT : res := EditStr(StrP^,xpos,len,modeS,oksetS,just);
- BoolT,
- EnumT : res := EditEnum(EnumP^,EnumAntall,len,just,EnumStr^);
- ByteT,
- IntT,
- WordT,
- LongT : res := EditNum(e);
- END;
- END;
- TextAttr := attr;
- ShowOne(e);
- END;
-
- PROCEDURE EditVar(VAR v);
- VAR i : INTEGER;
- BEGIN
- FOR i := 0 TO EAntall-1 DO BEGIN
- IF Addr(v) = Erec[i]^.StrP THEN EditOne(Erec[i]^);
- Inc(i);
- END;
- END;
-
- PROCEDURE EditARecord(n : WORD);
- BEGIN
- IF n < Eantall THEN EditOne(Erec[n]^);
- END;
-
- PROCEDURE EditAllRecords;
- BEGIN
- REPEAT
- EditARecord(LastRecord);
- Case EditChar OF
- #80 : LastRecord := Succ(LastRecord) MOD Eantall;
- #72 : LastRecord := Pred(LastRecord + Eantall) MOD Eantall;
- ELSE
- Exit;
- END;
- UNTIL EditChar = #27;
- END;
-
- END.
-