home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------- *)
- (* TXEDIT.PAS *)
- (* Modifizierte EDITORS.PAS *)
- (* Portions Copyright (c) Borland International *)
- (* ------------------------------------------------- *)
- UNIT TxEdit;
-
- {$F+,I-,O+,S-,V-,X+,D-}
-
- INTERFACE
-
- USES Drivers, Objects, Views, MsgBox;
-
- CONST
- cmSave = 80;
- cmSaveAs = 81;
- cmFind = 82;
- cmReplace = 83;
- cmSearchAgain = 84;
- cmGoto = 85;
- cmGetWord = 86;
-
- CONST
- cmCharLeft = 500;
- cmCharRight = 501;
- cmWordLeft = 502;
- cmWordRight = 503;
- cmLineStart = 504;
- cmLineEnd = 505;
- cmLineUp = 506;
- cmLineDown = 507;
- cmPageUp = 508;
- cmPageDown = 509;
- cmTextStart = 510;
- cmTextEnd = 511;
- cmNewLine = 512;
- cmBackSpace = 513;
- cmDelChar = 514;
- cmDelWord = 515;
- cmDelStart = 516;
- cmDelEnd = 517;
- cmDelLine = 518;
- cmInsMode = 519;
- cmStartSelect = 520;
- cmHideSelect = 521;
- cmIndentMode = 522;
- cmUpdateTitle = 523;
-
- CONST
- edOutOfMemory = 0;
- edReadError = 1;
- edWriteError = 2;
- edCreateError = 3;
- edSaveModify = 4;
- edSaveUntitled = 5;
- edSaveAs = 6;
- edFind = 7;
- edSearchFailed = 8;
- edReplace = 9;
- edReplacePrompt = 10;
- edGoto = 11;
- edGetWord = 12;
-
- CONST
- efCaseSensitive = $0001;
- efWholeWordsOnly = $0002;
- efPromptOnReplace = $0004;
- efReplaceAll = $0008;
- efDoReplace = $0010;
- efBackupFiles = $0020;
-
- CONST
- cIndicator = #2#3;
- cEditor = #6#7;
-
- CONST
- MaxLineLength = 256;
-
- (* ------------------------------------------------- *)
-
- TYPE
- tEditorDialog = FUNCTION(Dialog : INTEGER;
- Info : POINTER) : WORD;
-
- (* ------------------------------------------------- *)
-
- TYPE
- pIndicator = ^tIndicator;
- tIndicator = OBJECT (tView)
- Location : tPoint;
- Modified : BOOLEAN;
-
- CONSTRUCTOR Init(VAR Bounds : tRect);
- PROCEDURE Draw; VIRTUAL;
- FUNCTION GetPalette : pPalette; VIRTUAL;
- PROCEDURE SetState(aState : WORD;
- Enable : BOOLEAN); VIRTUAL;
- PROCEDURE SetValue(aLocation : tPoint;
- aModified : BOOLEAN);
- END;
-
- (* ------------------------------------------------- *)
-
- TYPE
- pEditBuffer = ^tEditBuffer;
- tEditBuffer = ARRAY [0..65519] OF CHAR;
-
- TYPE
- pEditor = ^tEditor;
- tEditor = OBJECT (tView)
- HScrollBar : pScrollBar;
- VScrollBar : pScrollBar;
- Indicator : pIndicator;
- Buffer : pEditBuffer;
- BufSize : WORD;
- BufLen : WORD;
- GapLen : WORD;
- SelStart : WORD;
- SelEnd : WORD;
- CurPtr : WORD;
- CurPos : tPoint;
- Delta : tPoint;
- Limit : tPoint;
- DrawLine : INTEGER;
- DrawPtr : WORD;
- DelCount : WORD;
- InsCount : WORD;
- IsValid : BOOLEAN;
- CanUndo : BOOLEAN;
- Modified : BOOLEAN;
- Selecting : BOOLEAN;
- Overwrite : BOOLEAN;
- AutoIndent : BOOLEAN;
-
- CONSTRUCTOR Init(VAR Bounds : tRect;
- aHScrollBar,
- aVScrollBar : pScrollBar;
- aIndicator : pIndicator;
- aBufSize : WORD);
- CONSTRUCTOR Load(VAR S : tStream);
- DESTRUCTOR Done; VIRTUAL;
- FUNCTION BufChar(P : WORD) : CHAR;
- FUNCTION BufPtr(P : WORD) : WORD;
- PROCEDURE ChangeBounds(VAR Bounds : tRect);
- VIRTUAL;
- PROCEDURE ConvertEvent(VAR Event : tEvent);
- VIRTUAL;
- FUNCTION CursorVisible : BOOLEAN;
- PROCEDURE DeleteSelect;
- PROCEDURE DoneBuffer; VIRTUAL;
- PROCEDURE Draw; VIRTUAL;
- FUNCTION GetPalette : pPalette; VIRTUAL;
- PROCEDURE HandleEvent(VAR Event : tEvent);
- VIRTUAL;
- PROCEDURE InitBuffer; VIRTUAL;
- PROCEDURE CurrentWord;
- FUNCTION InsertBuffer(VAR P : pEditBuffer;
- Offset,
- Length : WORD;
- AllowUndo,
- SelectText : BOOLEAN) : BOOLEAN;
-
- FUNCTION InsertFrom(Editor : pEditor) : BOOLEAN;
- VIRTUAL;
- FUNCTION InsertText(Text : POINTER;
- Length : WORD;
- SelectText : BOOLEAN) : BOOLEAN;
- PROCEDURE ScrollTo(X, Y : INTEGER);
- PROCEDURE SetPos(Row, Col : INTEGER);
- FUNCTION Search(FindStr : STRING;
- Opts : WORD) : BOOLEAN;
- FUNCTION SetBufSize(NewSize : WORD) : BOOLEAN;
- VIRTUAL;
- PROCEDURE SetCmdState(Command : WORD;
- Enable : BOOLEAN);
- PROCEDURE SetSelect(NewStart, NewEnd : WORD;
- CurStart : BOOLEAN);
- PROCEDURE SetState(AState : WORD;
- Enable : BOOLEAN); VIRTUAL;
- PROCEDURE Store(VAR S : tStream);
- PROCEDURE TrackCursor(Center : BOOLEAN);
- PROCEDURE Undo;
- PROCEDURE UpdateCommands; VIRTUAL;
- FUNCTION Valid(Command : WORD) : BOOLEAN;
- VIRTUAL;
-
- PRIVATE
- LockCount : BYTE;
- UpdateFlags : BYTE;
- KeyState : INTEGER;
-
- FUNCTION CharPos(P, Target : WORD) : INTEGER;
- FUNCTION CharPtr(P : WORD;
- Target : INTEGER) : WORD;
- FUNCTION ClipCopy : BOOLEAN;
- PROCEDURE ClipCut;
- PROCEDURE ClipPaste;
- PROCEDURE DeleteRange(StartPtr, EndPtr : WORD;
- DelSelect : BOOLEAN);
- PROCEDURE DoUpdate;
- PROCEDURE DoSearchReplace;
- PROCEDURE DoGoto;
-
- PROCEDURE DrawLines(Y, Count : INTEGER;
- LinePtr : WORD);
- PROCEDURE FormatLine(VAR DrawBuf; LinePtr : WORD;
- Width : INTEGER;
- Colors : WORD);
- PROCEDURE Find;
- FUNCTION GetMousePtr(Mouse : TPoint) : WORD;
- FUNCTION HasSelection : BOOLEAN;
- PROCEDURE HideSelect;
- FUNCTION IsClipboard : BOOLEAN;
- FUNCTION LineEnd(P : WORD) : WORD;
- FUNCTION LineMove(P : WORD;
- Count : INTEGER) : WORD;
- FUNCTION LineStart(P : WORD) : WORD;
- PROCEDURE Lock;
- PROCEDURE NewLine;
- FUNCTION NextChar(P : WORD) : WORD;
- FUNCTION NextLine(P : WORD) : WORD;
- FUNCTION NextWord(P : WORD) : WORD;
- FUNCTION PrevChar(P : WORD) : WORD;
- FUNCTION PrevLine(P : WORD) : WORD;
- FUNCTION PrevWord(P : WORD) : WORD;
- PROCEDURE Replace;
- PROCEDURE SetBufLen(Length : WORD);
- PROCEDURE SetCurPtr(P : WORD;
- SelectMode : BYTE);
- PROCEDURE StartSelect;
- PROCEDURE ToggleInsMode;
- PROCEDURE Unlock;
- PROCEDURE Update(AFlags : BYTE);
- END;
-
- (* ------------------------------------------------- *)
-
- TYPE
- pFileEditor = ^tFileEditor;
- tFileEditor = OBJECT (tEditor)
- FileName : FNameStr;
-
- CONSTRUCTOR Init(VAR Bounds : tRect;
- aHScrollBar,
- aVScrollBar : pScrollBar;
- aIndicator : pIndicator;
- aFileName : FNameStr);
- CONSTRUCTOR Load(VAR S : tStream);
- PROCEDURE DoneBuffer; VIRTUAL;
- PROCEDURE HandleEvent(VAR Event : TEvent);
- VIRTUAL;
- PROCEDURE InitBuffer; VIRTUAL;
- FUNCTION ActFileName : FNameStr;
- FUNCTION LoadFile : BOOLEAN;
- FUNCTION Save : BOOLEAN;
- FUNCTION SaveAs : BOOLEAN;
- FUNCTION SaveFile : BOOLEAN;
- FUNCTION SetBufSize(NewSize : WORD) : BOOLEAN;
- VIRTUAL;
- PROCEDURE Store(VAR S : tStream);
- PROCEDURE UpdateCommands; VIRTUAL;
- FUNCTION Valid(Command : WORD) : BOOLEAN;
- VIRTUAL;
- END;
-
- (* ------------------------------------------------- *)
-
- TYPE
- pEditWindow = ^tEditWindow;
- tEditWindow = OBJECT (tWindow)
- Editor : pFileEditor;
-
- CONSTRUCTOR Init(VAR Bounds : tRect;
- FileName : FNameStr;
- aNumber : INTEGER);
- CONSTRUCTOR Load(VAR S : tStream);
- PROCEDURE Close; VIRTUAL;
- FUNCTION GetTitle(MaxSize : INTEGER): tTitleStr;
- VIRTUAL;
- PROCEDURE HandleEvent(VAR Event : tEvent);
- VIRTUAL;
- PROCEDURE Store(VAR S : tStream);
- END;
-
- (* ------------------------------------------------- *)
-
- FUNCTION DefEditorDialog(Dialog : INTEGER;
- Info : POINTER) : WORD;
-
- (* ------------------------------------------------- *)
-
- CONST
- WordChars : SET OF CHAR =
- ['0'..'9', 'A'..'Z', '_', 'a'..'z'];
- EditorDialog : tEditorDialog = DefEditorDialog;
- EditorFlags : WORD = efBackupFiles +
- efPromptOnReplace;
- FindStr : STRING [80] = '';
- ReplaceStr : STRING [80] = '';
- Clipboard : pEditor = NIL;
-
- (* ------------------------------------------------- *)
-
- TYPE
- tFindDialogRec = RECORD
- Find : STRING [80];
- Options : WORD;
- END;
-
- tReplaceDialogRec = RECORD
- Find : STRING [80];
- Replace : STRING [80];
- Options : WORD;
- END;
-
- tGotoDialogRec = RECORD
- Row : STRING [5];
- Col : STRING [5];
- END;
-
- (* ------------------------------------------------- *)
-
- CONST
- rEditor : tStreamRec = (
- ObjType : 70;
- VmtLink : Ofs(TypeOf(tEditor)^);
- Load : @tEditor.Load;
- Store : @tEditor.Store);
-
- rFileEditor : tStreamRec = (
- ObjType : 71;
- VmtLink : Ofs(TypeOf(tFileEditor)^);
- Load : @tFileEditor.Load;
- Store : @tFileEditor.Store);
-
- rIndicator : tStreamRec = (
- ObjType : 72;
- VmtLink : Ofs(TypeOf(tIndicator)^);
- Load : @tIndicator.Load;
- Store : @tIndicator.Store);
-
- rEditWindow : tStreamRec = (
- ObjType : 73;
- VmtLink : Ofs(TypeOf(tEditWindow)^);
- Load : @tEditWindow.Load;
- Store : @tEditWindow.Store);
-
- PROCEDURE RegisterEditors;
-
- (* ------------------------------------------------- *)
- IMPLEMENTATION
-
- USES Memory, Buffers, Dos;
-
- CONST
- ufUpdate = $01;
- ufLine = $02;
- ufView = $04;
-
- CONST
- smExtend = $01;
- smDouble = $02;
-
- CONST
- sfSearchFailed = $FFFF;
-
- CONST
- FirstKeys : ARRAY [0..37*2] OF WORD =
- (37,
- ORD(^A), cmWordLeft,
- ORD(^C), cmPageDown,
- ORD(^D), cmCharRight,
- ORD(^E), cmLineUp,
- ORD(^F), cmWordRight,
- ORD(^G), cmDelChar,
- ORD(^H), cmBackSpace,
- ORD(^K), $FF02,
- ORD(^L), cmSearchAgain,
- ORD(^M), cmNewLine,
- ORD(^O), cmIndentMode,
- ORD(^Q), $FF01,
- ORD(^R), cmPageUp,
- ORD(^S), cmCharLeft,
- ORD(^T), cmDelWord,
- ORD(^U), cmUndo,
- ORD(^V), cmInsMode,
- ORD(^X), cmLineDown,
- ORD(^Y), cmDelLine,
- kbLeft, cmCharLeft,
- kbRight, cmCharRight,
- kbCtrlLeft, cmWordLeft,
- kbCtrlRight, cmWordRight,
- kbHome, cmLineStart,
- kbEnd, cmLineEnd,
- kbUp, cmLineUp,
- kbDown, cmLineDown,
- kbPgUp, cmPageUp,
- kbPgDn, cmPageDown,
- kbCtrlPgUp, cmTextStart,
- kbCtrlPgDn, cmTextEnd,
- kbIns, cmInsMode,
- kbDel, cmDelChar,
- kbShiftIns, cmPaste,
- kbShiftDel, cmCut,
- kbCtrlIns, cmCopy,
- kbCtrlDel, cmClear);
-
- QuickKeys : ARRAY [0..8*2] OF WORD =
- (8,
- ORD('A'), cmReplace,
- ORD('C'), cmTextEnd,
- ORD('D'), cmLineEnd,
- ORD('F'), cmFind,
- ORD('H'), cmDelStart,
- ORD('R'), cmTextStart,
- ORD('S'), cmLineStart,
- ORD('Y'), cmDelEnd);
-
- BlockKeys : ARRAY [0..5*2] OF WORD =
- (5,
- ORD('B'), cmStartSelect,
- ORD('C'), cmPaste,
- ORD('H'), cmHideSelect,
- ORD('K'), cmCopy,
- ORD('Y'), cmCut);
-
- KeyMap : ARRAY [0..2] OF POINTER =
- (@FirstKeys, @QuickKeys, @BlockKeys);
-
- (* ------------------------------------------------- *)
-
- FUNCTION DefEditorDialog(Dialog : INTEGER;
- Info : POINTER) : WORD;
- BEGIN
- DefEditorDialog := cmCancel;
- END;
-
- FUNCTION Min(X, Y : INTEGER) : INTEGER; ASSEMBLER;
- ASM
- MOV AX,X
- CMP AX,Y
- JLE @@1
- MOV AX,Y
- @@1:
- END;
-
- FUNCTION Max(X, Y : INTEGER) : INTEGER; ASSEMBLER;
- ASM
- MOV AX,X
- CMP AX,Y
- JGE @@1
- MOV AX,Y
- @@1:
- END;
-
- FUNCTION MinWord(X, Y : WORD) : WORD; ASSEMBLER;
- ASM
- MOV AX,X
- CMP AX,Y
- JBE @@1
- MOV AX,Y
- @@1:
- END;
-
- FUNCTION MaxWord(X, Y : WORD) : WORD; ASSEMBLER;
- ASM
- MOV AX,X
- CMP AX,Y
- JAE @@1
- MOV AX,Y
- @@1:
- END;
-
- FUNCTION CountLines(VAR Buf; Count : WORD) : INTEGER;
- ASSEMBLER;
- ASM
- LES DI,Buf
- MOV CX,Count
- XOR DX,DX
- MOV AL,0DH
- CLD
- @@1:
- JCXZ @@2
- REPNE SCASB
- JNE @@2
- INC DX
- JMP @@1
- @@2:
- MOV AX,DX
- END;
-
- FUNCTION ScanKeyMap(KeyMap : POINTER;
- KeyCode : WORD) : WORD;
- ASSEMBLER;
- ASM
- PUSH DS
- LDS SI,KeyMap
- MOV DX,KeyCode
- CLD
- LODSW
- MOV CX,AX
- @@1:
- LODSW
- MOV BX,AX
- LODSW
- CMP BL,DL
- JNE @@3
- OR BH,BH
- JE @@4
- CMP BH,DH
- JE @@4
- @@3:
- LOOP @@1
- XOR AX,AX
- @@4:
- POP DS
- END;
-
- FUNCTION Scan(VAR Block; Size : WORD;
- Str : STRING) : WORD; ASSEMBLER;
- ASM
- PUSH DS
- LES DI,Block
- LDS SI,STR
- MOV CX,Size
- JCXZ @@3
- CLD
- LODSB
- CMP AL,1
- JB @@5
- JA @@1
- LODSB
- REPNE SCASB
- JNE @@3
- JMP @@5
- @@1:
- XOR AH,AH
- MOV BX,AX
- DEC BX
- MOV DX,CX
- SUB DX,AX
- JB @@3
- LODSB
- INC DX
- INC DX
- @@2:
- DEC DX
- MOV CX,DX
- REPNE SCASB
- JNE @@3
- MOV DX,CX
- MOV CX,BX
- REP CMPSB
- JE @@4
- SUB CX,BX
- ADD SI,CX
- ADD DI,CX
- INC DI
- OR DX,DX
- JNE @@2
- @@3:
- XOR AX,AX
- JMP @@6
- @@4:
- SUB DI,BX
- @@5:
- MOV AX,DI
- SUB AX,WORD PTR Block
- @@6:
- DEC AX
- POP DS
- END;
-
- FUNCTION IScan(VAR Block; Size : WORD;
- Str : STRING) : WORD; ASSEMBLER;
- VAR
- S : STRING;
- ASM
- PUSH DS
- MOV AX,SS
- MOV ES,AX
- LEA DI,S
- LDS SI,STR
- XOR AH,AH
- LODSB
- STOSB
- MOV CX,AX
- MOV BX,AX
- JCXZ @@9
- @@1:
- LODSB
- CMP AL,'a'
- JB @@2
- CMP AL,'z'
- JA @@2
- SUB AL,20H
- @@2:
- STOSB
- LOOP @@1
- SUB DI,BX
- LDS SI,Block
- MOV CX,Size
- JCXZ @@8
- CLD
- SUB CX,BX
- JB @@8
- INC CX
- @@4:
- MOV AH,ES:[DI]
- AND AH,$DF
- @@5:
- LODSB
- AND AL,$DF
- CMP AL,AH
- LOOPNE @@5
- JNE @@8
- DEC SI
- MOV DX,CX
- MOV CX,BX
- @@6:
- REPE CMPSB
- JE @@10
- MOV AL,DS:[SI-1]
- CMP AL,'a'
- JB @@7
- CMP AL,'z'
- JA @@7
- SUB AL,20H
- @@7:
- CMP AL,ES:[DI-1]
- JE @@6
- SUB CX,BX
- ADD SI,CX
- ADD DI,CX
- INC SI
- MOV CX,DX
- JNE @@4
- @@8:
- XOR AX,AX
- JMP @@11
- @@9:
- MOV AX, 1
- JMP @@11
- @@10:
- SUB SI,BX
- MOV AX,SI
- SUB AX,WORD PTR Block
- INC AX
- @@11:
- DEC AX
- POP DS
- END;
-
- (* ------------------------------------------------- *)
- (* tIndicator *)
-
- CONSTRUCTOR TIndicator.Init(VAR Bounds : tRect);
- VAR
- R : tRect;
- BEGIN
- tView.Init(Bounds);
- GrowMode := gfGrowLoY + gfGrowHiY;
- END;
-
- PROCEDURE tIndicator.Draw;
- VAR
- Color : BYTE;
- Frame : CHAR;
- L : ARRAY [0..1] OF LONGINT;
- S : STRING [15];
- B : tDrawBuffer;
- BEGIN
- IF State AND sfDragging = 0 THEN BEGIN
- Color := GetColor(1);
- Frame := #205;
- END ELSE BEGIN
- Color := GetColor(2);
- Frame := #196;
- END;
- MoveChar(B, Frame, Color, Size.X);
- IF Modified THEN WordRec(B[0]).Lo := 15;
- L[0] := Location.Y+1;
- L[1] := Location.X+1;
- FormatStr(S, ' %d:%d ', L);
- MoveStr(B[8-Pos(':', S)], S, Color);
- WriteBuf(0, 0, Size.X, 1, B);
- END;
-
- FUNCTION tIndicator.GetPalette : pPalette;
- CONST
- P : STRING [Length(cIndicator)] = cIndicator;
- BEGIN
- GetPalette := @P;
- END;
-
- PROCEDURE tIndicator.SetState(aState : WORD;
- Enable : BOOLEAN);
- BEGIN
- tView.SetState(aState, Enable);
- IF AState = sfDragging THEN DrawView;
- END;
-
- PROCEDURE tIndicator.SetValue(aLocation : tPoint;
- aModified : BOOLEAN);
- BEGIN
- IF (LongInt(Location) <> LongInt(aLocation)) OR
- (Modified <> aModified) THEN BEGIN
- Location := aLocation;
- Modified := aModified;
- DrawView;
- END;
- END;
-
- (* ------------------------------------------------- *)
- (* tEditor *)
-
- CONSTRUCTOR tEditor.Init(VAR Bounds : tRect;
- aHScrollBar,
- aVScrollBar : pScrollBar;
- aIndicator : pIndicator;
- aBufSize : WORD);
- BEGIN
- tView.Init(Bounds);
- GrowMode := gfGrowHiX + gfGrowHiY;
- Options := Options OR ofSelectable;
- EventMask := evMouseDown + evKeyDown +
- evCommand + evBroadcast;
- ShowCursor;
- HScrollBar := aHScrollBar;
- VScrollBar := aVScrollBar;
- Indicator := aIndicator;
- BufSize := aBufSize;
- CanUndo := TRUE;
- InitBuffer;
- IF Buffer <> NIL THEN
- IsValid := TRUE
- ELSE BEGIN
- EditorDialog(edOutOfMemory, NIL);
- BufSize := 0;
- END;
- SetBufLen(0);
- AutoIndent := TRUE;
- END;
-
- CONSTRUCTOR tEditor.Load(VAR S : tStream);
- BEGIN
- tView.Load(S);
- GetPeerViewPtr(S, HScrollBar);
- GetPeerViewPtr(S, VScrollBar);
- GetPeerViewPtr(S, Indicator);
- S.Read(BufSize, SizeOf(WORD));
- S.Read(CanUndo, SizeOf(BOOLEAN));
- InitBuffer;
- IF Buffer <> NIL THEN
- IsValid := TRUE
- ELSE BEGIN
- EditorDialog(edOutOfMemory, NIL);
- BufSize := 0;
- END;
- Lock;
- SetBufLen(0);
- END;
-
- PROCEDURE tEditor.CurrentWord;
- VAR
- ThisPtr, Diff : WORD;
- s : STRING;
- BEGIN
- ThisPtr := CurPtr;
-
- SetCurPtr(PrevWord(CurPtr), 0);
-
- Diff := ThisPtr - CurPtr;
-
- Move(Buffer^[CurPtr-1], s, Diff+1); (* -1, +1 *)
- s[0] := Char(Diff);
- EditorDialog(edGetWord, @s);
- (* Do not update now *)
- SetCurPtr(ThisPtr, 0);
- Update(ufView);
- END;
-
- DESTRUCTOR tEditor.Done;
- BEGIN
- DoneBuffer;
- tView.Done;
- END;
-
- FUNCTION tEditor.BufChar(P : WORD) : CHAR; ASSEMBLER;
- ASM
- LES DI,Self
- MOV BX,P
- CMP BX,ES:[DI].tEditor.CurPtr
- JB @@1
- ADD BX,ES:[DI].tEditor.GapLen
- @@1:
- LES DI,ES:[DI].tEditor.Buffer
- MOV AL,ES:[DI+BX]
- END;
-
- FUNCTION tEditor.BufPtr(P : WORD) : WORD; ASSEMBLER;
- ASM
- LES DI,Self
- MOV AX,P
- CMP AX,ES:[DI].tEditor.CurPtr
- JB @@1
- ADD AX,ES:[DI].tEditor.GapLen
- @@1:
- END;
-
- PROCEDURE tEditor.ChangeBounds(VAR Bounds : tRect);
- BEGIN
- SetBounds(Bounds);
- Delta.X := Max(0, Min(Delta.X, Limit.X-Size.X));
- Delta.Y := Max(0, Min(Delta.Y, Limit.Y-Size.Y));
- Update(ufView);
- END;
-
- FUNCTION tEditor.CharPos(P, Target : WORD) : INTEGER;
- VAR
- Pos : INTEGER;
- BEGIN
- Pos := 0;
- WHILE P < Target DO BEGIN
- IF BufChar(P) = #9 THEN Pos := Pos OR 7;
- INC(Pos);
- INC(P);
- END;
- CharPos := Pos;
- END;
-
- FUNCTION tEditor.CharPtr(P : WORD;
- Target : INTEGER) : WORD;
- VAR
- Pos : INTEGER;
- BEGIN
- Pos := 0;
- WHILE (Pos < Target) AND (P < BufLen) AND
- (BufChar(P) <> #13) DO BEGIN
- IF BufChar(P) = #9 THEN Pos := Pos OR 7;
- INC(Pos);
- INC(P);
- END;
- IF Pos > Target THEN DEC(P);
- CharPtr := P;
- END;
-
- FUNCTION tEditor.ClipCopy : BOOLEAN;
- BEGIN
- ClipCopy := FALSE;
- IF (Clipboard <> NIL) AND
- (Clipboard <> @Self) THEN BEGIN
- ClipCopy := Clipboard^.InsertFrom(@Self);
- Selecting := FALSE;
- Update(ufUpdate);
- END;
- END;
-
- PROCEDURE tEditor.ClipCut;
- BEGIN
- IF ClipCopy THEN DeleteSelect;
- END;
-
- PROCEDURE tEditor.ClipPaste;
- BEGIN
- IF (Clipboard <> NIL) AND (Clipboard <> @Self) THEN
- InsertFrom(Clipboard);
- END;
-
- PROCEDURE tEditor.ConvertEvent(VAR Event : tEvent);
- VAR
- ShiftState : BYTE ABSOLUTE $40:$17;
- Key : WORD;
- BEGIN
- IF Event.What = evKeyDown THEN BEGIN
- IF (ShiftState AND $03 <> 0) AND
- (Event.ScanCode >= $47) AND
- (Event.ScanCode <= $51) THEN
- Event.CharCode := #0;
- Key := Event.KeyCode;
- IF KeyState <> 0 THEN BEGIN
- IF (Lo(Key) >= $01) AND (Lo(Key) <= $1A) THEN
- INC(Key, $40);
- IF (Lo(Key) >= $61) AND (Lo(Key) <= $7A) THEN
- DEC(Key, $20);
- END;
- Key := ScanKeyMap(KeyMap[KeyState], Key);
- KeyState := 0;
- IF Key <> 0 THEN
- IF Hi(Key) = $FF THEN BEGIN
- KeyState := Lo(Key);
- ClearEvent(Event);
- END ELSE BEGIN
- Event.What := evCommand;
- Event.Command := Key;
- END;
- END;
- END;
-
- FUNCTION tEditor.CursorVisible : BOOLEAN;
- BEGIN
- CursorVisible := (CurPos.Y >= Delta.Y) AND
- (CurPos.Y < Delta.Y+Size.Y);
- END;
-
- PROCEDURE tEditor.DeleteRange(StartPtr,
- EndPtr : WORD;
- DelSelect : BOOLEAN);
- BEGIN
- IF HasSelection AND DelSelect THEN
- DeleteSelect
- ELSE BEGIN
- SetSelect(CurPtr, EndPtr, TRUE);
- DeleteSelect;
- SetSelect(StartPtr, CurPtr, FALSE);
- DeleteSelect;
- END;
- END;
-
- PROCEDURE tEditor.DeleteSelect;
- BEGIN
- InsertText(NIL, 0, FALSE);
- END;
-
- PROCEDURE tEditor.DoneBuffer;
- BEGIN
- IF Buffer <> NIL THEN FreeMem(Buffer, BufSize);
- END;
-
- PROCEDURE tEditor.SetPos(Row, Col : INTEGER);
- (* wr 04.07.91 15:00 *)
- VAR
- Target, ToMove : tPoint;
- i : INTEGER;
- BEGIN
- Target.X := Col; ToMove.X := Target.X - CurPos.X;
- Target.Y := Row; ToMove.Y := Target.Y - CurPos.Y;
- SetCurPtr(LineMove(CurPtr, ToMove.Y), 0);
- (* Up/Dn *)
- IF ToMove.X < 0 THEN BEGIN
- (* Scroll ToMove.X chars left *)
- FOR i := 1 TO Abs(ToMove.X) DO
- SetCurPtr(PrevChar(CurPtr), 0);
- END ELSE IF ToMove.X > 0 THEN BEGIN
- (* Scroll ToMove.X chars right *)
- FOR i := 1 TO ToMove.X DO
- SetCurPtr(NextChar(CurPtr), 0);
- END;
- DoUpdate;
- END;
-
- PROCEDURE tEditor.DoGoto;
- VAR
- GotoRec : tGotoDialogRec;
- Control : WORD;
- x, y, c : INTEGER;
- sx, sy : STRING;
- BEGIN
- Str(CurPos.x+1, sx); Str(CurPos.y+1, sy);
- GotoRec.Col := sx;
- GotoRec.Row := sy;
- Control := EditorDialog(edGoto, @GotoRec);
- IF Control = cmOk THEN BEGIN
- Val(GotoRec.Col, x, c);
- Val(GotoRec.Row, y, c);
- IF y < 1 THEN y := 1;
- IF x < 1 THEN x := 1;
- SetPos(y-1, x-1);
- TrackCursor(TRUE);
- END;
- END;
-
- PROCEDURE tEditor.DoSearchReplace;
- VAR
- I : WORD;
- C : tPoint;
- BEGIN
- REPEAT
- I := cmCancel;
- IF NOT Search(FindStr, EditorFlags) THEN BEGIN
- IF EditorFlags AND
- (efReplaceAll+efDoReplace) <>
- (efReplaceAll+efDoReplace) THEN
- EditorDialog(edSearchFailed, NIL);
- END ELSE IF EditorFlags AND
- efDoReplace <> 0 THEN BEGIN
- I := cmYes;
- IF EditorFlags AND
- efPromptOnReplace <> 0 THEN BEGIN
- MakeGlobal(Cursor, C);
- I := EditorDialog(edReplacePrompt,
- Pointer(C));
- END;
- IF I = cmYes THEN BEGIN
- Lock;
- InsertText(@ReplaceStr[1],
- Length(ReplaceStr), FALSE);
- TrackCursor(FALSE);
- Unlock;
- END;
- END;
- UNTIL (I = cmCancel) OR
- (EditorFlags AND efReplaceAll = 0);
- END;
-
- PROCEDURE tEditor.DoUpdate;
- BEGIN
- IF UpdateFlags <> 0 THEN BEGIN
- SetCursor(CurPos.X-Delta.X, CurPos.Y-Delta.Y);
- IF UpdateFlags AND ufView <> 0 THEN
- DrawView
- ELSE IF UpdateFlags AND ufLine <> 0 THEN
- DrawLines(CurPos.Y-Delta.Y, 1,
- LineStart(CurPtr));
- IF HScrollBar <> NIL THEN
- HScrollBar^.SetParams(Delta.X, 0,
- Limit.X-Size.X, Size.X DIV 2, 1);
- IF VScrollBar <> NIL THEN
- VScrollBar^.SetParams(Delta.Y, 0,
- Limit.Y-Size.Y, Size.Y-1, 1);
- IF Indicator <> NIL THEN
- Indicator^.SetValue(CurPos, Modified);
- IF State AND sfActive <> 0 THEN UpdateCommands;
- UpdateFlags := 0;
- END;
- END;
-
- PROCEDURE tEditor.Draw;
- BEGIN
- IF DrawLine <> Delta.Y THEN BEGIN
- DrawPtr := LineMove(DrawPtr, Delta.Y-DrawLine);
- DrawLine := Delta.Y;
- END;
- DrawLines(0, Size.Y, DrawPtr);
- END;
-
- PROCEDURE tEditor.DrawLines(Y, Count : INTEGER;
- LinePtr : WORD);
- VAR
- Color : WORD;
- B : ARRAY [0..MaxLineLength-1] OF WORD;
- BEGIN
- Color := GetColor($0201);
- WHILE Count > 0 DO BEGIN
- FormatLine(B, LinePtr, Delta.X+Size.X, Color);
- WriteBuf(0, Y, Size.X, 1, B[Delta.X]);
- LinePtr := NextLine(LinePtr);
- INC(Y);
- DEC(Count);
- END;
- END;
-
- PROCEDURE tEditor.Find;
- VAR
- FindRec : tFindDialogRec;
- BEGIN
- WITH FindRec DO BEGIN
- Find := FindStr;
- Options := EditorFlags;
- IF EditorDialog(edFind, @FindRec) <>
- cmCancel THEN BEGIN
- FindStr := Find;
- EditorFlags := Options AND NOT efDoReplace;
- DoSearchReplace;
- END;
- END;
- END;
-
- PROCEDURE tEditor.FormatLine(VAR DrawBuf;
- LinePtr : WORD;
- Width : INTEGER;
- Colors : WORD);
- ASSEMBLER;
- ASM
- PUSH DS
- LDS BX,Self
- LES DI,DrawBuf
- MOV SI,LinePtr
- XOR DX,DX
- CLD
- MOV AH,Colors.BYTE[0]
- MOV CX,DS:[BX].tEditor.SelStart
- CALL @@10
- MOV AH,Colors.BYTE[1]
- MOV CX,DS:[BX].tEditor.CurPtr
- CALL @@10
- ADD SI,DS:[BX].tEditor.GapLen
- MOV CX,DS:[BX].tEditor.SelEnd
- ADD CX,DS:[BX].tEditor.GapLen
- CALL @@10
- MOV AH,Colors.BYTE[0]
- MOV CX,DS:[BX].tEditor.BufSize
- CALL @@10
- JMP @@31
- @@10:
- SUB CX,SI
- JA @@11
- RETN
- @@11:
- LDS BX,DS:[BX].tEditor.Buffer
- ADD SI,BX
- MOV BX,Width
- @@12:
- LODSB
- CMP AL,' '
- JB @@20
- @@13:
- STOSW
- INC DX
- @@14:
- CMP DX,BX
- JAE @@30
- LOOP @@12
- LDS BX,Self
- SUB SI,DS:[BX].tEditor.Buffer.WORD[0]
- RETN
- @@20:
- CMP AL,0DH
- JE @@30
- CMP AL,09H
- JNE @@13
- MOV AL,' '
- @@21:
- STOSW
- INC DX
- TEST DL,7
- JNE @@21
- JMP @@14
- @@30:
- POP CX
- @@31:
- MOV AL,' '
- MOV CX,Width
- SUB CX,DX
- JBE @@32
- REP STOSW
- @@32:
- POP DS
- END;
-
- FUNCTION tEditor.GetMousePtr(Mouse : tPoint) : WORD;
- BEGIN
- MakeLocal(Mouse, Mouse);
- Mouse.X := Max(0, Min(Mouse.X, Size.X-1));
- Mouse.Y := Max(0, Min(Mouse.Y, Size.Y-1));
- GetMousePtr := CharPtr(LineMove(DrawPtr,
- Mouse.Y+Delta.Y-DrawLine),
- Mouse.X+Delta.X);
- END;
-
- FUNCTION tEditor.GetPalette : pPalette;
- CONST
- P : STRING [Length(cEditor)] = cEditor;
- BEGIN
- GetPalette := @P;
- END;
-
- PROCEDURE tEditor.HandleEvent(VAR Event : tEvent);
- VAR
- ShiftState : BYTE ABSOLUTE $40:$17;
- CenterCursor : BOOLEAN;
- SelectMode : BYTE;
- I : INTEGER;
- NewPtr : WORD;
- D, Mouse : tPoint;
-
- PROCEDURE CheckScrollBar(P : pScrollBar;
- VAR D : INTEGER);
- BEGIN
- IF (Event.InfoPtr = P) AND
- (P^.Value <> D) THEN BEGIN
- D := P^.Value;
- Update(ufView);
- END;
- END;
-
- BEGIN
- TView.HandleEvent(Event);
- ConvertEvent(Event);
- CenterCursor := NOT CursorVisible;
- SelectMode := 0;
- IF Selecting OR (ShiftState AND $03 <> 0) THEN
- SelectMode := smExtend;
- CASE Event.What OF
- evMouseDown :
- BEGIN
- IF Event.DOUBLE THEN
- SelectMode := SelectMode OR smDouble;
- REPEAT
- Lock;
- IF Event.What = evMouseAuto THEN BEGIN
- MakeLocal(Event.Where, Mouse);
- D := Delta;
- IF Mouse.X < 0 THEN DEC(D.X);
- IF Mouse.X >= Size.X THEN INC(D.X);
- IF Mouse.Y < 0 THEN DEC(D.Y);
- IF Mouse.Y >= Size.Y THEN INC(D.Y);
- ScrollTo(D.X, D.Y);
- END;
- SetCurPtr(GetMousePtr(Event.Where),
- SelectMode);
- SelectMode := SelectMode OR smExtend;
- Unlock;
- UNTIL NOT MouseEvent(Event,
- evMouseMove + evMouseAuto);
- END;
- evKeyDown :
- CASE Event.CharCode OF
- #9, #32..#255 :
- BEGIN
- Lock;
- IF Overwrite AND NOT HasSelection THEN
- IF CurPtr <> LineEnd(CurPtr) THEN
- SelEnd := NextChar(CurPtr);
- InsertText(@Event.CharCode, 1, FALSE);
- TrackCursor(CenterCursor);
- Unlock;
- END;
- ELSE
- Exit;
- END;
- evCommand :
- CASE Event.Command OF
- cmFind : Find;
- cmReplace : Replace;
- cmSearchAgain : DoSearchReplace;
- cmGoto : DoGoto;
- cmGetWord : CurrentWord;
- ELSE BEGIN
- Lock;
- CASE Event.Command OF
- cmCut : ClipCut;
- cmCopy : ClipCopy;
- cmPaste : ClipPaste;
- cmUndo : Undo;
- cmClear : DeleteSelect;
- cmCharLeft : SetCurPtr(PrevChar(CurPtr),
- SelectMode);
- cmCharRight : SetCurPtr(NextChar(CurPtr),
- SelectMode);
- cmWordLeft : SetCurPtr(PrevWord(CurPtr),
- SelectMode);
- cmWordRight : SetCurPtr(NextWord(CurPtr),
- SelectMode);
- cmLineStart : SetCurPtr(LineStart(CurPtr),
- SelectMode);
- cmLineEnd : SetCurPtr(LineEnd(CurPtr),
- SelectMode);
- cmLineUp : SetCurPtr(LineMove(CurPtr,
- -1), SelectMode);
- cmLineDown : SetCurPtr(LineMove(CurPtr,
- 1), SelectMode);
- cmPageUp : SetCurPtr(LineMove(CurPtr,
- -(Size.Y-1)),
- SelectMode);
- cmPageDown : SetCurPtr(LineMove(CurPtr,
- Size.Y-1),
- SelectMode);
- cmTextStart : SetCurPtr(0, SelectMode);
- cmTextEnd : SetCurPtr(BufLen,
- SelectMode);
- cmNewLine : NewLine;
- cmBackSpace : DeleteRange(PrevChar(CurPtr),
- CurPtr, TRUE);
- cmDelChar : DeleteRange(CurPtr,
- NextChar(CurPtr), TRUE);
- cmDelWord : DeleteRange(CurPtr,
- NextWord(CurPtr), FALSE);
- cmDelStart : DeleteRange(LineStart(CurPtr),
- CurPtr, FALSE);
- cmDelEnd : DeleteRange(CurPtr,
- LineEnd(CurPtr), FALSE);
- cmDelLine : DeleteRange(LineStart(CurPtr),
- NextLine(CurPtr), FALSE);
- cmInsMode : ToggleInsMode;
- cmStartSelect : StartSelect;
- cmHideSelect : HideSelect;
- cmIndentMode : AutoIndent :=
- NOT AutoIndent;
- ELSE
- Unlock;
- Exit;
- END;
- TrackCursor(CenterCursor);
- Unlock;
- END;
- END;
- evBroadcast :
- CASE Event.Command OF
- cmScrollBarChanged :
- BEGIN
- CheckScrollBar(HScrollBar, Delta.X);
- CheckScrollBar(VScrollBar, Delta.Y);
- END;
- ELSE
- Exit;
- END;
- END;
- ClearEvent(Event);
- END;
-
- FUNCTION tEditor.HasSelection : BOOLEAN;
- BEGIN
- HasSelection := SelStart <> SelEnd;
- END;
-
- PROCEDURE tEditor.HideSelect;
- BEGIN
- Selecting := FALSE;
- SetSelect(CurPtr, CurPtr, FALSE);
- END;
-
- PROCEDURE tEditor.InitBuffer;
- BEGIN
- Buffer := MemAlloc(BufSize);
- END;
-
- FUNCTION tEditor.InsertBuffer(VAR P : pEditBuffer;
- Offset,
- Length : WORD;
- AllowUndo,
- SelectText : BOOLEAN) : BOOLEAN;
- VAR
- SelLen, DelLen, SelLines, Lines : WORD;
- NewSize : LONGINT;
- BEGIN
- InsertBuffer := TRUE;
- Selecting := FALSE;
- SelLen := SelEnd-SelStart;
- IF (SelLen = 0) AND (Length = 0) THEN Exit;
- DelLen := 0;
- IF AllowUndo THEN BEGIN
- IF CurPtr = SelStart THEN
- DelLen := SelLen
- ELSE
- IF SelLen > InsCount THEN
- DelLen := SelLen-InsCount;
- END;
- NewSize := LongInt(BufLen+DelCount-
- SelLen+DelLen)+Length;
- IF NewSize > BufLen+DelCount THEN BEGIN
- IF (NewSize > $FFF0) OR
- NOT SetBufSize(NewSize) THEN BEGIN
- EditorDialog(edOutOfMemory, NIL);
- InsertBuffer := FALSE;
- Exit;
- END;
- END;
- SelLines := CountLines(Buffer^[BufPtr(SelStart)],
- SelLen);
- IF CurPtr = SelEnd THEN BEGIN
- IF AllowUndo THEN BEGIN
- IF DelLen > 0 THEN
- Move(Buffer^[SelStart],
- Buffer^[CurPtr+GapLen-DelCount-DelLen],
- DelLen);
- DEC(InsCount, SelLen-DelLen);
- END;
- CurPtr := SelStart;
- DEC(CurPos.Y, SelLines);
- END;
- IF Delta.Y > CurPos.Y THEN BEGIN
- DEC(Delta.Y, SelLines);
- IF Delta.Y < CurPos.Y THEN Delta.Y := CurPos.Y;
- END;
- IF Length > 0 THEN
- Move(P^[Offset], Buffer^[CurPtr], Length);
- Lines := CountLines(Buffer^[CurPtr], Length);
- INC(CurPtr, Length);
- INC(CurPos.Y, Lines);
- DrawLine := CurPos.Y;
- DrawPtr := LineStart(CurPtr);
- CurPos.X := CharPos(DrawPtr, CurPtr);
- IF NOT SelectText THEN SelStart := CurPtr;
- SelEnd := CurPtr;
- INC(BufLen, Length-SelLen);
- DEC(GapLen, Length-SelLen);
- IF AllowUndo THEN BEGIN
- INC(DelCount, DelLen);
- INC(InsCount, Length);
- END;
- INC(Limit.Y, Lines-SelLines);
- Delta.Y := Max(0, Min(Delta.Y, Limit.Y-Size.Y));
- IF NOT IsClipboard THEN Modified := TRUE;
- SetBufSize(BufLen+DelCount);
- IF (SelLines = 0) AND (Lines = 0) THEN
- Update(ufLine)
- ELSE
- Update(ufView);
- END;
-
- FUNCTION tEditor.InsertFrom
- (Editor : pEditor) : BOOLEAN;
- BEGIN
- InsertFrom :=
- InsertBuffer(Editor^.Buffer,
- Editor^.BufPtr(Editor^.SelStart),
- Editor^.SelEnd-Editor^.SelStart,
- CanUndo, IsClipboard);
- END;
-
- FUNCTION tEditor.InsertText(Text : Pointer;
- Length : WORD;
- SelectText : BOOLEAN) : BOOLEAN;
- BEGIN
- InsertText := InsertBuffer(pEditBuffer(Text),
- 0, Length, CanUndo,
- SelectText);
- END;
-
- FUNCTION tEditor.IsClipboard : BOOLEAN;
- BEGIN
- IsClipboard := Clipboard = @Self;
- END;
-
- FUNCTION tEditor.LineEnd(P : WORD) : WORD; ASSEMBLER;
- ASM
- PUSH DS
- LDS SI,Self
- LES BX,DS:[SI].tEditor.Buffer
- MOV DI,P
- MOV AL,0DH
- CLD
- MOV CX,DS:[SI].tEditor.CurPtr
- SUB CX,DI
- JBE @@1
- ADD DI,BX
- REPNE SCASB
- JE @@2
- MOV DI,DS:[SI].tEditor.CurPtr
- @@1:
- MOV CX,DS:[SI].tEditor.BufLen
- SUB CX,DI
- JCXZ @@4
- ADD BX,DS:[SI].tEditor.GapLen
- ADD DI,BX
- REPNE SCASB
- JNE @@3
- @@2:
- DEC DI
- @@3:
- SUB DI,BX
- @@4:
- MOV AX,DI
- POP DS
- END;
-
- FUNCTION tEditor.LineMove(P : WORD;
- Count : INTEGER) : WORD;
- VAR
- Pos : INTEGER;
- I : WORD;
- BEGIN
- I := P;
- P := LineStart(P);
- Pos := CharPos(P, I);
- WHILE Count <> 0 DO BEGIN
- I := P;
- IF Count < 0 THEN BEGIN
- P := PrevLine(P);
- INC(Count);
- END ELSE BEGIN
- P := NextLine(P);
- DEC(Count);
- END;
- END;
- IF P <> I THEN P := CharPtr(P, Pos);
- LineMove := P;
- END;
-
- FUNCTION tEditor.LineStart(P : WORD) : WORD;
- ASSEMBLER;
- ASM
- PUSH DS
- LDS SI,Self
- LES BX,DS:[SI].tEditor.Buffer
- MOV DI,P
- MOV AL,0DH
- STD
- MOV CX,DI
- SUB CX,DS:[SI].tEditor.CurPtr
- JBE @@1
- ADD BX,DS:[SI].tEditor.GapLen
- ADD DI,BX
- DEC DI
- REPNE SCASB
- JE @@2
- SUB BX,DS:[SI].tEditor.GapLen
- MOV DI,DS:[SI].tEditor.CurPtr
- @@1:
- MOV CX,DI
- JCXZ @@4
- ADD DI,BX
- DEC DI
- REPNE SCASB
- JNE @@3
- @@2:
- INC DI
- INC DI
- SUB DI,BX
- CMP DI,DS:[SI].tEditor.CurPtr
- JE @@4
- CMP DI,DS:[SI].tEditor.BufLen
- JE @@4
- CMP ES:[BX+DI].BYTE,0AH
- JNE @@4
- INC DI
- JMP @@4
- @@3:
- XOR DI,DI
- @@4:
- MOV AX,DI
- POP DS
- END;
-
- PROCEDURE tEditor.Lock;
- BEGIN
- INC(LockCount);
- END;
-
- PROCEDURE tEditor.NewLine;
- CONST
- CrLf : ARRAY [1..2] OF CHAR = #13#10;
- VAR
- I, P : WORD;
- BEGIN
- P := LineStart(CurPtr);
- I := P;
- WHILE (I < CurPtr) AND
- ((Buffer^[I] = ' ') OR (Buffer^[I] = #9)) DO
- INC(I);
- InsertText(@CrLf, 2, FALSE);
- IF AutoIndent THEN
- InsertText(@Buffer^[P], I-P, FALSE);
- END;
-
- FUNCTION tEditor.NextChar(P : WORD) : WORD;
- ASSEMBLER;
- ASM
- PUSH DS
- LDS SI,Self
- MOV DI,P
- CMP DI,DS:[SI].tEditor.BufLen
- JE @@2
- INC DI
- CMP DI,DS:[SI].tEditor.BufLen
- JE @@2
- LES BX,DS:[SI].tEditor.Buffer
- CMP DI,DS:[SI].tEditor.CurPtr
- JB @@1
- ADD BX,DS:[SI].tEditor.GapLen
- @@1:
- CMP ES:[BX+DI-1].WORD, 0A0Dh
- JNE @@2
- INC DI
- @@2:
- MOV AX,DI
- POP DS
- END;
-
- FUNCTION tEditor.NextLine(P : WORD) : WORD;
- BEGIN
- NextLine := NextChar(LineEnd(P));
- END;
-
- FUNCTION tEditor.NextWord(P : WORD) : WORD;
- BEGIN
- WHILE (P < BufLen) AND (BufChar(P) IN WordChars) DO
- P := NextChar(P);
- WHILE (P < BufLen) AND
- NOT (BufChar(P) IN WordChars) DO
- P := NextChar(P);
- NextWord := P;
- END;
-
- FUNCTION tEditor.PrevChar(P : WORD) : WORD;
- ASSEMBLER;
- ASM
- PUSH DS
- LDS SI,Self
- MOV DI,P
- OR DI,DI
- JE @@2
- DEC DI
- JE @@2
- LES BX,DS:[SI].tEditor.Buffer
- CMP DI,DS:[SI].tEditor.CurPtr
- JB @@1
- ADD BX,DS:[SI].tEditor.GapLen
- @@1:
- CMP ES:[BX+DI-1].WORD, 0A0Dh
- JNE @@2
- DEC DI
- @@2:
- MOV AX,DI
- POP DS
- END;
-
- FUNCTION tEditor.PrevLine(P : WORD) : WORD;
- BEGIN
- PrevLine := LineStart(PrevChar(P));
- END;
-
- FUNCTION tEditor.PrevWord(P : WORD) : WORD;
- BEGIN
- WHILE (P > 0) AND
- NOT (BufChar(PrevChar(P)) IN WordChars) DO
- P := PrevChar(P);
- WHILE (P > 0) AND
- (BufChar(PrevChar(P)) IN WordChars) DO
- P := PrevChar(P);
- PrevWord := P;
- END;
-
- PROCEDURE tEditor.Replace;
- VAR
- ReplaceRec : tReplaceDialogRec;
- BEGIN
- WITH ReplaceRec DO BEGIN
- Find := FindStr;
- Replace := ReplaceStr;
- Options := EditorFlags;
- IF EditorDialog(edReplace, @ReplaceRec) <>
- cmCancel THEN BEGIN
- FindStr := Find;
- ReplaceStr := Replace;
- EditorFlags := Options OR efDoReplace;
- DoSearchReplace;
- END;
- END;
- END;
-
- PROCEDURE tEditor.ScrollTo(X, Y : INTEGER);
- BEGIN
- X := Max(0, Min(X, Limit.X-Size.X));
- Y := Max(0, Min(Y, Limit.Y-Size.Y));
- IF (X <> Delta.X) OR (Y <> Delta.Y) THEN BEGIN
- Delta.X := X;
- Delta.Y := Y;
- Update(ufView);
- END;
- END;
-
- FUNCTION tEditor.Search(FindStr : STRING;
- Opts : WORD) : BOOLEAN;
- VAR
- I, Pos : WORD;
- BEGIN
- Search := FALSE;
- Pos := CurPtr;
- REPEAT
- IF Opts AND efCaseSensitive <> 0 THEN
- I := Scan(Buffer^[BufPtr(Pos)],
- BufLen-Pos, FindStr)
- ELSE
- I := IScan(Buffer^[BufPtr(Pos)],
- BufLen-Pos, FindStr);
- IF (I <> sfSearchFailed) THEN BEGIN
- INC(I, Pos);
- IF (Opts AND efWholeWordsOnly = 0) OR
- NOT (((I <> 0) AND
- (BufChar(I-1) IN WordChars)) OR
- ((I+Length(FindStr) <> BufLen) AND
- (BufChar(I+Length(FindStr)) IN WordChars)))
- THEN BEGIN
- Lock;
- SetSelect(I, I+Length(FindStr), FALSE);
- TrackCursor(NOT CursorVisible);
- Unlock;
- Search := TRUE;
- Exit;
- END ELSE
- Pos := I+1;
- END;
- UNTIL I = sfSearchFailed;
- END;
-
- PROCEDURE tEditor.SetBufLen(Length : WORD);
- BEGIN
- BufLen := Length;
- GapLen := BufSize-Length;
- SelStart := 0;
- SelEnd := 0;
- CurPtr := 0;
- LongInt(CurPos) := 0;
- LongInt(Delta) := 0;
- Limit.X := MaxLineLength;
- Limit.Y := CountLines(Buffer^[GapLen],
- BufLen)+1;
- DrawLine := 0;
- DrawPtr := 0;
- DelCount := 0;
- InsCount := 0;
- Modified := FALSE;
- Update(ufView);
- END;
-
- FUNCTION tEditor.SetBufSize(NewSize : WORD): BOOLEAN;
- BEGIN
- SetBufSize := NewSize <= BufSize;
- END;
-
- PROCEDURE tEditor.SetCmdState(Command : WORD;
- Enable : BOOLEAN);
- VAR
- S : tCommandSet;
- BEGIN
- S := [Command];
- IF Enable AND (State AND sfActive <> 0) THEN
- EnableCommands(S)
- ELSE
- DisableCommands(S);
- END;
-
- PROCEDURE tEditor.SetCurPtr(P : WORD;
- SelectMode : BYTE);
- VAR
- Anchor : WORD;
- BEGIN
- IF SelectMode AND smExtend = 0 THEN
- Anchor := P
- ELSE IF CurPtr = SelStart THEN
- Anchor := SelEnd
- ELSE
- Anchor := SelStart;
- IF P < Anchor THEN BEGIN
- IF SelectMode AND smDouble <> 0 THEN BEGIN
- P := PrevLine(NextLine(P));
- Anchor := NextLine(PrevLine(Anchor));
- END;
- SetSelect(P, Anchor, TRUE);
- END ELSE BEGIN
- IF SelectMode AND smDouble <> 0 THEN BEGIN
- P := NextLine(P);
- Anchor := PrevLine(NextLine(Anchor));
- END;
- SetSelect(Anchor, P, FALSE);
- END;
- END;
-
- PROCEDURE tEditor.SetSelect(NewStart, NewEnd : WORD;
- CurStart : BOOLEAN);
- VAR
- Flags : BYTE;
- P, L : WORD;
- BEGIN
- IF CurStart THEN P := NewStart
- ELSE P := NewEnd;
- Flags := ufUpdate;
- IF (NewStart <> SelStart) OR
- (NewEnd <> SelEnd) THEN
- IF (NewStart <> NewEnd) OR
- (SelStart <> SelEnd) THEN
- Flags := ufView;
- IF P <> CurPtr THEN BEGIN
- IF P > CurPtr THEN BEGIN
- L := P-CurPtr;
- Move(Buffer^[CurPtr+GapLen],
- Buffer^[CurPtr], L);
- INC(CurPos.Y, CountLines(Buffer^[CurPtr], L));
- CurPtr := P;
- END ELSE BEGIN
- L := CurPtr-P;
- CurPtr := P;
- DEC(CurPos.Y, CountLines(Buffer^[CurPtr], L));
- Move(Buffer^[CurPtr],
- Buffer^[CurPtr+GapLen], L);
- END;
- DrawLine := CurPos.Y;
- DrawPtr := LineStart(P);
- CurPos.X := CharPos(DrawPtr, P);
- DelCount := 0;
- InsCount := 0;
- SetBufSize(BufLen);
- END;
- SelStart := NewStart;
- SelEnd := NewEnd;
- Update(Flags);
- END;
-
- PROCEDURE tEditor.SetState(aState : WORD;
- Enable : BOOLEAN);
- BEGIN
- tView.SetState(aState, Enable);
- CASE aState OF
- sfActive :
- BEGIN
- IF HScrollBar <> NIL THEN
- HScrollBar^.SetState(sfVisible,
- Enable);
- IF VScrollBar <> NIL THEN
- VScrollBar^.SetState(sfVisible,
- Enable);
- IF Indicator <> NIL THEN
- Indicator^.SetState(sfVisible,
- Enable);
- UpdateCommands;
- END;
- sfExposed :
- IF Enable THEN Unlock;
- END;
- END;
-
- PROCEDURE tEditor.StartSelect;
- BEGIN
- HideSelect;
- Selecting := TRUE;
- END;
-
- PROCEDURE tEditor.Store(VAR S : tStream);
- BEGIN
- tView.Store(S);
- PutPeerViewPtr(S, HScrollBar);
- PutPeerViewPtr(S, VScrollBar);
- PutPeerViewPtr(S, Indicator);
- S.Write(BufSize, SizeOf(WORD));
- S.Write(CanUndo, SizeOf(BOOLEAN));
- END;
-
- PROCEDURE tEditor.ToggleInsMode;
- BEGIN
- Overwrite := NOT Overwrite;
- SetState(sfCursorIns, NOT GetState(sfCursorIns));
- END;
-
- PROCEDURE tEditor.TrackCursor(Center : BOOLEAN);
- BEGIN
- IF Center THEN
- ScrollTo(CurPos.X-Size.X+1,
- CurPos.Y-Size.Y DIV 2)
- ELSE
- ScrollTo(Max(CurPos.X-Size.X+1, Min(Delta.X,
- CurPos.X)),
- Max(CurPos.Y-Size.Y+1, Min(Delta.Y,
- CurPos.Y)));
- END;
-
- PROCEDURE tEditor.Undo;
- VAR
- Length : WORD;
- BEGIN
- IF (DelCount <> 0) OR (InsCount <> 0) THEN BEGIN
- SelStart := CurPtr-InsCount;
- SelEnd := CurPtr;
- Length := DelCount;
- DelCount := 0;
- InsCount := 0;
- InsertBuffer(Buffer, CurPtr+GapLen-Length,
- Length, FALSE, TRUE);
- END;
- END;
-
- PROCEDURE tEditor.Unlock;
- BEGIN
- IF LockCount > 0 THEN BEGIN
- DEC(LockCount);
- IF LockCount = 0 THEN DoUpdate;
- END;
- END;
-
- PROCEDURE tEditor.Update(aFlags : BYTE);
- BEGIN
- UpdateFlags := UpdateFlags OR aFlags;
- IF LockCount = 0 THEN DoUpdate;
- END;
-
- PROCEDURE tEditor.UpdateCommands;
- BEGIN
- SetCmdState(cmUndo, (DelCount <> 0) OR
- (InsCount <> 0));
- IF NOT IsClipboard THEN BEGIN
- SetCmdState(cmCut, HasSelection);
- SetCmdState(cmCopy, HasSelection);
- SetCmdState(cmPaste, (Clipboard <> NIL) AND
- (Clipboard^.HasSelection));
- END;
- SetCmdState(cmClear, HasSelection);
- SetCmdState(cmFind, TRUE);
- SetCmdState(cmReplace, TRUE);
- SetCmdState(cmSearchAgain, TRUE);
- SetCmdState(cmGoto, TRUE);
- SetCmdState(cmGetWord, TRUE);
- END;
-
- FUNCTION tEditor.Valid(Command : WORD) : BOOLEAN;
- BEGIN
- Valid := IsValid;
- END;
-
- (* ------------------------------------------------- *)
- (* tFileEditor *)
-
- CONSTRUCTOR tFileEditor.Init(VAR Bounds : tRect;
- aHScrollBar,
- aVScrollBar : pScrollBar;
- aIndicator : pIndicator;
- aFileName : FNameStr);
- BEGIN
- tEditor.Init(Bounds, aHScrollBar, aVScrollBar,
- aIndicator, 0);
- IF aFileName <> '' THEN BEGIN
- FileName := FExpand(aFileName);
- IF IsValid THEN IsValid := LoadFile;
- END;
- END;
-
- CONSTRUCTOR tFileEditor.Load(VAR S : tStream);
- VAR
- SStart, SEnd, Curs : WORD;
- BEGIN
- tEditor.Load(S);
- S.Read(FileName[0], SizeOf(CHAR));
- S.Read(FileName[1], Length(FileName));
- IF IsValid THEN IsValid := LoadFile;
- S.Read(SStart, SizeOf(WORD));
- S.Read(SEnd, SizeOf(WORD));
- S.Read(Curs, SizeOf(WORD));
- IF IsValid AND(SEnd <= BufLen) THEN BEGIN
- SetSelect(SStart, SEnd, Curs = SStart);
- TrackCursor(TRUE);
- END;
- END;
-
- FUNCTION tFileEditor.ActFileName : FNameStr;
- BEGIN
- ActFileName := FileName;
- END;
-
- PROCEDURE tFileEditor.DoneBuffer;
- BEGIN
- IF Buffer <> NIL THEN DisposeBuffer(Buffer);
- END;
-
- PROCEDURE tFileEditor.HandleEvent(VAR Event: tEvent);
- BEGIN
- tEditor.HandleEvent(Event);
- CASE Event.What OF
- evCommand :
- CASE Event.Command OF
- cmSave : Save;
- cmSaveAs : SaveAs;
- ELSE
- Exit;
- END;
- ELSE
- Exit;
- END;
- ClearEvent(Event);
- END;
-
- PROCEDURE tFileEditor.InitBuffer;
- BEGIN
- NewBuffer(Pointer(Buffer));
- END;
-
- FUNCTION tFileEditor.LoadFile : BOOLEAN;
- VAR
- Length : WORD;
- FSize : LONGINT;
- F : FILE;
- BEGIN
- LoadFile := FALSE;
- Length := 0;
- Assign(F, FileName);
- Reset(F, 1);
- IF IoResult <> 0 THEN
- LoadFile := TRUE
- ELSE BEGIN
- FSize := FileSize(F);
- IF (FSize > $FFF0) OR
- NOT SetBufSize(WORD(FSize)) THEN
- EditorDialog(edOutOfMemory, NIL)
- ELSE BEGIN
- BlockRead(F,
- Buffer^[BufSize-WORD(FSize)], FSize);
- IF IoResult <> 0 THEN
- EditorDialog(edReadError, @FileName)
- ELSE BEGIN
- LoadFile := TRUE;
- Length := FSize;
- END;
- END;
- Close(F);
- END;
- SetBufLen(Length);
- END;
-
- FUNCTION tFileEditor.Save : BOOLEAN;
- BEGIN
- IF FileName = '' THEN Save := SaveAs
- ELSE Save := SaveFile;
- END;
-
- FUNCTION tFileEditor.SaveAs : BOOLEAN;
- BEGIN
- SaveAs := FALSE;
- IF EditorDialog(edSaveAs, @FileName) <>
- cmCancel THEN BEGIN
- FileName := FExpand(FileName);
- Message(Owner, evBroadcast, cmUpdateTitle, NIL);
- SaveAs := SaveFile;
- IF IsClipboard THEN FileName := '';
- END;
- END;
-
- FUNCTION tFileEditor.SaveFile : BOOLEAN;
- VAR
- f : FILE;
- BackupName : FNameStr;
- D : DirStr;
- N : NameStr;
- E : ExtStr;
- BEGIN
- SaveFile := FALSE;
- IF EditorFlags AND efBackupFiles <> 0 THEN BEGIN
- FSplit(FileName, D, N, E);
- BackupName := D + N + '.BAK';
- Assign(f, BackupName);
- Erase(f);
- Assign(f, FileName);
- Rename(f, BackupName);
- InOutRes := 0;
- END;
- Assign(f, FileName);
- Rewrite(f, 1);
- IF IoResult <> 0 THEN
- EditorDialog(edCreateError, @FileName)
- ELSE BEGIN
- BlockWrite(f, Buffer^, CurPtr);
- BlockWrite(f, Buffer^[CurPtr+GapLen],
- BufLen-CurPtr);
- IF IoResult <> 0 THEN
- EditorDialog(edWriteError, @FileName)
- ELSE BEGIN
- Modified := FALSE;
- Update(ufUpdate);
- SaveFile := TRUE;
- END;
- Close(f);
- END;
- END;
-
- FUNCTION tFileEditor.SetBufSize
- (NewSize : WORD) : BOOLEAN;
- VAR
- N : WORD;
- BEGIN
- SetBufSize := FALSE;
- IF NewSize > $F000 THEN
- NewSize := $FFF0
- ELSE
- NewSize := (NewSize+$0FFF) AND $F000;
- IF NewSize <> BufSize THEN BEGIN
- IF NewSize > BufSize THEN
- IF NOT SetBufferSize(Buffer,NewSize) THEN Exit;
- N := BufLen-CurPtr+DelCount;
- Move(Buffer^[BufSize-N], Buffer^[NewSize-N], N);
- IF NewSize < BufSize THEN
- SetBufferSize(Buffer, NewSize);
- BufSize := NewSize;
- GapLen := BufSize-BufLen;
- END;
- SetBufSize := TRUE;
- END;
-
- PROCEDURE tFileEditor.Store(VAR S : tStream);
- BEGIN
- tEditor.Store(S);
- S.Write(FileName, Length(FileName)+1);
- S.Write(SelStart, SizeOf(WORD)*3);
- END;
-
- PROCEDURE tFileEditor.UpdateCommands;
- BEGIN
- tEditor.UpdateCommands;
- SetCmdState(cmSave, TRUE);
- SetCmdState(cmSaveAs, TRUE);
- END;
-
- FUNCTION tFileEditor.Valid(Command : WORD) : BOOLEAN;
- VAR
- D : INTEGER;
- BEGIN
- IF Command = cmValid THEN
- Valid := IsValid
- ELSE BEGIN
- Valid := TRUE;
- IF Modified THEN BEGIN
- IF FileName = '' THEN
- D := edSaveUntitled
- ELSE
- D := edSaveModify;
- CASE EditorDialog(D, @FileName) OF
- cmYes : Valid := Save;
- cmNo : Modified := FALSE;
- cmCancel : Valid := FALSE;
- END;
- END;
- END;
- END;
-
- (* ------------------------------------------------- *)
- (* tEditWindow *)
-
- CONSTRUCTOR tEditWindow.Init(VAR Bounds : tRect;
- FileName : FNameStr;
- aNumber : INTEGER);
- VAR
- HScrollBar, VScrollBar : pScrollBar;
- Indicator : pIndicator;
- R : tRect;
- BEGIN
- tWindow.Init(Bounds, '', aNumber);
- Options := Options OR ofTileable;
-
- R.Assign(18, Size.Y-1, Size.X-2, Size.Y);
- HScrollBar := New(pScrollBar, Init(R));
- HScrollBar^.Hide;
- Insert(HScrollBar);
-
- R.Assign(Size.X-1, 1, Size.X, Size.Y-1);
- VScrollBar := New(pScrollBar, Init(R));
- VScrollBar^.Hide;
- Insert(VScrollBar);
-
- R.Assign(2, Size.Y-1, 16, Size.Y);
- Indicator := New(pIndicator, Init(R));
- Indicator^.Hide;
- Insert(Indicator);
-
- GetExtent(R);
- R.Grow(-1, -1);
- Editor := New(pFileEditor, Init(
- R, HScrollBar, VScrollBar,
- Indicator, FileName));
- Insert(Editor);
- END;
-
- CONSTRUCTOR tEditWindow.Load(VAR S : tStream);
- BEGIN
- tWindow.Load(S);
- GetSubViewPtr(S, Editor);
- END;
-
- PROCEDURE tEditWindow.Close;
- BEGIN
- IF Editor^.IsClipboard THEN Hide
- ELSE tWindow.Close;
- END;
-
- FUNCTION tEditWindow.GetTitle
- (MaxSize : INTEGER) : tTitleStr;
- BEGIN
- IF Editor^.IsClipboard THEN
- GetTitle := 'Clipboard'
- ELSE IF Editor^.FileName = '' THEN
- GetTitle := 'Untitled'
- ELSE
- GetTitle := Editor^.FileName;
- END;
-
- PROCEDURE tEditWindow.HandleEvent(VAR Event: tEvent);
- BEGIN
- tWindow.HandleEvent(Event);
- IF (Event.What = evBroadcast) AND
- (Event.Command = cmUpdateTitle) THEN BEGIN
- Frame^.DrawView;
- ClearEvent(Event);
- END;
- END;
-
- PROCEDURE tEditWindow.Store(VAR S : tStream);
- BEGIN
- tWindow.Store(S);
- PutSubViewPtr(S, Editor);
- END;
-
- PROCEDURE RegisterEditors;
- BEGIN
- RegisterType(rEditor);
- RegisterType(rFileEditor);
- RegisterType(rIndicator);
- RegisterType(rEditWindow);
- END;
-
- END.
- (* ------------------------------------------------- *)
- (* Ende von TXEDIT.PAS *)
-