home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* DATAWIN.PAS *)
- (* Zweck dieser Unit: Daten in einem Fenster bearbeiten. *)
- (* Dazu werden ein paar Prozeduren vom Objekt *)
- (* "DataWinObj" implementiert. *)
- (* (c) 1990 R.Reichert & TOOLBOX *)
- (* ------------------------------------------------------ *)
- UNIT DataWin;
-
- INTERFACE
-
- USES
- StandWin,
- Buffer5,
- SB,
- Crt;
-
- CONST
- ScrYLength : BYTE = 25;
-
- TYPE
- DataWinObjPtr = ^DataWinObj;
- DataWinObj = OBJECT
- ScrollBarV, { Horiz. Scrollbalken }
- ScrollBarH, { Vertik. Scrollbalken }
- Access, { Zugriff erlaubt }
- MoveCur, { Cursor bewegen }
- OnlyBuf : BOOLEAN; { Nur im Puffer }
- CurX, CurY, { X-und Y-Positionen }
- px1, py1, { Begrenzungen }
- px2, py2,
- Ls, Ts,
- Rs, Bs : INTEGER;
- Buf : BufferObjPtr; { Puffer }
-
- Win : StandardWindowPtr;
-
- SBVertikal, { Scrollbalken-Objekte }
- SBHoriz : ScrollBarObj;
-
- CONSTRUCTOR Init;
- CONSTRUCTOR WinInit;
- CONSTRUCTOR BufInit;
-
- PROCEDURE WriteComment; VIRTUAL;
- PROCEDURE ShowBars; VIRTUAL;
- PROCEDURE ScrollBuf(x, y : INTEGER); VIRTUAL;
- PROCEDURE SaveASCII(Name : STRING;
- VAR Err : INTEGER); VIRTUAL;
- PROCEDURE LoadASCII(Name : STRING;
- VAR Err : INTEGER); VIRTUAL;
- PROCEDURE ShowBufPart(y1, y2 : INTEGER); VIRTUAL;
- PROCEDURE ShowBuf; VIRTUAL;
- FUNCTION GetWinXLength : BYTE; VIRTUAL;
- FUNCTION GetWinYLength : BYTE; VIRTUAL;
- FUNCTION GetCols : INTEGER; VIRTUAL;
- FUNCTION GetRows : INTEGER; VIRTUAL;
- FUNCTION InWindow(x, y : INTEGER) : BOOLEAN; VIRTUAL;
-
- DESTRUCTOR Done; VIRTUAL;
-
- { ---- Neu implementierte Methoden aus BufferObj ----- }
-
- PROCEDURE WriteStrXY(x, y : INTEGER;
- Str : STRING); VIRTUAL;
- PROCEDURE WriteStr(Str : STRING); VIRTUAL;
- PROCEDURE SetCursor(x, y : INTEGER); VIRTUAL;
- PROCEDURE InsLines(y, No : INTEGER); VIRTUAL;
- PROCEDURE DelLines(y, No : INTEGER); VIRTUAL;
- PROCEDURE SetWriteColors(Col, Back : BYTE); VIRTUAL;
- PROCEDURE ChangeColor(x1, y1, x2, y2 : INTEGER;
- Col, Back : BYTE); VIRTUAL;
- FUNCTION ConvertLine(y : INTEGER) : STRING; VIRTUAL;
- FUNCTION GetLineLength(y : INTEGER) : INTEGER; VIRTUAL;
-
- { ---- Neu implementierte Methoden aus StandardWindow -}
-
- PROCEDURE Open; VIRTUAL;
- PROCEDURE MoveWin(x, y : INTEGER); VIRTUAL;
- PROCEDURE ZoomWin(x, y : INTEGER); VIRTUAL;
- PROCEDURE ChangeFrame(NF : BYTE); VIRTUAL;
- PROCEDURE Show; VIRTUAL;
- PROCEDURE Hide; VIRTUAL;
- PROCEDURE ReOpen(WinData : StandardWindow); VIRTUAL;
- PROCEDURE Close; VIRTUAL
- END;
-
-
- IMPLEMENTATION
-
- CONSTRUCTOR DataWinObj.Init;
- (* ---------------------------------------------------- *)
- (* Initialisiert das Objekt. Dabei werden auch die *)
- (* Init-Konstruktoren der beiden Instanzen "Buf" und *)
- (* "Win" aufgerufen. Die Reihenfolge sollte nicht *)
- (* geändert werden. Ein Nachkomme sollte die Initiali- *)
- (* sierung aufrufen, Access abfragen und wenn TRUE zu- *)
- (* rückkommt, die Variablen auf eigene Werte setzen. *)
- (* ---------------------------------------------------- *)
- BEGIN
- Access := TRUE;
- WinInit;
- IF Access THEN BEGIN
- ScrollBarV := TRUE; ScrollBarH := TRUE;
- Ls := 2; Ts := 1;
- Rs := 2; Bs := 2;
- px1 := 1; py1 := 1;
- px2 := GetWinXLength;
- py2 := GetWinYLength;
- CurX := 1; CurY := 1;
- MoveCur := TRUE; OnlyBuf := FALSE;
- BufInit;
- IF NOT Access THEN BEGIN
- Done; Fail;
- END;
- END ELSE Done;
- END;
-
- CONSTRUCTOR DataWinObj.WinInit;
- (* ---------------------------------------------------- *)
- (* Dieser Konstruktor kümmert sich um die Window- *)
- (* initialisation und -daten. *)
- (* ---------------------------------------------------- *)
- BEGIN
- { Durch die erweiterte Funktion von New ist es mög-
- lich, Win auch auf einen Nachfolger zeigen zu
- lassen, ohne den Typ von Win zu ändern. Als zweiter
- Parameter bleibt der Konstruktor. }
- Win := New(StandardWindowPtr, Init(StandWinData));
-
- IF Win = NIL THEN
- Access := FALSE
- ELSE
- WITH Win^ DO BEGIN
- FrameColor := 7;
- x1 := 1; x2 := 78;
- y1 := 1; y2 := 20;
- ShaVisible := TRUE;
- ShaColor := 7; ShaChr := '░';
- ShaXl := 1; ShaYl := 1;
- Framevisible := TRUE; ShaTranspar := FALSE;
- MoveAllowed := TRUE; ZoomAllowed := TRUE;
- Visible := FALSE;
- BackColor := 7;
- TopLine := 'Demonstration von DataWinObj';
- BottomLine := '(c) 1990 R.Reichert & TOOLBOX'
- END;
- END;
-
- CONSTRUCTOR DataWinObj.BufInit;
- { Will man eine typisierte Konstante von "BufferObj"
- z.B. zum temporären Speichern des Inhalts von "Buf",
- so kann man - schließlich kommt es auf den Anfangswert
- der einzelnen Variablen nicht an - das Weglassen auf
- die Spitze treiben : }
- CONST
- TempBufData : BufferObj = ();
- BEGIN
- TempBufData := BufData; { Retten der Daten }
- WITH BufData DO BEGIN
- IF Columns < GetWinXLength THEN
- Columns := GetWinXLength;
- IF Columns > MaxColumns THEN Access := FALSE;
- IF Lines < ScrYLength THEN Lines := ScrYLength;
- IF Lines > MaxLines THEN Access := FALSE;
- LineForm := Left;
- BufCol := 15; BufBackCol := 0;
- MoveBufCur := TRUE; LineFeed := TRUE;
- KillWrite := TRUE;
- END;
- IF Access THEN
- Buf := New(BufferObjPtr, Init(BufData));
- IF (Buf = NIL) OR (Buf^.InitError) THEN Access := FALSE;
- BufData := TempBufData;
- END;
-
- PROCEDURE DataWinObj.WriteComment;
- BEGIN
- IF Access THEN BEGIN
- IF ScrollBarV AND (Rs > 0) THEN
- WITH SBVertikal DO BEGIN
- x1 := Pred(Win^.x2);
- y1 := Win^.y1 + Ts;
- x2 := x1;
- y2 := Win^.y2 - Bs;
-
- TBBCol := 7; Horiz := FALSE;
- BTLChr := Chr(24); BBRChr := Chr(25);
- PosCol := 15; PosChr := '▒';
- BarCol := $70; BarChr := '▒';
- Max := Buf^.Lines; Pos := CurY;
-
- ShowBar;
- END;
- IF ScrollBarH AND (Bs > 0) THEN
- WITH SBHoriz DO BEGIN
- x1 := Win^.x1 + Ls;
- y1 := Pred(Win^.y2);
- x2 := Win^.x2 - Rs;
- y2 := y1;
-
- TBBCol := 7; Horiz := TRUE;
- BTLChr := Chr(27); BBRChr := Chr(26);
- PosCol := 15; PosChr := '▒';
- BarCol := $70; BarChr := '▒';
- Max := Buf^.Columns; Pos := CurX;
-
- ShowBar;
- END;
- END;
- END;
-
- PROCEDURE DataWinObj.ShowBars;
- BEGIN
- IF Access THEN BEGIN
- IF ScrollBarV THEN
- SBVertikal.ShowNewPos(CurY, Buf^.Lines);
- IF ScrollBarH THEN
- SBHoriz.ShowNewPos(CurX, Buf^.Columns)
- END;
- END;
-
- PROCEDURE DataWinObj.ScrollBuf (x, y : INTEGER);
- (* ---------------------------------------------------- *)
- (* Scrollt den Pufferinhalt in dem Fenster nach *)
- (* unten/oben(y) und rechts/links(x). ACHTUNG: x und y *)
- (* sind RELATIV zu px1/px2 und py1/py2 ! *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Access THEN BEGIN
- IF (px1+x < 1) THEN x := -Pred(px1);
- IF (px2+x > Buf^.Columns) THEN x := Buf^.Columns-px2;
- IF (py1+y < 1) THEN y := -Pred (py1);
- IF (py2+y > Buf^.Lines) THEN y := Buf^.Lines - py2;
- IF (x <> 0) OR (y <> 0) THEN BEGIN
- Inc(px1, x); Inc(px2, x);
- Inc(py1, y); Inc(py2, y);
- IF Buf^.AllSaved THEN Buf^.LoadPart(py1, py2);
- ShowBuf;
- END;
- END;
- END;
-
- PROCEDURE DataWinObj.SaveASCII(Name : STRING;
- VAR Err : INTEGER);
- VAR
- t : Text; i : INTEGER; s : STRING;
- BEGIN
- IF Access THEN BEGIN
- Assign(t, Name);
- {$I-}
- Rewrite(t);
- {$I+}
- Err := IOResult;
- IF Err = 0 THEN BEGIN
- i := 1;
- err := 0;
- WHILE (i <= Buf^.Lines) AND (Err = 0) DO BEGIN
- s := ConvertLine(i);
- {$I-}
- WriteLn(t, s);
- {$I+}
- Inc(i);
- Err := IOResult;
- IF (Buf^.BufDosErr <> 0) AND (Err = 0) THEN
- { Fehler in BufferObj aufgetreten? wenn ja
- und kein eigener Fehler, dann übertragen,
- sonst hat eigener Fehler Vorrang. }
- Err := Buf^.BufDosErr
- END;
- {$I-}
- System.Close(t);
- {$I+}
- Err := IOResult;
- { MUSS ABGEFRAGT WERDEN, sonst kommt es bei
- (falls I/O-Checking On ist) der nächsten
- I/O-Funktion zu einem Run-Time-Error 101,
- auch bei Readln oder Writeln ! }
- END;
- END;
- END;
-
- PROCEDURE DataWinObj.LoadASCII(Name : STRING;
- VAR Err : INTEGER);
- CONST
- TempBufData : BufferObj = ();
- TempOwn : DataWinObj= ();
- VAR
- t : Text; i : INTEGER; s : STRING;
- BEGIN
- IF Access THEN BEGIN
- Assign(t, Name);
- {$I-}
- Reset(t);
- {$I+}
- Err := IOResult;
- IF Err=0 THEN BEGIN
- SetCursor(1, 1);
- DelLines(Succ(GetWinYLength),
- (Buf^.Lines - GetWinYLength));
- WITH Buf^ DO { Zeilen im Fenster neu machen }
- FOR i := 1 TO GetWinYLength DO
- GetNewLine(Attr, TextBuf^[i]^);
- TempBufData := Buf^;
- TempOwn := Self;
- WITH Buf^ DO BEGIN
- KillWrite := FALSE;
- KillLineRest := FALSE;
- LineFeed := FALSE;
- MoveBufCur := FALSE
- END;
- OnlyBuf := TRUE;
- MoveCur := FALSE;
- i := 1;
- Err := 0;
- WHILE (i <= MaxLines) AND (Err = 0) AND
- NOT EoF(t) DO BEGIN
- {$I-}
- ReadLn(t, s);
- {$I+}
- WriteStrXY(1, i, s);
- Inc(i);
- Err := IOResult;
- IF (Buf^.BufDosErr <> 0) AND (Err = 0) THEN
- Err := Buf^.BufDosErr;
- END;
- Buf^.SetMaxLines (1);
- { manipulierte Daten wieder herstellen. Dabei
- muß berücksichtigt werden, daß
- Buf^ := TempBufData;
- NICHT funktioniert, da Variablen von "Buf"
- ihre Werte bei dem Ladevorgang verändert haben
- können. Deshalb werden nur die vier veränderten
- Variablen einzeln wieder gesetzt. }
- WITH Buf^ DO BEGIN
- KillWrite := TempBufData.KillWrite;
- KillLineRest := TempBufData.KillLineRest;
- LineFeed := TempBufData.LineFeed;
- MoveBufCur := TempBufData.MoveBufCur
- END;
- Self := TempOwn;
- ShowBuf;
- SetCursor(1, 1);
- {$I-}
- System.Close(t);
- {$I+}
- Err := IOResult;
- END;
- END;
- END;
-
- PROCEDURE DataWinObj.ShowBufPart(y1, y2 : INTEGER);
- (*----------------------------------------------------- *)
- (* Zeigt den Pufferbereich px1-px2, y1-y2 im Fenster an *)
- (* Bedingung: y1 und y2 in py1-py2 ! *)
- (*----------------------------------------------------- *)
- VAR
- i : INTEGER;
- BEGIN
- IF Access AND Win^.Visible THEN BEGIN
- IF InWindow(px1, y1) AND InWindow(px1, y2) AND
- (y1 <= y2) THEN
- FOR i := 1 TO Succ(y2-y1) DO
- Move(Buf^.TextBuf^[Pred(y1+i)]^[px1],
- Screen^[Win^.y1+(y1-py1)+i+Ts,
- Succ (Win^.x1+Ls)],
- GetWinXLength*2);
- END;
- END;
-
- PROCEDURE DataWinObj.ShowBuf;
- BEGIN
- ShowBufPart(py1, py2);
- END;
-
- FUNCTION DataWinObj.GetWinXLength : BYTE;
- BEGIN
- IF Access THEN WITH Win^ DO
- GetWinXLength := Pred(x2-x1-Ls-Rs);
- END;
-
- FUNCTION DataWinObj.GetWinYLength : BYTE;
- BEGIN
- IF Access THEN WITH Win^ DO
- GetWinYLength := Pred(y2-y1-Ts-Bs);
- END;
-
- FUNCTION DataWinObj.GetCols : INTEGER;
- BEGIN
- IF Access THEN
- GetCols := Buf^.Columns
- ELSE
- GetCols := 0
- END;
-
- FUNCTION DataWinObj.GetRows : INTEGER;
- BEGIN
- IF Access THEN
- GetRows := Buf^.Lines
- ELSE
- GetRows := 0
- END;
-
- FUNCTION DataWinObj.InWindow(x, y: INTEGER) : BOOLEAN;
- BEGIN
- InWindow := ((x >= px1) AND (x <= px2) AND
- (y >= py1) AND (y <= py2));
- END;
-
- DESTRUCTOR DataWinObj.Done;
- (* ---------------------------------------------------- *)
- (* Gibt den belegten Speicher wieder frei, indem die *)
- (* Destruktoren von "Buf" und "Win" aufgerufen werden. *)
- (* anderer Speicher wurde von "DataWinObj" nicht belegt *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Buf <> NIL THEN Dispose(Buf, Done);
- IF Win <> NIL THEN Dispose(Win, Done)
- END;
-
- PROCEDURE DataWinObj.WriteStrXY(x, y : INTEGER;
- Str : STRING);
- BEGIN
- IF Access AND (Win^.Visible OR OnlyBuf) THEN BEGIN
- Buf^.WriteStrXY(x, y, Str);
- IF (y >= py1) AND (y <= py2) AND NOT OnlyBuf THEN
- IF (Py2-Py1 = 0) THEN
- ShowBufPart(y, y)
- ELSE
- ShowBufPart(y, Succ(y));
- { Cursor setzen. Wenn x,y ausserhalb des Fensters,
- dann übernimmt es SetCursor, zu scrollen. }
- SetCursor (Buf^.BufCurX, Buf^.BufCurY)
- END;
- END;
-
- PROCEDURE DataWinObj.WriteStr(Str : STRING);
- BEGIN
- WriteStrXY(CurX, CurY, Str);
- END;
-
- PROCEDURE DataWinObj.SetCursor(x, y : INTEGER);
- (* ---------------------------------------------------- *)
- (* Setzt den Cursor an Pufferkoordinaten (x,y). Sind *)
- (* sie ausserhalb des Fensters, so wird gescrollt, *)
- (* sofern OnlyBuf=FALSE und MoveCur=TRUE sind. *)
- (*----------------------------------------------------- *)
- BEGIN
- IF Access AND Win^.Visible THEN BEGIN
- IF x < 1 THEN x := 1;
- IF x > GetCols THEN x := GetCols;
- IF y < 1 THEN y := 1;
- IF y > GetRows THEN y := GetRows;
- IF NOT OnlyBuf AND MoveCur THEN BEGIN
- IF NOT InWindow(x, y) THEN
- IF InWindow(x, py1) THEN BEGIN
- IF CurY-y < 0 THEN
- ScrollBuf(0, py2-CurY+y-py2)
- ELSE
- ScrollBuf(0, py1-CurY+y-py1)
- END ELSE IF CurX-x < 0 THEN
- ScrollBuf(px2-CurX+x-px2, 0)
- ELSE
- ScrollBuf(px1-CurX+x-px1, 0);
- GotoXY(Succ(BYTE(Win^.x1+x - (px1-Ls))),
- Succ(BYTE(Win^.y1+y - (py1-Ts))));
- END;
- IF MoveCur THEN BEGIN
- Buf^.BufCurX := x; Buf^.BufCurY := y;
- CurX := x; CurY := y
- END;
- IF MoveCur AND NOT OnlyBuf THEN ShowBars;
- END;
- END;
-
- PROCEDURE DataWinObj.InsLines(y, No : INTEGER);
- BEGIN
- IF Access AND (Win^.Visible OR OnlyBuf) THEN BEGIN
- Buf^.InsLines(y, No);
- IF (y >= py1) AND (y <= py2) THEN ShowBufPart(y, py2);
- END;
- END;
-
- PROCEDURE DataWinObj.DelLines(y, No : INTEGER);
- BEGIN
- IF Access AND (Win^.Visible OR OnlyBuf) THEN BEGIN
- Buf^.DelLines(y, No);
- IF (y >= py1) AND (y <= py2) THEN ShowBufPart(y, py2);
- END;
- END;
-
- PROCEDURE DataWinObj.SetWriteColors(Col, Back : BYTE);
- BEGIN
- IF Access THEN Buf^.SetWriteColor(Col, Back);
- END;
-
- PROCEDURE DataWinObj.ChangeColor(x1, y1, x2, y2 : INTEGER;
- Col, Back : BYTE);
- BEGIN
- IF Access AND (Win^.Visible OR OnlyBuf) THEN BEGIN
- IF x1 < 1 THEN x1 := 1;
- IF y1 < 1 THEN y1 := 1;
- IF x2 > GetCols THEN x2 := GetCols;
- IF y2 > GetRows THEN y2 := GetRows;
- Buf^.ChangeColor(x1, y1, x2, y2, Col, Back);
- IF InWindow(px1, y1) THEN ShowBufPart(py1, y1);
- IF InWindow(px1, y2) THEN ShowBufPart(y2, py2);
- END;
- END;
-
- FUNCTION DataWinObj.ConvertLine (y: INTEGER) : STRING;
- (* ---------------------------------------------------- *)
- (* Wandelt Zeile y aus dem Puffer in String um. *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Access THEN ConvertLine := Buf^.Convert2Str(y)
- ELSE ConvertLine := '';
- END;
-
- FUNCTION DataWinObj.GetLineLength(y : INTEGER) : INTEGER;
- BEGIN
- IF Access THEN GetLineLength := Buf^.GetLineLength(y)
- ELSE GetLineLength := -1;
- END;
-
- PROCEDURE DataWinObj.Open;
- VAR
- x, y : INTEGER;
- BEGIN
- IF Access AND NOT Win^.Visible THEN BEGIN
- Win^.Open;
- IF NOT Win^.Visible AND NOT OnlyBuf THEN
- Access := FALSE
- ELSE IF Win^.Visible THEN BEGIN
- Access := TRUE;
- WriteComment;
- ShowBuf;
- SetCursor(CurX, CurY);
- END;
- END;
- END;
-
- PROCEDURE DataWinObj.MoveWin(x, y : INTEGER);
- (* ---------------------------------------------------- *)
- (* Bewegt das Fenster RELATIV um x/y. *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Access AND Win^.Visible THEN BEGIN
- Win^.MoveWinRel(x, y);
- WriteComment;
- ShowBuf;
- SetCursor(CurX, CurY);
- END;
- END;
-
- PROCEDURE DataWinObj.ZoomWin(x, y : INTEGER);
- (* ---------------------------------------------------- *)
- (* Zoomt das FENSTER RELATIV um x/y. *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Access AND Win^.Visible THEN
- WITH Win^ DO
- IF (x2+x <= Buf^.Columns) AND { WICHTIG !!! }
- (y2+y <= Buf^.Lines) THEN BEGIN
- ZoomWinRel(x, y);
- WriteComment;
- px2 := px2 + x;
- py2 := py2 + y;
- WITH Buf^ DO BEGIN
- IF px2 > Columns THEN BEGIN
- px2 := Columns;
- px1 := px2 - GetWinXLength;
- END;
- IF py2 > Lines THEN BEGIN
- py2 := Lines;
- py1 := py2 - GetWinYLength;
- END;
- END;
- IF CurX > Px2 THEN CurX := Px2;
- IF CurY > Py2 THEN CurY := py2;
- ShowBuf;
- SetCursor(CurX, CurY);
- END;
- END;
-
- PROCEDURE DataWinObj.ChangeFrame(NF : BYTE);
- BEGIN
- IF Access AND Win^.Visible THEN Win^.ChangeFrame(nf);
- END;
-
- PROCEDURE DataWinObj.Show;
- BEGIN
- Open;
- END;
-
- PROCEDURE DataWinObj.Hide;
- BEGIN
- Close;
- END;
-
- PROCEDURE DataWinObj.ReOpen(WinData : StandardWindow);
- (* ---------------------------------------------------- *)
- (* Öffnet das Fenster mit neuen Daten. *)
- (* ---------------------------------------------------- *)
- BEGIN
- IF Access AND Win^.Visible THEN BEGIN
- Close;
- Win^ := WinData;
- Win^.Visible := FALSE;
- px2 := Pred(px1 + GetWinXLength);
- py2 := Pred(py1 + GetWinYLength);
- IF CurX > Px2 THEN CurX := Px2;
- IF CurY > Py2 THEN CurY := py2;
- Open;
- END;
- END;
-
- PROCEDURE DataWinObj.Close;
- BEGIN
- IF Access AND Win^.Visible THEN Win^.Close;
- END;
-
- END.
- (* ------------------------------------------------------ *)
- (* Ende von DATAWIN.PAS *)
-
-