source: 2.19_branch/Sibyl/SPCC/EDITORS.PAS@ 376

Last change on this file since 376 was 7, checked in by RBRi, 19 years ago

+ sibyl staff

  • Property svn:eol-style set to native
File size: 231.4 KB
Line 
1
2{ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
3 º º
4 º Sibyl Portable Component Classes º
5 º º
6 º Copyright (C) 1995,97 SpeedSoft Germany, All rights reserved. º
7 º º
8 ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ}
9
10Unit Editors;
11
12
13Interface
14
15{$IFDEF OS2}
16Uses PmWin;
17{$ENDIF}
18{$IFDEF Win95}
19Uses WinUser;
20{$ENDIF}
21
22Uses Dos,SysUtils,Classes,Forms,StdCtrls,Dialogs;
23
24
25Const
26 NormalChars : Set Of Char = ['0'..'9','A'..'Z','a'..'z','_',
27 '„','Ž','”','™','','š','á'];
28 StringLength = 255;
29
30 ciNormal = 0;
31 ciBookMark0 = 1;
32 ciBookMarkMask = 1 + 2 + 4 + 8;
33 ciSelected = 16;
34
35 {codes For TColorArray}
36 fgcPlainText = 0;
37 bgcPlainText = 1;
38 fgcMarkedBlock = 2;
39 bgcMarkedBlock = 3;
40 fgcSearchMatch = 4;
41 bgcSearchMatch = 5;
42 fgcRightMargin = 6;
43
44 kbPreCtrlK = kb_Ctrl + 8192;
45 kbPreCtrlQ = kb_Ctrl + 16384;
46 kbPreCtrlO = kb_Ctrl + 32768;
47 kbPreCtrlU = kb_Ctrl + 65536;
48
49 {Ctrl-K codes}
50 kbCtrlKA = kbPreCtrlK + kb_Char + kbA;
51 kbCtrlKB = kbPreCtrlK + kb_Char + kbB;
52 kbCtrlKC = kbPreCtrlK + kb_Char + kbC;
53 kbCtrlKD = kbPreCtrlK + kb_Char + kbD;
54 kbCtrlKE = kbPreCtrlK + kb_Char + kbE;
55 kbCtrlKF = kbPreCtrlK + kb_Char + kbF;
56 kbCtrlKG = kbPreCtrlK + kb_Char + kbG;
57 kbCtrlKH = kbPreCtrlK + kb_Char + kbH;
58 kbCtrlKI = kbPreCtrlK + kb_Char + kbI;
59 kbCtrlKJ = kbPreCtrlK + kb_Char + kbJ;
60 kbCtrlKK = kbPreCtrlK + kb_Char + kbK;
61 kbCtrlKL = kbPreCtrlK + kb_Char + kbL;
62 kbCtrlKM = kbPreCtrlK + kb_Char + kbM;
63 kbCtrlKN = kbPreCtrlK + kb_Char + kbN;
64 kbCtrlKO = kbPreCtrlK + kb_Char + kbO;
65 kbCtrlKP = kbPreCtrlK + kb_Char + kbP;
66 kbCtrlKQ = kbPreCtrlK + kb_Char + kbQ;
67 kbCtrlKR = kbPreCtrlK + kb_Char + kbR;
68 kbCtrlKS = kbPreCtrlK + kb_Char + kbS;
69 kbCtrlKT = kbPreCtrlK + kb_Char + kbT;
70 kbCtrlKU = kbPreCtrlK + kb_Char + kbU;
71 kbCtrlKV = kbPreCtrlK + kb_Char + kbV;
72 kbCtrlKW = kbPreCtrlK + kb_Char + kbW;
73 kbCtrlKX = kbPreCtrlK + kb_Char + kbX;
74 kbCtrlKY = kbPreCtrlK + kb_Char + kbY;
75 kbCtrlKZ = kbPreCtrlK + kb_Char + kbZ;
76
77 {Ctrl-Q codes}
78 kbCtrlQA = kbPreCtrlQ + kb_Char + kbA;
79 kbCtrlQB = kbPreCtrlQ + kb_Char + kbB;
80 kbCtrlQC = kbPreCtrlQ + kb_Char + kbC;
81 kbCtrlQD = kbPreCtrlQ + kb_Char + kbD;
82 kbCtrlQE = kbPreCtrlQ + kb_Char + kbE;
83 kbCtrlQF = kbPreCtrlQ + kb_Char + kbF;
84 kbCtrlQG = kbPreCtrlQ + kb_Char + kbG;
85 kbCtrlQH = kbPreCtrlQ + kb_Char + kbH;
86 kbCtrlQI = kbPreCtrlQ + kb_Char + kbI;
87 kbCtrlQJ = kbPreCtrlQ + kb_Char + kbJ;
88 kbCtrlQK = kbPreCtrlQ + kb_Char + kbK;
89 kbCtrlQL = kbPreCtrlQ + kb_Char + kbL;
90 kbCtrlQM = kbPreCtrlQ + kb_Char + kbM;
91 kbCtrlQN = kbPreCtrlQ + kb_Char + kbN;
92 kbCtrlQO = kbPreCtrlQ + kb_Char + kbO;
93 kbCtrlQP = kbPreCtrlQ + kb_Char + kbP;
94 kbCtrlQQ = kbPreCtrlQ + kb_Char + kbQ;
95 kbCtrlQR = kbPreCtrlQ + kb_Char + kbR;
96 kbCtrlQS = kbPreCtrlQ + kb_Char + kbS;
97 kbCtrlQT = kbPreCtrlQ + kb_Char + kbT;
98 kbCtrlQU = kbPreCtrlQ + kb_Char + kbU;
99 kbCtrlQV = kbPreCtrlQ + kb_Char + kbV;
100 kbCtrlQW = kbPreCtrlQ + kb_Char + kbW;
101 kbCtrlQX = kbPreCtrlQ + kb_Char + kbX;
102 kbCtrlQY = kbPreCtrlQ + kb_Char + kbY;
103 kbCtrlQZ = kbPreCtrlQ + kb_Char + kbZ;
104
105 kbCtrlShiftP = kb_Ctrl + kb_Shift + kb_Char + 80;
106 kbCtrlShiftR = kb_Ctrl + kb_Shift + kb_Char + 82;
107 kbCtrlShiftS = kb_Ctrl + kb_Shift + kb_Char + 83;
108 kbCtrlShiftI = kb_Ctrl + kb_Shift + kb_Char + 73;
109 kbCtrlShiftU = kb_Ctrl + kb_Shift + kb_Char + 85;
110 kbCtrlShiftY = kb_Ctrl + kb_Shift + kb_Char + 89;
111 kbCtrlShiftZ = kb_Ctrl + kb_Shift + kb_Char + 90;
112 kbCtrlSlash = kb_Ctrl + kb_Shift + kb_Char + 47;
113 kbCtrlBackSlash = kb_Ctrl + kb_Shift + kb_Char + 92;
114
115 kbCtrlShiftCLeft = kb_Ctrl + kb_Shift + kbCLeft;
116 kbCtrlShiftCRight = kb_Ctrl + kb_Shift + kbCRight;
117 kbCtrlShiftHome = kb_Ctrl + kb_Shift + kbHome;
118 kbCtrlShiftEnd = kb_Ctrl + kb_Shift + kbEnd;
119 kbCtrlShiftPageUp = kb_Ctrl + kb_Shift + kbPageUp;
120 kbCtrlShiftPageDown = kb_Ctrl + kb_Shift + kbPageDown;
121
122 kbCtrlAltShiftCLeft = kb_Ctrl + kb_Alt + kb_Shift + kbCLeft;
123 kbCtrlAltShiftCRight= kb_Ctrl + kb_Alt + kb_Shift + kbCRight;
124 kbCtrlAltShiftHome = kb_Ctrl + kb_Alt + kb_Shift + kbHome;
125 kbCtrlAltShiftEnd = kb_Ctrl + kb_Alt + kb_Shift + kbEnd;
126 kbCtrlAltShiftPageUp= kb_Ctrl + kb_Alt + kb_Shift + kbPageUp;
127 kbCtrlAltShiftPageDown = kb_Ctrl + kb_Alt + kb_Shift + kbPageDown;
128
129 kbAltShiftBkSp = kb_Alt + kb_Shift + kbBkSp;
130 kbAltShiftCLeft = kb_Alt + kb_Shift + kbCLeft;
131 kbAltShiftCRight = kb_Alt + kb_Shift + kbCRight;
132 kbAltShiftCUp = kb_Alt + kb_Shift + kbCUp;
133 kbAltShiftCDown = kb_Alt + kb_Shift + kbCDown;
134 kbAltShiftPageUp = kb_Alt + kb_Shift + kbPageUp;
135 kbAltShiftPageDown = kb_Alt + kb_Shift + kbPageDown;
136 kbAltShiftHome = kb_Alt + kb_Shift + kbHome;
137 kbAltShiftEnd = kb_Alt + kb_Shift + kbEnd;
138
139 kbCtrlOC = kbPreCtrlO + kb_Char + kbC;
140 kbCtrlOK = kbPreCtrlO + kb_Char + kbK;
141 kbCtrlOU = kbPreCtrlO + kb_Char + kbU;
142 kbCtrlK0 = kbPreCtrlK + kb_Char + kb0;
143 kbCtrlK9 = kbPreCtrlK + kb_Char + kb9;
144 kbCtrlQ0 = kbPreCtrlQ + kb_Char + kb0;
145 kbCtrlQ9 = kbPreCtrlQ + kb_Char + kb9;
146 kbCtrlU0 = kbPreCtrlU + kb_Char + kb0;
147 kbCtrlU9 = kbPreCtrlU + kb_Char + kb9;
148 kbCtrlUU = kbPreCtrlU + kb_Char + kbU;
149
150
151Type
152 PLine=^TLine;
153 TLine=Record
154 Prev: PLine;
155 zk: PString;
156 flag: LongWord;
157 Add: LongWord;
158 Next: PLine;
159 End;
160
161 TColorTable=Array[0..255] Of TColor;
162
163 TColorIndex=Record
164 Fgc: Byte;
165 Bgc: Byte;
166 End;
167
168 TColorArray=Array[1..StringLength] Of TColorIndex;
169
170 TEditorPos=Record
171 Y: LongInt;
172 X: Integer;
173 End;
174
175 TLineX=Record
176 Line: PLine;
177 X: Integer;
178 End;
179
180 TICB=Record {internal Clipboard}
181 First: TLineX;
182 Last: TLineX;
183 End;
184
185 TUndoGroup=(ugNoGroup,ugGroup,ugCursorMove,
186 ugInsertChar,ugOverwriteChar,ugDeleteChar,ugBackspaceChar,
187 ugDeleteActLine,ugDeleteRightWord,ugBlockLeft,ugBlockRight,
188 ugBreakLine,ugEnter,ugTabulator,
189 ugInsertLine,ugDeleteLine,ugReplaceLine);
190
191 PUndo=^TUndo;
192 TUndo=Record
193 Memory: Boolean;
194 EventType: TUndoGroup;
195 Modified: Boolean;
196 ICBFL: LongInt;
197 ICBFX: Integer;
198 ICBLL: LongInt;
199 ICBLX: Integer;
200 FFileCursor: TEditorPos;
201 FrameBegin: LongInt;
202 FrameEnd: LongInt;
203 FirstUndoLine: PLine;
204 LastUndoLine: PLine;
205 Lines: LongInt;
206 End;
207
208{$M+}
209 TEditOpt=Set Of (eoCreateBackups,eoAppendBAK,eoAutoIndent,
210 eoUnindent,eoUndoGroups,eoCursorClimb,
211 eoPersistentBlocks,eoOverwriteBlock,
212 eoAutoSave,eo2ClickLine,eoSmartTabs,eoHomeFirstWord);
213
214 TKeystrokeMap=(kmWordStar,kmCUA,kmDefault);
215{$M-}
216
217 TCursorShape=(csUnderline,csVertical);
218
219 TSelectMode=(smNonInclusiveBlock,smColumnBlock);
220
221 TICBPosition=Set Of (ipBeforeICBFirst,ipAfterICBFirst,ipWithinICB,
222 ipBeforeICBLast,ipAfterICBLast);
223
224 TFindAction=(faNothing,faFind,faReplace,faIncSearch);
225
226 TFindReplace=Record
227 Find: String;
228 replace: String;
229 Direction: TFindDirection;
230 Origin: TFindOrigin;
231 Scope: TFindScope;
232 Options: TFindOptions;
233 Confirm: Boolean;
234 replall: Boolean;
235 End;
236
237
238 TEditor=Class(TForm)
239 Private
240 FCaret: TCaret;
241 FOldCaption: String;
242 FKeyMap: TKeystrokeMap;
243 FInsertMode: Boolean;
244 FReadOnly: Boolean;
245 FModified: Boolean;
246 FUntitled: Boolean;
247 FEditOpt: TEditOpt;
248 FTabSize: Integer;
249 FCountLines: LongInt;
250 FBottomScrollBar: TScrollBar;
251 FRightScrollBar: TScrollBar;
252 ClientArea: TRect;
253 IgnoreRedraw: Integer;
254 FWinSize: TPoint;
255 FFileCursor: TEditorPos;
256 FScrCursor: TEditorPos;
257 FFirstLine: PLine;
258 FLastLine: PLine;
259 FActLine: PLine;
260 FTopScreenLine: PLine;
261 WLactivated: Boolean;
262 FWorkLine: String;
263 ICB: TICB;
264 ICBVisible: Boolean;
265 MaxUndo: LongInt;
266 KeyRepeat: Integer;
267 FPreCtrl: TKeyCode;
268 BookMarkX: Array[1..10] Of Integer;
269 HadFocus: Integer;
270 IncSearchList: TList;
271 IncSearchText: String;
272 FindICB: TICB;
273 fMask: String;
274 FSelColor: TColor;
275 FSelBackColor: TColor;
276 FFoundColor: TColor;
277 FFoundBackColor: TColor;
278 FWrapLineColor: TColor;
279 FSaveEvents: Integer;
280 FEventsCounter: Integer;
281 WrapLineX: Integer;
282 ScrOffsX: Integer;
283 FFileName: String;
284 FMacroList: TList;
285 FRecording: Boolean;
286 FPlaying: Boolean;
287 FCursorShape: TCursorShape;
288 FSelectMode: TSelectMode;
289 FWordWrap: Boolean;
290 FWordWrapColumn: Integer;
291 FFindReplace: TFindReplace;
292 FLastFind: TFindAction;
293 FBorderWidth: LongInt;
294 FCtl3D: Boolean;
295 FUndoList: TList;
296 FRedoList: TList;
297 FTempFileName: String;
298 FDragRect: TRect;
299 IsDBCSFont: Boolean;
300 Procedure CalcSizes;
301 Procedure SetFont(NewFont:TFont);Override;
302 Procedure SetCtl3D(Value:Boolean);
303 Procedure SetKeyMap(km:TKeystrokeMap);
304 Procedure SetInsertMode(im:Boolean);
305 Procedure ToggleInsertMode;
306 Procedure SetEditOpt(eo:TEditOpt);
307 Procedure SetTabSize(ts:Integer);
308 Procedure SetSaveEvents(cnt:Integer);
309 Procedure SetLastUndoGroup(ug:TUndoGroup);
310 Function GetLastUndoGroup:TUndoGroup;
311 Procedure SetCursorShape(CS:TCursorShape);
312 Procedure SetSelectMode(sm:TSelectMode);
313 Procedure SetWordWrap(Wrap:Boolean);
314 Procedure SetWordWrapColumn(Column:Integer);
315 Function GetUndoCount:LongInt;
316 Function GetRedoCount:LongInt;
317 {basic structure}
318 Function _Index2PLine(Y:LongInt):PLine;
319 Function _PLine2Index(pl:PLine):LongInt;
320 Function _PLine2PString(pl:PLine):PString;
321 Function _Connect(pl1,pl2:PLine):Boolean;
322 Function _CountLines(pl1,pl2:PLine):LongInt;
323 {Undo/Redo}
324 Function _CountUndoLines(FirstL,LastL:PLine):LongInt;
325 Procedure _StoreUndoCursor(List:TList);
326 Function _CopyUndoLines(FirstL,LastL:PLine):LongInt;
327 Function _MoveUndoLines(List:TList;FirstL,LastL:PLine):LongInt;
328 Procedure _CreateUndoEvent(List:TList;U:PUndo);
329 Procedure _UpdateLastUndoEvent(List:TList;Index:LongInt);
330 Procedure _FreeUndoEvent(List:TObject;Item:Pointer);
331 Procedure _SetMaxUndo(cnt:LongInt);
332 {WorkLine Manipulation}
333 Procedure _ReadWorkLine;
334 Procedure _WriteWorkLine;
335 Function _WriteString(X:Integer; S:String):Boolean;
336 Function _InsertString(X:Integer; S:String):Boolean;
337 Function _DeleteString(X,CX:Integer):Boolean;
338 Function _ReadString(pl:PLine; X,CX:Integer):String;
339 Procedure _Set(Y:LongInt;Const S:String);
340 Function _Get(Y:LongInt):String;
341 Function _FindBookMark(I:Byte):PLine;
342 Function _FindNextTab(pl:PLine; X:Integer):Integer;
343 {Insert/Delete Lines}
344 Function _InsertLine(pl:PLine):PLine;
345 Function _DeleteLine(pl:PLine):PLine;
346 {Text block operations}
347 Function _GetFileText(S:String; Var P:Pointer; Var len:LongInt):Boolean;
348 Function _GetEditorText(Var P:Pointer; Var len:LongInt):Boolean;
349 Function _GetEditorBlock(Var P:Pointer; Var len:LongInt):Boolean;
350 Function _InsertText(P:Pointer; len:LongInt; marknew:Boolean):TLineX;
351 {Caret Movement}
352 Function _HorizMove:Boolean;
353 Function _GotoPosition(P:TEditorPos):Boolean;
354 Function _CursorDown:Boolean;
355 Function _CursorUp:Boolean;
356 Function _CursorRight:Boolean;
357 Function _CursorLeft:Boolean;
358 Function _CursorHome:Boolean;
359 Function _CursorEnd:Boolean;
360 Function _CursorPageDown:Boolean;
361 Function _CursorPageUp:Boolean;
362 Function _CursorRollUp:Boolean;
363 Function _CursorRollDown:Boolean;
364 Function _CursorWordRight:Boolean;
365 Function _CursorWordLeft:Boolean;
366 {Selection}
367 Function _ICBExist:Boolean;
368 Function _ICBPersistent:Boolean;
369 Function _ICBOverwrite:Boolean;
370 Function _ICBClearICB:Boolean;
371 Function _ICBClearMark:Boolean;
372 Function _ICBSetMark:Boolean;
373 Function _ICBDeleteICB:Boolean;
374 Procedure _ICBCheckX;
375 Procedure _ICBSetBegin(pl:PLine; X:Integer);
376 Procedure _ICBSetEnd(pl:PLine; X:Integer);
377 Function _ICBPos(pl:PLine; X:Integer):TICBPosition;
378 {Extend Selection}
379 Function _ICBActPos:TLineX;
380 Function _ICBExtSetICB:Boolean;
381 Function _ICBExtCorrectICB:Boolean;
382 Function _ICBExtCorrectICB2:Boolean;
383 Function _ICBTestIEW(Var y1,y2:Integer):Boolean;
384 {Clipboard}
385 Function _SetClipBoardText(P:Pointer; len:LongInt):Boolean;
386 Function _GetClipBoardText(Var P:Pointer; Var len:LongInt):Boolean;
387 Protected
388 IndentRect: TRect;
389 Procedure SetupComponent;Override;
390 Procedure SetupShow;Override;
391 Function CloseQuery:Boolean;Override;
392 Procedure CharEvent(Var key:Char;RepeatCount:Byte);Override;
393 Procedure ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);Override;
394 Procedure SetFocus;Override;
395 Procedure KillFocus;Override;
396 Procedure Resize;Override;
397 Procedure MouseDown(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
398 Procedure MouseUp(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
399 Procedure MouseMove(ShiftState:TShiftState;X,Y:LongInt);Override;
400 Procedure MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);Override;
401 Procedure Scroll(Sender:TScrollBar;ScrollCode:TScrollCode;Var ScrollPos:LongInt);Override;
402 Procedure CanDrag(X,Y:LongInt;Var Accept:Boolean);Override;
403 Procedure DoStartDrag(Var DragData:TDragDropData);Override;
404 Procedure DoEndDrag(target:TObject; X,Y:LongInt);Override;
405 Procedure DragOver(Source:TObject;X,Y:LongInt;State:TDragState;Var Accept:Boolean);Override;
406 Procedure SetSliderValues;
407 Procedure SetSliderPosition;
408 Procedure FlushWorkLine;
409 Function GetCursorFromMouse(pt:TPoint):TEditorPos;
410 Function GetMouseFromCursor(Pos:TEditorPos):TPoint;
411 {Caret Movement}
412 Procedure cmCursorDown;
413 Procedure cmCursorUp;
414 Procedure cmCursorRight;
415 Procedure cmCursorLeft;
416 Procedure cmCursorHome;
417 Procedure cmCursorEnd;
418 Procedure cmCursorPageDown;
419 Procedure cmCursorPageUp;
420 Procedure cmCursorRollUp;
421 Procedure cmCursorRollDown;
422 Procedure cmCursorWordRight;
423 Procedure cmCursorWordLeft;
424 Procedure cmCursorFileBegin;
425 Procedure cmCursorFileEnd;
426 Procedure cmCursorPageHome;
427 Procedure cmCursorPageEnd;
428 {Selection}
429 Procedure cmICBExtLeft;
430 Procedure cmICBExtRight;
431 Procedure cmICBExtUp;
432 Procedure cmICBExtDown;
433 Procedure cmICBExtPageUp;
434 Procedure cmICBExtPageDown;
435 Procedure cmICBExtHome;
436 Procedure cmICBExtEnd;
437 Procedure cmICBExtWordLeft;
438 Procedure cmICBExtWordRight;
439 Procedure cmICBExtFileBegin;
440 Procedure cmICBExtFileEnd;
441 Procedure cmICBExtPageBegin;
442 Procedure cmICBExtPageEnd;
443 {ICB edit}
444 Procedure cmICBReadBlock;Virtual;
445 Procedure cmICBWriteBlock;Virtual;
446 Procedure cmICBMoveLeft;Virtual;
447 Procedure cmICBMoveRight;Virtual;
448 Procedure cmICBCopyBlock;Virtual;
449 Procedure cmICBMoveBlock;Virtual;
450 Procedure cmICBDeleteBlock;Virtual;
451 Procedure cmICBUpcaseBlock;Virtual;
452 Procedure cmICBLowcaseBlock;Virtual;
453 Procedure cmICBUpcaseWord;Virtual;
454 Procedure cmICBLowcaseWord;Virtual;
455 Procedure cmToggleCase;Virtual;
456 {edit}
457 Procedure cmBreakLine;Virtual;
458 Procedure cmDeleteLine;Virtual;
459 Procedure cmDeleteLineEnd;Virtual;
460 Procedure cmDeleteRightWord;Virtual;
461 Procedure cmDeleteLeftWord;Virtual;
462 Procedure cmTabulator;Virtual;
463 Procedure cmPrevTabulator;Virtual;
464 Procedure cmDeleteChar;Virtual;
465 Procedure cmBackSpace;Virtual;
466 Procedure cmEnter;Virtual;
467 Procedure cmFindText;Virtual;
468 Procedure cmReplaceText;Virtual;
469 Procedure cmSearchTextAgain;Virtual;
470 Procedure cmIncrementalSearch;Virtual;
471 Procedure cmRecordMacro;Virtual;
472 Procedure cmPlayMacro;Virtual;
473 {overwrite This Methods For personal Use}
474 Function GetReadOnly:Boolean;Virtual;
475 Procedure SetReadOnly(Value:Boolean);Virtual;
476 Procedure SetModified(Value:Boolean);Virtual;
477 Procedure UpdateEditorState;Virtual;
478 Procedure SetStateMessage(Const S:String);Virtual;
479 Procedure SetErrorMessage(Const S:String);Virtual;
480 Function SetQueryMessage(Const S:String;Typ:TMsgDlgType;Buttons:TMsgDlgButtons):TMsgDlgReturn;Virtual;
481 Function SetReplaceConfirmMessage:TMsgDlgReturn;Virtual;
482 Function UpdateLineColorFlag(pl:PLine):Boolean;Virtual;
483 Procedure SetLineColorFlag(pl1,pl2:PLine);Virtual;
484 Procedure CalcLineColor(pl:PLine;Var LineColor:TColorArray);Virtual;
485 Procedure InvalidateScreenLine(ScrY:Integer);Virtual;
486 Procedure InvalidateWorkLine;Virtual;
487 Procedure InvalidateEditor(y1,y2:Integer);Virtual;
488 Procedure SetScreenCursor;Virtual;
489 Function QueryConvertPos(Var Pos:TPoint):Boolean;Override;
490 Procedure SetIncSearchText(S:String);Virtual;
491 Function TestSaveAsName(Const FName:String):TMsgDlgReturn;Virtual;
492 Procedure FileNameChange(Const OldName,NewName:String);Virtual;
493 Procedure TestAutoSave;Virtual;
494 Procedure SetFileName(Const FName:String);Virtual;
495 Procedure SetAvailabeFileTypes(CFOD:TOpenDialog);Virtual;
496 Function EmulateWordStar(Var KeyCode,PreControl:TKeyCode):Boolean;Virtual;
497 Function EmulateCUA(Var KeyCode,PreControl:TKeyCode):Boolean;Virtual;
498 Function EmulateDefault(Var KeyCode,PreControl:TKeyCode):Boolean;Virtual;
499 Procedure SetColorEntry(ColorIndex:Integer;NewColor:TColor);Virtual;
500 Function GetColorEntry(ColorIndex:Integer):TColor;Virtual;
501 Property FirstLine:PLine Read FFirstLine;
502 Property LastLine:PLine Read FLastLine;
503 Property ActLine:PLine Read FActLine;
504 Property TopScreenLine:PLine Read FTopScreenLine;
505 Property indices[pl:PLine]:LongInt Read _PLine2Index;
506 Property PLines[Index:LongInt]:PLine Read _Index2PLine;
507 Property PStrings[pl:PLine]:PString Read _PLine2PString;
508 Property LastUndoGroup:TUndoGroup Read GetLastUndoGroup Write SetLastUndoGroup;
509 Property MacroList:TList Read FMacroList Write FMacroList;
510 Property MacroRecording:Boolean Read FRecording;
511 Property MacroPlaying:Boolean Read FPlaying;
512 Property LastFind:TFindAction Read FLastFind Write FLastFind;
513 Public
514 Destructor Destroy;Override;
515 Procedure BeginUpdate;
516 Procedure EndUpdate;
517 Procedure DragDrop(Source:TObject;X,Y:LongInt);Override;
518 Procedure Redraw(Const rc:TRect);Override;
519 Function LoadFromFile(Const FName:String):Boolean;Virtual;
520 Function SaveToFile(Const FName:String):Boolean;Virtual;
521 Function LoadFromStream(Stream:TStream):Boolean;
522 Function SaveToStream(Stream:TStream):Boolean;
523 Function SaveFile:Boolean;Virtual;
524 Function SaveFileAs(Const FName:String):Boolean;Virtual;
525 Function InsertLine(Y:LongInt;Const S:String):LongInt;
526 Function DeleteLine(Y:LongInt):LongInt;
527 Function AppendLine(Const S:String):LongInt;
528 Function ReplaceLine(Y:LongInt;Const S:String):LongInt;
529 Procedure SetSelectionStart(P:TEditorPos);
530 Procedure SetSelectionEnd(P:TEditorPos);
531 Function GetSelectionStart(Var P:TEditorPos):Boolean;
532 Function GetSelectionEnd(Var P:TEditorPos):Boolean;
533 Procedure SelectLine(P:TEditorPos);
534 Procedure SelectWord(P:TEditorPos);
535 Procedure SelectAll;
536 Procedure DeselectAll;
537 Procedure HideSelection;
538 Procedure ShowSelection;
539 Procedure DeleteSelection;
540 Procedure GotoPosition(Pos:TEditorPos);
541 Function SetBookMark(I:Byte; P:TEditorPos):Boolean;
542 Function GetBookMark(I:Byte;Var P:TEditorPos):Boolean;
543 Function GotoBookMark(I:Byte):Boolean;
544 Function ClearBookMark(I:Byte):Boolean;
545 Function ClearAllBookMarks:Boolean;
546 Function GetChar(P:TEditorPos):Char;
547 Function GetWord(P:TEditorPos):String;
548 Function GetTextAfterWord(P:TEditorPos):String;
549 Function GetPartialText(p1,p2:TEditorPos;Var P:Pointer; Var len:LongInt):Boolean;
550 Function GetText(Var P:Pointer; Var len:LongInt; Selected:Boolean):Boolean;
551 Procedure InsertText(P:Pointer; len:LongInt);
552 Function FindTextPos(Find:String; direct:TFindDirection; Origin:TFindOrigin;
553 Scope:TFindScope; opt:TFindOptions; Var pt:TEditorPos):Boolean;
554 Function FindText(Const Find:String; direct:TFindDirection; Origin:TFindOrigin;
555 Scope:TFindScope; opt:TFindOptions):Boolean;
556 Function ReplaceText(Const Find,replace:String; direct:TFindDirection;
557 Origin:TFindOrigin;Scope:TFindScope;opt:TFindOptions;
558 Confirm:Boolean;replaceall:Boolean):Boolean;
559 Procedure Undo;
560 Procedure Redo;
561 Procedure ClearUndo;
562 Procedure ClearRedo;
563 Procedure CutToClipBoard;Virtual;
564 Procedure CopyToClipboard;Virtual;
565 Function PasteFromClipBoard:Boolean;Virtual;
566 Function InsertFromFile(Const FName:String):Boolean;Virtual;
567 Procedure SearchTextAgain;
568 Procedure FindTextDlg;
569 Procedure ReplaceTextDlg;
570 Property FileName:String Read FFileName Write SetFileName;
571 Property CountLines:LongInt Read FCountLines;
572 Property Lines[Index:LongInt]:String Read _Get Write _Set; Default;
573 Property CursorPos:TEditorPos Read FFileCursor Write GotoPosition;
574 Property OffsetPos:TEditorPos Read FScrCursor;
575 Property MaxUndoEvents:LongInt Read MaxUndo Write _SetMaxUndo;
576 Property UndoCount:LongInt Read GetUndoCount;
577 Property RedoCount:LongInt Read GetRedoCount;
578 Property AutoSaveEvents:Integer Read FSaveEvents Write SetSaveEvents;
579 Property BottomScrollBar:TScrollBar Read FBottomScrollBar Write FBottomScrollBar;
580 Property RightScrollBar:TScrollBar Read FRightScrollBar Write FRightScrollBar;
581 Property Mask:String Read fMask Write fMask;
582 Property Selected:Boolean Read _ICBExist;
583 Property Columns:LongInt Read FWinSize.X;
584 Property Rows:LongInt Read FWinSize.Y;
585 Property ColorEntry[ColorIndex:Integer]:TColor Read GetColorEntry Write SetColorEntry;
586 Property CursorShape:TCursorShape Read FCursorShape Write SetCursorShape;
587 Property SelectMode:TSelectMode Read FSelectMode Write SetSelectMode;
588 Property WordWrap:Boolean Read FWordWrap Write SetWordWrap;
589 Property WordWrapColumn:Integer Read FWordWrapColumn Write SetWordWrapColumn;
590 Property InsertMode:Boolean Read FInsertMode Write SetInsertMode;
591 Property Modified:Boolean Read FModified Write SetModified;
592 Property Untitled:Boolean Read FUntitled Write FUntitled;
593 Property ReadOnly:Boolean Read GetReadOnly Write SetReadOnly;
594 Published
595 Property KeystrokeMap:TKeystrokeMap Read FKeyMap Write SetKeyMap;
596 Property EditOptions:TEditOpt Read FEditOpt Write SetEditOpt;
597 Property TabSize:Integer Read FTabSize Write SetTabSize;
598 Property Ctl3D:Boolean Read FCtl3D Write SetCtl3D;
599 End;
600
601 TEditorClass=Class Of TEditor;
602
603
604
605Function CheckWordsOnly(pl:PLine; Var I:Integer; Const S:String):Boolean;
606Function GetDefaultExt(Mask:String):String;
607Function EditorPos(Line:LongInt;Column:Integer):TEditorPos;
608
609
610Implementation
611
612Const
613 SpaceChar:Char=#32;
614
615
616{$B+} {Complete Boolean Evaluation}
617
618Function CheckWordsOnly(pl:PLine; Var I:Integer; Const S:String):Boolean;
619Begin
620 Result := False;
621 If I = 0 Then Exit;
622
623 If I > 1 Then
624 If pl^.zk^[I-1] In NormalChars Then
625 Begin
626 I := - I;
627 Exit;
628 End;
629
630 If I+Length(S)-1 < Length(pl^.zk^) Then
631 If pl^.zk^[I+Length(S)] In NormalChars Then
632 Begin
633 I := - I;
634 Exit;
635 End;
636 Result := True;
637End;
638
639
640Function GetDefaultExt(Mask:String):String;
641Var P:Integer;
642Begin
643 Result := '';
644 If Mask = '*.*' Then Exit;
645 P := Pos('.',Mask);
646 If P = 0 Then Exit;
647 Delete(Mask,1,P);
648 Result := Mask;
649End;
650
651
652Function EditorPos(Line:LongInt;Column:Integer):TEditorPos;
653Begin
654 Result.Y := Line;
655 Result.X := Column;
656End;
657
658
659{
660ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
661º º
662º Speed-Pascal/2 Version 2.0 º
663º º
664º Speed-Pascal Component Classes (SPCC) º
665º º
666º This section: TEditor Class Implementation º
667º º
668º (C) 1995,97 SpeedSoft. All rights reserved. Disclosure probibited ! º
669º º
670ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍŒ
671}
672
673Procedure TEditor.SetFont(NewFont:TFont);
674Begin
675 If NewFont = Nil Then Exit;
676 If NewFont.Pitch = fpFixed Then
677 If NewFont.FontType = ftBitmap Then
678 Begin
679 Inherited SetFont(NewFont);
680
681 IsDBCSFont := NewFont.CharSet <> fcsSBCS;
682 If Handle = 0 Then Exit;
683
684 Canvas.Font := NewFont;
685 CalcSizes;
686 SetCursorShape(FCursorShape);
687 Invalidate;
688 End;
689End;
690
691
692Procedure TEditor.SetKeyMap(km:TKeystrokeMap);
693Begin
694 FKeyMap := km;
695 ICBVisible := True;
696 InvalidateEditor(0,0);
697End;
698
699
700Procedure TEditor.SetInsertMode(im:Boolean);
701Begin
702 FInsertMode := im;
703 SetCursorShape(FCursorShape); {Update}
704End;
705
706
707Procedure TEditor.SetCursorShape(CS:TCursorShape);
708Var X,Y:Integer;
709Begin
710 FCursorShape := CS;
711
712 FCaret.Remove;
713 If Not FInsertMode Then
714 Begin
715 X := Canvas.FontWidth;
716 Y := Canvas.FontHeight;
717 End
718 Else
719 If FCursorShape = csUnderline Then
720 Begin
721 X := Canvas.FontWidth;
722 Y := 2;
723 End
724 Else
725 Begin
726 X := 1;
727 Y := Canvas.FontHeight;
728 End;
729 FCaret.SetSize(X,Y);
730 SetScreenCursor;
731 If HadFocus > 0 Then FCaret.Show;
732End;
733
734
735Procedure TEditor.SetSelectMode(sm:TSelectMode);
736Begin
737 If Application.DBCSSystem Then sm := smNonInclusiveBlock;
738
739 FSelectMode := sm;
740 ICBVisible := True;
741 _ICBCheckX;
742 InvalidateEditor(0,0);
743End;
744
745
746Procedure TEditor.SetEditOpt(eo:TEditOpt);
747Begin
748 FEditOpt := eo;
749End;
750
751
752Procedure TEditor.SetTabSize(ts:Integer);
753Begin
754 If (ts > 0) And (ts < StringLength) Then FTabSize := ts;
755End;
756
757
758Procedure TEditor.SetWordWrap(Wrap:Boolean);
759Begin
760 If FWordWrap <> Wrap Then
761 Begin
762 FWordWrap := Wrap;
763 InvalidateEditor(0,0);
764 End;
765End;
766
767
768Procedure TEditor.SetWordWrapColumn(Column:Integer);
769Begin
770 FWordWrapColumn := Column;
771 If FWordWrap Then InvalidateEditor(0,0);
772End;
773
774
775Function TEditor.GetUndoCount:LongInt;
776Begin
777 Result := FUndoList.Count;
778End;
779
780
781Function TEditor.GetRedoCount:LongInt;
782Begin
783 Result := FRedoList.Count;
784End;
785
786
787Procedure TEditor.FlushWorkLine;
788Begin
789 If WLactivated Then _WriteWorkLine;
790End;
791
792
793{Convert Line Number (1..N) To Line Pointer}
794Function TEditor._Index2PLine(Y:LongInt):PLine;
795Var I:LongInt;
796Begin
797 Result := Nil;
798 If (Y < 1) Or (Y > FCountLines) Then Exit;
799
800 If Y < (FCountLines Shr 1) Then {Search Forward}
801 Begin
802 Result := FFirstLine;
803 For I := 2 To Y Do
804 Begin
805 If Result <> Nil Then Result := Result^.Next
806 Else Exit;
807 End;
808 End
809 Else {Search backward}
810 Begin
811 Result := FLastLine;
812 For I := FCountLines-1 DownTo Y Do
813 Begin
814 If Result <> Nil Then Result := Result^.Prev
815 Else Exit;
816 End;
817 End;
818End;
819
820
821{Convert Line Pointer To Line Number (1..N)}
822Function TEditor._PLine2Index(pl:PLine):LongInt;
823Var pl1:PLine;
824Begin
825 Result := 0;
826 pl1 := FFirstLine;
827 While pl1 <> Nil Do
828 Begin
829 Inc(Result);
830 If pl1 = pl Then Exit;
831 pl1 := pl1^.Next;
832 End;
833 Result := 0;
834End;
835
836
837{return the Pointer To the String Of the Line}
838Function TEditor._PLine2PString(pl:PLine):PString;
839Begin
840 If pl <> Nil Then
841 Begin
842 If pl^.zk <> Nil Then Result := pl^.zk
843 Else Result := @FWorkLine;
844 End
845 Else Result := Nil;
846End;
847
848
849{Connect two Line pointers}
850Function TEditor._Connect(pl1,pl2:PLine):Boolean;
851Begin
852 If pl1 <> Nil Then pl1^.Next := pl2
853 Else FFirstLine := pl2;
854 If pl2 <> Nil Then pl2^.Prev := pl1
855 Else FLastLine := pl1;
856 Result := True;
857End;
858
859
860{Count Number Of Lines including both Lines}
861Function TEditor._CountLines(pl1,pl2:PLine):LongInt;
862Var pl:PLine;
863Begin
864 Result := 0;
865 pl := pl1;
866 While pl <> Nil Do
867 Begin
868 Inc(Result);
869 If pl = pl2 Then Exit;
870 pl := pl^.Next;
871 End;
872 Result := 0;
873 pl := pl1;
874 While pl <> Nil Do
875 Begin
876 Dec(Result);
877 If pl = pl2 Then Exit;
878 pl := pl^.Prev;
879 End;
880 Result := 0;
881End;
882
883
884{ +++ Undo +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ }
885
886{Count the Lines from FirstL To LastL And Reset the Line color}
887Function TEditor._CountUndoLines(FirstL,LastL:PLine):LongInt;
888Var TempL:PLine;
889Begin
890 Result := _CountLines(FirstL,LastL);
891 If Result > 0 Then
892 Begin
893 TempL := FirstL;
894 While TempL <> LastL Do
895 Begin
896 TempL^.flag := ciNormal;
897 TempL := TempL^.Next;
898 End;
899 If LastL <> Nil Then LastL^.flag := ciNormal;
900 End
901 Else Result := 0;
902End;
903
904
905{save the File Cursor Position}
906Procedure TEditor._StoreUndoCursor(List:TList);
907Var U:PUndo;
908Begin
909 New(U);
910 U^.Memory := False;
911 U^.EventType := ugCursorMove;
912 U^.Modified := Modified;
913 U^.ICBFL := _PLine2Index(ICB.First.Line);
914 U^.ICBFX := ICB.First.X;
915 U^.ICBLL := _PLine2Index(ICB.Last.Line);
916 U^.ICBLX := ICB.Last.X;
917 U^.FFileCursor := FFileCursor;
918 _CreateUndoEvent(List,U);
919End;
920
921
922{save the File Cursor Position And Copy the specified Lines In the stack}
923Function TEditor._CopyUndoLines(FirstL,LastL:PLine):LongInt;
924Var U:PUndo;
925 FUL,LUL:PLine;
926 pl:PLine;
927 ptnew:PLine;
928 ptlast:PLine;
929 CL:LongInt;
930 lzk:Integer;
931Begin
932 FlushWorkLine;
933 CL := 0;
934 ptnew := Nil;
935 pl := FirstL;
936 While pl <> LastL^.Next Do
937 Begin
938 New(ptnew);
939 If CL = 0 Then FUL := ptnew;
940 lzk := Length(pl^.zk^);
941 GetMem(ptnew^.zk, lzk+1);
942 ptnew^.zk^ := pl^.zk^;
943 ptnew^.flag := ciNormal;
944 ptnew^.Add := 0;
945 If CL > 0 Then _Connect(ptlast,ptnew);
946 pl := pl^.Next;
947 ptlast := ptnew;
948 Inc(CL);
949 End;
950 LUL := ptnew;
951
952 New(U);
953 U^.Memory := True;
954 U^.EventType := ugNoGroup;
955 U^.Modified := Modified;
956 U^.ICBFL := _PLine2Index(ICB.First.Line);
957 U^.ICBFX := ICB.First.X;
958 U^.ICBLL := _PLine2Index(ICB.Last.Line);
959 U^.ICBLX := ICB.Last.X;
960 U^.FFileCursor := FFileCursor;
961 U^.FrameBegin := _PLine2Index(FirstL)-1;
962 U^.FrameEnd := _PLine2Index(LastL)+1; {Default: Count Of Lines constant}
963 U^.FirstUndoLine := FUL;
964 U^.LastUndoLine := LUL;
965 U^.Lines := CL;
966 _CreateUndoEvent(FUndoList,U);
967 Result := U^.Lines;
968End;
969
970
971{save the File Cursor Position And Move the specified Lines In the stack}
972Function TEditor._MoveUndoLines(List:TList;FirstL,LastL:PLine):LongInt;
973Var U:PUndo;
974Begin
975 FlushWorkLine;
976 New(U);
977 U^.Memory := True;
978 U^.EventType := ugNoGroup;
979 U^.Modified := Modified;
980 U^.ICBFL := _PLine2Index(ICB.First.Line);
981 U^.ICBFX := ICB.First.X;
982 U^.ICBLL := _PLine2Index(ICB.Last.Line);
983 U^.ICBLX := ICB.Last.X;
984 U^.FFileCursor := FFileCursor;
985
986 U^.Lines := _CountUndoLines(FirstL,LastL); {Count Lines For Undo stack}
987 If U^.Lines > 0 Then
988 Begin
989 U^.FrameBegin := _PLine2Index(FirstL)-1;
990 U^.FirstUndoLine := FirstL;
991 U^.LastUndoLine := LastL;
992 End
993 Else
994 Begin
995 U^.FrameBegin := _PLine2Index(LastL);
996 U^.FirstUndoLine := Nil;
997 U^.LastUndoLine := Nil;
998 End;
999 _CreateUndoEvent(List,U);
1000 Result := U^.Lines;
1001End;
1002
1003
1004{Create an Undo event}
1005Procedure TEditor._CreateUndoEvent(List:TList;U:PUndo);
1006Begin
1007 List.Add(U);
1008
1009 If MaxUndo < 0 Then Exit; {unlimited}
1010 If List.Count > MaxUndo Then List.Delete(0);
1011End;
1012
1013{Update the Frame End Of the Last Undo event}
1014Procedure TEditor._UpdateLastUndoEvent(List:TList;Index:LongInt);
1015Var U:PUndo;
1016Begin
1017 If List.Count = 0 Then Exit;
1018 U := List.Last;
1019 If U = Nil Then Exit;
1020 U^.FrameEnd := Index;
1021End;
1022
1023
1024{Release the Memory allocated by the Lines For the Undo stack And the Item}
1025{$HINTS OFF}
1026Procedure TEditor._FreeUndoEvent(List:TObject;Item:Pointer);
1027Var pl:PLine;
1028 ptnext:PLine;
1029 I:LongInt;
1030 lzk:Integer;
1031 U:PUndo;
1032Begin
1033 U := Item;
1034 If U = Nil Then Exit;
1035 If U^.Memory Then {Not only Cursor event}
1036 Begin
1037 pl := U^.FirstUndoLine;
1038 For I := 1 To U^.Lines Do
1039 Begin
1040 If pl = Nil Then Exit;
1041 ptnext := pl^.Next;
1042 If pl^.zk <> Nil Then
1043 Begin
1044 lzk := Length(pl^.zk^);
1045 FreeMem(pl^.zk, lzk+1);
1046 End;
1047 Dispose(pl);
1048 pl := ptnext;
1049 End;
1050 End;
1051 Dispose(U);
1052End;
1053{$HINTS ON}
1054
1055Procedure TEditor._SetMaxUndo(cnt:LongInt);
1056Begin
1057 MaxUndo := cnt;
1058 If MaxUndo < 0 Then Exit; {unlimited}
1059
1060 While FUndoList.Count > MaxUndo Do FUndoList.Delete(0);
1061 While FRedoList.Count > MaxUndo Do FRedoList.Delete(0);
1062 UpdateEditorState;
1063End;
1064
1065
1066
1067{Move FActLine To FWorkLine}
1068Procedure TEditor._ReadWorkLine;
1069Var lzk:Integer;
1070Begin
1071 WLactivated := True;
1072 If FActLine^.zk = Nil Then Exit;
1073
1074 FillChar(FWorkLine[1], StringLength, 32); {NoANSI}
1075 lzk := Length(FActLine^.zk^);
1076 FWorkLine := FActLine^.zk^;
1077 FreeMem(FActLine^.zk, lzk+1);
1078 FActLine^.zk := Nil;
1079End;
1080
1081
1082{Write back FWorkLine To FActLine}
1083Procedure TEditor._WriteWorkLine;
1084Var lwl:Integer;
1085Begin
1086 WLactivated := False;
1087 If FActLine^.zk <> Nil Then Exit;
1088 While (Length(FWorkLine) > 0) And (FWorkLine[Length(FWorkLine)] = ' ')
1089 Do SetLength(FWorkLine,Length(FWorkLine)-1);
1090 If Length(FWorkLine) > StringLength Then SetLength(FWorkLine,StringLength);
1091
1092 lwl := Length(FWorkLine);
1093 GetMem(FActLine^.zk, lwl+1);
1094 FActLine^.zk^ := FWorkLine;
1095End;
1096
1097
1098{overwrite FWorkLine At Position X With String S}
1099Function TEditor._WriteString(X:Integer; S:String):Boolean;
1100Var I,newend:Integer;
1101 lwl:Integer;
1102Begin
1103 Result := True;
1104 If Not WLactivated Then _ReadWorkLine;
1105 If Length(S) = 0 Then Exit;
1106
1107 lwl := Length(FWorkLine);
1108 I := X - (lwl+1);
1109 If I > 0 Then FillChar(FWorkLine[lwl+1], I, 32);
1110
1111 If X + (Length(S)-1) > StringLength Then
1112 Begin
1113 SetLength(S,StringLength-X+1);
1114 Result := False;
1115 End;
1116
1117 System.Move(S[1], FWorkLine[X], Length(S)); {NoANSI}
1118 newend := X + (Length(S)-1);
1119 If Length(FWorkLine) < newend Then SetLength(FWorkLine,newend);
1120 Modified := True;
1121End;
1122
1123
1124{Insert String S In the FWorkLine At Position X}
1125Function TEditor._InsertString(X:Integer; S:String):Boolean;
1126Var lS,I:Integer;
1127 lwl:Integer;
1128Begin
1129 If Not WLactivated Then _ReadWorkLine;
1130 Result := True;
1131 lS := Length(S);
1132 If lS = 0 Then Exit;
1133
1134 lwl := Length(FWorkLine);
1135 If X > lwl+1 Then
1136 Begin
1137 I := X - (lwl+1);
1138 FillChar(FWorkLine[lwl+1], I, 32);
1139 SetLength(FWorkLine,X-1);
1140 End;
1141 If lS + Length(FWorkLine) > StringLength Then Result := False;
1142 System.Insert(S, FWorkLine, X);
1143 If Length(FWorkLine) > StringLength Then SetLength(FWorkLine,StringLength);
1144 Modified := True;
1145End;
1146
1147
1148{Delete CX chars In the FWorkLine At Position X}
1149Function TEditor._DeleteString(X,CX:Integer):Boolean;
1150Begin
1151 If Not WLactivated Then _ReadWorkLine;
1152 Result := True;
1153 If CX = 0 Then Exit;
1154 If X > Length(FWorkLine) Then Exit;
1155 Delete(FWorkLine, X, CX);
1156 Modified := True;
1157End;
1158
1159
1160{Read CX chars from Line pl At Position X; If CX Is < 0 the Until End Of Line}
1161Function TEditor._ReadString(pl:PLine; X,CX:Integer):String;
1162Var zk:PString;
1163 S:String;
1164Begin
1165 Result := '';
1166 If pl = Nil Then Exit;
1167 zk := _PLine2PString(pl);
1168
1169 If CX >= 0 Then
1170 Begin
1171 If X+CX-1 > Length(zk^) Then
1172 Begin
1173 FillChar(S[1], StringLength, 32); {NoANSI}
1174 System.Move(zk^[1], S[1], Length(zk^));
1175 SetLength(S,StringLength);
1176 zk := @S; {NoANSI}
1177 End;
1178 End
1179 Else CX := StringLength;
1180 Result := Copy(zk^,X,CX);
1181End;
1182
1183
1184{Get the String from Line Y (1..N)}
1185Function TEditor._Get(Y:LongInt):String;
1186Var pl:PLine;
1187Begin
1188 Result := '';
1189 pl := _Index2PLine(Y);
1190 If pl = Nil Then Exit; {indexerror}
1191 If pl^.zk <> Nil Then Result := pl^.zk^
1192 Else Result := FWorkLine;
1193End;
1194
1195
1196Procedure TEditor._Set(Y:LongInt;Const S:String);
1197Begin
1198 ReplaceLine(Y,S);
1199End;
1200
1201
1202{Find the Line With the bookmark I}
1203Function TEditor._FindBookMark(I:Byte):PLine;
1204Var pl:PLine;
1205 BM,W:LongWord;
1206Begin
1207 BM := I * ciBookMark0;
1208 pl := FFirstLine;
1209 While pl <> Nil Do
1210 Begin
1211 W := pl^.flag And ciBookMarkMask;
1212 If W = I Then
1213 Begin
1214 Result := pl;
1215 Exit;
1216 End;
1217 pl := pl^.Next;
1218 End;
1219 Result := Nil;
1220End;
1221
1222
1223{Find Next cmTabulator; from Line pl And Position X}
1224Function TEditor._FindNextTab(pl:PLine; X:Integer):Integer;
1225Var tabstring:String;
1226Begin
1227 FlushWorkLine;
1228 Result := 1;
1229 If FTabSize = 0 Then exit;
1230
1231 tabstring := '!';
1232 While pl <> Nil Do
1233 Begin
1234 If Length(pl^.zk^) <> 0 Then
1235 Begin
1236 tabstring := pl^.zk^;
1237 pl := Nil;
1238 End
1239 Else pl := pl^.Prev;
1240 End;
1241
1242 If (X = 1) And (tabstring[1] <> ' ') Then {For cmEnter}
1243 Begin
1244 Result := 1;
1245 Exit;
1246 End;
1247
1248 If X <= Length(tabstring) Then
1249 Begin
1250 Dec(X);
1251 While (tabstring[X] <> ' ') And (X <= Length(tabstring)) Do Inc(X);
1252 While (tabstring[X] = ' ') And (X <= Length(tabstring)) Do Inc(X);
1253 End
1254 Else X := (((X-2) Div FTabSize)+1)*FTabSize + 1;
1255
1256 If X > StringLength Then X := StringLength;
1257 Result := X;
1258End;
1259
1260
1261Function QueryDBCSFirstByte(Var S:String; Pos:LongInt):Boolean;
1262Var I:LongInt;
1263Begin
1264 Result := False;
1265 If Pos > Length(S) Then Exit;
1266 For I := 1 To Pos Do
1267 Begin
1268 {$IFDEF OS2}
1269 If IsDBCSFirstByte(S[I]) Then
1270 Begin
1271 If I = Pos Then
1272 Begin
1273 Result := True;
1274 Exit;
1275 End;
1276 Inc(I); {onto Second Byte}
1277 End;
1278 {$ENDIF}
1279 End;
1280End;
1281
1282
1283
1284{transform mouse coordinates into Screen Cursor coordinates}
1285Function TEditor.GetCursorFromMouse(pt:TPoint):TEditorPos;
1286Var I,XLeft,yTop:LongInt;
1287 pl:PLine;
1288 ps:PString;
1289Begin
1290 XLeft := FBorderWidth + IndentRect.Left;
1291 yTop := FBorderWidth + IndentRect.Top;
1292 Result.X := Round( (pt.X - XLeft) / Canvas.FontWidth) + 1;
1293 Result.Y := (ClientArea.Top - pt.Y - yTop) Div Canvas.FontHeight + 1;
1294
1295 If Application.DBCSSystem Then
1296 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1297 pl := FTopScreenLine;
1298 For I := 2 To Result.Y Do
1299 If pl <> Nil Then pl := pl^.Next;
1300 If pl = Nil Then Exit;
1301
1302 ps := _PLine2PString(pl);
1303 If QueryDBCSFirstByte(ps^,(FFileCursor.X-FScrCursor.X)+Result.X-1)
1304 Then Dec(Result.X);
1305 End;
1306End;
1307
1308
1309{transform Screen Cursor coordinates into mouse coordinates}
1310Function TEditor.GetMouseFromCursor(Pos:TEditorPos):TPoint;
1311Var XLeft,yTop:LongInt;
1312Begin
1313 XLeft := FBorderWidth + IndentRect.Left;
1314 yTop := FBorderWidth + IndentRect.Top;
1315 Result.X := XLeft + ((Pos.X-1) * Canvas.FontWidth);
1316 Result.Y := ClientArea.Top - (Pos.Y * Canvas.FontHeight) - yTop;
1317End;
1318
1319
1320
1321{Insert A New Line after pl}
1322Function TEditor._InsertLine(pl:PLine):PLine;
1323Var plnext:PLine;
1324Begin
1325 If pl = Nil Then plnext := FFirstLine
1326 Else plnext := pl^.Next;
1327 New(Result);
1328 Result^.zk := Nil;
1329 Result^.flag := ciNormal;
1330 Result^.Add := 0;
1331 _Connect(Result,plnext);
1332 _Connect(pl,Result);
1333 Inc(FCountLines);
1334 Modified := True;
1335End;
1336
1337
1338{Delete the Line pl}
1339Function TEditor._DeleteLine(pl:PLine):PLine;
1340Var lzk:Integer;
1341Begin
1342 If (FCountLines = 1) Or (pl = Nil) Then
1343 Begin
1344 Result := Nil;
1345 Exit;
1346 End;
1347 Result := pl^.Prev;
1348 If pl^.zk <> Nil Then
1349 Begin
1350 lzk := Length(pl^.zk^);
1351 FreeMem(pl^.zk, lzk+1);
1352 End;
1353 _Connect(pl^.Prev,pl^.Next);
1354 Dispose(pl);
1355 Dec(FCountLines);
1356 Modified := True;
1357End;
1358
1359
1360{Copy contents Of A File into Memory}
1361Function TEditor._GetFileText(S:String; Var P:Pointer; Var len:LongInt):Boolean;
1362Var utF:File;
1363 p0:^Byte;
1364Begin
1365 System.Assign(utF,S);
1366 {$I-}
1367 FileMode := fmInput;
1368 Reset(utF,1);
1369 FileMode := fmInOut;
1370 Result := InOutRes = 0;
1371 If InOutRes = 0 Then len := FileSize(utF)
1372 Else len := 0;
1373 {$I+}
1374
1375 If len > 0 Then
1376 Begin
1377 Inc(len);
1378 GetMem(P,len);
1379 {$I-}
1380 BlockRead(utF,P^,len-1);
1381 {$I+}
1382 Result := InOutRes = 0;
1383 p0 := P;
1384 Inc(p0,len-1);
1385 p0^ := 0; {terminal #0}
1386 End;
1387 {$I-}
1388 System.Close(utF);
1389 {$I+}
1390End;
1391
1392
1393{Copy All To A Text block With the Length len; return True If successful}
1394Function TEditor._GetEditorText(Var P:Pointer; Var len:LongInt):Boolean;
1395Var OldICB:TICB;
1396 OldSelectMode:TSelectMode;
1397Begin
1398 OldICB := ICB;
1399 ICB.First.Line := FFirstLine;
1400 ICB.First.X := 1;
1401 ICB.Last.Line := FLastLine;
1402 ICB.Last.X := Length(_PLine2PString(FLastLine)^);
1403 Inc(ICB.Last.X);
1404 OldSelectMode := FSelectMode;
1405 FSelectMode := smNonInclusiveBlock;
1406
1407 Result := _GetEditorBlock(P,len);
1408
1409 ICB := OldICB;
1410 FSelectMode := OldSelectMode;
1411End;
1412
1413
1414{Copy the area To A Text block With the Length len; return True If successful}
1415Function TEditor.GetPartialText(p1,p2:TEditorPos;Var P:Pointer; Var len:LongInt):Boolean;
1416Var OldICB:TICB;
1417 OldSelectMode:TSelectMode;
1418Begin
1419 Result := False;
1420 If p1.Y > p2.Y Then Exit;
1421 If p1.Y = p2.Y Then
1422 If p1.X >= p2.X Then Exit;
1423 If p1.Y < 1 Then Exit;
1424 If p2.Y > FCountLines Then Exit;
1425
1426 OldICB := ICB;
1427 ICB.First.Line := _Index2PLine(p1.Y);
1428 ICB.First.X := 1;
1429 ICB.Last.Line := _Index2PLine(p2.Y);
1430 ICB.Last.X := Length(_PLine2PString(FLastLine)^);
1431 Inc(ICB.Last.X);
1432 OldSelectMode := FSelectMode;
1433 FSelectMode := smNonInclusiveBlock;
1434
1435 Result := _GetEditorBlock(P,len);
1436
1437 ICB := OldICB;
1438 FSelectMode := OldSelectMode;
1439End;
1440
1441
1442{Copy ICB To A Text block With the Length len; return True If successful}
1443Function TEditor._GetEditorBlock(Var P:Pointer; Var len:LongInt):Boolean;
1444Var pl:PLine;
1445 Ptr:Pointer;
1446 Str:String;
1447 zk:PString;
1448 lzk:Integer;
1449 CRLF:String;
1450 area:TICB;
1451Begin
1452 Result := False;
1453 _ICBExtCorrectICB2; {reorder firstx lastx If extselection}
1454 len := -1;
1455 area := ICB;
1456 If (area.First.Line = Nil) Or (area.Last.Line = Nil) Then Exit;
1457
1458 If area.First.Line = area.Last.Line Then
1459 Begin
1460 len := area.Last.X - area.First.X;
1461 If len > 0 Then
1462 Begin
1463 Inc(len); {terminating #0}
1464 GetMem(P,len);
1465 Str := _ReadString(area.First.Line,area.First.X,len-1) + #0;
1466 System.Move(Str[1], P^, len); {NoANSI}
1467 Result := True;
1468 End;
1469 End
1470 Else
1471 Begin
1472 If FSelectMode <> smColumnBlock Then
1473 Begin
1474 pl := area.First.Line;
1475 lzk := Length(_PLine2PString(pl)^);
1476 {correct If To LONG}
1477 If area.First.X > lzk Then area.First.X := lzk+1;
1478 len := lzk - area.First.X+1+2; {First Line}
1479 pl := pl^.Next;
1480 While pl <> area.Last.Line Do
1481 Begin
1482 lzk := Length(_PLine2PString(pl)^);
1483 Inc(len, lzk +2);
1484 pl := pl^.Next;
1485 If pl = Nil Then Exit;
1486 End;
1487 Inc(len, area.Last.X); {Last Line + terminating #0}
1488 End
1489 Else {Extended Selection}
1490 Begin
1491 pl := area.First.Line;
1492 lzk := area.Last.X - area.First.X;
1493 len := lzk +2; {First Line}
1494 pl := pl^.Next;
1495 While pl <> area.Last.Line Do
1496 Begin
1497 Inc(len, lzk +2);
1498 pl := pl^.Next;
1499 If pl = Nil Then Exit;
1500 End;
1501 Inc(len, lzk +1); {Last Line + terminating #0}
1502 End;
1503
1504 GetMem(P,len);
1505
1506 CRLF := #13#10;
1507 pl := area.First.Line;
1508 Ptr := P;
1509 {First area Line}
1510 If FSelectMode <> smColumnBlock
1511 Then Str := _ReadString(area.First.Line,area.First.X,-1)
1512 Else Str := _ReadString(area.First.Line,area.First.X,lzk);
1513 System.Move(Str[1], Ptr^, Length(Str)); {NoANSI}
1514 Inc(Ptr, Length(Str));
1515 System.Move(CRLF[1], Ptr^, 2); {NoANSI}
1516 Inc(Ptr, 2);
1517 pl := pl^.Next;
1518 While pl <> area.Last.Line Do
1519 Begin
1520 If FSelectMode <> smColumnBlock Then
1521 Begin
1522 zk := _PLine2PString(pl);
1523 System.Move(zk^[1], Ptr^, Length(zk^)); {NoANSI}
1524 Inc(Ptr, Length(zk^));
1525 End
1526 Else
1527 Begin
1528 Str := _ReadString(pl,area.First.X,lzk);
1529 System.Move(Str[1], Ptr^, lzk); {NoANSI}
1530 Inc(Ptr, lzk);
1531 End;
1532 System.Move(CRLF[1], Ptr^, 2); {NoANSI}
1533 Inc(Ptr, 2);
1534 pl := pl^.Next;
1535 End;
1536 {Last area Line}
1537 If FSelectMode <> smColumnBlock
1538 Then Str := _ReadString(area.Last.Line,1,area.Last.X-1) + #0
1539 Else Str := _ReadString(area.Last.Line,area.First.X,lzk) + #0;
1540 System.Move(Str[1], Ptr^, Length(Str)); {NoANSI}
1541 Result := True;
1542 End;
1543End;
1544
1545
1546{Insert the Text block At the curent Position And Change the ICB If neccesary}
1547Function TEditor._InsertText(P:Pointer; len:LongInt; marknew:Boolean):TLineX;
1548Var laststr,NewStr:String;
1549 Tabs,StrL:LongWord;
1550 NewLine:Boolean;
1551 OldActLine:PLine;
1552 lwl:Integer;
1553Begin
1554 FillChar(Result, SizeOf(Result), 0);
1555
1556 If (len <= 0) Or (P = Nil) Then Exit;
1557
1558 If FSelectMode = smColumnBlock Then marknew := False;
1559 OldActLine := FActLine;
1560 If marknew Then
1561 Begin
1562 _ICBClearMark;
1563 ICB.First.Line := FActLine;
1564 ICB.First.X := FFileCursor.X;
1565 End;
1566 If Not WLactivated Then _ReadWorkLine;
1567 If FFileCursor.X > Length(FWorkLine) Then laststr := ''
1568 Else laststr := Copy(FWorkLine,FFileCursor.X,255);
1569 SetLength(FWorkLine,FFileCursor.X-1);
1570
1571 Tabs := FTabSize;
1572 StrL := StringLength;
1573 While len > 0 Do
1574 Begin
1575 Asm
1576 CLD
1577 MOV NewLine,0
1578 LEA EDI,NewStr
1579 MOV ESI,p
1580 Inc EDI
1581 Xor ECX,ECX
1582!ib1:
1583 CMPD len,0
1584 JE !ib9
1585 CMP ECX,StrL
1586 JB !ib10
1587 CMPB [ESI+0],13
1588 JE !ib10
1589 CMPB [ESI+0],10
1590 JE !ib10
1591 JMP !ib6
1592!ib10:
1593 LODSB
1594 DECD len
1595 CMP AL,13
1596 JE !ib3
1597 CMP AL,10
1598 JE !ib4
1599 CMP AL,9
1600 JE !ib2
1601 CMP AL,32
1602 JAE !ib5
1603 MOV AL,32
1604 JMP !ib5
1605!ib2: {#9}
1606 MOV EBX,ECX
1607 MOV EDX,Tabs
1608 // Insert spaces Until To the Next tab Mark
1609!ib8:
1610 CMP EDX,EBX
1611 JA !ib7
1612 ADD EDX,Tabs
1613 JMP !ib8
1614!ib7:
1615 SUB EDX,EBX
1616 // EDX = Count Of spaces
1617 ADD EBX,EDX
1618 CMP EBX,StrL
1619 JA !ib6
1620 MOV ECX,EDX
1621 MOV AL,32
1622 REP
1623 STOSB
1624 MOV ECX,EBX
1625 JMP !ib1
1626!ib3: {#13}
1627 CMPB [ESI],10
1628 JNE !ib6
1629 LODSB
1630 DECD len
1631 JMP !ib6
1632!ib4: {#10}
1633 CMPB [ESI],13
1634 JNE !ib6
1635 LODSB
1636 DECD len
1637 JMP !ib6
1638!ib5: {>#31}
1639 STOSB
1640 Inc ECX
1641 CMP ECX,StrL
1642 JBE !ib1
1643!ib6:
1644 MOV NewLine,1
1645!ib9:
1646 MOV P,ESI
1647 MOV NewStr,CL
1648 End;
1649
1650 FWorkLine := FWorkLine + NewStr;
1651 If Length(FWorkLine) > StringLength Then SetLength(FWorkLine,StringLength);
1652 lwl := Length(FWorkLine);
1653 GetMem(FActLine^.zk, lwl+1);
1654 FActLine^.zk^ := FWorkLine;
1655 WLactivated := False;
1656 If NewLine Then
1657 Begin
1658 _InsertLine(FActLine);
1659 FActLine := FActLine^.Next;
1660 FWorkLine := '';
1661 End;
1662 End;
1663
1664 _ReadWorkLine;
1665
1666 // Set Result To the End Of the inserted block
1667 Result.Line := FActLine;
1668 Result.X := Length(FWorkLine);
1669 Inc(Result.X);
1670
1671 If marknew Then ICB.Last := Result;
1672
1673 FWorkLine := FWorkLine + laststr;
1674 _WriteWorkLine;
1675
1676 _ICBCheckX;
1677 _ICBSetMark;
1678 ICBVisible := True;
1679 SetSliderValues;
1680 SetLineColorFlag(OldActLine,FActLine);
1681 FActLine := OldActLine;
1682 Modified := True;
1683End;
1684
1685
1686
1687{determine whether the viewarea Change its horizontal Position}
1688Function TEditor._HorizMove:Boolean;
1689Begin
1690 Result := ScrOffsX <> FFileCursor.X-FScrCursor.X+1;
1691 ScrOffsX := FFileCursor.X-FScrCursor.X+1;
1692End;
1693
1694
1695{Change the actual File Cursor Position}
1696Function TEditor._GotoPosition(P:TEditorPos):Boolean;
1697Var deltaY,deltaX,I:LongInt;
1698 pl:PLine;
1699 ps:PString;
1700Begin
1701 Result := False;
1702 If (P.Y < 1) Or (P.Y > FCountLines) Or
1703 (P.X < 1) Or (P.X > StringLength) Then Exit;
1704 FlushWorkLine;
1705
1706 deltaX := P.X - FFileCursor.X;
1707 FFileCursor.X := P.X;
1708 If (FScrCursor.X + deltaX < 1) Or (FScrCursor.X + deltaX > FWinSize.X) Then
1709 Begin
1710 FScrCursor.X := FWinSize.X;
1711 If FScrCursor.X <= 0 Then FScrCursor.X := 1;
1712 If P.X < FScrCursor.X Then FScrCursor.X := P.X;
1713 Result := True;
1714 End
1715 Else FScrCursor.X := FScrCursor.X + deltaX;
1716
1717 deltaY := P.Y - FFileCursor.Y;
1718 FFileCursor.Y := P.Y;
1719 If (FScrCursor.Y + deltaY < 1) Or (FScrCursor.Y + deltaY > FWinSize.Y) Then
1720 Begin
1721 FScrCursor.Y := FWinSize.Y Div 2;
1722 If FScrCursor.Y <= 0 Then FScrCursor.Y := 1;
1723 If P.Y < FScrCursor.Y Then FScrCursor.Y := P.Y;
1724 Result := True;
1725 End
1726 Else FScrCursor.Y := FScrCursor.Y + deltaY;
1727
1728 pl := _Index2PLine(P.Y);
1729 FActLine := pl;
1730 For I := FScrCursor.Y DownTo 2 Do
1731 If pl <> Nil Then pl := pl^.Prev;
1732 If pl = Nil Then pl := FActLine;
1733 FTopScreenLine := pl;
1734
1735
1736 If Application.DBCSSystem Then
1737 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1738 ps := _PLine2PString(FActLine);
1739 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
1740 Begin
1741 KeyRepeat := 1;
1742 _CursorLeft;
1743 End;
1744 End;
1745End;
1746
1747
1748{basic Cursor Movement}
1749Function TEditor._CursorDown:Boolean;
1750Var ToScroll:Integer;
1751 maxrep,REP,T:Integer;
1752 ps:PString;
1753Begin
1754 Result := False;
1755 If FFileCursor.Y = FCountLines Then Exit;
1756 FlushWorkLine;
1757
1758 REP := KeyRepeat;
1759 maxrep := (FWinSize.Y Div 2) + 1;
1760 If REP > maxrep Then REP := maxrep;
1761 If FFileCursor.Y + REP > FCountLines Then REP := FCountLines - FFileCursor.Y;
1762 If REP = 0 Then Exit;
1763
1764 Inc(FFileCursor.Y,REP);
1765 For T := 1 To REP Do FActLine := FActLine^.Next;
1766 If FScrCursor.Y + REP > FWinSize.Y Then {ScrollDown}
1767 Begin
1768 ToScroll := (FScrCursor.Y+REP) - FWinSize.Y;
1769 FScrCursor.Y := FWinSize.Y;
1770 For T := 1 To ToScroll Do FTopScreenLine := FTopScreenLine^.Next;
1771 Result := True;
1772 End
1773 Else Inc(FScrCursor.Y,REP);
1774
1775
1776 If Application.DBCSSystem Then
1777 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1778 ps := _PLine2PString(FActLine);
1779 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
1780 Begin
1781 KeyRepeat := 1;
1782 _CursorLeft;
1783 End;
1784 End;
1785End;
1786
1787
1788Function TEditor._CursorUp:Boolean;
1789Var ToScroll:Integer;
1790 maxrep,REP,T:Integer;
1791 ps:PString;
1792Begin
1793 Result := False;
1794 If FFileCursor.Y = 1 Then Exit;
1795 FlushWorkLine;
1796
1797 REP := KeyRepeat;
1798 maxrep := (FWinSize.Y Div 2) + 1;
1799 If REP > maxrep Then REP := maxrep;
1800 If FFileCursor.Y <= REP Then REP := FFileCursor.Y - 1;
1801 If REP = 0 Then Exit;
1802
1803 Dec(FFileCursor.Y,REP);
1804 For T := 1 To REP Do FActLine := FActLine^.Prev;
1805 If REP >= FScrCursor.Y Then {ScrollUp}
1806 Begin
1807 ToScroll := REP - FScrCursor.Y + 1;
1808 FScrCursor.Y := 1;
1809 For T := 1 To ToScroll Do FTopScreenLine := FTopScreenLine^.Prev;
1810 Result := True;
1811 End
1812 Else Dec(FScrCursor.Y,REP);
1813
1814
1815 If Application.DBCSSystem Then
1816 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1817 ps := _PLine2PString(FActLine);
1818 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
1819 Begin
1820 KeyRepeat := 1;
1821 _CursorLeft;
1822 End;
1823 End;
1824End;
1825
1826
1827Function TEditor._CursorRight:Boolean;
1828Var maxrep,REP:Integer;
1829 ps:PString;
1830Begin
1831 Result := False;
1832 If FFileCursor.X >= StringLength Then Exit;
1833
1834 REP := KeyRepeat;
1835 maxrep := (FWinSize.X Div 2) + 1;
1836 If REP > maxrep Then REP := maxrep;
1837 If FFileCursor.X + REP > StringLength Then REP := StringLength - FFileCursor.X;
1838
1839 If Application.DBCSSystem Then
1840 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1841 ps := _PLine2PString(FActLine);
1842 If QueryDBCSFirstByte(ps^, FFileCursor.X+REP-1) Then Inc(REP);
1843 End;
1844
1845 Inc(FFileCursor.X,REP);
1846 If FScrCursor.X + REP > FWinSize.X Then
1847 Begin
1848 FScrCursor.X := FWinSize.X;
1849 Result := True;
1850 End
1851 Else Inc(FScrCursor.X,REP);
1852End;
1853
1854
1855Function TEditor._CursorLeft:Boolean;
1856Var maxrep,REP:Integer;
1857 ps:PString;
1858Begin
1859 Result := False;
1860 If FFileCursor.X <= 1 Then Exit;
1861
1862 REP := KeyRepeat;
1863 maxrep := (FWinSize.X Div 2) + 1;
1864 If REP > maxrep Then REP := maxrep;
1865 If FFileCursor.X <= REP Then REP := FFileCursor.X - 1;
1866
1867 If Application.DBCSSystem Then
1868 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1869 ps := _PLine2PString(FActLine);
1870 If QueryDBCSFirstByte(ps^, FFileCursor.X-REP-1) Then Inc(REP);
1871 End;
1872
1873 Dec(FFileCursor.X,REP);
1874 If FScrCursor.X - REP < 1 Then
1875 Begin
1876 FScrCursor.X := 1;
1877 Result := True;
1878 End
1879 Else Dec(FScrCursor.X,REP);
1880End;
1881
1882
1883Function TEditor._CursorHome:Boolean;
1884Begin
1885 Result := False;
1886 If FFileCursor.X = 1 Then Exit;
1887
1888 _HorizMove;
1889 FFileCursor.X := 1;
1890 FScrCursor.X := 1;
1891 Result := _HorizMove;
1892End;
1893
1894
1895Function TEditor._CursorEnd:Boolean;
1896Var LastChar:Integer;
1897Begin
1898 Result := False;
1899 FlushWorkLine;
1900 LastChar := Length(_PLine2PString(FActLine)^);
1901 Inc(LastChar);
1902 If LastChar > StringLength Then LastChar := StringLength;
1903 If FFileCursor.X = LastChar Then Exit;
1904
1905 _HorizMove;
1906 FScrCursor.X := LastChar - (FFileCursor.X - FScrCursor.X);
1907 FFileCursor.X := LastChar;
1908 If FScrCursor.X < 1 Then FScrCursor.X := LastChar;
1909 If FScrCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X;
1910 Result := _HorizMove;
1911End;
1912
1913
1914Function TEditor._CursorPageDown:Boolean;
1915Var I:Integer;
1916 ps:PString;
1917Begin
1918 Result := False;
1919 If FFileCursor.Y >= FCountLines Then Exit;
1920
1921 FlushWorkLine;
1922 For I := 1 To FWinSize.Y-1 Do
1923 Begin
1924 If FActLine^.Next <> Nil Then
1925 Begin
1926 {SrollDown}
1927 FActLine := FActLine^.Next;
1928 FTopScreenLine := FTopScreenLine^.Next;
1929 Inc(FFileCursor.Y);
1930 End;
1931 End;
1932 Result := True;
1933
1934
1935 If Application.DBCSSystem Then
1936 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1937 ps := _PLine2PString(FActLine);
1938 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
1939 Begin
1940 KeyRepeat := 1;
1941 _CursorLeft;
1942 End;
1943 End;
1944End;
1945
1946
1947Function TEditor._CursorPageUp:Boolean;
1948Var I:Integer;
1949 ps:PString;
1950Begin
1951 Result := False;
1952 If FFileCursor.Y <= 1 Then Exit;
1953
1954 FlushWorkLine;
1955 For I := 1 To FWinSize.Y-1 Do
1956 Begin
1957 If FTopScreenLine^.Prev <> Nil Then
1958 Begin
1959 {ScrollUp}
1960 FActLine := FActLine^.Prev;
1961 FTopScreenLine := FTopScreenLine^.Prev;
1962 Dec(FFileCursor.Y);
1963 End
1964 Else
1965 Begin
1966 If FActLine^.Prev <> Nil Then
1967 Begin
1968 {JumpUp}
1969 FActLine := FActLine^.Prev;
1970 Dec(FFileCursor.Y);
1971 Dec(FScrCursor.Y);
1972 End;
1973 End;
1974 End;
1975 Result := True;
1976
1977
1978 If Application.DBCSSystem Then
1979 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
1980 ps := _PLine2PString(FActLine);
1981 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
1982 Begin
1983 KeyRepeat := 1;
1984 _CursorLeft;
1985 End;
1986 End;
1987End;
1988
1989
1990Function TEditor._CursorRollUp:Boolean;
1991Var ps:PString;
1992Begin
1993 Result := False;
1994 If FTopScreenLine^.Prev = Nil Then Exit;
1995
1996 FlushWorkLine;
1997 FTopScreenLine := FTopScreenLine^.Prev;
1998 If FScrCursor.Y >= FWinSize.Y Then
1999 Begin
2000 FActLine := FActLine^.Prev;
2001 Dec(FFileCursor.Y);
2002
2003 If Application.DBCSSystem Then
2004 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
2005 ps := _PLine2PString(FActLine);
2006 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
2007 Begin
2008 KeyRepeat := 1;
2009 _CursorLeft;
2010 End;
2011 End;
2012 End
2013 Else Inc(FScrCursor.Y);
2014 Result := True;
2015End;
2016
2017
2018Function TEditor._CursorRollDown:Boolean;
2019Var ps:PString;
2020Begin
2021 Result := False;
2022 If FActLine^.Next = Nil Then Exit;
2023
2024 FlushWorkLine;
2025 FTopScreenLine := FTopScreenLine^.Next;
2026 If FScrCursor.Y <= 1 Then
2027 Begin
2028 FActLine := FActLine^.Next;
2029 Inc(FFileCursor.Y);
2030
2031 If Application.DBCSSystem Then
2032 Begin {Make sure, that the Cursor cannot occur within A dbcs Char}
2033 ps := _PLine2PString(FActLine);
2034 If QueryDBCSFirstByte(ps^, FFileCursor.X-1) Then
2035 Begin
2036 KeyRepeat := 1;
2037 _CursorLeft;
2038 End;
2039 End;
2040 End
2041 Else Dec(FScrCursor.Y);
2042 Result := True;
2043End;
2044
2045
2046Function TEditor._CursorWordRight:Boolean;
2047Var pl:PLine;
2048 I,dFCY:LongInt;
2049 FCX:Integer;
2050 cc:Integer;
2051Begin
2052 Result := False;
2053
2054 _HorizMove;
2055 FlushWorkLine;
2056 If (FFileCursor.X > Length(FActLine^.zk^)) Or
2057 (FFileCursor.X = StringLength) Then
2058 Begin
2059 pl := FActLine^.Next;
2060 If pl = Nil Then
2061 Begin
2062 Result := _CursorEnd;
2063 Exit;
2064 End;
2065 FFileCursor.X := 1;
2066 FScrCursor.X := 1;
2067 dFCY := 0;
2068 cc := 0;
2069 While (pl <> Nil) And (cc = 0) Do
2070 Begin
2071 Inc(dFCY);
2072 If Length(pl^.zk^) = 0 Then pl := pl^.Next
2073 Else cc := 1; {Line With <> '' found}
2074 End;
2075
2076 For I := 1 To dFCY Do
2077 Begin
2078 FActLine := FActLine^.Next;
2079 Inc(FFileCursor.Y);
2080 If FScrCursor.Y = FWinSize.Y Then
2081 Begin
2082 FTopScreenLine := FTopScreenLine^.Next;
2083 Result := True;
2084 End
2085 Else Inc(FScrCursor.Y);
2086 End;
2087 End
2088 Else cc := 2; {Next Word In the same Line}
2089
2090 FCX := 0;
2091 If ((cc=1) And Not (FActLine^.zk^[1] In NormalChars)) Or (cc = 2) Then
2092 Begin
2093 While (FActLine^.zk^[FFileCursor.X+FCX] In NormalChars) And
2094 (FFileCursor.X+FCX <= Length(FActLine^.zk^)) Do Inc(FCX);
2095 While (Not (FActLine^.zk^[FFileCursor.X+FCX] In NormalChars)) And
2096 (FFileCursor.X+FCX <= Length(FActLine^.zk^)) Do Inc(FCX);
2097 End;
2098
2099 FFileCursor.X := FFileCursor.X+FCX;
2100 If FFileCursor.X > StringLength Then FFileCursor.X := StringLength;
2101 FScrCursor.X := FScrCursor.X+FCX;
2102 If FScrCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X;
2103
2104 Result := Result Or _HorizMove;
2105End;
2106
2107
2108Function TEditor._CursorWordLeft:Boolean;
2109Var pl:PLine;
2110 I,dFCY:LongInt;
2111 FCX:Integer;
2112 cc:Integer;
2113 lzk:Integer;
2114Begin
2115 Result := False;
2116
2117 _HorizMove;
2118 FlushWorkLine;
2119 lzk := Length(FActLine^.zk^);
2120 If FFileCursor.X > lzk+1 Then _CursorEnd;
2121 If FFileCursor.X > 1 Then
2122 Begin
2123 cc := 0;
2124 FCX := 1;
2125 If Not (FActLine^.zk^[FFileCursor.X-FCX] In NormalChars) Then
2126 While (Not (FActLine^.zk^[FFileCursor.X-FCX] In NormalChars)) And
2127 (FFileCursor.X-FCX > 0) Do Inc(FCX);
2128 If FFileCursor.X-FCX = 0 Then cc := 1;
2129
2130 While (FActLine^.zk^[FFileCursor.X-FCX] In NormalChars) And
2131 (FFileCursor.X-FCX > 0) Do Inc(FCX);
2132
2133 FFileCursor.X := FFileCursor.X-FCX+1;
2134 If FCX > FScrCursor.X Then FScrCursor.X := 1
2135 Else FScrCursor.X := FScrCursor.X-FCX+1;
2136 End
2137 Else cc := 1; {minimal 1 Line up}
2138
2139 If cc = 1 Then
2140 Begin
2141 pl := FActLine^.Prev;
2142 If pl = Nil Then
2143 Begin
2144 Result := _CursorHome;
2145 Exit;
2146 End;
2147 dFCY := 0;
2148 While (pl <> Nil) Do
2149 Begin
2150 Inc(dFCY);
2151 If Length(pl^.zk^) = 0 Then pl := pl^.Prev
2152 Else pl := Nil; {Line With <> '' found}
2153 End;
2154
2155 For I := 1 To dFCY Do
2156 Begin
2157 FActLine := FActLine^.Prev;
2158 Dec(FFileCursor.Y);
2159 If FScrCursor.Y = 1 Then
2160 Begin
2161 FTopScreenLine := FTopScreenLine^.Prev;
2162 Result := True;
2163 End
2164 Else Dec(FScrCursor.Y);
2165 End;
2166 Result := _CursorEnd Or Result;
2167 End;
2168 Result := Result Or _HorizMove;
2169End;
2170
2171
2172
2173{determine whether the internal Clipboard Is Empty Or Not}
2174Function TEditor._ICBExist:Boolean;
2175Begin
2176 Result := False;
2177 If Not ICBVisible Then Exit;
2178 If (ICB.First.Line = Nil) Or (ICB.Last.Line = Nil) Then Exit;
2179 If (ICB.First.Line = ICB.Last.Line) And (ICB.First.X = ICB.Last.X) Then Exit;
2180 If FSelectMode = smColumnBlock Then
2181 If ICB.First.X = ICB.Last.X Then Exit;
2182 Result := True;
2183End;
2184
2185
2186{determine whether the ICB Is persistent}
2187Function TEditor._ICBPersistent:Boolean;
2188Begin
2189 Result := eoPersistentBlocks In FEditOpt;
2190End;
2191
2192
2193{determine whether the ICB MUST be overwritten Or Not}
2194Function TEditor._ICBOverwrite:Boolean;
2195Begin
2196 Result := eoOverwriteBlock In FEditOpt;
2197End;
2198
2199
2200{Clear the Mark Of the Lines Of the actual ICB And Set ICB To Nil}
2201Function TEditor._ICBClearICB:Boolean;
2202Begin
2203 Result := _ICBClearMark;
2204 ICB.First.Line := Nil;
2205 ICB.Last.Line := Nil;
2206End;
2207
2208
2209{Clear the Mark Of the Lines Of the actual ICB}
2210Function TEditor._ICBClearMark:Boolean;
2211Var pl:PLine;
2212Begin
2213 If (ICB.First.Line <> Nil) And (ICB.Last.Line <> Nil) Then
2214 Begin
2215 pl := ICB.First.Line;
2216 While pl <> ICB.Last.Line Do
2217 Begin
2218 pl^.flag := pl^.flag And Not ciSelected;
2219 pl := pl^.Next;
2220 End;
2221 pl^.flag := pl^.flag And Not ciSelected;
2222 Result := True;
2223 End
2224 Else Result := False;
2225End;
2226
2227
2228{Set the Mark Of the Lines Of the actual ICB}
2229Function TEditor._ICBSetMark:Boolean;
2230Var pl:PLine;
2231Begin
2232 If (ICB.First.Line <> Nil) And (ICB.Last.Line <> Nil) Then
2233 Begin
2234 pl := ICB.First.Line;
2235 While pl <> ICB.Last.Line Do
2236 Begin
2237 pl^.flag := pl^.flag Or ciSelected;
2238 pl := pl^.Next;
2239 End;
2240 pl^.flag := pl^.flag Or ciSelected;
2241 Result := True;
2242 End
2243 Else Result := False;
2244End;
2245
2246
2247{Delete the ICB block, including Undo}
2248Function TEditor._ICBDeleteICB:Boolean;
2249Var FrameFirst:PLine;
2250 FrameLast:PLine;
2251 firststring:String;
2252 laststring:String;
2253 CL:LongInt;
2254 P:TEditorPos;
2255Begin
2256 Result := False;
2257 If Not _ICBExist Then Exit;
2258 FlushWorkLine;
2259
2260 P.Y := _PLine2Index(ICB.First.Line);
2261 P.X := ICB.First.X;
2262 _GotoPosition(P);
2263
2264 If FSelectMode <> smColumnBlock Then
2265 Begin
2266 firststring := _ReadString(ICB.First.Line,1,ICB.First.X-1);
2267 laststring := _ReadString(ICB.Last.Line,ICB.Last.X,-1);
2268
2269 FrameFirst := ICB.First.Line^.Prev;
2270 FrameLast := ICB.Last.Line^.Next;
2271 (*Undo*)
2272 CL := _MoveUndoLines(FUndoList,ICB.First.Line,ICB.Last.Line);
2273 (*Undo*)
2274 _Connect(FrameFirst,FrameLast);
2275 Dec(FCountLines,CL);
2276 Modified := True;
2277
2278 FActLine := _InsertLine(FrameFirst);
2279 If FScrCursor.Y = 1 Then FTopScreenLine := FActLine;
2280 FWorkLine := firststring + laststring;
2281 _WriteWorkLine;
2282
2283 ICB.First.Line := FActLine;
2284 ICB.First.X := FFileCursor.X;
2285 ICB.Last := ICB.First;
2286
2287 _ICBSetMark;
2288 ICBVisible := True;
2289 SetSliderValues;
2290 If FrameFirst <> Nil Then SetLineColorFlag(FrameFirst,FActLine)
2291 Else UpdateLineColorFlag(FActLine);
2292
2293 (*Undo*)
2294 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FrameLast));
2295 (*Undo*)
2296 End
2297 Else {Extended Selection}
2298 Begin
2299 (*Undo*)
2300 _CopyUndoLines(ICB.First.Line,ICB.Last.Line);
2301 (*Undo*)
2302 _ICBClearMark;
2303 FActLine := ICB.First.Line;
2304 While FActLine <> ICB.Last.Line^.Next Do
2305 Begin
2306 If Length(FActLine^.zk^) >= ICB.First.X Then
2307 Begin
2308 _ReadWorkLine;
2309 _DeleteString(ICB.First.X, ICB.Last.X - ICB.First.X);
2310 _WriteWorkLine;
2311 End;
2312 FActLine := FActLine^.Next;
2313 End;
2314 FActLine := ICB.First.Line;
2315
2316 ICB.Last := ICB.First;
2317 _ICBSetMark;
2318 ICBVisible := True;
2319 SetLineColorFlag(ICB.First.Line,ICB.Last.Line);
2320 End;
2321 (*Undo*)
2322 LastUndoGroup := ugNoGroup;
2323 (*Undo*)
2324 Result := True;
2325End;
2326
2327
2328{Cut the ICB.X values At the End Of Lines}
2329Procedure TEditor._ICBCheckX;
2330Var zk:PString;
2331 lzk:Integer;
2332Begin
2333 If FSelectMode = smColumnBlock Then Exit;
2334
2335 If ICB.First.Line <> Nil Then
2336 Begin
2337 zk := _PLine2PString(ICB.First.Line);
2338 lzk := Length(zk^);
2339 If Length(zk^) < ICB.First.X Then ICB.First.X := lzk+1;
2340 If StringLength < ICB.First.X Then ICB.First.X := StringLength;
2341 End;
2342
2343 If ICB.Last.Line <> Nil Then
2344 Begin
2345 zk := _PLine2PString(ICB.Last.Line);
2346 lzk := Length(zk^);
2347 If Length(zk^) < ICB.Last.X Then ICB.Last.X := lzk+1;
2348 If StringLength < ICB.Last.X Then ICB.Last.X := StringLength;
2349 End;
2350End;
2351
2352
2353{Set the New Selection Position And Mark the Lines If neccesary}
2354Procedure TEditor._ICBSetBegin(pl:PLine; X:Integer);
2355Var pl1:PLine;
2356Begin
2357 If ICB.Last.Line <> Nil Then
2358 Begin
2359 _ICBClearMark;
2360
2361 pl1 := ICB.Last.Line;
2362 While (pl1 <> Nil) And (pl <> pl1) Do pl1 := pl1^.Prev;
2363 If (pl = ICB.Last.Line) And (X > ICB.Last.X) Then pl1 := Nil;
2364
2365 If pl1 = Nil Then ICB.Last.Line := Nil;
2366 End;
2367
2368 {Set the Begin Mark}
2369 ICB.First.Line := pl;
2370 ICB.First.X := X;
2371 _ICBCheckX;
2372 _ICBSetMark;
2373 ICBVisible := True;
2374 _ICBExtCorrectICB2; {reorder firstx lastx If extselection}
2375End;
2376
2377
2378{Set the New Selection Position And Mark the Lines If neccesary}
2379Procedure TEditor._ICBSetEnd(pl:PLine; X:Integer);
2380Var pl1:PLine;
2381Begin
2382 If ICB.First.Line <> Nil Then
2383 Begin
2384 _ICBClearMark;
2385
2386 pl1 := ICB.First.Line;
2387 While (pl1 <> Nil) And (pl <> pl1) Do pl1 := pl1^.Next;
2388 If (pl = ICB.First.Line) And (X < ICB.First.X) Then pl1 := Nil;
2389
2390 If pl1 = Nil Then ICB.First.Line := Nil;
2391 End;
2392
2393 {Set the End Mark}
2394 ICB.Last.Line := pl;
2395 ICB.Last.X := X;
2396 _ICBCheckX;
2397 _ICBSetMark;
2398 ICBVisible := True;
2399 _ICBExtCorrectICB2; {reorder firstx lastx If extselection}
2400End;
2401
2402
2403{calculate Code Of Current Position To ICB}
2404Function TEditor._ICBPos(pl:PLine; X:Integer):TICBPosition;
2405Begin
2406 Result := [];
2407 If pl = Nil Then Exit;
2408
2409 If pl = ICB.First.Line Then
2410 Begin
2411 If X < ICB.First.X Then Result := Result + [ipBeforeICBFirst]
2412 Else Result := Result + [ipAfterICBFirst];
2413 End;
2414
2415 If pl = ICB.Last.Line Then
2416 Begin
2417 If X < ICB.Last.X Then Result := Result + [ipBeforeICBLast]
2418 Else Result := Result + [ipAfterICBLast];
2419 End;
2420
2421 If Result = [] Then
2422 If pl^.flag And ciSelected <> 0 Then Result := [ipWithinICB];
2423End;
2424
2425
2426{transform the actual Position To the ICB Position}
2427Function TEditor._ICBActPos:TLineX;
2428Var len:Integer;
2429 zk:PString;
2430Begin
2431 If FSelectMode <> smColumnBlock Then
2432 Begin
2433 zk := _PLine2PString(FActLine);
2434 len := Length(zk^);
2435 While (len > 0) And (zk^[len] = ' ') Do Dec(len);
2436 If FFileCursor.X > len Then Result.X := len+1
2437 Else Result.X := FFileCursor.X;
2438 End
2439 Else Result.X := FFileCursor.X;
2440 If Result.X > StringLength Then Result.X := StringLength;
2441 Result.Line := FActLine;
2442End;
2443
2444
2445{Set the New ICB Position To the actual Position And Clear the ICB Mark}
2446Function TEditor._ICBExtSetICB:Boolean;
2447Var actLineX:TLineX;
2448Begin
2449 Result := False;
2450
2451 actLineX := _ICBActPos;
2452 _ICBClearMark;
2453 If Not ICBVisible Then {force To Create New ICB}
2454 Begin
2455 ICB.First.Line := Nil;
2456 ICBVisible := True;
2457 End;
2458
2459 If (ICB.First.Line = Nil) Or (ICB.Last.Line = Nil) Then
2460 Begin
2461 ICB.First := actLineX;
2462 ICB.Last := actLineX;
2463 Exit;
2464 End;
2465
2466 If (ICB.First = actLineX) Or (ICB.Last = actLineX) Then Exit;
2467
2468 If FSelectMode = smColumnBlock Then
2469 Begin
2470 If ICB.First.Line = actLineX.Line Then
2471 If ICB.Last.X = actLineX.X Then
2472 Begin
2473 ICB.Last.X := ICB.First.X;
2474 ICB.First.X := actLineX.X;
2475 Result := True;
2476 Exit;
2477 End;
2478
2479 If ICB.Last.Line = actLineX.Line Then
2480 If ICB.First.X = actLineX.X Then
2481 Begin
2482 ICB.First.X := ICB.Last.X;
2483 ICB.Last.X := actLineX.X;
2484 Result := True;
2485 Exit;
2486 End;
2487 End;
2488
2489 ICB.First := actLineX;
2490 ICB.Last := actLineX;
2491 Result := True;
2492End;
2493
2494
2495{reorder the Begin And the End Of the ICB If neccessary}
2496Function TEditor._ICBExtCorrectICB:Boolean;
2497Var pl:PLine;
2498 LineX:TLineX;
2499Begin
2500 Result := False;
2501 pl := ICB.First.Line;
2502 If (ICB.First.Line = ICB.Last.Line) And (ICB.First.X > ICB.Last.X)
2503 Then pl := Nil;
2504 While (pl <> ICB.Last.Line) And (pl <> Nil) Do pl := pl^.Next;
2505
2506 If pl = Nil Then {Exchange First & Last}
2507 Begin
2508 LineX := ICB.First;
2509 ICB.First := ICB.Last;
2510 ICB.Last := LineX;
2511 Result := True;
2512 End;
2513End;
2514
2515
2516{reorder the Left And Right Of the ICB If neccessary}
2517Function TEditor._ICBExtCorrectICB2:Boolean;
2518Var X:Integer;
2519Begin
2520 Result := False;
2521 If FSelectMode = smColumnBlock Then
2522 If ICB.First.X > ICB.Last.X Then {Exchange Left & Right}
2523 Begin
2524 X := ICB.First.X;
2525 ICB.First.X := ICB.Last.X;
2526 ICB.Last.X := X;
2527 Result := True;
2528 End;
2529End;
2530
2531
2532Function TEditor._ICBTestIEW(Var y1,y2:Integer):Boolean;
2533Var _y1,_y2:LongInt;
2534Begin
2535 Result := False;
2536 If FSelectMode <> smColumnBlock Then Exit;
2537 If (ICB.First.Line = Nil) Or (ICB.Last.Line = Nil) Then Exit;
2538 If ICB.First.Line = ICB.Last.Line Then Exit;
2539 {determine Screen Lines Of ICB And Update y1,y2}
2540 If FActLine = ICB.First.Line Then _y1 := FFileCursor.Y
2541 Else _y1 := _PLine2Index(ICB.First.Line);
2542 If FActLine = ICB.Last.Line Then _y2 := FFileCursor.Y
2543 Else _y2 := _PLine2Index(ICB.Last.Line);
2544 _y1 := FScrCursor.Y - (FFileCursor.Y - _y1); {FTopScreenLine}
2545 _y2 := FScrCursor.Y - (FFileCursor.Y - _y2); {FTopScreenLine}
2546 If _y1 < y1 Then y1 := _y1;
2547 If _y2 > y2 Then y2 := _y2;
2548 Result := True;
2549End;
2550
2551
2552{Clipboard}
2553
2554Function TEditor._SetClipBoardText(P:Pointer; len:LongInt):Boolean;
2555Var clip:Pointer;
2556Begin
2557 Result := False;
2558 If Clipboard.Open(Handle) Then
2559 Begin
2560 Try
2561 GetSharedMem(clip,len);
2562 Except
2563 clip := Nil;
2564 End;
2565 If clip = Nil Then
2566 Begin
2567 Clipboard.Close;
2568 SetErrorMessage(LoadNLSStr(SCouldNotCopyText)+'.');
2569 Exit;
2570 End;
2571 System.Move(P^,clip^,len);
2572 Clipboard.Empty;
2573 Clipboard.SetData(LongWord(clip),cfText);
2574 Clipboard.Close;
2575 Result := True;
2576 End
2577 Else SetErrorMessage(LoadNLSStr(SCouldNotAccessClipboard)+'.');
2578End;
2579
2580
2581Function TEditor._GetClipBoardText(Var P:Pointer; Var len:LongInt):Boolean;
2582Var clip:Pointer;
2583Begin
2584 Result := False;
2585 If Clipboard.Open(Handle) Then
2586 Begin
2587 clip := Pointer(Clipboard.GetData(cfText));
2588 If clip = Nil Then
2589 Begin
2590 Clipboard.Close;
2591 Exit;
2592 End;
2593 Asm {Search terminal #0}
2594 CLD
2595 MOV ECX,0
2596 MOV ESI,clip
2597!gt:
2598 Inc ECX
2599 LODSB
2600 CMP AL,0
2601 JNE !gt
2602 MOV EDI,len
2603 MOV [EDI],ECX
2604 End;
2605
2606 If len > 1 Then
2607 Begin
2608 GetMem(P,len);
2609 System.Move(clip^,P^,len);
2610 Result := True;
2611 End;
2612 Clipboard.Close;
2613 End
2614 Else SetErrorMessage(LoadNLSStr(SCouldNotAccessClipboard)+'.');
2615End;
2616
2617
2618{+++ Protected ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
2619
2620{Test whether Window can be closed}
2621Function TEditor.CloseQuery:Boolean;
2622Var resp:TMsgDlgReturn;
2623 Text:String;
2624Begin
2625 CloseQuery := True;
2626 If Modified Then
2627 Begin
2628 If Untitled And (FFileName = '')
2629 Then Text := FmtLoadNLSStr(SSaveQuery,[Caption])
2630 Else Text := FmtLoadNLSStr(SSaveQuery,[FFileName]);
2631 resp := SetQueryMessage(Text,mtInformation,mbYesNoCancel);
2632 Case resp Of
2633 mrYes : If Not SaveFile Then CloseQuery := False;
2634 mrCancel : CloseQuery := False;
2635 End;
2636 End;
2637End;
2638
2639
2640{CloseQuery Result True - Form will be destroyed}
2641Destructor TEditor.Destroy;
2642Var pl:PLine;
2643 plnext:PLine;
2644 I:Integer;
2645 lzk:Integer;
2646 pp:^TEditorPos;
2647Begin
2648 FlushWorkLine;
2649 pl := FFirstLine;
2650 While pl <> Nil Do
2651 Begin
2652 lzk := Length(pl^.zk^);
2653 FreeMem(pl^.zk, lzk+1);
2654 plnext := pl^.Next;
2655 Dispose(pl);
2656 pl := plnext;
2657 End;
2658
2659 FUndoList.Destroy;
2660 FRedoList.Destroy;
2661
2662 For I := IncSearchList.Count-1 DownTo 0 Do
2663 Begin
2664 pp := IncSearchList.Items[I];
2665 Dispose(pp);
2666 End;
2667 IncSearchList.Destroy;
2668
2669 If FMacroList <> Nil Then FMacroList.Destroy;
2670
2671 If FCaret <> Nil Then FCaret.Destroy;
2672 FCaret := Nil;
2673
2674 Inherited Destroy;
2675End;
2676
2677
2678{Window Is getting A Char event}
2679Procedure TEditor.CharEvent(Var key:Char;RepeatCount:Byte);
2680Var iew:Boolean;
2681 ip:TICBPosition;
2682 I,N,DX,Right,brk:Integer;
2683 NewL,wrapit:Boolean;
2684 rest,S:String;
2685 Code:TKeyCode;
2686Begin
2687 If key < #32 Then key := #32;
2688
2689 If WindowState = wsMinimized Then
2690 Begin
2691 key := #0;
2692 Exit;
2693 End;
2694 KeyRepeat := 1;
2695
2696 If FindICB.First.Line <> Nil Then
2697 Begin
2698 FindICB.First.Line := Nil;
2699 InvalidateEditor(0,0);
2700 End;
2701
2702 If FPreCtrl > 0 Then
2703 Begin
2704 Code := Ord(key) + kb_Char + kb_Ctrl;
2705 ScanEvent(Code,RepeatCount);
2706 key := #0;
2707 Exit;
2708 End;
2709
2710 If FRecording Then
2711 Begin
2712 FMacroList.Add(Pointer(Ord((key))));
2713 FMacroList.Add(Pointer(RepeatCount));
2714 End;
2715
2716 If FLastFind = faIncSearch Then
2717 Begin
2718 IncSearchText := IncSearchText + key;
2719 cmIncrementalSearch;
2720 key := #0;
2721 Exit;
2722 End;
2723
2724 If ReadOnly Then
2725 Begin
2726 key := #0;
2727 Exit;
2728 End;
2729 TestAutoSave;
2730
2731 If _ICBOverwrite Then iew := _ICBDeleteICB
2732 Else iew := False;
2733
2734 {Test Word wrapping}
2735 If Not WLactivated Then _ReadWorkLine;
2736 wrapit := False;
2737 If FWordWrap Then
2738 Begin
2739 If FWordWrapColumn > 0 Then Right := FWordWrapColumn
2740 Else Right := FWinSize.X + FFileCursor.X - FScrCursor.X -1;
2741
2742 For I := Length(FWorkLine) DownTo 1 Do
2743 If FWorkLine[I] = ' ' Then SetLength(FWorkLine,Length(FWorkLine)-1)
2744 Else break;
2745
2746 N := Length(FWorkLine);
2747 If (FFileCursor.X > N) And (key <> ' ') Then N := FFileCursor.X
2748 Else If (FInsertMode) And (N < StringLength) Then Inc(N);
2749 If N > Right Then wrapit := True;
2750 End;
2751
2752
2753 If FInsertMode Then
2754 Begin
2755 (*Undo*)
2756 If (LastUndoGroup <> ugInsertChar) Or wrapit Then
2757 Begin
2758 _CopyUndoLines(FActLine,FActLine);
2759 LastUndoGroup := ugInsertChar;
2760 End;
2761 (*Undo*)
2762 If Not _InsertString(FFileCursor.X,key) Then Beep(1000,10);
2763 If FSelectMode <> smColumnBlock Then
2764 Begin
2765 ip := _ICBPos(FActLine,FFileCursor.X);
2766 If ip * [ipBeforeICBFirst] <> [] Then Inc(ICB.First.X);
2767 If ip * [ipBeforeICBLast] <> [] Then Inc(ICB.Last.X);
2768 _ICBCheckX;
2769 End;
2770 End
2771 Else
2772 Begin
2773 (*Undo*)
2774 If (LastUndoGroup <> ugOverwriteChar) Or wrapit Then
2775 Begin
2776 _CopyUndoLines(FActLine,FActLine);
2777 LastUndoGroup := ugOverwriteChar;
2778 End;
2779 (*Undo*)
2780 If Not _WriteString(FFileCursor.X,key) Then Beep(1000,10);
2781 End;
2782
2783 {iew := _CursorRight Or iew;}
2784 If FFileCursor.X < StringLength Then
2785 Begin
2786 Inc(FFileCursor.X,1);
2787 If FScrCursor.X + 1 > FWinSize.X Then
2788 Begin
2789 FScrCursor.X := FWinSize.X;
2790 iew := True;
2791 End
2792 Else Inc(FScrCursor.X,1);
2793 End;
2794
2795 {Word wrapping}
2796 If wrapit Then
2797 Begin
2798 For I := Length(FWorkLine) DownTo 1 Do
2799 If FWorkLine[I] = ' ' Then SetLength(FWorkLine,Length(FWorkLine)-1)
2800 Else break;
2801
2802 If Length(FWorkLine) > Right Then
2803 Begin
2804 brk := Length(FWorkLine);
2805 {Search Last break chance B4 Right}
2806 For I := Length(FWorkLine) DownTo 1 Do
2807 Begin
2808 If FWorkLine[I] = ' ' Then
2809 Begin
2810 brk := I;
2811 If brk <= Right Then break;
2812 End;
2813 End;
2814 If brk = Length(FWorkLine) Then brk := Right;
2815 DX := FFileCursor.X - brk;
2816
2817 rest := Copy(FWorkLine,brk+1,255);
2818 While (rest[1] = ' ') And (Length(rest) > 0) Do
2819 Begin
2820 Delete(rest,1,1);
2821 If DX > 1 Then Dec(DX);
2822 End;
2823 SetLength(FWorkLine,brk);
2824 _WriteWorkLine;
2825 NewL := True; {Insert A New Line}
2826 If CountLines > FFileCursor.Y Then
2827 Begin
2828 S := _PLine2PString(FActLine^.Next)^;
2829 N := Length(rest);
2830 If S <> '' Then
2831 If N + Length(S) < Right Then NewL := False;
2832 End;
2833
2834 LastUndoGroup := ugGroup; {group Events}
2835 If NewL Then InsertLine(FFileCursor.Y+1,rest)
2836 Else ReplaceLine(FFileCursor.Y+1,rest +' '+ S);
2837 LastUndoGroup := ugGroup; {group Events}
2838
2839 If (DX > 1) And (key <> ' ') Then
2840 Begin
2841 KeyRepeat := 1;
2842 _CursorDown;
2843 FFileCursor.X := DX;
2844 If DX <= FWinSize.X Then FScrCursor.X := DX
2845 Else FScrCursor.X := 1;
2846 _StoreUndoCursor(FUndoList);
2847 LastUndoGroup := ugGroup; {group Events}
2848 End;
2849 iew := True;
2850 End;
2851 End;
2852
2853 FRedoList.Clear;
2854 If iew Then
2855 Begin
2856 UpdateLineColorFlag(FActLine);
2857 InvalidateEditor(0,0);
2858 End
2859 Else InvalidateWorkLine;
2860
2861 key := #0;
2862End;
2863
2864
2865{Window Is getting A scan event}
2866Procedure TEditor.ScanEvent(Var KeyCode:TKeyCode;RepeatCount:Byte);
2867Var pp:^TEditorPos;
2868 MsgHandled:Boolean;
2869Begin
2870 If WindowState = wsMinimized Then
2871 Begin
2872 If KeyCode In [kbCR,kbEnter] Then WindowState := wsNormal;
2873 KeyCode := kbNull;
2874 Exit;
2875 End;
2876
2877 If FindICB.First.Line <> Nil Then
2878 Begin
2879 FindICB.First.Line := Nil;
2880 InvalidateEditor(0,0);
2881 End;
2882
2883 If FRecording Then
2884 Begin
2885 FMacroList.Add(Pointer(KeyCode));
2886 FMacroList.Add(Pointer(RepeatCount));
2887 End;
2888
2889 KeyRepeat := RepeatCount;
2890 If FLastFind = faIncSearch Then
2891 Begin
2892 If KeyCode = kbShift Then
2893 Begin
2894 KeyCode := kbNull;
2895 Exit;
2896 End;
2897 If KeyCode = kbAltGraf Then
2898 Begin
2899 KeyCode := kbNull;
2900 Exit;
2901 End;
2902 If KeyCode = kbBkSp Then
2903 Begin
2904 Delete(IncSearchText,Length(IncSearchText),1);
2905 If IncSearchList.Count > 0 Then
2906 Begin
2907 pp := IncSearchList.First; {Get previous Position}
2908 IncSearchList.Delete(0); {Delete entry}
2909 _GotoPosition(pp^);
2910 Dispose(pp);
2911 cmIncrementalSearch;
2912 If IncSearchList.Count > 0 Then
2913 Begin
2914 pp := IncSearchList.First;
2915 IncSearchList.Delete(0); {Remove Last Position from stack}
2916 Dispose(pp);
2917 End;
2918 InvalidateEditor(0,0);
2919 KeyCode := kbNull;
2920 Exit;
2921 End;
2922 End;
2923 FLastFind := faNothing;
2924 SetIncSearchText('');
2925 IncSearchText := '';
2926 End;
2927
2928 Case FKeyMap Of
2929 kmWordStar: MsgHandled := EmulateWordStar(KeyCode,FPreCtrl);
2930 kmCUA: MsgHandled := EmulateCUA(KeyCode,FPreCtrl);
2931 kmDefault: MsgHandled := EmulateDefault(KeyCode,FPreCtrl);
2932 Else Beep(100,100);
2933 End;
2934
2935 If MsgHandled Then KeyCode := kbNull
2936 Else Inherited ScanEvent(KeyCode,RepeatCount);
2937End;
2938
2939
2940{IDE Classic}
2941Function TEditor.EmulateWordStar(Var KeyCode,PreControl:TKeyCode):Boolean;
2942Var P:TEditorPos;
2943 key:TKeyCode;
2944Begin
2945 Result := True;
2946 key := KeyCode;
2947 KeyCode := PreControl Or KeyCode;
2948 If Not (key In [kbCtrl,kbShift]) Then PreControl := 0;
2949
2950 Case KeyCode Of
2951 kbCtrlS : cmCursorLeft;
2952 kbCtrlD : cmCursorRight;
2953 kbCtrlE : cmCursorUp;
2954 kbCtrlX : cmCursorDown;
2955 kbCtrlR : cmCursorPageUp;
2956 kbCtrlC : cmCursorPageDown;
2957 kbCtrlW : cmCursorRollDown;
2958 kbCtrlZ : cmCursorRollUp;
2959 kbCtrlF : cmCursorWordRight;
2960 kbCtrlA : cmCursorWordLeft;
2961 kbCtrlQR : cmCursorFileBegin;
2962 kbCtrlQC : cmCursorFileEnd;
2963 kbCtrlQE : cmCursorPageHome;
2964 kbCtrlQX : cmCursorPageEnd;
2965 {kbCtrlQT : ;}
2966 {kbCtrlQU : ;}
2967 kbCtrlQB : If GetSelectionStart(P) Then GotoPosition(P);
2968 kbCtrlQK : If GetSelectionEnd(P) Then GotoPosition(P);
2969 kbCtrlQS : cmCursorHome;
2970 kbCtrlQD : cmCursorEnd;
2971 kbCtrlQF : cmFindText;
2972 kbCtrlQA : cmReplaceText;
2973 kbCtrlQI : cmIncrementalSearch; {*}
2974 kbCtrlQY : cmDeleteLineEnd;
2975 kbCtrlKB : SetSelectionStart(FFileCursor);
2976 kbCtrlKK : SetSelectionEnd(FFileCursor);
2977 kbCtrlKT : SelectWord(FFileCursor);
2978 kbCtrlKL : SelectLine(FFileCursor);
2979 kbCtrlV : ToggleInsertMode;
2980 kbCtrlKH : If ICBVisible Then HideSelection
2981 Else ShowSelection;
2982 kbCtrlKR : cmICBReadBlock;
2983 kbCtrlKW : cmICBWriteBlock;
2984 kbCtrlKU : cmICBMoveLeft;
2985 kbCtrlKI : cmICBMoveRight;
2986 kbCtrlKC : cmICBCopyBlock;
2987 kbCtrlKV : cmICBMoveBlock;
2988 kbCtrlKY : cmICBDeleteBlock;
2989 kbCtrlKN : cmICBUpcaseBlock;
2990 kbCtrlKO : cmICBLowcaseBlock;
2991 kbCtrlKF : cmICBUpcaseWord;
2992 kbCtrlKE : cmICBLowcaseWord;
2993 kbCtrlKS : SaveFile;
2994 kbCtrlN : cmBreakLine;
2995 kbCtrlY : cmDeleteLine;
2996 kbCtrlT : cmDeleteRightWord;
2997 kbCtrlBkSp : cmDeleteLeftWord;
2998 kbCtrlI : cmTabulator;
2999 kbCtrlG : cmDeleteChar;
3000 kbCtrlH : cmBackSpace;
3001 kbCtrlL : cmSearchTextAgain;
3002 kbCtrlShiftS : cmIncrementalSearch;
3003
3004 kbCLeft : cmCursorLeft;
3005 kbCRight : cmCursorRight;
3006 kbCUp : cmCursorUp;
3007 kbCDown : cmCursorDown;
3008 kbHome : cmCursorHome;
3009 kbEnd : cmCursorEnd;
3010 kbPageDown : cmCursorPageDown;
3011 kbPageUp : cmCursorPageUp;
3012 kbCtrlCLeft : cmCursorWordLeft;
3013 kbCtrlCRight : cmCursorWordRight;
3014 kbCtrlCUp : cmICBUpcaseBlock; {*}
3015 kbCtrlCDown : cmICBLowcaseBlock; {*}
3016 kbCtrlPageUp : cmCursorFileBegin;
3017 kbCtrlPageDown : cmCursorFileEnd;
3018 kbCtrlHome : cmCursorPageHome;
3019 kbCtrlEnd : cmCursorPageEnd;
3020 kbShiftCLeft : cmICBExtLeft;
3021 kbShiftCRight : cmICBExtRight;
3022 kbShiftCUp : cmICBExtUp;
3023 kbShiftCDown : cmICBExtDown;
3024 kbShiftPageUp : cmICBExtPageUp;
3025 kbShiftPageDown : cmICBExtPageDown;
3026 kbShiftHome : cmICBExtHome;
3027 kbShiftEnd : cmICBExtEnd;
3028 kbAltShiftCLeft : Begin SelectMode:=smColumnBlock; cmICBExtLeft; End;
3029 kbAltShiftCRight : Begin SelectMode:=smColumnBlock; cmICBExtRight; End;
3030 kbAltShiftCUp : Begin SelectMode:=smColumnBlock; cmICBExtUp; End;
3031 kbAltShiftCDown : Begin SelectMode:=smColumnBlock; cmICBExtDown; End;
3032 kbAltShiftPageUp : Begin SelectMode:=smColumnBlock; cmICBExtPageUp; End;
3033 kbAltShiftPageDown : Begin SelectMode:=smColumnBlock; cmICBExtPageDown; End;
3034 kbAltShiftHome : Begin SelectMode:=smColumnBlock; cmICBExtHome; End;
3035 kbAltShiftEnd : Begin SelectMode:=smColumnBlock; cmICBExtEnd; End;
3036 kbCtrlShiftCLeft : cmICBExtWordLeft;
3037 kbCtrlShiftCRight : cmICBExtWordRight;
3038 kbCtrlShiftHome : cmICBExtPageBegin;
3039 kbCtrlShiftEnd : cmICBExtPageEnd;
3040 kbCtrlShiftPageUp : cmICBExtFileBegin;
3041 kbCtrlShiftPageDown : cmICBExtFileEnd;
3042 kbCtrlAltShiftCLeft : Begin SelectMode:=smColumnBlock; cmICBExtWordLeft; End;
3043 kbCtrlAltShiftCRight: Begin SelectMode:=smColumnBlock; cmICBExtWordRight; End;
3044 kbCtrlAltShiftHome : Begin SelectMode:=smColumnBlock; cmICBExtPageBegin; End;
3045 kbCtrlAltShiftEnd : Begin SelectMode:=smColumnBlock; cmICBExtPageEnd; End;
3046 kbCtrlAltShiftPageUp: Begin SelectMode:=smColumnBlock; cmICBExtFileBegin; End;
3047 kbCtrlAltShiftPageDown : Begin SelectMode:=smColumnBlock; cmICBExtFileEnd; End;
3048 kbCtrlSlash : SelectAll; {*}
3049 kbCtrlBackSlash : DeselectAll; {*}
3050 kbCtrlK0..kbCtrlK9 : SetBookMark((KeyCode And Not kbPreCtrlK)-48,FFileCursor);
3051 kbCtrlQ0..kbCtrlQ9 : GotoBookMark((KeyCode And Not kbPreCtrlQ)-48);
3052 kbCtrl0..kbCtrl9 : GotoBookMark((KeyCode And Not (kb_Ctrl+kb_Char))-48);
3053 kbCtrlU0..kbCtrlU9 : ClearBookMark((KeyCode And Not kbPreCtrlU)-48); {*}
3054 kbCtrlUU : ClearAllBookMarks; {*}
3055 kbAltBkSp : Undo;
3056 kbAltShiftBkSp : Redo;
3057 kbAltCLeft : cmICBMoveLeft;
3058 kbAltCRight : cmICBMoveRight;
3059 kbTab : cmTabulator;
3060 kbShiftTab : cmPrevTabulator;
3061 kbDel : cmDeleteChar;
3062 kbBkSp : cmBackSpace;
3063 kbShiftBkSp : cmBackSpace;
3064 kbShiftSpace : CharEvent(SpaceChar,1);
3065 kbCtrlSpace : CharEvent(SpaceChar,1);
3066 kbCR,
3067 kbShiftCR : cmEnter;
3068 {$IFDEF OS2}
3069 kbEnter,
3070 kbShiftEnter : cmEnter;
3071 {$ENDIF}
3072 kbCtrlDel : cmICBDeleteBlock;
3073 kbShiftDel : CutToClipBoard;
3074 kbCtrlIns : CopyToClipboard;
3075 kbShiftIns : PasteFromClipBoard;
3076 kbIns : ToggleInsertMode;
3077 kbCtrlOC : SelectMode := smColumnBlock;
3078 kbCtrlOK : SelectMode := smNonInclusiveBlock;
3079 {kbCtrlOI : SelectMode := smInklusiveBlock;
3080 kbCtrlOL : SelectMode := smLineBlock;}
3081 kbCtrlOU : cmToggleCase;
3082 kbCtrlShiftR : cmRecordMacro;
3083 kbCtrlShiftP : cmPlayMacro;
3084 kbCtrlK : PreControl := kbPreCtrlK;
3085 kbCtrlQ : PreControl := kbPreCtrlQ;
3086 kbCtrlU : PreControl := kbPreCtrlU;
3087 kbCtrlO : PreControl := kbPreCtrlO;
3088 Else Result := False;
3089 End;
3090End;
3091
3092
3093{CUA}
3094Function TEditor.EmulateCUA(Var KeyCode,PreControl:TKeyCode):Boolean;
3095Var key:TKeyCode;
3096Begin
3097 Result := True;
3098 key := KeyCode;
3099 KeyCode := PreControl Or KeyCode;
3100 If Not (key In [kbCtrl,kbShift]) Then PreControl := 0;
3101
3102 Case KeyCode Of
3103 kbCtrlF7 : cmICBMoveLeft;
3104 kbCtrlF8 : cmICBMoveRight;
3105 kbCtrlBkSp : cmDeleteLine;
3106 kbCtrlY : cmDeleteLine;
3107 kbCtrlS : cmFindText;
3108 kbCtrlF : cmFindText;
3109 kbCtrlR : cmReplaceText;
3110 kbCtrlN : cmSearchTextAgain;
3111 kbCtrlE : cmIncrementalSearch;
3112 kbCtrlI : cmIncrementalSearch;
3113 kbCLeft : cmCursorLeft;
3114 kbCRight : cmCursorRight;
3115 kbCUp : cmCursorUp;
3116 kbCDown : cmCursorDown;
3117 kbHome : cmCursorHome;
3118 kbEnd : cmCursorEnd;
3119 kbPageDown : cmCursorPageDown;
3120 kbPageUp : cmCursorPageUp;
3121 kbCtrlCLeft : cmCursorWordLeft;
3122 kbCtrlCRight : cmCursorWordRight;
3123 kbCtrlCUp : cmICBUpcaseBlock;
3124 kbCtrlCDown : cmICBLowcaseBlock;
3125 kbCtrlPageUp : cmCursorPageHome;
3126 kbCtrlPageDown : cmCursorPageEnd;
3127 kbCtrlHome : cmCursorFileBegin;
3128 kbCtrlEnd : cmCursorFileEnd;
3129 kbShiftCLeft : cmICBExtLeft;
3130 kbShiftCRight : cmICBExtRight;
3131 kbShiftCUp : cmICBExtUp;
3132 kbShiftCDown : cmICBExtDown;
3133 kbShiftPageUp : cmICBExtPageUp;
3134 kbShiftPageDown : cmICBExtPageDown;
3135 kbShiftHome : cmICBExtHome;
3136 kbShiftEnd : cmICBExtEnd;
3137 kbCtrlShiftCLeft : cmICBExtWordLeft;
3138 kbCtrlShiftCRight : cmICBExtWordRight;
3139 kbCtrlShiftHome : cmICBExtFileBegin;
3140 kbCtrlShiftEnd : cmICBExtFileEnd;
3141 kbCtrlShiftPageUp : cmICBExtPageBegin;
3142 kbCtrlShiftPageDown : cmICBExtPageEnd;
3143 kbCtrlSlash : SelectAll;
3144 kbCtrlBackSlash : DeselectAll;
3145 kbCtrlK0..kbCtrlK9 : SetBookMark((KeyCode And Not kbPreCtrlK)-48,FFileCursor);
3146 kbCtrlQ0..kbCtrlQ9 : GotoBookMark((KeyCode And Not kbPreCtrlQ)-48);
3147 kbCtrlU0..kbCtrlU9 : ClearBookMark((KeyCode And Not kbPreCtrlU)-48);
3148 kbCtrlUU : ClearAllBookMarks;
3149 kbAltBkSp : Undo;
3150 kbAltShiftBkSp : Redo;
3151 kbAltCLeft : cmICBMoveLeft;
3152 kbAltCRight : cmICBMoveRight;
3153 kbTab : cmTabulator;
3154 kbShiftTab : cmPrevTabulator;
3155 kbDel : cmDeleteChar;
3156 kbBkSp : cmBackSpace;
3157 kbShiftBkSp : cmBackSpace;
3158 kbShiftSpace : CharEvent(SpaceChar,1);
3159 kbCtrlSpace : CharEvent(SpaceChar,1);
3160 kbCR,
3161 kbShiftCR : cmEnter;
3162 {$IFDEF OS2}
3163 kbEnter,
3164 kbShiftEnter : cmEnter;
3165 {$ENDIF}
3166 kbCtrlDel : cmICBDeleteBlock;
3167 kbShiftDel : CutToClipBoard;
3168 kbCtrlIns : CopyToClipboard;
3169 kbShiftIns : PasteFromClipBoard;
3170 kbIns : ToggleInsertMode;
3171 kbCtrlShiftR : cmRecordMacro;
3172 kbCtrlShiftP : cmPlayMacro;
3173 kbCtrlK : PreControl := kbPreCtrlK;
3174 kbCtrlQ : PreControl := kbPreCtrlQ;
3175 kbCtrlU : PreControl := kbPreCtrlU;
3176 Else Result := False;
3177 End;
3178End;
3179
3180
3181{Delphi Default}
3182Function TEditor.EmulateDefault(Var KeyCode,PreControl:TKeyCode):Boolean;
3183Var P:TEditorPos;
3184 key:TKeyCode;
3185Begin
3186 Result := True;
3187 key := KeyCode;
3188 KeyCode := PreControl Or KeyCode;
3189 If Not (key In [kbCtrl,kbShift]) Then PreControl := 0;
3190
3191 Case KeyCode Of
3192 kbCtrlS : SaveFile;
3193 kbCtrlE : cmIncrementalSearch;
3194 kbCtrlR : cmReplaceText;
3195 kbCtrlF : cmFindText;
3196 kbCtrlI : cmTabulator;
3197 kbCtrlN : cmBreakLine;
3198 kbCtrlT : cmDeleteRightWord;
3199 kbCtrlY : cmDeleteLine;
3200 kbCtrlZ : Undo;
3201 kbCtrlShiftI : cmICBMoveRight;
3202 kbCtrlShiftU : cmICBMoveLeft;
3203 kbCtrlShiftY : cmDeleteLineEnd;
3204 kbCtrlShiftZ : Redo;
3205 kbHome : cmCursorHome;
3206 kbEnd : cmCursorEnd;
3207 kbCR,
3208 kbShiftCR : cmEnter;
3209 {$IFDEF OS2}
3210 kbEnter,
3211 kbShiftEnter : cmEnter;
3212 {$ENDIF}
3213 kbIns : ToggleInsertMode;
3214 kbDel : cmDeleteChar;
3215 kbBkSp : cmBackSpace;
3216 kbTab : cmTabulator;
3217 kbCLeft : cmCursorLeft;
3218 kbCRight : cmCursorRight;
3219 kbCUp : cmCursorUp;
3220 kbCDown : cmCursorDown;
3221 kbPageDown : cmCursorPageDown;
3222 kbPageUp : cmCursorPageUp;
3223 kbCtrlCLeft : cmCursorWordLeft;
3224 kbCtrlCRight : cmCursorWordRight;
3225 kbCtrlBkSp : cmDeleteLeftWord;
3226 kbCtrlPageUp : cmCursorPageHome;
3227 kbCtrlPageDown : cmCursorPageEnd;
3228 kbCtrlHome : cmCursorFileBegin;
3229 kbCtrlEnd : cmCursorFileEnd;
3230 kbCtrlSpace : CharEvent(SpaceChar,1);
3231 kbCtrlDel : cmICBDeleteBlock;
3232 kbCtrlCUp : cmCursorRollDown;
3233 kbCtrlCDown : cmCursorRollUp;
3234 kbShiftTab : cmPrevTabulator;
3235 kbShiftBkSp : cmBackSpace;
3236 kbShiftCLeft : cmICBExtLeft;
3237 kbShiftCRight : cmICBExtRight;
3238 kbShiftCUp : cmICBExtUp;
3239 kbShiftCDown : cmICBExtDown;
3240 kbShiftPageUp : cmICBExtPageUp;
3241 kbShiftPageDown : cmICBExtPageDown;
3242 kbShiftHome : cmICBExtHome;
3243 kbShiftEnd : cmICBExtEnd;
3244 kbShiftSpace : CharEvent(SpaceChar,1);
3245 kbAltBkSp : Undo;
3246 kbAltShiftBkSp : Redo;
3247 kbAltCLeft : cmICBMoveLeft;
3248 kbAltCRight : cmICBMoveRight;
3249 kbAltShiftCLeft : Begin SelectMode:=smColumnBlock; cmICBExtLeft; End;
3250 kbAltShiftCRight : Begin SelectMode:=smColumnBlock; cmICBExtRight; End;
3251 kbAltShiftCUp : Begin SelectMode:=smColumnBlock; cmICBExtUp; End;
3252 kbAltShiftCDown : Begin SelectMode:=smColumnBlock; cmICBExtDown; End;
3253 kbAltShiftPageUp : Begin SelectMode:=smColumnBlock; cmICBExtPageUp; End;
3254 kbAltShiftPageDown : Begin SelectMode:=smColumnBlock; cmICBExtPageDown; End;
3255 kbAltShiftHome : Begin SelectMode:=smColumnBlock; cmICBExtHome; End;
3256 kbAltShiftEnd : Begin SelectMode:=smColumnBlock; cmICBExtEnd; End;
3257 kbCtrlShiftCLeft : cmICBExtWordLeft;
3258 kbCtrlShiftCRight : cmICBExtWordRight;
3259 kbCtrlShiftHome : cmICBExtFileBegin;
3260 kbCtrlShiftEnd : cmICBExtFileEnd;
3261 kbCtrlShiftPageUp : cmICBExtPageBegin;
3262 kbCtrlShiftPageDown : cmICBExtPageEnd;
3263 kbCtrlAltShiftCLeft : Begin SelectMode:=smColumnBlock; cmICBExtWordLeft; End;
3264 kbCtrlAltShiftCRight: Begin SelectMode:=smColumnBlock; cmICBExtWordRight; End;
3265 kbCtrlAltShiftHome : Begin SelectMode:=smColumnBlock; cmICBExtFileBegin; End;
3266 kbCtrlAltShiftEnd : Begin SelectMode:=smColumnBlock; cmICBExtFileEnd; End;
3267 kbCtrlAltShiftPageUp: Begin SelectMode:=smColumnBlock; cmICBExtPageBegin; End;
3268 kbCtrlAltShiftPageDown : Begin SelectMode:=smColumnBlock; cmICBExtPageEnd; End;
3269 kbCtrlKB : SetSelectionStart(FFileCursor);
3270 kbCtrlKC : cmICBCopyBlock;
3271 kbCtrlKH : If ICBVisible Then HideSelection
3272 Else ShowSelection;
3273 kbCtrlKI : cmICBMoveRight;
3274 kbCtrlKK : SetSelectionEnd(FFileCursor);
3275 kbCtrlKL : SelectLine(FFileCursor);
3276 kbCtrlKN : cmICBUpcaseBlock;
3277 kbCtrlKO : cmICBLowcaseBlock;
3278 kbCtrlKR : cmICBReadBlock;
3279 kbCtrlKT : SelectWord(FFileCursor);
3280 kbCtrlKU : cmICBMoveLeft;
3281 kbCtrlKV : cmICBMoveBlock;
3282 kbCtrlKW : cmICBWriteBlock;
3283 kbCtrlKY : cmICBDeleteBlock;
3284 kbCtrlOC : SelectMode := smColumnBlock;
3285 kbCtrlOK : SelectMode := smNonInclusiveBlock;
3286 {kbCtrlOI : SelectMode := smInklusiveBlock;
3287 kbCtrlOL : SelectMode := smLineBlock;}
3288 kbCtrlQB : If GetSelectionStart(P) Then GotoPosition(P);
3289 kbCtrlQC : cmCursorFileEnd;
3290 kbCtrlQD : cmCursorEnd;
3291 kbCtrlQE : cmCursorPageHome;
3292 kbCtrlQK : If GetSelectionEnd(P) Then GotoPosition(P);
3293 kbCtrlQR : cmCursorFileBegin;
3294 kbCtrlQS : cmCursorHome;
3295 {kbCtrlQT : ;}
3296 {kbCtrlQU : ;}
3297 kbCtrlQX : cmCursorPageEnd;
3298 kbCtrlK0..kbCtrlK9 : SetBookMark((KeyCode And Not kbPreCtrlK)-48,FFileCursor);
3299 kbCtrlQ0..kbCtrlQ9 : GotoBookMark((KeyCode And Not kbPreCtrlQ)-48);
3300 kbCtrl0..kbCtrl9 : GotoBookMark((KeyCode And Not (kb_Ctrl+kb_Char))-48);
3301 kbCtrlU0..kbCtrlU9 : ClearBookMark((KeyCode And Not kbPreCtrlU)-48); {*}
3302 kbCtrlUU : ClearAllBookMarks; {*}
3303 kbCtrlKF : cmICBUpcaseWord;
3304 kbCtrlKE : cmICBLowcaseWord;
3305 kbCtrlKS : SaveFile;
3306 kbCtrlQF : cmFindText;
3307 kbCtrlQA : cmReplaceText;
3308 kbCtrlQI : cmIncrementalSearch; {*}
3309 kbCtrlQY : cmDeleteLineEnd;
3310 kbCtrlOU : cmToggleCase;
3311 kbShiftDel : CutToClipBoard;
3312 kbCtrlIns : CopyToClipboard;
3313 kbShiftIns : PasteFromClipBoard;
3314 kbCtrlX : CutToClipBoard;
3315 kbCtrlC : CopyToClipboard;
3316 kbCtrlV : PasteFromClipBoard;
3317 kbCtrlShiftR : cmRecordMacro;
3318 kbCtrlShiftP : cmPlayMacro;
3319 //kbCtrlCUp : cmICBUpcaseBlock; {*}
3320 //kbCtrlCDown : cmICBLowcaseBlock; {*}
3321 kbCtrlSlash : SelectAll; {*}
3322 kbCtrlBackSlash : DeselectAll; {*}
3323 kbCtrlK : PreControl := kbPreCtrlK;
3324 kbCtrlQ : PreControl := kbPreCtrlQ;
3325 kbCtrlU : PreControl := kbPreCtrlU;
3326 kbCtrlO : PreControl := kbPreCtrlO;
3327 Else Result := False;
3328 End;
3329End;
3330
3331
3332{Window Is getting the Focus}
3333Procedure TEditor.SetFocus;
3334Begin
3335 If HadFocus = 0 Then HadFocus := 1;
3336 If FCaret <> Nil Then
3337 If FCaret.created Then
3338 Begin
3339 FCaret.SetSize(FCaret.Width,FCaret.Height);
3340 FCaret.SetPos(FCaret.Left,FCaret.Bottom);
3341 If FCaret.BlinkTime <> 0
3342 Then FCaret.BlinkTime := FCaret.BlinkTime;
3343 FCaret.Show;
3344 End;
3345
3346 Inherited SetFocus;
3347 FPreCtrl := 0;
3348End;
3349
3350
3351{Window Is loosing the Focus}
3352Procedure TEditor.KillFocus;
3353Begin
3354 HadFocus := 0;
3355 If FCaret <> Nil Then
3356 If FCaret.created Then
3357 Begin
3358 {$IFDEF Win95}
3359 FCaret.BlinkTime := -1;
3360 {$ENDIF}
3361 FCaret.Remove;
3362 FCaret.created := True; //Deleted by DestroyCursor
3363 End;
3364
3365 Inherited KillFocus;
3366End;
3367
3368
3369{Window Change its Size}
3370Procedure TEditor.Resize;
3371Begin
3372 Inherited Resize;
3373 CalcSizes;
3374End;
3375
3376
3377{$HINTS OFF}
3378Procedure TEditor.MouseDblClick(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
3379Begin
3380 Inherited MouseDblClick(Button,ShiftState,X,Y);
3381
3382 If Button <> mbLeft Then Exit;
3383
3384 If FEditOpt * [eo2ClickLine] <> [] Then SelectLine(FFileCursor)
3385 Else SelectWord(FFileCursor);
3386 HadFocus := 1; {ignore MouseMove}
3387 LastMsg.Handled := True;
3388End;
3389{$HINTS ON}
3390
3391
3392Procedure TEditor.MouseDown(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
3393Var Scr:TEditorPos;
3394 T:Integer;
3395 iew:Boolean;
3396Begin
3397 Inherited MouseDown(Button,ShiftState,X,Y);
3398
3399 If Button <> mbLeft Then Exit;
3400
3401 LastMsg.Handled := True;
3402 MouseCapture := True;
3403 If HadFocus = 0 Then Exit; {receive Focus}
3404 HadFocus := 2;
3405
3406 If FindICB.First.Line <> Nil Then
3407 Begin
3408 FindICB.First.Line := Nil;
3409 InvalidateEditor(0,0);
3410 End;
3411 Update;
3412 (*Undo*)
3413 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3414 LastUndoGroup := ugCursorMove;
3415 (*Undo*)
3416
3417 FlushWorkLine;
3418 Scr := GetCursorFromMouse(Point(X,Y));
3419
3420 If Scr.X < 1 Then Scr.X := 1;
3421 If Scr.X > FWinSize.X Then Scr.X := FWinSize.X;
3422 If Scr.Y < 1 Then Scr.Y := 1;
3423 If Scr.Y > FWinSize.Y Then Scr.Y := FWinSize.Y;
3424
3425 If Scr.X > FScrCursor.X Then Inc(FFileCursor.X,Scr.X-FScrCursor.X)
3426 Else Dec(FFileCursor.X,FScrCursor.X-Scr.X);
3427 FScrCursor.X := Scr.X;
3428
3429 If (FFileCursor.Y+Scr.Y)-FScrCursor.Y > FCountLines
3430 Then Scr.Y := FCountLines-FFileCursor.Y+FScrCursor.Y;
3431
3432 If Scr.Y > FScrCursor.Y Then
3433 Begin
3434 Inc(FFileCursor.Y,Scr.Y-FScrCursor.Y);
3435 For T := 1 To Scr.Y-FScrCursor.Y Do FActLine := FActLine^.Next;
3436 FScrCursor.Y := Scr.Y;
3437 End
3438 Else
3439 Begin
3440 Dec(FFileCursor.Y,FScrCursor.Y-Scr.Y);
3441 For T := 1 To FScrCursor.Y-Scr.Y Do FActLine := FActLine^.Prev;
3442 FScrCursor.Y := Scr.Y;
3443 End;
3444
3445 iew := _ICBExtSetICB;
3446 _ICBSetMark;
3447 ICBVisible := True;
3448 {iew := iew Or _ICBTestIEW; {Extended Selection}
3449 If iew Then InvalidateEditor(0,0)
3450 Else SetScreenCursor;
3451
3452 FCaret.Hide;
3453End;
3454
3455
3456Procedure TEditor.MouseUp(Button:TMouseButton;ShiftState:TShiftState;X,Y:LongInt);
3457Begin
3458 If Button = mbLeft Then
3459 Begin
3460 If HadFocus > 0 Then FCaret.Show;
3461 HadFocus := 1;
3462 _ICBExtCorrectICB2;
3463 End;
3464
3465 Inherited MouseUp(Button,ShiftState,X,Y);
3466
3467 If Button = mbLeft Then
3468 Begin
3469 LastMsg.Handled := True;
3470 MouseCapture := False;
3471 End;
3472End;
3473
3474
3475Procedure TEditor.MouseMove(ShiftState:TShiftState;X,Y:LongInt);
3476Var Scr:TEditorPos;
3477 FC:TLineX;
3478 iew:Boolean;
3479 Down:Boolean;
3480 ScrY:Integer;
3481 y1,y2:Integer;
3482Begin
3483 Inherited MouseMove(ShiftState,X,Y);
3484
3485 LastMsg.Handled := True;
3486 If HadFocus < 2 Then Exit;
3487 If ShiftState * [ssLeft] = [] Then Exit;
3488 MouseCapture := True; {!!}
3489
3490 FC := _ICBActPos;
3491 Scr := GetCursorFromMouse(Point(X,Y));
3492
3493 KeyRepeat := Abs(Scr.X - FScrCursor.X);
3494 If Scr.X > FScrCursor.X Then iew := _CursorRight
3495 Else iew := _CursorLeft;
3496
3497 ScrY := FScrCursor.Y;
3498 Down := Scr.Y > FScrCursor.Y;
3499 KeyRepeat := Abs(Scr.Y - FScrCursor.Y);
3500 If Scr.Y > FScrCursor.Y Then iew := _CursorDown Or iew
3501 Else iew := _CursorUp Or iew;
3502
3503 _ICBClearMark;
3504 If FC = ICB.First Then ICB.First := _ICBActPos
3505 Else ICB.Last := _ICBActPos;
3506
3507 _ICBExtCorrectICB;
3508 _ICBSetMark;
3509 ICBVisible := True;
3510
3511 If Not iew Then
3512 Begin
3513 If Down Then
3514 Begin
3515 y1 := ScrY;
3516 y2 := FScrCursor.Y;
3517 End
3518 Else
3519 Begin
3520 y1 := FScrCursor.Y;
3521 y2 := ScrY;
3522 End;
3523 _ICBTestIEW(y1,y2); {Extended Selection}
3524 InvalidateEditor(y1,y2)
3525 End
3526 Else InvalidateEditor(0,0);
3527End;
3528
3529
3530
3531Procedure TEditor.Scroll(Sender:TScrollBar;ScrollCode:TScrollCode;Var ScrollPos:LongInt);
3532Var SliderValue:LongInt;
3533 L,cnt:LongInt;
3534Begin
3535 Inherited Scroll(Sender,ScrollCode,ScrollPos);
3536
3537 If (Sender <> FBottomScrollBar) And (Sender <> FRightScrollBar) Then Exit;
3538
3539 (*Undo*)
3540 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3541 LastUndoGroup := ugCursorMove;
3542 (*Undo*)
3543
3544 Case ScrollCode Of
3545 scColumnLeft,
3546 scColumnRight,
3547 scPageLeft,
3548 scPageRight,
3549 scHorzTrack,
3550 scHorzPosition:
3551 Begin
3552 FFileCursor.X := ScrollPos + FScrCursor.X -1;
3553 If Not _ICBPersistent Then _ICBClearICB;
3554 InvalidateEditor(0,0);
3555 End;
3556 scLineUp: cmCursorRollDown;
3557 scLineDown: cmCursorRollUp;
3558 scPageUp: cmCursorPageUp;
3559 scPageDown: cmCursorPageDown;
3560 scVertTrack,
3561 scVertPosition:
3562 Begin
3563 FlushWorkLine;
3564
3565 SliderValue := FFileCursor.Y - FScrCursor.Y + 1;
3566 If ScrollPos = SliderValue Then Exit;
3567
3568 If ScrollPos > SliderValue Then {downward}
3569 Begin
3570 cnt := ScrollPos - SliderValue;
3571 For L := 1 To cnt Do
3572 Begin
3573 If FActLine^.Next <> Nil Then
3574 Begin
3575 Inc(FFileCursor.Y);
3576 FActLine := FActLine^.Next;
3577 FTopScreenLine := FTopScreenLine^.Next;
3578 End;
3579 End;
3580 End
3581 Else
3582 Begin {upward}
3583 cnt := SliderValue - ScrollPos;
3584 For L := 1 To cnt Do
3585 Begin
3586 If FTopScreenLine^.Prev <> Nil Then
3587 Begin
3588 Dec(FFileCursor.Y);
3589 FActLine := FActLine^.Prev;
3590 FTopScreenLine := FTopScreenLine^.Prev;
3591 End;
3592 End;
3593 End;
3594 If Not _ICBPersistent Then _ICBClearICB;
3595 InvalidateEditor(0,0);
3596 End;
3597 End;
3598
3599 If Sender = FBottomScrollBar
3600 Then ScrollPos := FFileCursor.X - FScrCursor.X + 1
3601 Else ScrollPos := FFileCursor.Y - FScrCursor.Y + 1;
3602End;
3603
3604
3605Procedure TEditor.SetSliderValues;
3606Begin
3607 If IgnoreRedraw > 0 Then Exit;
3608 If FBottomScrollBar <> Nil
3609 Then FBottomScrollBar.SetScrollRange(1,StringLength,FWinSize.X);
3610 If FRightScrollBar <> Nil
3611 Then FRightScrollBar.SetScrollRange(1,FCountLines,FWinSize.Y);
3612
3613 SetSliderPosition;
3614End;
3615
3616
3617Procedure TEditor.SetSliderPosition;
3618Var xl:LongInt;
3619Begin
3620 If IgnoreRedraw > 0 Then Exit;
3621 If FBottomScrollBar <> Nil Then
3622 Begin
3623 xl := FFileCursor.X - FScrCursor.X + 1;
3624 FBottomScrollBar.Position := xl; {LongInt Property !}
3625 End;
3626 If FRightScrollBar <> Nil
3627 Then FRightScrollBar.Position := FFileCursor.Y - FScrCursor.Y + 1;
3628End;
3629
3630
3631Procedure TEditor.CalcSizes;
3632Var CursorMoved:Boolean;
3633 FC:TEditorPos;
3634Begin
3635 ClientArea := ClientRect;
3636 {??????????+-1}
3637 Inc(ClientArea.Right);
3638 Inc(ClientArea.Top);
3639 FWinSize.X := (ClientArea.Right - ClientArea.Left -
3640 IndentRect.Left - IndentRect.Right -
3641 2 * Integer(FBorderWidth)) Div Canvas.FontWidth;
3642 FWinSize.Y := (ClientArea.Top - ClientArea.Bottom -
3643 IndentRect.Bottom - IndentRect.Top -
3644 2 * Integer(FBorderWidth)) Div Canvas.FontHeight;
3645
3646
3647 CursorMoved := False;
3648 If FScrCursor.Y > FWinSize.Y Then
3649 Begin
3650 FC.Y := FFileCursor.Y-FScrCursor.Y+FWinSize.Y;
3651 CursorMoved := True;
3652 End
3653 Else FC.Y := FFileCursor.Y;
3654 If FScrCursor.X > FWinSize.X Then
3655 Begin
3656 FC.X := FFileCursor.X-FScrCursor.X+FWinSize.X;
3657 CursorMoved := True;
3658 End
3659 Else FC.X := FFileCursor.X;
3660 If CursorMoved Then
3661 Begin
3662 Inc(IgnoreRedraw);
3663 GotoPosition(FC);
3664 Dec(IgnoreRedraw);
3665 End;
3666 SetScreenCursor;
3667 SetSliderValues;
3668End;
3669
3670
3671{ +++ CursorMove-Events ++++++++++++++++++++++++++++++++++++++++++++++++++++ }
3672
3673Procedure TEditor.cmCursorDown;
3674Var iew:Boolean;
3675Begin
3676 If FWinSize.Y = 0 Then Exit;
3677 (*Undo*)
3678 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3679 (*Undo*)
3680
3681 iew := _CursorDown;
3682 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3683
3684 If iew Then InvalidateEditor(0,0)
3685 Else SetScreenCursor;
3686 (*Undo*)
3687 LastUndoGroup := ugCursorMove;
3688 (*Undo*)
3689End;
3690
3691
3692Procedure TEditor.cmCursorUp;
3693Var iew:Boolean;
3694Begin
3695 If FWinSize.Y = 0 Then Exit;
3696 (*Undo*)
3697 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3698 (*Undo*)
3699
3700 iew := _CursorUp;
3701 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3702
3703 If iew Then InvalidateEditor(0,0)
3704 Else SetScreenCursor;
3705 (*Undo*)
3706 LastUndoGroup := ugCursorMove;
3707 (*Undo*)
3708End;
3709
3710
3711Procedure TEditor.cmCursorRight;
3712Var iew:Boolean;
3713 climb:Boolean;
3714Begin
3715 climb := False;
3716 If FEditOpt * [eoCursorClimb] <> [] Then
3717 If FFileCursor.X > Length(_PLine2PString(FActLine)^) Then
3718 If FFileCursor.Y < CountLines Then climb := True
3719 Else Exit;
3720
3721 If _ICBPersistent Then
3722 If (FFileCursor.X >= StringLength) And Not climb Then Exit;
3723
3724 (*Undo*)
3725 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3726 (*Undo*)
3727
3728 iew := _CursorRight;
3729 If climb Then
3730 Begin
3731 iew := _CursorDown Or iew;
3732 iew := _CursorHome Or iew;
3733 End;
3734 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3735
3736 If iew Then InvalidateEditor(0,0)
3737 Else SetScreenCursor;
3738 (*Undo*)
3739 LastUndoGroup := ugCursorMove;
3740 (*Undo*)
3741End;
3742
3743
3744Procedure TEditor.cmCursorLeft;
3745Var iew:Boolean;
3746 climb:Boolean;
3747Begin
3748 climb := False;
3749 If FEditOpt * [eoCursorClimb] <> [] Then
3750 If FFileCursor.X <= 1 Then
3751 If FFileCursor.Y > 1 Then climb := True
3752 Else Exit;
3753
3754 (*Undo*)
3755 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3756 (*Undo*)
3757
3758 iew := _CursorLeft;
3759 If climb Then
3760 Begin
3761 iew := _CursorUp Or iew;
3762 iew := _CursorEnd Or iew;
3763 End;
3764 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3765
3766 If iew Then InvalidateEditor(0,0)
3767 Else SetScreenCursor;
3768 (*Undo*)
3769 LastUndoGroup := ugCursorMove;
3770 (*Undo*)
3771End;
3772
3773
3774Procedure TEditor.cmCursorHome;
3775Var iew:Boolean;
3776 I,p1:Integer;
3777Begin
3778 If _ICBPersistent Then
3779 If FFileCursor.X = 1 Then Exit;
3780
3781 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3782 (*Undo*)
3783
3784 If Not WLactivated Then _ReadWorkLine;
3785 p1 := 1;
3786 If FEditOpt * [eoHomeFirstWord] <> [] Then
3787 Begin
3788 For I := 1 To FFileCursor.X-1 Do
3789 Begin
3790 If I > Length(FWorkLine) Then break;
3791
3792 If FWorkLine[I] > ' ' Then
3793 Begin
3794 p1 := I; {onto First Word}
3795 break;
3796 End;
3797 End;
3798 End;
3799
3800 If p1 > 1 Then
3801 Begin
3802 _HorizMove;
3803 FFileCursor.X := p1;
3804 FScrCursor.X := p1;
3805 If FScrCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X;
3806 iew := _HorizMove;
3807 End
3808 Else iew := _CursorHome;
3809 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3810
3811 If iew Then InvalidateEditor(0,0)
3812 Else SetScreenCursor;
3813 (*Undo*)
3814 LastUndoGroup := ugCursorMove;
3815 (*Undo*)
3816End;
3817
3818
3819Procedure TEditor.cmCursorEnd;
3820Var iew:Boolean;
3821 lzk:Integer;
3822Begin
3823 FlushWorkLine;
3824 lzk := Length(_PLine2PString(FActLine)^);
3825 If _ICBPersistent Then
3826 If FFileCursor.X = lzk+1 Then Exit;
3827 (*Undo*)
3828 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3829 (*Undo*)
3830
3831 iew := _CursorEnd;
3832 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3833
3834 If iew Then InvalidateEditor(0,0)
3835 Else SetScreenCursor;
3836 (*Undo*)
3837 LastUndoGroup := ugCursorMove;
3838 (*Undo*)
3839End;
3840
3841
3842Procedure TEditor.cmCursorPageDown;
3843Begin
3844 If _ICBPersistent Then
3845 If FFileCursor.Y >= FCountLines Then Exit;
3846 (*Undo*)
3847 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3848 (*Undo*)
3849
3850 _CursorPageDown;
3851 If Not _ICBPersistent Then _ICBClearICB;
3852
3853 InvalidateEditor(0,0);
3854 (*Undo*)
3855 LastUndoGroup := ugCursorMove;
3856 (*Undo*)
3857End;
3858
3859
3860Procedure TEditor.cmCursorPageUp;
3861Begin
3862 If _ICBPersistent Then
3863 If FFileCursor.Y <= 1 Then Exit;
3864 (*Undo*)
3865 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3866 (*Undo*)
3867
3868 _CursorPageUp;
3869 If Not _ICBPersistent Then _ICBClearICB;
3870
3871 InvalidateEditor(0,0);
3872 (*Undo*)
3873 LastUndoGroup := ugCursorMove;
3874 (*Undo*)
3875End;
3876
3877
3878Procedure TEditor.cmCursorRollDown;
3879Var FCY:LongInt;
3880Begin
3881 If FWinSize.Y = 0 Then Exit;
3882 If FTopScreenLine^.Prev = Nil Then Exit;
3883 (*Undo*)
3884 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3885 (*Undo*)
3886
3887 FCY := FFileCursor.Y;
3888 _CursorRollUp;
3889 If (Not _ICBPersistent) And (FCY <> FFileCursor.Y) Then _ICBClearICB;
3890
3891 InvalidateEditor(0,0);
3892 (*Undo*)
3893 LastUndoGroup := ugCursorMove;
3894 (*Undo*)
3895End;
3896
3897
3898Procedure TEditor.cmCursorRollUp;
3899Var FCY:LongInt;
3900Begin
3901 If FWinSize.Y = 0 Then Exit;
3902 If FActLine^.Next = Nil Then Exit;
3903 (*Undo*)
3904 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3905 (*Undo*)
3906
3907 FCY := FFileCursor.Y;
3908 _CursorRollDown;
3909 If (Not _ICBPersistent) And (FCY <> FFileCursor.Y) Then _ICBClearICB;
3910
3911 InvalidateEditor(0,0);
3912 (*Undo*)
3913 LastUndoGroup := ugCursorMove;
3914 (*Undo*)
3915End;
3916
3917
3918Procedure TEditor.cmCursorWordRight;
3919Var iew:Boolean;
3920Begin
3921 (*Undo*)
3922 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3923 (*Undo*)
3924
3925 iew := _CursorWordRight;
3926 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3927
3928 If iew Then InvalidateEditor(0,0)
3929 Else SetScreenCursor;
3930 (*Undo*)
3931 LastUndoGroup := ugCursorMove;
3932 (*Undo*)
3933End;
3934
3935
3936Procedure TEditor.cmCursorWordLeft;
3937Var iew:Boolean;
3938Begin
3939 (*Undo*)
3940 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
3941 (*Undo*)
3942
3943 iew := _CursorWordLeft;
3944 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
3945
3946 If iew Then InvalidateEditor(0,0)
3947 Else SetScreenCursor;
3948 (*Undo*)
3949 LastUndoGroup := ugCursorMove;
3950 (*Undo*)
3951End;
3952
3953
3954Procedure TEditor.cmCursorFileBegin;
3955Var P:TEditorPos;
3956Begin
3957 P.X := 1;
3958 P.Y := 1;
3959 GotoPosition(P);
3960End;
3961
3962
3963Procedure TEditor.cmCursorFileEnd;
3964Var P:TEditorPos;
3965Begin
3966 P.X := Length(_PLine2PString(FLastLine)^);
3967 Inc(P.X);
3968 P.Y := FCountLines;
3969 GotoPosition(P);
3970End;
3971
3972
3973Procedure TEditor.cmCursorPageHome;
3974Var P:TEditorPos;
3975Begin
3976 P.X := FFileCursor.X;
3977 P.Y := FFileCursor.Y-FScrCursor.Y+1;
3978 GotoPosition(P);
3979End;
3980
3981
3982Procedure TEditor.cmCursorPageEnd;
3983Var P:TEditorPos;
3984Begin
3985 P.X := FFileCursor.X;
3986 P.Y := FFileCursor.Y+FWinSize.Y-FScrCursor.Y;
3987 GotoPosition(P);
3988End;
3989
3990
3991{Extend Selection}
3992
3993Procedure TEditor.cmICBExtLeft;
3994Var iew:Boolean;
3995 y1,y2:Integer;
3996 climb:Boolean;
3997Label L;
3998Begin
3999 climb := False;
4000 If FEditOpt * [eoCursorClimb] <> [] Then
4001 If FSelectMode <> smColumnBlock Then
4002 If FFileCursor.X <= 1 Then
4003 If FFileCursor.Y > 1 Then climb := True
4004 Else Exit;
4005
4006 (*Undo*)
4007 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4008 LastUndoGroup := ugCursorMove;
4009 (*Undo*)
4010 iew := _ICBExtSetICB;
4011
4012 If _ICBActPos = ICB.First Then
4013 Begin
4014 iew := _CursorLeft Or iew;
4015 If climb Then
4016 Begin
4017 iew := _CursorUp Or iew;
4018 iew := _CursorEnd Or iew;
4019 End;
4020 ICB.First := _ICBActPos;
4021 Goto L;
4022 End;
4023
4024 If _ICBActPos = ICB.Last Then
4025 Begin
4026 iew := _CursorLeft Or iew;
4027 If climb Then
4028 Begin
4029 iew := _CursorUp Or iew;
4030 iew := _CursorEnd Or iew;
4031 End;
4032 ICB.Last := _ICBActPos;
4033 End;
4034L:
4035 _ICBExtCorrectICB;
4036 _ICBExtCorrectICB2;
4037 _ICBSetMark;
4038 ICBVisible := True;
4039 If Not iew Then
4040 Begin
4041 y1 := FScrCursor.Y;
4042 y2 := FScrCursor.Y;
4043 If climb Then Inc(y2);
4044 _ICBTestIEW(y1,y2); {Extended Selection}
4045 InvalidateEditor(y1,y2)
4046 End
4047 Else InvalidateEditor(0,0);
4048End;
4049
4050
4051Procedure TEditor.cmICBExtRight;
4052Var iew:Boolean;
4053 y1,y2:Integer;
4054 climb:Boolean;
4055Label L;
4056Begin
4057 climb := False;
4058 If FEditOpt * [eoCursorClimb] <> [] Then
4059 If FSelectMode <> smColumnBlock Then
4060 If FFileCursor.X > Length(_PLine2PString(FActLine)^) Then
4061 If FFileCursor.Y < CountLines Then climb := True
4062 Else Exit;
4063
4064 (*Undo*)
4065 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4066 LastUndoGroup := ugCursorMove;
4067 (*Undo*)
4068 iew := _ICBExtSetICB;
4069
4070 If _ICBActPos = ICB.Last Then
4071 Begin
4072 iew := _CursorRight Or iew;
4073 If climb Then
4074 Begin
4075 iew := _CursorDown Or iew;
4076 iew := _CursorHome Or iew;
4077 End;
4078 ICB.Last := _ICBActPos;
4079 Goto L;
4080 End;
4081
4082 If _ICBActPos = ICB.First Then
4083 Begin
4084 iew := _CursorRight Or iew;
4085 If climb Then
4086 Begin
4087 iew := _CursorDown Or iew;
4088 iew := _CursorHome Or iew;
4089 End;
4090 ICB.First := _ICBActPos;
4091 End;
4092L:
4093 _ICBExtCorrectICB;
4094 _ICBExtCorrectICB2;
4095 _ICBSetMark;
4096 ICBVisible := True;
4097 If Not iew Then
4098 Begin
4099 y1 := FScrCursor.Y;
4100 y2 := FScrCursor.Y;
4101 If climb Then Dec(y1);
4102 _ICBTestIEW(y1,y2); {Extended Selection}
4103 InvalidateEditor(y1,y2)
4104 End
4105 Else InvalidateEditor(0,0);
4106End;
4107
4108
4109Procedure TEditor.cmICBExtUp;
4110Var iew:Boolean;
4111 ScrY:Integer;
4112Label L;
4113Begin
4114 (*Undo*)
4115 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4116 LastUndoGroup := ugCursorMove;
4117 (*Undo*)
4118 iew := _ICBExtSetICB;
4119
4120 ScrY := FScrCursor.Y;
4121 If _ICBActPos = ICB.First Then
4122 Begin
4123 iew := _CursorUp Or iew;
4124 ICB.First := _ICBActPos;
4125 Goto L;
4126 End;
4127
4128 If _ICBActPos = ICB.Last Then
4129 Begin
4130 iew := _CursorUp Or iew;
4131 ICB.Last := _ICBActPos;
4132 End;
4133L:
4134 _ICBExtCorrectICB;
4135 _ICBExtCorrectICB2;
4136 _ICBSetMark;
4137 ICBVisible := True;
4138 {iew := iew Or _ICBTestIEW; {Extended Selection}
4139 If iew Then InvalidateEditor(0,0)
4140 Else InvalidateEditor(FScrCursor.Y,ScrY);
4141End;
4142
4143
4144Procedure TEditor.cmICBExtDown;
4145Var iew:Boolean;
4146 ScrY:Integer;
4147Label L;
4148Begin
4149 (*Undo*)
4150 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4151 LastUndoGroup := ugCursorMove;
4152 (*Undo*)
4153 iew := _ICBExtSetICB;
4154
4155 ScrY := FScrCursor.Y;
4156 If _ICBActPos = ICB.Last Then
4157 Begin
4158 iew := _CursorDown Or iew;
4159 ICB.Last := _ICBActPos;
4160 Goto L;
4161 End;
4162
4163 If _ICBActPos = ICB.First Then
4164 Begin
4165 iew := _CursorDown Or iew;
4166 ICB.First := _ICBActPos;
4167 End;
4168L:
4169 _ICBExtCorrectICB;
4170 _ICBExtCorrectICB2;
4171 _ICBSetMark;
4172 ICBVisible := True;
4173 {iew := iew Or _ICBTestIEW; {Extended Selection}
4174 If iew Then InvalidateEditor(0,0)
4175 Else InvalidateEditor(ScrY,FScrCursor.Y);
4176End;
4177
4178
4179Procedure TEditor.cmICBExtPageUp;
4180Var iew:Boolean;
4181Label L;
4182Begin
4183 (*Undo*)
4184 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4185 LastUndoGroup := ugCursorMove;
4186 (*Undo*)
4187 iew := _ICBExtSetICB;
4188
4189 If _ICBActPos = ICB.First Then
4190 Begin
4191 iew := _CursorPageUp Or iew;
4192 ICB.First := _ICBActPos;
4193 Goto L;
4194 End;
4195
4196 If _ICBActPos = ICB.Last Then
4197 Begin
4198 iew := _CursorPageUp Or iew;
4199 ICB.Last := _ICBActPos;
4200 End;
4201L:
4202 _ICBExtCorrectICB;
4203 _ICBExtCorrectICB2;
4204 _ICBSetMark;
4205 ICBVisible := True;
4206 {iew := iew Or _ICBTestIEW; {Extended Selection}
4207 If iew Then InvalidateEditor(0,0);
4208End;
4209
4210
4211Procedure TEditor.cmICBExtPageDown;
4212Var iew:Boolean;
4213Label L;
4214Begin
4215 (*Undo*)
4216 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4217 LastUndoGroup := ugCursorMove;
4218 (*Undo*)
4219 iew := _ICBExtSetICB;
4220
4221 If _ICBActPos = ICB.Last Then
4222 Begin
4223 iew := _CursorPageDown Or iew;
4224 ICB.Last := _ICBActPos;
4225 Goto L;
4226 End;
4227
4228 If _ICBActPos = ICB.First Then
4229 Begin
4230 iew := _CursorPageDown Or iew;
4231 ICB.First := _ICBActPos;
4232 End;
4233L:
4234 _ICBExtCorrectICB;
4235 _ICBExtCorrectICB2;
4236 _ICBSetMark;
4237 ICBVisible := True;
4238 {iew := iew Or _ICBTestIEW; {Extended Selection}
4239 If iew Then InvalidateEditor(0,0);
4240End;
4241
4242
4243Procedure TEditor.cmICBExtHome;
4244Var iew:Boolean;
4245 y1,y2:Integer;
4246 I,p1:Integer;
4247 icbap:TLineX;
4248Label L;
4249Begin
4250 (*Undo*)
4251 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4252 LastUndoGroup := ugCursorMove;
4253 (*Undo*)
4254 iew := _ICBExtSetICB;
4255 icbap := _ICBActPos;
4256
4257 If Not WLactivated Then _ReadWorkLine;
4258 p1 := 1;
4259 If FEditOpt * [eoHomeFirstWord] <> [] Then
4260 Begin
4261 For I := 1 To FFileCursor.X-1 Do
4262 Begin
4263 If I > Length(FWorkLine) Then break;
4264
4265 If FWorkLine[I] > ' ' Then
4266 Begin
4267 p1 := I; {onto First Word}
4268 break;
4269 End;
4270 End;
4271 End;
4272
4273 If p1 > 1 Then
4274 Begin
4275 _HorizMove;
4276 FFileCursor.X := p1;
4277 FScrCursor.X := p1;
4278 If FScrCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X;
4279 iew := _HorizMove Or iew;
4280 End
4281 Else iew := _CursorHome Or iew;
4282
4283 If icbap = ICB.First Then
4284 Begin
4285 ICB.First := _ICBActPos;
4286 Goto L;
4287 End;
4288
4289 If icbap = ICB.Last Then
4290 Begin
4291 ICB.Last := _ICBActPos;
4292 End;
4293L:
4294 _ICBExtCorrectICB;
4295 _ICBExtCorrectICB2;
4296 _ICBSetMark;
4297 ICBVisible := True;
4298 If Not iew Then
4299 Begin
4300 y1 := FScrCursor.Y;
4301 y2 := FScrCursor.Y;
4302 _ICBTestIEW(y1,y2); {Extended Selection}
4303 InvalidateEditor(y1,y2)
4304 End
4305 Else InvalidateEditor(0,0);
4306End;
4307
4308
4309Procedure TEditor.cmICBExtEnd;
4310Var iew:Boolean;
4311 y1,y2:Integer;
4312Label L;
4313Begin
4314 (*Undo*)
4315 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4316 LastUndoGroup := ugCursorMove;
4317 (*Undo*)
4318 iew := _ICBExtSetICB;
4319
4320 If _ICBActPos = ICB.Last Then
4321 Begin
4322 iew := _CursorEnd Or iew;
4323 ICB.Last := _ICBActPos;
4324 Goto L;
4325 End;
4326
4327 If _ICBActPos = ICB.First Then
4328 Begin
4329 iew := _CursorEnd Or iew;
4330 ICB.First := _ICBActPos;
4331 End;
4332L:
4333 _ICBExtCorrectICB;
4334 _ICBExtCorrectICB2;
4335 _ICBSetMark;
4336 ICBVisible := True;
4337 If Not iew Then
4338 Begin
4339 y1 := FScrCursor.Y;
4340 y2 := FScrCursor.Y;
4341 _ICBTestIEW(y1,y2); {Extended Selection}
4342 InvalidateEditor(y1,y2)
4343 End
4344 Else InvalidateEditor(0,0);
4345End;
4346
4347
4348Procedure TEditor.cmICBExtWordLeft;
4349Var iew:Boolean;
4350 ScrY:Integer;
4351 y1,y2:Integer;
4352Label L;
4353Begin
4354 (*Undo*)
4355 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4356 LastUndoGroup := ugCursorMove;
4357 (*Undo*)
4358 iew := _ICBExtSetICB;
4359
4360 ScrY := FScrCursor.Y;
4361 If _ICBActPos = ICB.First Then
4362 Begin
4363 iew := _CursorWordLeft Or iew;
4364 ICB.First := _ICBActPos;
4365 Goto L;
4366 End;
4367
4368 If _ICBActPos = ICB.Last Then
4369 Begin
4370 iew := _CursorWordLeft Or iew;
4371 ICB.Last := _ICBActPos;
4372 End;
4373L:
4374 _ICBExtCorrectICB;
4375 _ICBExtCorrectICB2;
4376 _ICBSetMark;
4377 ICBVisible := True;
4378 If Not iew Then
4379 Begin
4380 y1 := FScrCursor.Y;
4381 y2 := ScrY;
4382 _ICBTestIEW(y1,y2); {Extended Selection}
4383 InvalidateEditor(y1,y2)
4384 End
4385 Else InvalidateEditor(0,0);
4386End;
4387
4388
4389Procedure TEditor.cmICBExtWordRight;
4390Var iew:Boolean;
4391 ScrY:Integer;
4392 y1,y2:Integer;
4393Label L;
4394Begin
4395 (*Undo*)
4396 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4397 LastUndoGroup := ugCursorMove;
4398 (*Undo*)
4399 iew := _ICBExtSetICB;
4400
4401 ScrY := FScrCursor.Y;
4402 If _ICBActPos = ICB.Last Then
4403 Begin
4404 iew := _CursorWordRight Or iew;
4405 ICB.Last := _ICBActPos;
4406 Goto L;
4407 End;
4408
4409 If _ICBActPos = ICB.First Then
4410 Begin
4411 iew := _CursorWordRight Or iew;
4412 ICB.First := _ICBActPos;
4413 End;
4414L:
4415 _ICBExtCorrectICB;
4416 _ICBExtCorrectICB2;
4417 _ICBSetMark;
4418 ICBVisible := True;
4419 If Not iew Then
4420 Begin
4421 y1 := ScrY;
4422 y2 := FScrCursor.Y;
4423 _ICBTestIEW(y1,y2); {Extended Selection}
4424 InvalidateEditor(y1,y2)
4425 End
4426 Else InvalidateEditor(0,0);
4427End;
4428
4429
4430Procedure TEditor.cmICBExtFileBegin;
4431Var iew:Boolean;
4432 P:TEditorPos;
4433 ScrY:Integer;
4434 y1,y2:Integer;
4435Label L;
4436Begin
4437 (*Undo*)
4438 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4439 LastUndoGroup := ugCursorMove;
4440 (*Undo*)
4441 iew := _ICBExtSetICB;
4442
4443 ScrY := FScrCursor.Y;
4444 P.X := 1;
4445 P.Y := 1;
4446 If _ICBActPos = ICB.First Then
4447 Begin
4448 iew := _GotoPosition(P) Or iew;
4449 ICB.First := _ICBActPos;
4450 Goto L;
4451 End;
4452
4453 If _ICBActPos = ICB.Last Then
4454 Begin
4455 iew := _GotoPosition(P) Or iew;
4456 ICB.Last := _ICBActPos;
4457 End;
4458L:
4459 _ICBExtCorrectICB;
4460 _ICBExtCorrectICB2;
4461 _ICBSetMark;
4462 ICBVisible := True;
4463 If Not iew Then
4464 Begin
4465 y1 := FScrCursor.Y;
4466 y2 := ScrY;
4467 _ICBTestIEW(y1,y2); {Extended Selection}
4468 InvalidateEditor(y1,y2)
4469 End
4470 Else InvalidateEditor(0,0);
4471End;
4472
4473
4474Procedure TEditor.cmICBExtFileEnd;
4475Var iew:Boolean;
4476 P:TEditorPos;
4477 ScrY:Integer;
4478 y1,y2:Integer;
4479Label L;
4480Begin
4481 (*Undo*)
4482 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4483 LastUndoGroup := ugCursorMove;
4484 (*Undo*)
4485 iew := _ICBExtSetICB;
4486
4487 ScrY := FScrCursor.Y;
4488 P.X := Length(_PLine2PString(FLastLine)^);
4489 Inc(P.X);
4490 If P.X > StringLength Then P.X := StringLength;
4491 P.Y := FCountLines;
4492 If _ICBActPos = ICB.Last Then
4493 Begin
4494 iew := _GotoPosition(P) Or iew;
4495 ICB.Last := _ICBActPos;
4496 Goto L;
4497 End;
4498
4499 If _ICBActPos = ICB.First Then
4500 Begin
4501 iew := _GotoPosition(P) Or iew;
4502 ICB.First := _ICBActPos;
4503 End;
4504L:
4505 _ICBExtCorrectICB;
4506 _ICBExtCorrectICB2;
4507 _ICBSetMark;
4508 ICBVisible := True;
4509 If Not iew Then
4510 Begin
4511 y1 := ScrY;
4512 y2 := FScrCursor.Y;
4513 _ICBTestIEW(y1,y2); {Extended Selection}
4514 InvalidateEditor(y1,y2)
4515 End
4516 Else InvalidateEditor(0,0);
4517End;
4518
4519
4520Procedure TEditor.cmICBExtPageBegin;
4521Var iew:Boolean;
4522 P:TEditorPos;
4523Label L;
4524Begin
4525 (*Undo*)
4526 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4527 LastUndoGroup := ugCursorMove;
4528 (*Undo*)
4529 iew := _ICBExtSetICB;
4530
4531 P.X := FFileCursor.X;
4532 P.Y := FFileCursor.Y-FScrCursor.Y+1;
4533 If _ICBActPos = ICB.First Then
4534 Begin
4535 iew := _GotoPosition(P) Or iew;
4536 ICB.First := _ICBActPos;
4537 Goto L;
4538 End;
4539
4540 If _ICBActPos = ICB.Last Then
4541 Begin
4542 iew := _GotoPosition(P) Or iew;
4543 ICB.Last := _ICBActPos;
4544 End;
4545L:
4546 _ICBExtCorrectICB;
4547 _ICBExtCorrectICB2;
4548 _ICBSetMark;
4549 ICBVisible := True;
4550 {iew := iew Or _ICBTestIEW; {Extended Selection}
4551 InvalidateEditor(0,0);
4552End;
4553
4554
4555Procedure TEditor.cmICBExtPageEnd;
4556Var iew:Boolean;
4557 P:TEditorPos;
4558Label L;
4559Begin
4560 (*Undo*)
4561 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
4562 LastUndoGroup := ugCursorMove;
4563 (*Undo*)
4564 iew := _ICBExtSetICB;
4565
4566 P.X := FFileCursor.X;
4567 P.Y := FFileCursor.Y+FWinSize.Y-FScrCursor.Y;
4568 If _ICBActPos = ICB.Last Then
4569 Begin
4570 iew := _GotoPosition(P) Or iew;
4571 ICB.Last := _ICBActPos;
4572 Goto L;
4573 End;
4574
4575 If _ICBActPos = ICB.First Then
4576 Begin
4577 iew := _GotoPosition(P) Or iew;
4578 ICB.First := _ICBActPos;
4579 End;
4580L:
4581 _ICBExtCorrectICB;
4582 _ICBExtCorrectICB2;
4583 _ICBSetMark;
4584 ICBVisible := True;
4585 {iew := iew Or _ICBTestIEW; {Extended Selection}
4586 InvalidateEditor(0,0);
4587End;
4588
4589
4590{Insert A Text block from A File And Select it}
4591Procedure TEditor.cmICBReadBlock;
4592Var S,dir,Name,ext:String;
4593 CFOD:TOpenDialog;
4594Begin
4595 CFOD.Create(Self);
4596 CFOD.Title := LoadNLSStr(SReadBlockFromFile);
4597 CFOD.OkName := LoadNLSStr(SOkButton);
4598 CFOD.FileName := fMask;
4599 CFOD.DefaultExt := GetDefaultExt(fMask);
4600 SetAvailabeFileTypes(CFOD);
4601
4602 If CFOD.Execute Then
4603 Begin
4604 S := CFOD.FileName;
4605 CFOD.Destroy;
4606
4607 If Not FileExists(S) Then
4608 Begin
4609 FSplit(S,dir,Name,ext);
4610 S := FmtLoadNLSStr(SFileNotFound,[Name + ext])+'.';
4611 SetErrorMessage(S);
4612 End
4613 Else InsertFromFile(S);
4614 End
4615 Else CFOD.Destroy;
4616End;
4617
4618
4619{Write the Selected area To A File}
4620Procedure TEditor.cmICBWriteBlock;
4621Var P:Pointer;
4622 len:LongInt;
4623 utF:File;
4624 S:String;
4625 CFSD:TSaveDialog;
4626Begin
4627 CFSD.Create(Self);
4628 CFSD.Title := LoadNLSStr(SWriteBlockToFile);
4629 CFSD.OkName := LoadNLSStr(SOkButton);
4630 CFSD.FileName := fMask;
4631 CFSD.DefaultExt := GetDefaultExt(fMask);
4632 SetAvailabeFileTypes(CFSD);
4633
4634 If CFSD.Execute Then
4635 Begin
4636 S := CFSD.FileName;
4637 CFSD.Destroy;
4638
4639 If Not _GetEditorBlock(P,len) Then Exit;
4640 System.Assign(utF,S);
4641 {$I-}
4642 Rewrite(utF,1);
4643 {$I+}
4644 If InOutRes = 0 Then
4645 Begin
4646 {$I-}
4647 BlockWrite(utF,P^,len-1); {without #0}
4648 {$I+}
4649 If InOutRes <> 0 Then SetErrorMessage(LoadNLSStr(SErrorWriting)+': '+S);
4650 {$I-}
4651 System.Close(utF);
4652 {$I+}
4653 End
4654 Else SetErrorMessage(LoadNLSStr(SErrorWriting)+': '+S);
4655 FreeMem(P,len);
4656 End
4657 Else CFSD.Destroy;
4658End;
4659
4660
4661Procedure TEditor.cmICBMoveLeft;
4662Var P:TEditorPos;
4663Begin
4664 If ReadOnly Then Exit;
4665 If Not _ICBExist Then Exit;
4666 TestAutoSave;
4667 FlushWorkLine;
4668 (*Undo*)
4669 _CopyUndoLines(ICB.First.Line,ICB.Last.Line);
4670 (*Undo*)
4671
4672 If FSelectMode <> smColumnBlock Then
4673 Begin
4674 If Length(ICB.First.Line^.zk^) > 0 Then
4675 If (ICB.First.Line^.zk^[1] = #32) And (ICB.First.X > 1)
4676 Then Dec(ICB.First.X);
4677
4678 FActLine := ICB.First.Line;
4679 While FActLine <> ICB.Last.Line Do
4680 Begin
4681 If Length(FActLine^.zk^) > 0 Then
4682 If FActLine^.zk^[1] = #32 Then
4683 Begin
4684 _ReadWorkLine;
4685 _DeleteString(1,1);
4686 _WriteWorkLine;
4687 End;
4688 FActLine := FActLine^.Next;
4689 End;
4690
4691 If (Length(ICB.Last.Line^.zk^) > 0) And (ICB.Last.X > 1) Then
4692 If ICB.Last.Line^.zk^[1] = #32 Then
4693 Begin
4694 _ReadWorkLine;
4695 _DeleteString(1,1);
4696 _WriteWorkLine;
4697 Dec(ICB.Last.X);
4698 End;
4699 End
4700 Else {Extended Selection}
4701 Begin
4702 FActLine := ICB.First.Line;
4703 While FActLine <> ICB.Last.Line^.Next Do
4704 Begin
4705 If Length(FActLine^.zk^) >= ICB.First.X Then
4706 Begin
4707 _ReadWorkLine;
4708 _DeleteString(ICB.First.X,1);
4709 _WriteWorkLine;
4710 End;
4711 FActLine := FActLine^.Next;
4712 End;
4713 SetLineColorFlag(ICB.First.Line,ICB.Last.Line);
4714 End;
4715
4716 FRedoList.Clear;
4717 If GetSelectionStart(P) Then
4718 Begin
4719 If _GotoPosition(P) Then InvalidateEditor(0,0)
4720 Else InvalidateEditor(FScrCursor.Y,0);
4721 End;
4722 (*Undo*)
4723 LastUndoGroup := ugBlockLeft;
4724 (*Undo*)
4725End;
4726
4727
4728Procedure TEditor.cmICBMoveRight;
4729Var P:TEditorPos;
4730Begin
4731 If ReadOnly Then Exit;
4732 If Not _ICBExist Then Exit;
4733 TestAutoSave;
4734 FlushWorkLine;
4735 (*Undo*)
4736 _CopyUndoLines(ICB.First.Line,ICB.Last.Line);
4737 (*Undo*)
4738
4739 If FSelectMode <> smColumnBlock Then
4740 Begin
4741 FActLine := ICB.First.Line;
4742 While FActLine <> ICB.Last.Line Do
4743 Begin
4744 If Length(FActLine^.zk^) < StringLength Then
4745 Begin
4746 _ReadWorkLine;
4747 _InsertString(1,' ');
4748 _WriteWorkLine;
4749 End;
4750 FActLine := FActLine^.Next;
4751 End;
4752
4753 If (Length(ICB.Last.Line^.zk^) < StringLength) And
4754 (ICB.Last.X > 1) Then
4755 Begin
4756 _ReadWorkLine;
4757 _InsertString(1,' ');
4758 _WriteWorkLine;
4759 If ICB.Last.X < StringLength Then Inc(ICB.Last.X);
4760 End;
4761 End
4762 Else {Extended Selection}
4763 Begin
4764 FActLine := ICB.First.Line;
4765 While FActLine <> ICB.Last.Line^.Next Do
4766 Begin
4767 If Length(FActLine^.zk^) < StringLength Then
4768 Begin
4769 _ReadWorkLine;
4770 _InsertString(ICB.First.X,' ');
4771 _WriteWorkLine;
4772 End;
4773 FActLine := FActLine^.Next;
4774 End;
4775 SetLineColorFlag(ICB.First.Line,ICB.Last.Line);
4776 End;
4777
4778 FRedoList.Clear;
4779 If GetSelectionStart(P) Then
4780 Begin
4781 If _GotoPosition(P) Then InvalidateEditor(0,0)
4782 Else InvalidateEditor(FScrCursor.Y,0);
4783 End;
4784 (*Undo*)
4785 LastUndoGroup := ugBlockRight;
4786 (*Undo*)
4787End;
4788
4789
4790Procedure TEditor.cmICBCopyBlock;
4791Var P:Pointer;
4792 len:LongInt;
4793Begin
4794 If ReadOnly Then Exit;
4795 If Not ICBVisible Then
4796 Begin
4797 ShowSelection;
4798 Exit;
4799 End;
4800 If Not _ICBExist Then Exit;
4801 TestAutoSave;
4802
4803 If _GetEditorBlock(P,len) Then
4804 Begin
4805 InsertText(P,len-1); {without terminal #0}
4806 FreeMem(P,len);
4807 End;
4808End;
4809
4810
4811Procedure TEditor.cmICBMoveBlock;
4812Var art:Byte;
4813 Cur:TLineX;
4814 laststr:String;
4815 icbstr:String;
4816 B,icb1:String;
4817 Licb:Integer;
4818 CurLinenext:PLine;
4819 ICBFirstLnext:PLine;
4820 ICBLastLnext:PLine;
4821 fl,LL:PLine;
4822 AL,IFL,ILL:LongInt;
4823 P:TEditorPos;
4824Begin
4825 If ReadOnly Then Exit;
4826 If Not ICBVisible Then
4827 Begin
4828 ShowSelection;
4829 Exit;
4830 End;
4831 If Not _ICBExist Then Exit;
4832 If FSelectMode = smColumnBlock Then Exit;
4833 TestAutoSave;
4834
4835 If FActLine^.flag And ciSelected <> 0 Then
4836 Begin
4837 art := 0; {CurPos Is within the ICB}
4838 If (FActLine = ICB.First.Line) And (FFileCursor.X < ICB.First.X)
4839 Then art := 1; {CurPos In ICB FFirstLine, before ICB firstx}
4840 If (FActLine = ICB.Last.Line) And (FFileCursor.X > ICB.Last.X)
4841 Then art := 2; {CurPos In ICB endline, after ICB lastx}
4842 End
4843 Else art := 3; {CurPos Not within the ICB Lines}
4844 If art = 0 Then Exit;
4845
4846 (*Undo*)
4847 AL := FFileCursor.Y;
4848 IFL := _PLine2Index(ICB.First.Line);
4849 ILL := _PLine2Index(ICB.Last.Line);
4850 If AL < IFL Then fl := FActLine
4851 Else fl := ICB.First.Line;
4852 If AL > ILL Then LL := FActLine
4853 Else LL := ICB.Last.Line;
4854 _CopyUndoLines(fl,LL);
4855 (*Undo*)
4856
4857 FlushWorkLine;
4858 Cur.Line := FActLine;
4859 Cur.X := FFileCursor.X;
4860 Case art Of
4861 1 :
4862 Begin
4863 laststr := _ReadString(ICB.First.Line,Cur.X,ICB.First.X-Cur.X);
4864 _DeleteString(Cur.X,Length(laststr));
4865 _WriteWorkLine;
4866 FActLine := ICB.Last.Line;
4867 If ICB.First.Line = ICB.Last.Line
4868 Then ICB.Last.X := ICB.Last.X - Length(laststr);
4869 If Not _InsertString(ICB.Last.X,laststr) Then Beep(1000,10);
4870 _WriteWorkLine;
4871 ICB.First.X := Cur.X;
4872 End;
4873 2 :
4874 Begin
4875 laststr := _ReadString(ICB.Last.Line,ICB.Last.X,Cur.X-ICB.Last.X);
4876 _DeleteString(ICB.Last.X,Length(laststr));
4877 _WriteWorkLine;
4878 FActLine := ICB.First.Line;
4879 If Not _InsertString(ICB.First.X,laststr) Then Beep(1000,10);
4880 _WriteWorkLine;
4881 If ICB.First.Line = ICB.Last.Line
4882 Then ICB.Last.X := ICB.Last.X + Length(laststr);
4883 ICB.First.X := ICB.First.X + Length(laststr);
4884 End;
4885 3 :
4886 Begin
4887 If ICB.First.Line = ICB.Last.Line Then
4888 Begin
4889 Licb := ICB.Last.X-ICB.First.X;
4890 icbstr := _ReadString(ICB.First.Line,ICB.First.X,Licb);
4891 If Not _InsertString(Cur.X,icbstr) Then Beep(1000,10);
4892 _ICBClearMark;
4893 _WriteWorkLine;
4894 FActLine := ICB.First.Line;
4895 _DeleteString(ICB.First.X,Licb);
4896 _WriteWorkLine;
4897 ICB.First := Cur;
4898 ICB.Last := Cur;
4899 Inc(ICB.Last.X,Licb);
4900 _ICBSetMark;
4901 End
4902 Else
4903 Begin
4904 laststr := _ReadString(Cur.Line,Cur.X,-1);
4905 B := _ReadString(ICB.Last.Line,ICB.Last.X,-1);
4906 icb1 := _ReadString(ICB.First.Line,ICB.First.X,-1);
4907 _ReadWorkLine;
4908 SetLength(FWorkLine,Cur.X-1);
4909 _WriteString(Cur.X,icb1);
4910 _WriteWorkLine;
4911 FActLine^.flag := FActLine^.flag Or ciSelected;
4912
4913 FActLine := ICB.First.Line;
4914 _ReadWorkLine;
4915 SetLength(FWorkLine,ICB.First.X-1);
4916 _WriteString(ICB.First.X,B);
4917 _WriteWorkLine;
4918 FActLine^.flag := FActLine^.flag And Not ciSelected;
4919
4920 FActLine := ICB.Last.Line;
4921 _ReadWorkLine;
4922 SetLength(FWorkLine,ICB.Last.X-1);
4923 _WriteString(ICB.Last.X,laststr);
4924 _WriteWorkLine;
4925
4926 CurLinenext := Cur.Line^.Next;
4927 ICBFirstLnext := ICB.First.Line^.Next;
4928 ICBLastLnext := ICB.Last.Line^.Next;
4929 _Connect(Cur.Line,ICBFirstLnext);
4930 _Connect(ICB.Last.Line,CurLinenext);
4931 _Connect(ICB.First.Line,ICBLastLnext);
4932 If CurLinenext = Nil Then FLastLine := ICB.Last.Line;
4933
4934 ICB.First := Cur;
4935 {Reference Point For _GotoPosition}
4936 FFileCursor.Y := 1;
4937 FScrCursor.Y := 1;
4938 FActLine := FFirstLine;
4939 FTopScreenLine := FFirstLine;
4940 End;
4941 End;
4942 End;
4943 _ICBCheckX;
4944
4945 If AL < IFL Then fl := _Index2PLine(AL)
4946 Else fl := _Index2PLine(IFL);
4947 If AL > ILL Then LL := _Index2PLine(AL)
4948 Else LL := _Index2PLine(ILL);
4949 SetLineColorFlag(fl,LL);
4950
4951 FRedoList.Clear;
4952 If GetSelectionStart(P) Then
4953 Begin
4954 _GotoPosition(P);
4955 InvalidateEditor(0,0);
4956 End;
4957 (*Undo*)
4958 LastUndoGroup := ugNoGroup;
4959 (*Undo*)
4960End;
4961
4962
4963Procedure TEditor.cmICBDeleteBlock;
4964Begin
4965 If ReadOnly Then Exit;
4966 If Not ICBVisible Then Exit;
4967 TestAutoSave;
4968 If _ICBDeleteICB Then
4969 Begin
4970 FRedoList.Clear;
4971 InvalidateEditor(0,0);
4972 End;
4973End;
4974
4975
4976Procedure TEditor.cmICBUpcaseBlock;
4977Var SaveAL:PLine;
4978 X1,x2,I:Integer;
4979Begin
4980 If ReadOnly Then Exit;
4981 If Not _ICBExist Then Exit;
4982 TestAutoSave;
4983 FlushWorkLine;
4984 (*Undo*)
4985 _CopyUndoLines(ICB.First.Line,ICB.Last.Line);
4986 LastUndoGroup := ugNoGroup;
4987 (*Undo*)
4988 SaveAL := FActLine;
4989 FActLine := ICB.First.Line;
4990
4991 X1 := ICB.First.X;
4992 x2 := ICB.Last.X-1;
4993 While FActLine <> ICB.Last.Line Do
4994 Begin
4995 _ReadWorkLine;
4996
4997 If FSelectMode <> smColumnBlock Then x2 := Length(FWorkLine);
4998 For I := X1 To x2 Do FWorkLine[I] := UpCase(FWorkLine[I]);
4999 If FSelectMode <> smColumnBlock Then X1 := 1;
5000
5001 _WriteWorkLine;
5002 FActLine := FActLine^.Next;
5003 End;
5004
5005 x2 := ICB.Last.X-1;
5006 _ReadWorkLine;
5007 For I := X1 To x2 Do FWorkLine[I] := UpCase(FWorkLine[I]);
5008 _WriteWorkLine;
5009
5010 FActLine := SaveAL;
5011 Modified := True;
5012 FRedoList.Clear;
5013 InvalidateEditor(0,0);
5014End;
5015
5016
5017Procedure TEditor.cmICBLowcaseBlock;
5018Var SaveAL:PLine;
5019 X1,x2,I:Integer;
5020Begin
5021 If ReadOnly Then Exit;
5022 If Not _ICBExist Then Exit;
5023 TestAutoSave;
5024 FlushWorkLine;
5025 (*Undo*)
5026 _CopyUndoLines(ICB.First.Line,ICB.Last.Line);
5027 LastUndoGroup := ugNoGroup;
5028 (*Undo*)
5029 SaveAL := FActLine;
5030 FActLine := ICB.First.Line;
5031
5032 X1 := ICB.First.X;
5033 x2 := ICB.Last.X-1;
5034 While FActLine <> ICB.Last.Line Do
5035 Begin
5036 _ReadWorkLine;
5037
5038 If FSelectMode <> smColumnBlock Then x2 := Length(FWorkLine);
5039 For I := X1 To x2 Do
5040 If FWorkLine[I] In ['A'..'Z','Ž','™','š']
5041 Then FWorkLine[I] := Chr(Ord(FWorkLine[I]) Or $20);
5042 If FSelectMode <> smColumnBlock Then X1 := 1;
5043
5044 _WriteWorkLine;
5045 FActLine := FActLine^.Next;
5046 End;
5047
5048 x2 := ICB.Last.X-1;
5049 _ReadWorkLine;
5050 For I := X1 To x2 Do
5051 If FWorkLine[I] In ['A'..'Z','Ž','™','š']
5052 Then FWorkLine[I] := Chr(Ord(FWorkLine[I]) Or $20);
5053 _WriteWorkLine;
5054
5055 FActLine := SaveAL;
5056 Modified := True;
5057 FRedoList.Clear;
5058 InvalidateEditor(0,0);
5059End;
5060
5061
5062Procedure TEditor.cmICBUpcaseWord;
5063Var lzk:LongInt;
5064 X:Integer;
5065Begin
5066 If ReadOnly Then Exit;
5067 TestAutoSave;
5068 (*Undo*)
5069 _CopyUndoLines(FActLine,FActLine);
5070 LastUndoGroup := ugNoGroup;
5071 (*Undo*)
5072
5073 If Not WLactivated Then _ReadWorkLine;
5074 lzk := Length(FWorkLine);
5075 X := FFileCursor.X;
5076 While (FWorkLine[X-1] In NormalChars) And (X > 1) Do Dec(X);
5077 While (FWorkLine[X] In NormalChars) And (X <= lzk) Do
5078 Begin
5079 FWorkLine[X] := UpCase(FWorkLine[X]);
5080 Inc(X);
5081 End;
5082 _WriteWorkLine;
5083
5084 Modified := True;
5085 FRedoList.Clear;
5086 InvalidateWorkLine;
5087End;
5088
5089
5090Procedure TEditor.cmICBLowcaseWord;
5091Var lzk:LongInt;
5092 X:Integer;
5093Begin
5094 If ReadOnly Then Exit;
5095 TestAutoSave;
5096 (*Undo*)
5097 _CopyUndoLines(FActLine,FActLine);
5098 LastUndoGroup := ugNoGroup;
5099 (*Undo*)
5100
5101 If Not WLactivated Then _ReadWorkLine;
5102 lzk := Length(FWorkLine);
5103 X := FFileCursor.X;
5104 While (FWorkLine[X-1] In NormalChars) And (X > 1) Do Dec(X);
5105 While (FWorkLine[X] In NormalChars) And (X <= lzk) Do
5106 Begin
5107 If FWorkLine[X] In ['A'..'Z','Ž','™','š']
5108 Then FWorkLine[X] := Chr(Ord(FWorkLine[X]) Or $20);
5109 Inc(X);
5110 End;
5111 _WriteWorkLine;
5112
5113 Modified := True;
5114 FRedoList.Clear;
5115 InvalidateWorkLine;
5116End;
5117
5118
5119Procedure TEditor.cmToggleCase;
5120Var X:Integer;
5121Begin
5122 If ReadOnly Then Exit;
5123 TestAutoSave;
5124 (*Undo*)
5125 _CopyUndoLines(FActLine,FActLine);
5126 LastUndoGroup := ugNoGroup;
5127 (*Undo*)
5128
5129 If Not WLactivated Then _ReadWorkLine;
5130 X := FFileCursor.X;
5131 If FWorkLine[X] In ['A'..'Z','Ž','™','š']
5132 Then FWorkLine[X] := Chr(Ord(FWorkLine[X]) Or $20)
5133 Else FWorkLine[X] := UpCase(FWorkLine[X]);
5134 _WriteWorkLine;
5135 If X <= Length(FWorkLine) Then cmCursorRight;
5136
5137 Modified := True;
5138 FRedoList.Clear;
5139 InvalidateWorkLine;
5140End;
5141
5142
5143Procedure TEditor.cmBreakLine;
5144Var newstring:String;
5145 ip:TICBPosition;
5146 FCX:Integer;
5147 AL:PLine;
5148 iew:Boolean;
5149Begin
5150 If ReadOnly Then Exit;
5151 TestAutoSave;
5152 (*Undo*)
5153 _CopyUndoLines(FActLine,FActLine);
5154 (*Undo*)
5155 If Not WLactivated Then _ReadWorkLine;
5156
5157 If FFileCursor.X > Length(FWorkLine) Then newstring := ''
5158 Else newstring := _ReadString(FActLine,FFileCursor.X,-1);
5159 SetLength(FWorkLine,FFileCursor.X-1);
5160 _WriteWorkLine;
5161
5162 _InsertLine(FActLine);
5163 {Update ICB}
5164 ip := _ICBPos(FActLine,FFileCursor.X);
5165 FCX := FFileCursor.X;
5166 AL := FActLine;
5167 If FSelectMode <> smColumnBlock Then
5168 Begin
5169 If ip * [ipBeforeICBFirst] <> [] Then
5170 Begin
5171 AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5172 AL^.flag := AL^.flag And Not ciSelected;
5173 Dec(ICB.First.X,FCX-1);
5174 ICB.First.Line := ICB.First.Line^.Next;
5175 End;
5176 If ip * [ipBeforeICBLast] <> [] Then
5177 Begin
5178 AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5179 Dec(ICB.Last.X,FCX-1);
5180 ICB.Last.Line := ICB.Last.Line^.Next;
5181 End;
5182 If ip * [ipAfterICBFirst,ipWithinICB] <> []
5183 Then AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5184 If ip * [ipAfterICBLast] <> []
5185 Then AL^.Next^.flag := AL^.Next^.flag And Not ciSelected;
5186 _ICBCheckX;
5187 End
5188 Else {Extended Selection}
5189 Begin
5190 If ip * [ipBeforeICBFirst,ipAfterICBFirst,ipWithinICB] <> [] Then
5191 If ip * [ipBeforeICBLast,ipAfterICBLast] = []
5192 Then AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5193 End;
5194
5195 FActLine := FActLine^.Next;
5196 FWorkLine := newstring;
5197 _WriteWorkLine;
5198
5199 FActLine := FActLine^.Prev;
5200 If Length(newstring) = 0 Then iew := _CursorEnd
5201 Else iew := False;
5202
5203 SetLineColorFlag(FActLine,FActLine^.Next);
5204 FRedoList.Clear;
5205 If ((FScrCursor.Y = FWinSize.Y) And (FScrCursor.Y > 1)) Then
5206 Begin
5207 Dec(FScrCursor.Y);
5208 FTopScreenLine := FTopScreenLine^.Next;
5209 InvalidateEditor(0,0);
5210 End
5211 Else
5212 Begin
5213 If iew Then InvalidateEditor(0,0)
5214 Else InvalidateEditor(FScrCursor.Y,0);
5215 End;
5216 SetSliderValues;
5217 (*Undo*)
5218 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FActLine^.Next^.Next));
5219 LastUndoGroup := ugBreakLine;
5220 (*Undo*)
5221End;
5222
5223
5224Procedure TEditor.cmDeleteLine;
5225Var NextLine:PLine;
5226 prevline:PLine;
5227 ip:TICBPosition;
5228Begin
5229 If ReadOnly Then Exit;
5230 TestAutoSave;
5231
5232 ip := _ICBPos(FActLine,0);
5233 NextLine := FActLine^.Next;
5234
5235 If NextLine <> Nil Then
5236 Begin
5237 If FTopScreenLine = FActLine Then FTopScreenLine := NextLine;
5238 prevline := FActLine^.Prev;
5239 (*Undo*)
5240 _MoveUndoLines(FUndoList,FActLine,FActLine);
5241 _Connect(prevline,NextLine);
5242 _UpdateLastUndoEvent(FUndoList,_PLine2Index(NextLine));
5243 Dec(FCountLines);
5244 (*Undo*)
5245 SetSliderValues;
5246 FActLine := NextLine;
5247 WLactivated := False;
5248 End
5249 Else
5250 Begin
5251 (*Undo*)
5252 _CopyUndoLines(FActLine,FActLine);
5253 If Not WLactivated Then _ReadWorkLine;
5254 (*Undo*)
5255 FWorkLine := '';
5256 End;
5257
5258 If ip * [ipBeforeICBFirst,ipAfterICBFirst] <> [] Then
5259 Begin
5260 If NextLine <> Nil Then ICB.First.Line := NextLine;
5261 If FSelectMode <> smColumnBlock Then ICB.First.X := 1;
5262 End;
5263 If ip * [ipBeforeICBLast,ipAfterICBLast] <> [] Then
5264 Begin
5265 If NextLine <> Nil Then ICB.Last.Line := NextLine;
5266 If FSelectMode <> smColumnBlock Then ICB.Last.X := 1;
5267 End;
5268 _ICBSetMark;
5269
5270 _HorizMove;
5271 FFileCursor.X := 1;
5272 FScrCursor.X := 1;
5273 Modified := True;
5274 If FActLine^.Prev <> Nil Then UpdateLineColorFlag(FActLine^.Prev)
5275 Else UpdateLineColorFlag(FActLine);
5276 FRedoList.Clear;
5277 If _HorizMove Then InvalidateEditor(0,0)
5278 Else InvalidateEditor(FScrCursor.Y,0);
5279 (*Undo*)
5280 LastUndoGroup := ugDeleteActLine;
5281 (*Undo*)
5282End;
5283
5284
5285Procedure TEditor.cmDeleteLineEnd;
5286Var ip:TICBPosition;
5287Begin
5288 If ReadOnly Then Exit;
5289 TestAutoSave;
5290 (*Undo*)
5291 _CopyUndoLines(FActLine,FActLine);
5292 (*Undo*)
5293 Modified := True;
5294 If Not WLactivated Then _ReadWorkLine;
5295 SetLength(FWorkLine,FFileCursor.X-1);
5296 _WriteWorkLine;
5297 If FSelectMode <> smColumnBlock Then
5298 Begin
5299 ip := _ICBPos(FActLine,FFileCursor.X);
5300 If ip * [ipBeforeICBFirst] <> [] Then ICB.First.X := FFileCursor.X;
5301 If ip * [ipBeforeICBLast] <> [] Then ICB.Last.X := FFileCursor.X;
5302 _ICBCheckX;
5303 End;
5304 FRedoList.Clear;
5305 InvalidateWorkLine;
5306 (*Undo*)
5307 LastUndoGroup := ugNoGroup;
5308 (*Undo*)
5309End;
5310
5311
5312Procedure TEditor.cmDeleteRightWord;
5313Var CX:Integer;
5314 newstring:String;
5315 ip:TICBPosition;
5316Begin
5317 If ReadOnly Then Exit;
5318 TestAutoSave;
5319 If Not WLactivated Then _ReadWorkLine;
5320 CX := 0;
5321 If FFileCursor.X <= Length(FWorkLine) Then
5322 Begin
5323 (*Undo*)
5324 _CopyUndoLines(FActLine,FActLine);
5325 (*Undo*)
5326 If Not WLactivated Then _ReadWorkLine;
5327 While (FWorkLine[FFileCursor.X+CX] In NormalChars) And
5328 (FFileCursor.X+CX <= Length(FWorkLine)) Do Inc(CX);
5329 If CX = 0 Then CX := 1;
5330 While (FWorkLine[FFileCursor.X+CX] = ' ') And
5331 (FFileCursor.X+CX <= Length(FWorkLine)) Do Inc(CX);
5332 _DeleteString(FFileCursor.X,CX);
5333 _WriteWorkLine;
5334 If FSelectMode <> smColumnBlock Then
5335 Begin
5336 ip := _ICBPos(FActLine,FFileCursor.X);
5337 If ip * [ipBeforeICBFirst] <> [] Then
5338 Begin
5339 If ICB.First.X-FFileCursor.X < CX
5340 Then ICB.First.X := FFileCursor.X
5341 Else Dec(ICB.First.X,CX);
5342 End;
5343 If ip * [ipBeforeICBLast] <> [] Then
5344 Begin
5345 If ICB.Last.X-FFileCursor.X < CX
5346 Then ICB.Last.X := FFileCursor.X
5347 Else Dec(ICB.Last.X,CX);
5348 End;
5349 _ICBCheckX;
5350 End;
5351 FRedoList.Clear;
5352 InvalidateWorkLine;
5353 (*Undo*)
5354 LastUndoGroup := ugDeleteRightWord;
5355 (*Undo*)
5356 End
5357 Else
5358 Begin
5359 If FActLine^.Next = Nil Then Exit;
5360 If FFileCursor.X + Length(FActLine^.Next^.zk^) <= StringLength Then
5361 Begin
5362 (*Undo*)
5363 _CopyUndoLines(FActLine,FActLine^.Next);
5364 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FActLine^.Next));
5365 (*Undo*)
5366 If Not WLactivated Then _ReadWorkLine;
5367 SetLength(FWorkLine,FFileCursor.X-1);
5368 CX := 1;
5369 While (FActLine^.Next^.zk^[CX] = ' ') And
5370 (CX <= Length(FActLine^.Next^.zk^)) Do Inc(CX);
5371 newstring := _ReadString(FActLine^.Next,CX,-1);
5372 _WriteString(FFileCursor.X,newstring);
5373 Dec(CX); {CX Count Of deletable ' '}
5374 ip := _ICBPos(FActLine^.Next,0);
5375 If ip * [ipBeforeICBFirst,ipAfterICBFirst] <> [] Then
5376 Begin
5377 ICB.First.Line := FActLine;
5378 If FSelectMode <> smColumnBlock Then
5379 Begin
5380 Inc(ICB.First.X,FFileCursor.X-1);
5381 If ICB.First.X-FFileCursor.X < CX
5382 Then ICB.First.X := FFileCursor.X
5383 Else Dec(ICB.First.X,CX);
5384 End;
5385 FActLine^.flag := FActLine^.flag Or
5386 (FActLine^.Next^.flag And ciSelected);
5387 End;
5388 If ip * [ipBeforeICBLast,ipAfterICBLast] <> [] Then
5389 Begin
5390 ICB.Last.Line := FActLine;
5391 If FSelectMode <> smColumnBlock Then
5392 Begin
5393 Inc(ICB.Last.X,FFileCursor.X-1);
5394 If ICB.Last.X-FFileCursor.X < CX
5395 Then ICB.Last.X := FFileCursor.X
5396 Else Dec(ICB.Last.X,CX);
5397 End;
5398 FActLine^.flag := FActLine^.flag Or
5399 (FActLine^.Next^.flag And ciSelected);
5400 End;
5401 _ICBCheckX;
5402 _DeleteLine(FActLine^.Next);
5403 SetSliderValues;
5404 UpdateLineColorFlag(FActLine);
5405 FRedoList.Clear;
5406 InvalidateEditor(FScrCursor.Y,0);
5407 (*Undo*)
5408 LastUndoGroup := ugNoGroup;
5409 (*Undo*)
5410 End
5411 Else SetErrorMessage(LoadNLSStr(SLineWouldBeTooLong)+'.');
5412 End;
5413End;
5414
5415
5416Procedure TEditor.cmDeleteLeftWord;
5417Var CX:Integer;
5418 ip:TICBPosition;
5419Begin
5420 If ReadOnly Then Exit;
5421 TestAutoSave;
5422 If Not WLactivated Then _ReadWorkLine;
5423 If FFileCursor.X > 1 Then
5424 Begin
5425 (*Undo*)
5426 _CopyUndoLines(FActLine,FActLine);
5427 (*Undo*)
5428 If Not WLactivated Then _ReadWorkLine;
5429 CX := FFileCursor.X;
5430 While Not (FWorkLine[CX-1] In NormalChars) And (CX > 1) Do Dec(CX);
5431 While (FWorkLine[CX-1] In NormalChars) And (CX > 1) Do Dec(CX);
5432 _DeleteString(CX,FFileCursor.X - CX);
5433 _WriteWorkLine;
5434 If FSelectMode <> smColumnBlock Then
5435 Begin
5436 ip := _ICBPos(FActLine,FFileCursor.X);
5437 If ip * [ipBeforeICBFirst] <> []
5438 Then Dec(ICB.First.X,FFileCursor.X - CX);
5439 If ip * [ipBeforeICBLast] <> []
5440 Then Dec(ICB.Last.X,FFileCursor.X - CX);
5441 _ICBCheckX;
5442 End;
5443 FRedoList.Clear;
5444 If _GotoPosition(EditorPos(FFileCursor.Y,CX))
5445 Then InvalidateEditor(0,0)
5446 Else InvalidateWorkLine;
5447 (*Undo*)
5448 LastUndoGroup := ugDeleteRightWord;
5449 (*Undo*)
5450 End;
5451End;
5452
5453
5454Procedure TEditor.cmTabulator;
5455Var P,I,cnt:Integer;
5456 emptystring:String;
5457 ip:TICBPosition;
5458 iew:Boolean;
5459Begin
5460 If ReadOnly Then Exit;
5461 TestAutoSave;
5462
5463 If _ICBOverwrite Then iew := _ICBDeleteICB
5464 Else iew := False;
5465 (*Undo*)
5466 _CopyUndoLines(FActLine,FActLine);
5467 (*Undo*)
5468 If FEditOpt * [eoSmartTabs] <> [] Then
5469 Begin
5470 P := _FindNextTab(FActLine^.Prev,FFileCursor.X+1); {Search from FCX+1}
5471 cnt := P - FFileCursor.X;
5472 End
5473 Else
5474 Begin
5475 P := _FindNextTab(Nil,FFileCursor.X+1); {Search from FCX+1}
5476 cnt := P - FFileCursor.X;
5477 End;
5478
5479 emptystring := '';
5480 For I := 1 To cnt Do emptystring := emptystring + ' ';
5481 If Not _InsertString(FFileCursor.X,emptystring) Then Beep(1000,10);
5482 If FSelectMode <> smColumnBlock Then
5483 Begin
5484 ip := _ICBPos(FActLine,FFileCursor.X);
5485 If ip * [ipBeforeICBFirst] <> [] Then Inc(ICB.First.X,cnt);
5486 If ip * [ipBeforeICBLast] <> [] Then Inc(ICB.Last.X,cnt);
5487 _ICBCheckX;
5488 End;
5489
5490 _HorizMove;
5491 FFileCursor.X := P;
5492 If FScrCursor.X+cnt <= FWinSize.X Then Inc(FScrCursor.X,cnt)
5493 Else FScrCursor.X := 3*(FWinSize.X Div 4)+1;
5494
5495
5496 FRedoList.Clear;
5497 If _HorizMove Or iew Then
5498 Begin
5499 UpdateLineColorFlag(FActLine);
5500 InvalidateEditor(0,0);
5501 End
5502 Else InvalidateWorkLine;
5503 (*Undo*)
5504 LastUndoGroup := ugTabulator;
5505 (*Undo*)
5506End;
5507
5508
5509Procedure TEditor.cmPrevTabulator;
5510Var iew:Boolean;
5511 P:TEditorPos;
5512Begin
5513 If FFileCursor.X = 1 Then Exit;
5514 (*Undo*)
5515 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
5516 (*Undo*)
5517
5518 P := FFileCursor;
5519 P.X := ((P.X-1) Div FTabSize * FTabSize) +1;
5520 iew := _GotoPosition(P);
5521 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
5522
5523 If iew Then InvalidateEditor(0,0)
5524 Else SetScreenCursor;
5525 (*Undo*)
5526 LastUndoGroup := ugCursorMove;
5527 (*Undo*)
5528End;
5529
5530
5531Procedure TEditor.cmDeleteChar;
5532Var newstring:String;
5533 lpl,lwl:Integer;
5534 ip:TICBPosition;
5535 CountDel:Integer;
5536Begin
5537 If ReadOnly Then Exit;
5538 TestAutoSave;
5539
5540 If _ICBOverwrite And _ICBExist Then
5541 Begin
5542 cmICBDeleteBlock;
5543 Exit;
5544 End;
5545
5546 If Not WLactivated Then _ReadWorkLine;
5547 If FFileCursor.X > Length(FWorkLine) Then
5548 Begin
5549 If FActLine^.Next = Nil Then Exit;
5550 (*Undo*)
5551 _CopyUndoLines(FActLine,FActLine^.Next);
5552 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FActLine^.Next));
5553 (*Undo*)
5554 If Not WLactivated Then _ReadWorkLine;
5555 lpl := Length(FActLine^.Next^.zk^);
5556 If lpl + FFileCursor.X <= StringLength Then
5557 Begin
5558 ip := _ICBPos(FActLine^.Next,0);
5559 If ip * [ipBeforeICBFirst,ipAfterICBFirst] <> [] Then
5560 Begin
5561 ICB.First.Line := FActLine;
5562 If FSelectMode <> smColumnBlock
5563 Then Inc(ICB.First.X,FFileCursor.X-1);
5564 If FActLine^.Next^.flag And ciSelected <> 0
5565 Then FActLine^.flag := FActLine^.flag Or ciSelected;
5566 End;
5567 If ip * [ipBeforeICBLast,ipAfterICBLast] <> [] Then
5568 Begin
5569 ICB.Last.Line := FActLine;
5570 If FSelectMode <> smColumnBlock
5571 Then Inc(ICB.Last.X,FFileCursor.X-1);
5572 End;
5573 _ICBCheckX;
5574 lwl := Length(FWorkLine);
5575 FillChar(FWorkLine[lwl+1],FFileCursor.X-lwl-1,32);
5576 newstring := _ReadString(FActLine^.Next,1,lpl);
5577 _WriteString(FFileCursor.X,newstring);
5578 _DeleteLine(FActLine^.Next);
5579
5580 SetSliderValues;
5581 UpdateLineColorFlag(FActLine);
5582 FRedoList.Clear;
5583 InvalidateEditor(FScrCursor.Y,0);
5584 (*Undo*)
5585 LastUndoGroup := ugNoGroup;
5586 (*Undo*)
5587 End
5588 Else SetErrorMessage(LoadNLSStr(SLineWouldBeTooLong)+'.');
5589 End
5590 Else
5591 Begin
5592 (*Undo*)
5593 If LastUndoGroup <> ugDeleteChar Then _CopyUndoLines(FActLine,FActLine);
5594 (*Undo*)
5595
5596 CountDel := 1;
5597 If Application.DBCSSystem Then
5598 Begin {Delete 2 chars If the Cursor Is ON the 1st Byte Of A dbcs Char}
5599 If QueryDBCSFirstByte(FWorkLine, FFileCursor.X) Then CountDel := 2;
5600 End;
5601
5602 If FSelectMode <> smColumnBlock Then
5603 Begin
5604 ip := _ICBPos(FActLine,FFileCursor.X);
5605 If ip * [ipBeforeICBFirst] <> [] Then Dec(ICB.First.X, CountDel);
5606 If ip * [ipBeforeICBLast] <> [] Then Dec(ICB.Last.X, CountDel);
5607 _ICBCheckX;
5608 End;
5609 _DeleteString(FFileCursor.X, CountDel);
5610 FRedoList.Clear;
5611 InvalidateWorkLine;
5612 (*Undo*)
5613 LastUndoGroup := ugDeleteChar;
5614 (*Undo*)
5615 End;
5616End;
5617
5618
5619Procedure TEditor.cmBackSpace;
5620Var prevline:PLine;
5621 ptline:PLine;
5622 oldstring:String;
5623 lpl:Integer;
5624 ip:TICBPosition;
5625 CountDel:Integer;
5626 FNT:Integer;
5627 iew:Boolean;
5628Begin
5629 If ReadOnly Then Exit;
5630 TestAutoSave;
5631
5632 If _ICBOverwrite And _ICBExist Then
5633 Begin
5634 cmICBDeleteBlock;
5635 Exit;
5636 End;
5637
5638 _HorizMove;
5639 If FFileCursor.X <= 1 Then
5640 Begin
5641 If FActLine^.Prev = Nil Then Exit;
5642 (*Undo*)
5643 _CopyUndoLines(FActLine^.Prev,FActLine);
5644 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FActLine));
5645 (*Undo*)
5646 If Not WLactivated Then _ReadWorkLine;
5647 oldstring := FWorkLine;
5648 prevline := FActLine^.Prev;
5649 lpl := Length(prevline^.zk^);
5650 If lpl + Length(FWorkLine) <= StringLength Then
5651 Begin
5652 ip := _ICBPos(FActLine,0);
5653 If ip * [ipBeforeICBFirst,ipAfterICBFirst] <> [] Then
5654 Begin
5655 ICB.First.Line := prevline;
5656 If FSelectMode <> smColumnBlock
5657 Then Inc(ICB.First.X,lpl);
5658 If FActLine^.flag And ciSelected <> 0
5659 Then prevline^.flag := prevline^.flag Or ciSelected;
5660 End;
5661 If ip * [ipBeforeICBLast,ipAfterICBLast] <> [] Then
5662 Begin
5663 ICB.Last.Line := prevline;
5664 If FSelectMode <> smColumnBlock
5665 Then Inc(ICB.Last.X,lpl);
5666 End;
5667 _ICBCheckX;
5668 If FScrCursor.Y > 1 Then Dec(FScrCursor.Y)
5669 Else FTopScreenLine := prevline;
5670 Dec(FFileCursor.Y);
5671 FActLine := prevline;
5672 _ReadWorkLine;
5673 iew := _CursorEnd;
5674 _WriteString(FFileCursor.X,oldstring);
5675 _DeleteLine(FActLine^.Next);
5676 UpdateLineColorFlag(FActLine);
5677 If _HorizMove Or iew Then InvalidateEditor(0,0)
5678 Else InvalidateEditor(FScrCursor.Y,0);
5679 SetSliderValues;
5680 End
5681 Else SetErrorMessage(LoadNLSStr(SLineWouldBeTooLong)+'.');
5682 (*Undo*)
5683 LastUndoGroup := ugNoGroup;
5684 (*Undo*)
5685 End
5686 Else
5687 Begin
5688 (*Undo*)
5689 If LastUndoGroup <> ugBackspaceChar Then _CopyUndoLines(FActLine,FActLine);
5690 (*Undo*)
5691
5692 FlushWorkLine;
5693 If FEditOpt * [eoUnindent] <> [] Then
5694 Begin
5695 If (_FindNextTab(FActLine,1) >= FFileCursor.X) Or
5696 (Length(FActLine^.zk^) = 0) Then
5697 Begin
5698 ptline := FActLine;
5699 Repeat
5700 If ptline^.Prev <> Nil Then
5701 Begin
5702 ptline := ptline^.Prev;
5703 FNT := _FindNextTab(ptline,1);
5704 End
5705 Else FNT := 1;
5706 Until FNT < FFileCursor.X;
5707 CountDel := FFileCursor.X-FNT;
5708 End
5709 Else
5710 Begin
5711 CountDel := 1;
5712 If Application.DBCSSystem Then
5713 Begin {Delete 2 chars If the Cursor Is behind the 2nd Byte Of A dbcs Char}
5714 If QueryDBCSFirstByte(FActLine^.zk^, FFileCursor.X-2)
5715 Then CountDel := 2;
5716 End;
5717 End;
5718 End
5719 Else
5720 Begin
5721 CountDel := 1;
5722 If Application.DBCSSystem Then
5723 Begin {Delete 2 chars If the Cursor Is behind the 2nd Byte Of A dbcs Char}
5724 If QueryDBCSFirstByte(FActLine^.zk^, FFileCursor.X-2)
5725 Then CountDel := 2;
5726 End;
5727 End;
5728
5729 Dec(FFileCursor.X, CountDel);
5730 If FSelectMode <> smColumnBlock Then
5731 Begin
5732 ip := _ICBPos(FActLine,FFileCursor.X);
5733 If ip * [ipBeforeICBFirst] <> [] Then
5734 Begin
5735 If ICB.First.X-FFileCursor.X > CountDel
5736 Then Dec(ICB.First.X,CountDel)
5737 Else ICB.First.X := FFileCursor.X;
5738 End;
5739 If ip * [ipBeforeICBLast] <> [] Then
5740 Begin
5741 If ICB.Last.X-FFileCursor.X > CountDel
5742 Then Dec(ICB.Last.X,CountDel)
5743 Else ICB.Last.X := FFileCursor.X;
5744 End;
5745 End;
5746 _DeleteString(FFileCursor.X,CountDel);
5747 FRedoList.Clear;
5748 If FScrCursor.X <= CountDel Then
5749 Begin
5750 FScrCursor.X := 1;
5751 UpdateLineColorFlag(FActLine);
5752 InvalidateEditor(0,0);
5753 End
5754 Else
5755 Begin
5756 Dec(FScrCursor.X,CountDel);
5757 InvalidateWorkLine;
5758 End;
5759 (*Undo*)
5760 LastUndoGroup := ugBackspaceChar;
5761 (*Undo*)
5762 End;
5763End;
5764
5765
5766Procedure TEditor.cmEnter;
5767Var newstring:String;
5768 emptystring:String;
5769 I:Integer;
5770 FNT:Integer;
5771 NCX:Integer;
5772 ip:TICBPosition;
5773 FCX:Integer;
5774 AL:PLine;
5775 iew:Boolean;
5776Begin
5777 If ReadOnly Then Exit;
5778 TestAutoSave;
5779
5780 If _ICBOverwrite Then iew := _ICBDeleteICB
5781 Else iew := False;
5782
5783 (*Undo*)
5784 _CopyUndoLines(FActLine,FActLine);
5785 (*Undo*)
5786 If Not WLactivated Then _ReadWorkLine;
5787
5788 If FFileCursor.X <= Length(FWorkLine) Then
5789 Begin
5790 newstring := _ReadString(FActLine,FFileCursor.X,-1);
5791 SetLength(FWorkLine,FFileCursor.X-1);
5792 End
5793 Else newstring := '';
5794 _WriteWorkLine;
5795
5796 _HorizMove;
5797 _InsertLine(FActLine);
5798 ip := _ICBPos(FActLine,FFileCursor.X);
5799 FCX := FFileCursor.X;
5800 AL := FActLine;
5801 FActLine := FActLine^.Next;
5802 If FEditOpt * [eoAutoIndent] <> [] Then
5803 Begin
5804 emptystring := '';
5805 If Length(FActLine^.Prev^.zk^) = 0 Then FNT := FFileCursor.X
5806 Else
5807 Begin
5808 FNT := 1;
5809 While (FActLine^.Prev^.zk^[FNT] = ' ') And
5810 (FNT <= Length(FActLine^.Prev^.zk^)) Do Inc(FNT);
5811 End;
5812 For I := 1 To FNT-1 Do emptystring := emptystring + ' ';
5813 FWorkLine := emptystring + newstring;
5814 _WriteWorkLine;
5815
5816 If Length(FActLine^.Prev^.zk^) = 0 Then NCX := _FindNextTab(FActLine,1)
5817 Else NCX := _FindNextTab(FActLine^.Prev,1);
5818 FFileCursor.X := NCX;
5819 FScrCursor.X := NCX;
5820 If FScrCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X;
5821 End
5822 Else
5823 Begin
5824 FFileCursor.X := 1;
5825 FScrCursor.X := 1;
5826 FWorkLine := newstring;
5827 _WriteWorkLine;
5828 FNT := 1;
5829 End;
5830 {Update ICB}
5831 If FSelectMode <> smColumnBlock Then
5832 Begin
5833 If ip * [ipBeforeICBFirst] <> [] Then
5834 Begin
5835 AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5836 AL^.flag := AL^.flag And Not ciSelected;
5837 Dec(ICB.First.X,FCX-1);
5838 Inc(ICB.First.X,FNT-1);
5839 ICB.First.Line := ICB.First.Line^.Next;
5840 End;
5841 If ip * [ipBeforeICBLast] <> [] Then
5842 Begin
5843 AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5844 Dec(ICB.Last.X,FCX-1);
5845 Inc(ICB.Last.X,FNT-1);
5846 ICB.Last.Line := ICB.Last.Line^.Next;
5847 End;
5848 If ip * [ipAfterICBFirst,ipWithinICB] <> []
5849 Then AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5850 If ip * [ipAfterICBLast] <> []
5851 Then AL^.Next^.flag := AL^.Next^.flag And Not ciSelected;
5852 _ICBCheckX;
5853 End
5854 Else {Extended Selection}
5855 Begin
5856 If ip * [ipBeforeICBFirst,ipAfterICBFirst,ipWithinICB] <> [] Then
5857 If ip * [ipBeforeICBLast,ipAfterICBLast] = []
5858 Then AL^.Next^.flag := AL^.Next^.flag Or (AL^.flag And ciSelected);
5859 End;
5860
5861 Inc(FFileCursor.Y);
5862 SetLineColorFlag(FActLine^.Prev,FActLine);
5863 FRedoList.Clear;
5864 If FScrCursor.Y = FWinSize.Y Then
5865 Begin
5866 FTopScreenLine := FTopScreenLine^.Next;
5867 InvalidateEditor(0,0);
5868 End
5869 Else
5870 Begin
5871 Inc(FScrCursor.Y);
5872 If _HorizMove Or iew Then InvalidateEditor(0,0)
5873 Else InvalidateEditor(FScrCursor.Y-1,0);
5874 End;
5875 SetSliderValues;
5876 (*Undo*)
5877 _UpdateLastUndoEvent(FUndoList,_PLine2Index(FActLine^.Next));
5878 LastUndoGroup := ugEnter;
5879 (*Undo*)
5880End;
5881
5882
5883
5884Procedure TEditor.CutToClipBoard;
5885Var P:Pointer;
5886 len:LongInt;
5887Begin
5888 If ReadOnly Then Exit;
5889 If Not Selected Then Exit;
5890 TestAutoSave;
5891 If _GetEditorBlock(P,len) Then {including terminal #0}
5892 Begin
5893 If _SetClipBoardText(P,len) Then
5894 Begin
5895 FRedoList.Clear;
5896 If _ICBDeleteICB Then InvalidateEditor(0,0);
5897 End;
5898 FreeMem(P,len);
5899 End;
5900End;
5901
5902
5903Procedure TEditor.CopyToClipboard;
5904Var P:Pointer;
5905 len:LongInt;
5906Begin
5907 If Not Selected Then Exit;
5908 If _GetEditorBlock(P,len) Then {including terminal #0}
5909 Begin
5910 _SetClipBoardText(P,len);
5911 FreeMem(P,len);
5912 End;
5913End;
5914
5915
5916Function TEditor.PasteFromClipBoard:Boolean;
5917Var P:Pointer;
5918 len:LongInt;
5919Begin
5920 Result := False;
5921 If ReadOnly Then Exit;
5922 TestAutoSave;
5923
5924 Result := _GetClipBoardText(P,len);
5925 If Result And (len > 0) Then
5926 Begin
5927 If _ICBOverwrite Then _ICBDeleteICB;
5928
5929 InsertText(P,len-1); {without terminal #0}
5930 FreeMem(P,len);
5931 End;
5932End;
5933
5934
5935Function TEditor.InsertFromFile(Const FName:String):Boolean;
5936Var P:Pointer;
5937 len:LongInt;
5938Begin
5939 Result := False;
5940 If ReadOnly Then Exit;
5941 TestAutoSave;
5942
5943 Result := _GetFileText(FName,P,len);
5944 If Result And (len > 0) Then
5945 Begin
5946 If _ICBOverwrite Then _ICBDeleteICB;
5947
5948 InsertText(P,len-1); {without terminal #0}
5949 FreeMem(P,len);
5950 End;
5951End;
5952
5953
5954Function TEditor.GetReadOnly:Boolean;
5955Begin
5956 Result := FReadOnly;
5957End;
5958
5959
5960Procedure TEditor.SetReadOnly(Value:Boolean);
5961Begin
5962 FReadOnly := Value;
5963End;
5964
5965
5966Procedure TEditor.SetModified(Value:Boolean);
5967Begin
5968 FModified := Value;
5969End;
5970
5971
5972{Show actual State Of the Editor}
5973Procedure TEditor.UpdateEditorState;
5974Begin
5975End;
5976
5977
5978{Use This method To Show additional State information; E.G. State Text}
5979{$HINTS OFF}
5980Procedure TEditor.SetStateMessage(Const S:String);
5981Begin
5982End;
5983{$HINTS ON}
5984
5985{Handle an Error Message}
5986Procedure TEditor.SetErrorMessage(Const S:String);
5987Begin
5988 MessageBox(S,mtError,[mbOk]);
5989 Focus;
5990End;
5991
5992
5993{Handle A Query from the Editor}
5994Function TEditor.SetQueryMessage(Const S:String;Typ:TMsgDlgType;Buttons:TMsgDlgButtons):TMsgDlgReturn;
5995Begin
5996 Result := MessageBox(S,Typ,Buttons);
5997 Focus;
5998End;
5999
6000
6001{Handle A Confirm Query from the Editor}
6002Function TEditor.SetReplaceConfirmMessage:TMsgDlgReturn;
6003Var Dlg:TMessageBox;
6004 pt:TPoint;
6005Begin
6006 BringToFront;
6007 If Application <> Nil Then Dlg.Create(Application.MainForm)
6008 Else Dlg.Create(Nil);
6009 Dlg.Message := LoadNLSStr(SReplaceThisString);
6010 Dlg.Buttons := mbYesNoCancel;
6011 Dlg.DlgType := mtInformation;
6012 Dlg.XAlign := xaNone;
6013 Dlg.YAlign := yaNone;
6014 Dlg.XStretch := xsFixed;
6015 Dlg.YStretch := ysFixed;
6016 Dlg.Width := 350;
6017 Dlg.Height := 130;
6018 pt := GetMouseFromCursor(FScrCursor);
6019 pt := ClientToScreen(pt); {pt Is the lower Left corner Of the Selection}
6020 If pt.Y > Dlg.Height Then Dec(pt.Y, Dlg.Height)
6021 Else Inc(pt.Y, Canvas.FontHeight);
6022 If pt.X + Dlg.Width > Screen.Width Then pt.X := Screen.Width - Dlg.Width;
6023 Dlg.Left := pt.X;
6024 Dlg.Bottom := pt.Y;
6025
6026 Dlg.Execute;
6027 Case Dlg.ModalResult Of
6028 cmYes:Result := mrYes;
6029 cmNo: Result := mrNo;
6030 Else Result := mrCancel;
6031 End;
6032 Dlg.Destroy;
6033End;
6034
6035
6036{Handle the FileName And the Caption Of the Editor Window}
6037Procedure TEditor.SetFileName(Const FName:String);
6038Begin
6039 If FFileName <> FName Then
6040 Begin
6041 FileNameChange(FFileName,FName);
6042 End;
6043 FFileName := FName;
6044End;
6045
6046
6047{Use This method To Update the color flag Of an Editor Line}
6048{$HINTS OFF}
6049Function TEditor.UpdateLineColorFlag(pl:PLine):Boolean;
6050Begin
6051 Result := False;
6052End;
6053
6054
6055{Use This method To Update the color flag Of Editor Lines}
6056Procedure TEditor.SetLineColorFlag(pl1,pl2:PLine);
6057Begin
6058End;
6059{$HINTS ON}
6060
6061
6062{Set the color values For the actual Output Line}
6063Procedure TEditor.CalcLineColor(pl:PLine;Var LineColor:TColorArray);
6064Var I:Integer;
6065 SelBegin:Integer;
6066 SelEnd:Integer;
6067 ac,acend:Integer;
6068Begin
6069 ac := FFileCursor.X-FScrCursor.X+1;
6070 acend := ac+FWinSize.X-1;
6071 For I := ac To acend Do
6072 Begin
6073 LineColor[I].Fgc := fgcPlainText;
6074 LineColor[I].Bgc := bgcPlainText;
6075 End;
6076
6077 If pl = Nil Then Exit;
6078
6079 If FindICB.First.Line = Nil Then {Test normal Selection}
6080 Begin
6081 If (pl^.flag And ciSelected = 0) Then Exit;
6082 If Not ICBVisible Then Exit;
6083
6084 If FSelectMode <> smColumnBlock Then
6085 Begin
6086 If ICB.First.Line = pl Then SelBegin := ICB.First.X
6087 Else SelBegin := 1;
6088 If ICB.Last.Line = pl Then SelEnd := ICB.Last.X-1
6089 Else SelEnd := acend;
6090
6091 If FKeyMap = kmCUA Then
6092 Begin
6093 I := Length(_PLine2PString(pl)^) +1;
6094 If I < SelEnd Then SelEnd := I;
6095 End;
6096 End
6097 Else {Extended Selection}
6098 Begin
6099 If ICB.First.X = ICB.Last.X Then Exit;
6100 If ICB.First.X < ICB.Last.X Then
6101 Begin
6102 SelBegin := ICB.First.X;
6103 SelEnd := ICB.Last.X-1;
6104 End
6105 Else
6106 Begin
6107 SelBegin := ICB.Last.X;
6108 SelEnd := ICB.First.X-1;
6109 End;
6110 End;
6111
6112 If SelBegin > acend Then Exit;
6113 If SelEnd > acend Then SelEnd := acend;
6114
6115 For I := SelBegin To SelEnd Do
6116 Begin
6117 LineColor[I].Fgc := fgcMarkedBlock;
6118 LineColor[I].Bgc := bgcMarkedBlock;
6119 End;
6120 End
6121 Else {Test Find Text block}
6122 Begin
6123 If FindICB.First.Line <> pl Then Exit;
6124 SelBegin := FindICB.First.X;
6125 SelEnd := FindICB.Last.X-1;
6126
6127 If SelBegin > acend Then Exit;
6128 If SelEnd > acend Then SelEnd := acend;
6129
6130 For I := SelBegin To SelEnd Do
6131 Begin
6132 LineColor[I].Fgc := fgcSearchMatch;
6133 LineColor[I].Bgc := bgcSearchMatch;
6134 End;
6135 End;
6136End;
6137
6138
6139Procedure ReplaceDBCSChars(Var S:String; maxchars:LongInt);
6140Var I:LongInt;
6141Begin
6142 If maxchars > Length(S) Then maxchars := Length(S);
6143 For I := 1 To maxchars Do
6144 Begin
6145 {$IFDEF OS2}
6146 If IsDBCSFirstByte(S[I]) Then
6147 Begin
6148 S[I] := ' ';
6149 Inc(I); {onto Second Byte}
6150 S[I] := ' ';
6151 End;
6152 {$ENDIF}
6153 End;
6154End;
6155
6156
6157Procedure ReplaceBoundingDBCSChars(Var S:String; First,Last:LongInt);
6158Var I:LongInt;
6159 DBCS1stByte:Boolean;
6160Begin
6161 If Last > Length(S) Then Last := Length(S);
6162 DBCS1stByte := False;
6163 For I := 1 To Last Do
6164 Begin
6165 {$IFDEF OS2}
6166 DBCS1stByte := IsDBCSFirstByte(S[I]);
6167 {$ELSE}
6168 DBCS1stByte := False;
6169 {$ENDIF}
6170
6171 If I = First-1 Then
6172 Begin
6173 {If First Is the Second Byte Of A dbcs Char - dont Draw it}
6174 If DBCS1stByte Then S[First] := ' ';
6175 End;
6176
6177 If I = Last Then
6178 Begin
6179 {If Last Is the First Byte Of A dbcs Char - dont Draw it}
6180 If DBCS1stByte Then S[Last] := ' ';
6181 End;
6182
6183 If DBCS1stByte Then Inc(I);
6184 End;
6185End;
6186
6187
6188{Redraw the specified Line In the Editor Window}
6189Procedure TEditor.InvalidateScreenLine(ScrY:Integer);
6190Var pl:PLine;
6191 X,Y:LongInt;
6192 ac:Integer;
6193 I,W:Integer;
6194 Count:Integer;
6195 ps:Integer;
6196 S:String;
6197 los:Integer;
6198 LineColor:TColorArray;
6199 OutputString:String;
6200 XLeft:LongInt;
6201 PenColorIndex:LongInt;
6202 BrushColorIndex:LongInt;
6203Begin
6204 If Handle = 0 Then Exit;
6205 pl := FTopScreenLine;
6206 For I := 2 To ScrY Do
6207 If pl <> Nil Then pl := pl^.Next;
6208
6209 CalcLineColor(pl,LineColor);
6210
6211 If pl <> Nil Then OutputString := _PLine2PString(pl)^
6212 Else OutputString := '';
6213
6214 ac := FFileCursor.X-FScrCursor.X+1; {1st Char In Window}
6215
6216 If Application.DBCSSystem Then
6217 Begin
6218 If IsDBCSFont Then
6219 Begin
6220 {Test If 1st Or Last character In the belong To A dbcs Char}
6221 ReplaceBoundingDBCSChars(OutputString,ac,ac+FWinSize.X-1);
6222 End
6223 Else
6224 Begin
6225 {replace All non-printable dbcs characters}
6226 ReplaceDBCSChars(OutputString,ac+FWinSize.X-1);
6227 End;
6228 End;
6229
6230 los := Length(OutputString);
6231 For I := los+1 To ac+FWinSize.X-1 Do OutputString[I] := #32;
6232 SetLength(OutputString,ac+FWinSize.X-1);
6233
6234 PenColorIndex := LineColor[ac].Fgc;
6235 BrushColorIndex := LineColor[ac].Bgc;
6236 Canvas.Pen.color := ColorEntry[PenColorIndex];
6237 Canvas.Brush.color := ColorEntry[BrushColorIndex];
6238
6239 Count := 0;
6240 ps := 0;
6241 XLeft := FBorderWidth + IndentRect.Left;
6242 Y := ClientArea.Top - (ScrY*Canvas.FontHeight) -
6243 IndentRect.Top - FBorderWidth;
6244 For I := ac To ac+FWinSize.X-1 Do
6245 Begin
6246 If (PenColorIndex <> LineColor[I].Fgc) Or
6247 (BrushColorIndex <> LineColor[I].Bgc) Then
6248 Begin
6249 X := XLeft + ps*Canvas.FontWidth;
6250 S := Copy(OutputString,ps+ac,Count);
6251 Canvas.TextOut(X,Y,S);
6252
6253 Inc(ps,Count);
6254 Count := 1;
6255 PenColorIndex := LineColor[I].Fgc;
6256 BrushColorIndex := LineColor[I].Bgc;
6257 Canvas.Pen.color := ColorEntry[PenColorIndex];
6258 Canvas.Brush.color := ColorEntry[BrushColorIndex];
6259 End
6260 Else Inc(Count);
6261 End;
6262 If Count <> 0 Then
6263 Begin
6264 X := XLeft+ps*Canvas.FontWidth;
6265 S := Copy(OutputString,ps+ac,Count);
6266 Canvas.TextOut(X,Y,S);
6267 End;
6268
6269 {WordWrap Line}
6270 WrapLineX := -1;
6271 If FWordWrap Then
6272 If ((FWordWrapColumn > ac) And (FWordWrapColumn < ac+FWinSize.X)) Or
6273 (FWordWrapColumn = 0) Then
6274 Begin
6275 If FWordWrapColumn = 0 Then W := FWinSize.X-1
6276 Else W := FWordWrapColumn - (FFileCursor.X - FScrCursor.X);
6277 XLeft := FBorderWidth+IndentRect.Left;
6278 WrapLineX := XLeft + W * Canvas.FontWidth;
6279 Canvas.Pen.color := ColorEntry[fgcRightMargin];
6280 Canvas.MoveTo(WrapLineX,Y);
6281 Inc(Y, Canvas.FontHeight-1);
6282 Canvas.LineTo(WrapLineX,Y);
6283 End;
6284End;
6285
6286
6287{Redraw the actual Cursor Line}
6288Procedure TEditor.InvalidateWorkLine;
6289Begin
6290 If Not UpdateLineColorFlag(FActLine) Then
6291 Begin
6292 If IgnoreRedraw > 0 Then Exit;
6293 FCaret.Hide;
6294 InvalidateScreenLine(FScrCursor.Y);
6295 SetScreenCursor;
6296 FCaret.Show;
6297 End
6298 Else InvalidateEditor(FScrCursor.Y,0);
6299End;
6300
6301
6302{Redraw the Lines In the Editor Window from Line y1 To Line y2}
6303Procedure TEditor.InvalidateEditor(y1,y2:Integer);
6304Var I:Integer;
6305 Y:LongInt;
6306 OldWrapLineX:Integer;
6307Begin
6308 If Handle = 0 Then Exit;
6309 If IgnoreRedraw > 0 Then Exit;
6310 OldWrapLineX := WrapLineX;
6311
6312 If y1 < 1 Then y1 := 1;
6313 If y2 < 1 Then y2 := FWinSize.Y;
6314 If y2 > FWinSize.Y Then y2 := FWinSize.Y;
6315 SetSliderPosition;
6316 FCaret.Hide;
6317 For I := y1 To y2 Do InvalidateScreenLine(I);
6318
6319 If OldWrapLineX > 0 Then
6320 Begin
6321 Canvas.Pen.color := ColorEntry[bgcPlainText];
6322 Y := ClientArea.Top -1;
6323 Y := Y - Integer(FBorderWidth);
6324 Canvas.MoveTo(OldWrapLineX,Y);
6325 Y := Y - IndentRect.Top;
6326 Canvas.LineTo(OldWrapLineX,Y);
6327
6328 Y := Y - (FWinSize.Y * Canvas.FontHeight) +2;
6329 Canvas.MoveTo(OldWrapLineX,Y);
6330 Y := Integer(FBorderWidth);
6331 Canvas.LineTo(OldWrapLineX,Y);
6332 End;
6333 If WrapLineX > 0 Then
6334 Begin
6335 Canvas.Pen.color := ColorEntry[fgcRightMargin];
6336 Y := ClientArea.Top -1 -Integer(FBorderWidth);
6337 Canvas.MoveTo(WrapLineX,Y);
6338 Y := Y -IndentRect.Top;
6339 Canvas.LineTo(WrapLineX,Y);
6340
6341 Y := Y - (FWinSize.Y * Canvas.FontHeight) +2;
6342 Canvas.MoveTo(WrapLineX,Y);
6343 Y := Integer(FBorderWidth);
6344 Canvas.LineTo(WrapLineX,Y);
6345 End;
6346
6347 SetScreenCursor;
6348 FCaret.Show;
6349End;
6350
6351
6352{Redraw All Lines And the indent borders In the Editor Window}
6353Procedure TEditor.Redraw(Const rc:TRect);
6354Var rec:TRect;
6355 FrameWidth:Integer;
6356Begin
6357 Canvas.ClipRect := rc;
6358 FrameWidth := Integer(FBorderWidth);
6359
6360 rec := ClientArea;
6361 rec.Top := rec.Top-(FWinSize.Y*Canvas.FontHeight+IndentRect.Top)+1;
6362 Dec(rec.Top,FrameWidth);
6363 Inc(rec.Bottom,FrameWidth);
6364 Inc(rec.Left,FrameWidth);
6365 Dec(rec.Right,FrameWidth);
6366 Canvas.FillRect(rec,ColorEntry[bgcPlainText]); {Bottom}
6367
6368 rec := ClientArea;
6369 rec.Bottom := rec.Top-IndentRect.Top;
6370 Inc(rec.Left,FrameWidth);
6371 Dec(rec.Right,FrameWidth);
6372 Dec(rec.Bottom,FrameWidth);
6373 Dec(rec.Top,FrameWidth);
6374 Canvas.FillRect(rec,ColorEntry[bgcPlainText]); {Top}
6375
6376 rec := ClientArea;
6377 rec.Right := IndentRect.Left;
6378 Inc(rec.Right,FrameWidth);
6379 Inc(rec.Bottom,FrameWidth);
6380 Inc(rec.Left,FrameWidth);
6381 Dec(rec.Top,FrameWidth);
6382 Canvas.FillRect(rec,ColorEntry[bgcPlainText]); {Left}
6383
6384 rec := ClientArea;
6385 rec.Left := FWinSize.X*Canvas.FontWidth+IndentRect.Left;
6386 Inc(rec.Left,FrameWidth);
6387 Inc(rec.Bottom,FrameWidth);
6388 Dec(rec.Right,FrameWidth);
6389 Dec(rec.Top,FrameWidth);
6390 Canvas.FillRect(rec,ColorEntry[bgcPlainText]); {Right}
6391
6392 rec := ClientArea;
6393 Dec(rec.Right);
6394 Dec(rec.Top);
6395 If FCtl3D Then
6396 Begin
6397 Canvas.ShadowedBorder(rec,clDkGray,clWhite);
6398 InflateRect(rec,-1,-1);
6399 Canvas.ShadowedBorder(rec,clBlack,clLtGray);
6400 End
6401 Else Canvas.ShadowedBorder(rec,clBlack,clBlack);
6402
6403 InvalidateEditor(0,0);
6404 Canvas.DeleteClipRegion;
6405End;
6406
6407
6408Procedure TEditor.SetScreenCursor;
6409Var pt:TPoint;
6410 W:LongInt;
6411 ps:PString;
6412Begin
6413 pt := GetMouseFromCursor(FScrCursor);
6414 FCaret.SetPos(pt.X,pt.Y);
6415 UpdateEditorState;
6416
6417 If Application.DBCSSystem Then
6418 Begin {Make sure, that the Caret has the same Width like the Char below}
6419 If (FCursorShape = csVertical) And FInsertMode Then Exit;
6420
6421 ps := _PLine2PString(FActLine);
6422 If QueryDBCSFirstByte(ps^, FFileCursor.X) Then W := 2 * Canvas.FontWidth
6423 Else W := Canvas.FontWidth;
6424
6425 If FCaret.Width <> W Then
6426 Begin
6427 FCaret.Remove;
6428 FCaret.SetSize(W, FCaret.Height);
6429 If HadFocus > 0 Then FCaret.Show;
6430 End;
6431 End;
6432End;
6433
6434
6435Function TEditor.QueryConvertPos(Var Pos:TPoint):Boolean;
6436Begin
6437 Pos := GetMouseFromCursor(FScrCursor);
6438 Result := True;
6439End;
6440
6441
6442Procedure TEditor.BeginUpdate;
6443Begin
6444 Inc(IgnoreRedraw);
6445End;
6446
6447
6448Procedure TEditor.EndUpdate;
6449Begin
6450 Dec(IgnoreRedraw);
6451 If IgnoreRedraw <= 0 Then
6452 Begin
6453 IgnoreRedraw := 0;
6454 InvalidateEditor(0,0);
6455 SetSliderValues;
6456 End;
6457End;
6458
6459
6460Procedure TEditor.SetupComponent;
6461Begin
6462 Inherited SetupComponent;
6463
6464 DBCSStatusLine := True;
6465 ScrollBars := ssBoth;
6466 FCaret.Create(Self);
6467 FOldCaption := '';
6468 FFirstLine := Nil;
6469 FLastLine := Nil;
6470 _InsertLine(Nil);
6471 FActLine := FFirstLine;
6472 FTopScreenLine := FActLine;
6473 FFileName := '';
6474 IndentRect.Top := 3;
6475 IndentRect.Left := 3;
6476 IndentRect.Right := 3 + Screen.SystemMetrics(smCxVScroll);
6477 IndentRect.Bottom := 3 + Screen.SystemMetrics(smCyHScroll);
6478 FWinSize.Y := 0;
6479 FWinSize.X := 0;
6480 FFileCursor.X := 1;
6481 FFileCursor.Y := 1;
6482 FScrCursor.X := 1;
6483 FScrCursor.Y := 1;
6484 TabSize := 8;
6485 IgnoreRedraw := 0;
6486 WLactivated := True;
6487 Untitled := True;
6488 Modified := False;
6489 ICBVisible := True;
6490 FWorkLine := '';
6491 ICB.First.Line := Nil;
6492 ICB.First.X := 0;
6493 ICB.Last.Line := Nil;
6494 ICB.Last.X := 0;
6495 FEditOpt := [eoCreateBackups,eoUndoGroups,eoAutoIndent,eoUnindent,
6496 eoPersistentBlocks,eoSmartTabs];
6497 FKeyMap := kmWordStar;
6498 FInsertMode := True;
6499 FReadOnly := False;
6500 MaxUndo := 128;
6501 FUndoList.Create;
6502 FUndoList.OnFreeItem := _FreeUndoEvent;
6503 FRedoList.Create;
6504 FRedoList.OnFreeItem := _FreeUndoEvent;
6505 KeyRepeat := 1;
6506 FPreCtrl := 0;
6507 HadFocus := 0;
6508 FFindReplace.Find := '';
6509 FFindReplace.replace := '';
6510 FFindReplace.Direction := fdForward;
6511 FFindReplace.Origin := foEntireScope;
6512 FFindReplace.Scope := fsGlobal;
6513 FFindReplace.Options := [];
6514 FLastFind := faNothing;
6515 IncSearchList.Create;
6516 IncSearchText := '';
6517 FindICB.First.Line := Nil;
6518 fMask := '*.*';
6519
6520 PenColor := clBlack;
6521 color := clWhite;
6522 FSelColor:=Color;
6523 FSelBackColor:=PenColor;
6524 FFoundColor := FSelColor;
6525 FFoundColor := FSelColor;
6526 FWrapLineColor := clLtGray;
6527 Font := Screen.FixedFont;
6528 FSaveEvents := -1;
6529 FWordWrap := False;
6530 FWordWrapColumn := 0;
6531 WrapLineX := -1;
6532 FCtl3D := True;
6533 FMacroList := Nil;
6534 FRecording := False;
6535 FPlaying := False;
6536 FCursorShape := csUnderline;
6537 SelectMode := smNonInclusiveBlock;
6538
6539 DragMode := dmAutomatic;
6540 DragCursor := crIBeam;
6541End;
6542
6543
6544Procedure TEditor.SetupShow;
6545Begin
6546 Inherited SetupShow;
6547
6548 FBottomScrollBar := HorzScrollBar;
6549 FRightScrollBar := VertScrollBar;
6550
6551 CalcSizes;
6552 Cursor := crIBeam;
6553 CursorShape := FCursorShape;
6554 FEventsCounter := FSaveEvents;
6555End;
6556
6557
6558Function TEditor.LoadFromStream(Stream:TStream):Boolean;
6559Var P:Pointer;
6560 len:LongInt;
6561Begin
6562 Result := False;
6563 If FReadOnly Then Exit; {F!}
6564 SetStateMessage(LoadNLSStr(SLoading));
6565
6566 Screen.Cursor := crHourGlass;
6567 Stream.Position:=0;
6568 len:=Stream.Size;
6569 GetMem(P,len);
6570 Stream.ReadBuffer(P^,len);
6571 Result:=True;
6572 If Result And (len > 0) Then
6573 Begin
6574 If _ICBOverwrite Then _ICBDeleteICB;
6575 _InsertText(P,len-1, False); {without terminal #0}
6576 FreeMem(P,len);
6577 End;
6578 Screen.Cursor := crDefault;
6579
6580 SetStateMessage('');
6581 FUndoList.Clear;
6582 FRedoList.Clear;
6583 Untitled := False;
6584 Modified := False;
6585 InvalidateEditor(0,0);
6586End;
6587
6588
6589Function TEditor.LoadFromFile(Const FName:String):Boolean;
6590Var P:Pointer;
6591 len:LongInt;
6592 S:String;
6593Begin
6594 Result := False;
6595 If FReadOnly Then Exit; {F!}
6596 S := FExpand(FName);
6597 SetStateMessage(LoadNLSStr(SLoading) + S);
6598
6599 SetFileName(S);
6600
6601 Screen.Cursor := crHourGlass;
6602 Result := _GetFileText(S,P,len);
6603 If Result And (len > 0) Then
6604 Begin
6605 If _ICBOverwrite Then _ICBDeleteICB;
6606 _InsertText(P,len-1, False); {without terminal #0}
6607 FreeMem(P,len);
6608 End;
6609 Screen.Cursor := crDefault;
6610 SetStateMessage('');
6611 FUndoList.Clear;
6612 FRedoList.Clear;
6613 Untitled := False;
6614 Modified := False;
6615 InvalidateEditor(0,0);
6616End;
6617
6618
6619{$HINTS OFF}
6620Procedure TEditor.SetAvailabeFileTypes(CFOD:TOpenDialog);
6621Begin
6622End;
6623{$HINTS ON}
6624
6625
6626Function TEditor.SaveToStream(Stream:TStream):Boolean;
6627Var Ptr:^LongWord;
6628 len:LongInt;
6629Begin
6630 SetStateMessage(LoadNLSStr(SSaving));
6631 If _GetEditorText(Ptr,len) Then
6632 Begin
6633 Stream.WriteBuffer(Ptr^,len);
6634 FreeMem(Ptr,len);
6635 End
6636 Else Result:=False;
6637 SetStateMessage('');
6638 UpdateEditorState;
6639End;
6640
6641
6642Const
6643 SaveAsISOLatin1:Boolean=FALSE;
6644 CurrentCodePage:LongInt=0;
6645
6646Type
6647 TCharArray=Array[1..MaxLongInt] Of Char;
6648 PCharArray=^TCharArray;
6649
6650Procedure ConvertToISOLatin1(Ptr:PCharArray;len:LongInt);
6651{$IFDEF OS2}
6652Var cptarget:INTEGER;
6653 cpsource:INTEGER;
6654 TempPtr:PCharArray;
6655 i:LongInt;
6656{$ENDIF}
6657Begin
6658 {$IFDEF OS2}
6659 If SaveAsISOLatin1 Then
6660 Begin
6661 cpsource := CurrentCodePage;
6662 cptarget := 1004;
6663 If cpsource = 0 Then Exit;
6664
6665 GetMem(TempPtr,len);
6666 Move(Ptr^,TempPtr^,len);
6667
6668 If WinCPTranslateString(AppHandle, cpsource, PChar(TempPtr)^, cptarget,
6669 len, PChar(Ptr)^) Then
6670 Begin
6671 For i := 1 To len Do
6672 If Ptr^[i] = #255 Then Ptr^[i] := TempPtr^[i];
6673 End;
6674
6675 FreeMem(TempPtr,len);
6676 End;
6677 {$ENDIF}
6678End;
6679
6680
6681Function TEditor.SaveToFile(Const FName:String):Boolean;
6682Var utF,eF:File;
6683 Ptr:^LongWord;
6684 len:LongInt;
6685 IoR:Integer;
6686 BackupName:String;
6687 D,N,E:String;
6688Begin
6689 Result := False;
6690
6691 SetStateMessage(LoadNLSStr(SSaving) + FName);
6692 Screen.Cursor := crHourGlass;
6693 If FEditOpt * [eoCreateBackups] <> [] Then
6694 Begin
6695 If FEditOpt * [eoAppendBAK] = [] Then
6696 Begin
6697 FSplit(FName,D,N,E);
6698 BackupName := D + N + '.BAK';
6699 End
6700 Else BackupName := FName + '.BAK';
6701 System.Assign(utF,FName);
6702 {$I-}
6703 Reset(utF);
6704 IoR := InOutRes;
6705 System.Close(utF);
6706 {$I+}
6707 If IoR = 0 Then
6708 Begin
6709 System.Assign(eF,BackupName);
6710 {$I-}
6711 Erase(eF);
6712 Rename(utF,BackupName);
6713 {$I+}
6714 End;
6715 End;
6716
6717 System.Assign(utF,FName);
6718 {$I-}
6719 Rewrite(utF,1);
6720 {$I+}
6721 If InOutRes <> 0 Then
6722 Begin
6723 SetStateMessage('');
6724 SetErrorMessage(LoadNLSStr(SErrorWriting)+': '+ FName);
6725 Screen.Cursor := crDefault;
6726 Exit;
6727 End;
6728 If _GetEditorText(Ptr,len) Then
6729 Begin
6730 ConvertToISOLatin1(PCharArray(Ptr),len);
6731
6732 {$I-}
6733 BlockWrite(utF,Ptr^,len-1); {without terminating #0}
6734 {$I+}
6735 FreeMem(Ptr,len);
6736 If InOutRes <> 0 Then
6737 Begin
6738 {$I-}
6739 System.Close(utF);
6740 {$I+}
6741 SetStateMessage('');
6742 SetErrorMessage(LoadNLSStr(SErrorWriting)+': '+ FName);
6743 Screen.Cursor := crDefault;
6744 Exit;
6745 End;
6746 End;
6747 {$I-}
6748 System.Close(utF);
6749 {$I+}
6750 Screen.Cursor := crDefault;
6751 Untitled := False;
6752 Modified := False;
6753 SetStateMessage('');
6754 UpdateEditorState;
6755 FEventsCounter := FSaveEvents;
6756
6757 SetFileName(FName);
6758 Result := True;
6759End;
6760
6761
6762Function TEditor.SaveFile:Boolean;
6763Var FName:String;
6764 CFSD:TSaveDialog;
6765 ret:Boolean;
6766Begin
6767 Result := False;
6768
6769 If Untitled Then
6770 Begin
6771 CFSD.Create(Self);
6772 CFSD.Caption := LoadNLSStr(SSaveFileAs);
6773 CFSD.FileName := FileName;
6774 CFSD.DefaultExt := GetDefaultExt(fMask);
6775 SetAvailabeFileTypes(CFSD);
6776
6777 ret := CFSD.Execute;
6778 FName := CFSD.FileName;
6779 CFSD.Destroy;
6780 If Not ret Then Exit;
6781
6782 Case TestSaveAsName(FName) Of
6783 mrNo:
6784 Begin {because Of CloseQuery}
6785 Result := True;
6786 Exit;
6787 End;
6788 mrCancel: Exit;
6789 End;
6790 End
6791 Else FName := FileName;
6792
6793
6794 If SaveToFile(FName) Then Result := True;
6795End;
6796
6797
6798Function TEditor.SaveFileAs(Const FName:String):Boolean;
6799Var S:String;
6800Begin
6801 Result := False;
6802 S := FExpand(FName);
6803
6804 Case TestSaveAsName(S) Of
6805 mrNo:
6806 Begin {because Of CloseQuery}
6807 Result := True;
6808 Exit;
6809 End;
6810 mrCancel: Exit;
6811 End;
6812
6813 If SaveToFile(S) Then Result := True;
6814End;
6815
6816
6817Function TEditor.TestSaveAsName(Const FName:String):TMsgDlgReturn;
6818Var Text:String;
6819Begin
6820 If FileExists(FName) Then
6821 Begin
6822 Text := FmtLoadNLSStr(SAlreadyExistsOverwrite,[FName]);
6823 Result := SetQueryMessage(Text,mtWarning,mbYesNoCancel);
6824 End
6825 Else Result := mrYes;
6826End;
6827
6828
6829{$HINTS OFF}
6830Procedure TEditor.FileNameChange(Const OldName,NewName:String);
6831Begin
6832End;
6833{$HINTS ON}
6834
6835
6836Procedure TEditor.TestAutoSave;
6837Begin
6838 If FEditOpt * [eoAutoSave] = [] Then Exit;
6839 If FSaveEvents <= 0 Then Exit;
6840 If FEventsCounter <= 0 Then
6841 Begin
6842 If Not Untitled Then SaveFile;
6843 FEventsCounter := FSaveEvents;
6844 End
6845 Else Dec(FEventsCounter);
6846End;
6847
6848
6849Procedure TEditor.SetSaveEvents(cnt:Integer);
6850Begin
6851 FSaveEvents := cnt;
6852 FEventsCounter := cnt;
6853End;
6854
6855
6856Procedure TEditor.SetLastUndoGroup(ug:TUndoGroup);
6857Var U:PUndo;
6858Begin
6859 If FUndoList = Nil Then Exit;
6860 If FUndoList.Count = 0 Then Exit;
6861 U := FUndoList.Last;
6862 If U = Nil Then Exit;
6863 U^.EventType := ug;
6864End;
6865
6866
6867Function TEditor.GetLastUndoGroup:TUndoGroup;
6868Var U:PUndo;
6869Begin
6870 Result := ugNoGroup;
6871 If FUndoList = Nil Then Exit;
6872 If FUndoList.Count = 0 Then Exit;
6873 U := FUndoList.Last;
6874 If U = Nil Then Exit;
6875 Result := U^.EventType;
6876End;
6877
6878
6879Procedure TEditor.SetCtl3D(Value:Boolean);
6880Begin
6881 If Value Then FBorderWidth := 2
6882 Else FBorderWidth := 1;
6883
6884 If Handle <> 0 Then
6885 Begin
6886 CalcSizes;
6887 Invalidate;
6888 End;
6889End;
6890
6891
6892Procedure TEditor.SetColorEntry(ColorIndex:Integer;NewColor:TColor);
6893Begin
6894 NewColor := SysColorToRGB(NewColor);
6895 {$IFDEF Win95}
6896 If NewColor = $00CCCCCC Then NewColor := clLtGray;
6897 {$ENDIF}
6898
6899 Case ColorIndex Of
6900 fgcPlainText: PenColor := NewColor;
6901 bgcPlainText: color := NewColor;
6902 fgcMarkedBlock: FSelColor := NewColor;
6903 bgcMarkedBlock: FSelBackColor := NewColor;
6904 fgcSearchMatch: FFoundColor := NewColor;
6905 bgcSearchMatch: FFoundBackColor := NewColor;
6906 fgcRightMargin: FWrapLineColor := NewColor;
6907 Else Exit;
6908 End;
6909 If Not (ColorIndex In [fgcPlainText,bgcPlainText]) Then Invalidate;
6910End;
6911
6912
6913Function TEditor.GetColorEntry(ColorIndex:Integer):TColor;
6914Begin
6915 Case ColorIndex Of
6916 fgcPlainText: Result := PenColor;
6917 bgcPlainText: Result := color;
6918 fgcMarkedBlock: Result := FSelColor;
6919 bgcMarkedBlock: Result := FSelBackColor;
6920 fgcSearchMatch: Result := FFoundColor;
6921 bgcSearchMatch: Result := FFoundBackColor;
6922 fgcRightMargin: Result := FWrapLineColor;
6923 Else Result := color;
6924 End;
6925End;
6926
6927
6928Function TEditor.InsertLine(Y:LongInt;Const S:String):LongInt;
6929Var pl,NewL,SaveAL:PLine;
6930Begin
6931 Result := -1;
6932 If ReadOnly Then Exit;
6933 TestAutoSave;
6934 FlushWorkLine;
6935 If Y < 1 Then Y := 1;
6936 If Y > FCountLines Then
6937 Begin
6938 Y := FCountLines +1;
6939 pl := FLastLine;
6940 End
6941 Else pl := _Index2PLine(Y-1);
6942 Result := Y;
6943
6944 (*Undo*)
6945 If pl <> Nil Then _CopyUndoLines(pl,pl)
6946 Else _MoveUndoLines(FUndoList,pl,pl);
6947 (*Undo*)
6948
6949 NewL := _InsertLine(pl);
6950 SaveAL := FActLine;
6951 FActLine := NewL;
6952 FWorkLine := S;
6953 _WriteWorkLine;
6954 FActLine := SaveAL;
6955
6956 If Y <= FFileCursor.Y Then {Y before FCY}
6957 Begin
6958 If Y > FFileCursor.Y - FScrCursor.Y Then {Y within Screen}
6959 Begin
6960 If Y = FFileCursor.Y - FScrCursor.Y +1 Then FTopScreenLine := NewL;
6961
6962 If FScrCursor.Y >= FWinSize.Y Then
6963 Begin
6964 Dec(FFileCursor.Y);
6965 FActLine := FActLine^.Prev;
6966 If Not _ICBPersistent Then _ICBClearICB;
6967 End
6968 Else Inc(FScrCursor.Y);
6969 End;
6970 Inc(FFileCursor.Y);
6971 End;
6972
6973 _ICBSetMark;
6974 SetSliderValues;
6975 If NewL^.Prev = Nil Then UpdateLineColorFlag(NewL)
6976 Else SetLineColorFlag(NewL^.Prev,NewL);
6977
6978 (*Undo*)
6979 _UpdateLastUndoEvent(FUndoList,_PLine2Index(NewL^.Next));
6980 LastUndoGroup := ugInsertLine;
6981 (*Undo*)
6982 FRedoList.Clear;
6983
6984 InvalidateEditor(0,0);
6985End;
6986
6987
6988Function TEditor.AppendLine(Const S:String):LongInt;
6989Begin
6990 Result := InsertLine(FCountLines+1,S);
6991End;
6992
6993
6994Function TEditor.DeleteLine(Y:LongInt):LongInt;
6995Var ip:TICBPosition;
6996 NextLine,prevline,ulcfline:PLine;
6997 SaveAL:PLine;
6998Begin
6999 Result := -1;
7000 If ReadOnly Then Exit;
7001 FlushWorkLine;
7002 If Y < 1 Then Exit;
7003 If Y > FCountLines Then Exit;
7004 TestAutoSave;
7005 Result := Y;
7006
7007 If FCountLines > 1 Then
7008 Begin
7009 SaveAL := FActLine;
7010 FActLine := _Index2PLine(Y);
7011 NextLine := FActLine^.Next;
7012 prevline := FActLine^.Prev;
7013 ip := _ICBPos(FActLine,0);
7014
7015 (*Undo*)
7016 If prevline <> Nil Then _CopyUndoLines(prevline,FActLine)
7017 Else _CopyUndoLines(FActLine,FActLine);
7018 _UpdateLastUndoEvent(FUndoList,Y);
7019 _DeleteLine(FActLine);
7020 (*Undo*)
7021
7022 SetSliderValues;
7023 WLactivated := False;
7024
7025 If prevline = Nil Then ulcfline := FFirstLine
7026 Else ulcfline := prevline;
7027
7028 If ip * [ipBeforeICBFirst,ipAfterICBFirst] <> [] Then
7029 Begin
7030 ICB.First.Line := NextLine;
7031 If FSelectMode <> smColumnBlock Then ICB.First.X := 1;
7032 End;
7033 If ip * [ipBeforeICBLast,ipAfterICBLast] <> [] Then
7034 Begin
7035 If NextLine <> Nil Then
7036 Begin
7037 ICB.Last.Line := NextLine;
7038 If FSelectMode <> smColumnBlock Then ICB.Last.X := 1;
7039 End
7040 Else
7041 Begin
7042 ICB.Last.Line := FLastLine;
7043 If FSelectMode <> smColumnBlock
7044 Then ICB.Last.X := StringLength;
7045 End;
7046 End;
7047
7048 FActLine := SaveAL;
7049 If Y = FFileCursor.Y Then
7050 Begin
7051 If NextLine = Nil Then
7052 Begin
7053 FActLine := FLastLine;
7054 FFileCursor.Y := FCountLines;
7055 If FScrCursor.Y > 1 Then Dec(FScrCursor.Y);
7056 End
7057 Else FActLine := NextLine;
7058 End
7059 Else
7060 If Y < FFileCursor.Y Then
7061 Begin
7062 If Y > FFileCursor.Y - FScrCursor.Y Then Dec(FScrCursor.Y);
7063 Dec(FFileCursor.Y);
7064 End;
7065
7066 FTopScreenLine := _Index2PLine(FFileCursor.Y - FScrCursor.Y +1);
7067 End
7068 Else
7069 Begin
7070 (*Undo*)
7071 _CopyUndoLines(FActLine,FActLine);
7072 If Not WLactivated Then _ReadWorkLine;
7073 (*Undo*)
7074 FWorkLine := '';
7075 _WriteWorkLine;
7076 ulcfline := FActLine;
7077 FFileCursor.X := 1;
7078 FScrCursor.X := 1;
7079 _ICBClearICB;
7080 End;
7081
7082 _ICBCheckX;
7083 _ICBSetMark;
7084 UpdateLineColorFlag(ulcfline);
7085 Modified := True;
7086
7087 (*Undo*)
7088 LastUndoGroup := ugDeleteLine;
7089 (*Undo*)
7090 FRedoList.Clear;
7091
7092 InvalidateEditor(0,0);
7093End;
7094
7095
7096Function TEditor.ReplaceLine(Y:LongInt;Const S:String):LongInt;
7097Var pl,SaveAL:PLine;
7098Begin
7099 Result := -1;
7100 If ReadOnly Then Exit;
7101 FlushWorkLine;
7102 If Y < 1 Then Exit;
7103 If Y > FCountLines Then Exit;
7104 TestAutoSave;
7105 pl := _Index2PLine(Y);
7106 If pl = Nil Then Exit;
7107 Result := Y;
7108 (*Undo*)
7109 _CopyUndoLines(pl,pl);
7110 LastUndoGroup := ugReplaceLine;
7111 (*Undo*)
7112
7113 SaveAL := FActLine;
7114 FActLine := pl;
7115 _ReadWorkLine;
7116 FWorkLine := S;
7117 _WriteWorkLine;
7118 FActLine := SaveAL;
7119
7120 _ICBCheckX;
7121 FRedoList.Clear;
7122 Modified := True;
7123
7124 InvalidateEditor(0,0);
7125End;
7126
7127
7128Procedure TEditor.ToggleInsertMode;
7129Begin
7130 FInsertMode := Not FInsertMode;
7131 SetInsertMode(FInsertMode);
7132End;
7133
7134
7135Procedure TEditor.SetSelectionStart(P:TEditorPos);
7136Begin
7137 If P.Y < 1 Then P.Y := 1;
7138 If P.Y > FCountLines Then P.Y := FCountLines;
7139 If P.X < 1 Then P.X := 1;
7140 If P.X > StringLength Then P.X := StringLength;
7141
7142 _ICBSetBegin(_Index2PLine(P.Y), P.X);
7143 InvalidateEditor(0,0);
7144End;
7145
7146
7147Procedure TEditor.SetSelectionEnd(P:TEditorPos);
7148Begin
7149 If P.Y < 1 Then P.Y := 1;
7150 If P.Y > FCountLines Then P.Y := FCountLines;
7151 If P.X < 1 Then P.X := 1;
7152 If P.X > StringLength Then P.X := StringLength;
7153
7154 _ICBSetEnd(_Index2PLine(P.Y), P.X);
7155 InvalidateEditor(0,0);
7156End;
7157
7158
7159Function TEditor.GetSelectionStart(Var P:TEditorPos):Boolean;
7160Begin
7161 Result := ICB.First.Line <> Nil;
7162 If Result Then
7163 Begin
7164 P.Y := _PLine2Index(ICB.First.Line);
7165 P.X := ICB.First.X;
7166 End
7167 Else P := FFileCursor;
7168End;
7169
7170
7171Function TEditor.GetSelectionEnd(Var P:TEditorPos):Boolean;
7172Begin
7173 Result := ICB.Last.Line <> Nil;
7174 If Result Then
7175 Begin
7176 P.Y := _PLine2Index(ICB.Last.Line);
7177 P.X := ICB.Last.X;
7178 End
7179 Else P := FFileCursor;
7180End;
7181
7182
7183Procedure TEditor.SelectLine(P:TEditorPos);
7184Var pl:PLine;
7185Begin
7186 _ICBClearICB;
7187 pl := _Index2PLine(P.Y);
7188 If pl <> Nil Then
7189 Begin
7190 ICB.First.Line := pl;
7191 ICB.First.X := 1;
7192 If (pl^.Next = Nil) Or (FSelectMode = smColumnBlock) Then
7193 Begin
7194 ICB.Last.Line := pl;
7195 ICB.Last.X := Length(_PLine2PString(pl)^);
7196 Inc(ICB.Last.X);
7197 End
7198 Else
7199 Begin
7200 ICB.Last.Line := pl^.Next;
7201 ICB.Last.X := 1;
7202 End;
7203 _ICBCheckX;
7204 _ICBSetMark;
7205 ICBVisible := True;
7206 End;
7207 InvalidateEditor(0,0);
7208End;
7209
7210
7211Procedure TEditor.SelectWord(P:TEditorPos);
7212Var FCX:Integer;
7213 pl:PLine;
7214 zk:PString;
7215 lzk:LongInt;
7216Label L;
7217Begin
7218 _ICBClearICB;
7219 pl := _Index2PLine(P.Y);
7220 If pl = Nil Then Goto L;
7221 zk := _PLine2PString(pl);
7222 FCX := P.X;
7223 lzk := Length(zk^);
7224 If P.X > lzk Then
7225 Begin
7226 If lzk = 0 Then Goto L;
7227 FCX := lzk;
7228 End;
7229
7230 While (zk^[FCX-1] In NormalChars) And (FCX > 1) Do Dec(FCX);
7231 ICB.First.Line := pl;
7232 ICB.First.X := FCX;
7233
7234 While (zk^[FCX] In NormalChars) And (FCX <= lzk) Do Inc(FCX);
7235 ICB.Last.Line := pl;
7236 ICB.Last.X := FCX;
7237
7238 _ICBSetMark;
7239 ICBVisible := True;
7240L:
7241 InvalidateEditor(0,0);
7242End;
7243
7244
7245Procedure TEditor.SelectAll;
7246Var pl:PLine;
7247 I:LongInt;
7248 len:Integer;
7249Begin
7250 ICB.First.Line := FFirstLine;
7251 ICB.First.X := 1;
7252 ICB.Last.Line := FLastLine;
7253 If FSelectMode = smColumnBlock Then
7254 Begin
7255 ICB.Last.X := 1;
7256 pl := FFirstLine;
7257 For I := 1 To CountLines Do
7258 Begin
7259 len := Length(_PLine2PString(pl)^);
7260 If len > ICB.Last.X Then ICB.Last.X := len;
7261 pl := pl^.Next;
7262 End;
7263 End
7264 Else ICB.Last.X := Length(_PLine2PString(FLastLine)^);
7265 Inc(ICB.Last.X);
7266 _ICBCheckX;
7267 _ICBSetMark;
7268 ICBVisible := True;
7269 InvalidateEditor(0,0);
7270End;
7271
7272
7273Procedure TEditor.DeselectAll;
7274Begin
7275 _ICBClearICB;
7276 InvalidateEditor(0,0);
7277End;
7278
7279
7280Procedure TEditor.HideSelection;
7281Begin
7282 ICBVisible := False;
7283 InvalidateEditor(0,0);
7284 UpdateEditorState;
7285End;
7286
7287
7288Procedure TEditor.ShowSelection;
7289Begin
7290 ICBVisible := True;
7291 InvalidateEditor(0,0);
7292 UpdateEditorState;
7293End;
7294
7295
7296Procedure TEditor.DeleteSelection;
7297Begin
7298 cmICBDeleteBlock;
7299End;
7300
7301
7302Function TEditor.SetBookMark(I:Byte; P:TEditorPos):Boolean;
7303Var pl:PLine;
7304 BM:LongWord;
7305Begin
7306 Result := False;
7307 If I > 9 Then Exit;
7308 Inc(I);
7309 If (P.X < 1) Or (P.X > StringLength) Then Exit;
7310 If (P.Y < 1) Or (P.Y > FCountLines) Then Exit;
7311 pl := _FindBookMark(I);
7312 BM := ciBookMarkMask;
7313 If pl <> Nil Then pl^.flag := pl^.flag And Not BM;
7314 pl := _Index2PLine(P.Y);
7315 If pl = Nil Then Exit;
7316 pl^.flag := pl^.flag And Not BM;
7317 BM := I * ciBookMark0;
7318 pl^.flag := pl^.flag Or BM;
7319 BookMarkX[I] := P.X;
7320 InvalidateEditor(0,0);
7321 Result := True;
7322End;
7323
7324
7325Function TEditor.GetBookMark(I:Byte;Var P:TEditorPos):Boolean;
7326Var pl:PLine;
7327Begin
7328 Result := False;
7329 If I > 9 Then Exit;
7330 Inc(I);
7331 pl := _FindBookMark(I);
7332 If pl = Nil Then Exit;
7333 P.Y := _PLine2Index(pl);
7334 P.X := BookMarkX[I];
7335 Result := True;
7336End;
7337
7338
7339Function TEditor.GotoBookMark(I:Byte):Boolean;
7340Var P:TEditorPos;
7341Begin
7342 Result := GetBookMark(I,P);
7343 If Result Then GotoPosition(P);
7344End;
7345
7346
7347Function TEditor.ClearBookMark(I:Byte):Boolean;
7348Var pl:PLine;
7349 BM:LongWord;
7350Begin
7351 Result := False;
7352 If I > 9 Then Exit;
7353 Inc(I);
7354 pl := _FindBookMark(I);
7355 If pl = Nil Then Exit;
7356 BM := ciBookMarkMask;
7357 pl^.flag := pl^.flag And Not BM;
7358 InvalidateEditor(0,0);
7359 Result := True;
7360End;
7361
7362
7363Function TEditor.ClearAllBookMarks:Boolean;
7364Var pl:PLine;
7365 BM:LongWord;
7366Begin
7367 BM := ciBookMarkMask;
7368 pl := FFirstLine;
7369 While pl <> Nil Do
7370 Begin
7371 pl^.flag := pl^.flag And Not BM;
7372 pl := pl^.Next;
7373 End;
7374 InvalidateEditor(0,0);
7375 Result := True;
7376End;
7377
7378
7379Procedure TEditor.GotoPosition(Pos:TEditorPos);
7380Var iew:Boolean;
7381Begin
7382 If Pos.Y < 1 Then Pos.Y := 1;
7383 If Pos.Y > FCountLines Then Pos.Y := FCountLines;
7384 If Pos.X < 1 Then Pos.X := 1;
7385 If Pos.X > StringLength Then Pos.X := StringLength;
7386 (*Undo*)
7387 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
7388 (*Undo*)
7389
7390 iew := _GotoPosition(Pos);
7391 If Not _ICBPersistent Then iew := _ICBClearICB Or iew;
7392
7393 If iew Then InvalidateEditor(0,0)
7394 Else SetScreenCursor;
7395 (*Undo*)
7396 LastUndoGroup := ugCursorMove;
7397 (*Undo*)
7398End;
7399
7400
7401Function TEditor.GetChar(P:TEditorPos):Char;
7402Var zk:PString;
7403 pl:PLine;
7404Begin
7405 Result := ' ';
7406 pl := _Index2PLine(P.Y);
7407 If pl = Nil Then Exit;
7408 zk := _PLine2PString(pl);
7409 If zk = Nil Then Exit;
7410 If P.X <= 0 Then P.X := 1;
7411 If Length(zk^) >= P.X Then Result := zk^[P.X];
7412End;
7413
7414
7415Function TEditor.GetWord(P:TEditorPos):String;
7416Var Count:Integer;
7417 zk:PString;
7418 pl:PLine;
7419 lzk:LongInt;
7420Begin
7421 Result := '';
7422 pl := _Index2PLine(P.Y);
7423 If pl = Nil Then Exit;
7424 zk := _PLine2PString(pl);
7425 If zk = Nil Then Exit;
7426 lzk := Length(zk^);
7427 If P.X > lzk Then P.X := lzk; {onto Last Char}
7428 If P.X <= 0 Then P.X := 1;
7429 While (zk^[P.X-1] In NormalChars) And (P.X > 1) Do Dec(P.X);
7430 Count := 0;
7431 While (zk^[P.X+Count] In NormalChars) And (P.X+Count <= lzk) Do Inc(Count);
7432 Result := Copy(zk^,P.X,Count);
7433End;
7434
7435
7436Function TEditor.GetTextAfterWord(P:TEditorPos):String;
7437Var
7438 zk:PString;
7439 pl:PLine;
7440 lzk:LongInt;
7441Begin
7442 Result := '';
7443 pl := _Index2PLine(P.Y);
7444 If pl = Nil Then Exit;
7445 zk := _PLine2PString(pl);
7446 lzk := Length(zk^);
7447 While (zk^[P.X] In NormalChars) And (P.X <= lzk) Do Inc(P.X);
7448 Result := Copy(zk^,P.X,StringLength);
7449End;
7450
7451
7452Function TEditor.GetText(Var P:Pointer; Var len:LongInt; Selected:Boolean):Boolean;
7453Begin
7454 If Selected Then Result := _GetEditorBlock(P,len)
7455 Else Result := _GetEditorText(P,len);
7456End;
7457
7458
7459Procedure TEditor.InsertText(P:Pointer; len:LongInt);
7460Var ActLineNext:PLine;
7461 Pos:TEditorPos;
7462 tlx:TLineX;
7463Begin
7464 (*Undo*)
7465 _CopyUndoLines(FActLine,FActLine);
7466 ActLineNext := FActLine^.Next;
7467 (*Undo*)
7468
7469 tlx := _InsertText(P,len, _ICBPersistent);
7470
7471 (*Undo*)
7472 _UpdateLastUndoEvent(FUndoList,_PLine2Index(ActLineNext));
7473 LastUndoGroup := ugNoGroup;
7474 (*Undo*)
7475
7476 If Not _ICBPersistent Then // Goto End Of inserted block
7477 Begin
7478 Pos.X := tlx.X;
7479 Pos.Y := _PLine2Index(tlx.Line);
7480 If Pos.Y > 0 Then GotoPosition(Pos);
7481 End;
7482
7483 FRedoList.Clear;
7484 InvalidateEditor(0,0);
7485End;
7486
7487
7488Function backpos(Const S:String; s1:String):Byte;
7489Var I:Byte;
7490Begin
7491 I := 0;
7492 Repeat
7493 Result := I;
7494 I := Pos(S,s1);
7495 s1[I] := #0;
7496 Until I = 0;
7497End;
7498
7499
7500Function TEditor.FindTextPos(Find:String; direct:TFindDirection;
7501 Origin:TFindOrigin; Scope:TFindScope;
7502 opt:TFindOptions; Var pt:TEditorPos):Boolean;
7503Const EmptyChar:Char=#1;
7504Var icbarea:TICB;
7505 pl1,pl2:PLine;
7506 m1,m2:Integer;
7507 S:String;
7508Label again;
7509Begin
7510 FlushWorkLine;
7511 Result := False;
7512 If Find = '' Then Exit;
7513 If Scope = fsGlobal Then
7514 Begin
7515 icbarea.First.Line := FFirstLine;
7516 icbarea.First.X := 1;
7517 icbarea.Last.Line := FLastLine;
7518 icbarea.Last.X := Length(FLastLine^.zk^);
7519 Inc(icbarea.Last.X);
7520 End
7521 Else icbarea := ICB;
7522
7523 If (icbarea.First.Line = Nil) Or (icbarea.Last.Line = Nil) Then Exit;
7524
7525 If opt * [foCaseSensitive] = [] Then Find := AnsiUpperCase(Find);
7526
7527 If direct = fdForward Then
7528 Begin
7529 If Origin = foCursor Then
7530 Begin
7531 m1 := _PLine2Index(icbarea.First.Line);
7532 m2 := _PLine2Index(icbarea.Last.Line);
7533 If FFileCursor.Y > m2 Then Exit;
7534 If (FFileCursor.Y = m2) And (FFileCursor.X >= icbarea.Last.X) Then Exit;
7535 If FFileCursor.Y > m1 Then icbarea.First := _ICBActPos;
7536 If (FFileCursor.Y = m1) And (FFileCursor.X > icbarea.First.X)
7537 Then icbarea.First.X := FFileCursor.X;
7538 End;
7539 pl1 := icbarea.First.Line;
7540 pl2 := icbarea.Last.Line^.Next;
7541 End
7542 Else
7543 Begin
7544 If Origin = foCursor Then
7545 Begin
7546 m1 := _PLine2Index(icbarea.First.Line);
7547 m2 := _PLine2Index(icbarea.Last.Line);
7548 If FFileCursor.Y < m1 Then Exit;
7549 If (FFileCursor.Y = m1) And (FFileCursor.X < icbarea.First.X) Then Exit;
7550 If FFileCursor.Y < m2 Then icbarea.Last := _ICBActPos;
7551 If (FFileCursor.Y = m2) And (FFileCursor.X < icbarea.Last.X)
7552 Then icbarea.Last.X := FFileCursor.X;
7553 End;
7554 pl1 := icbarea.Last.Line;
7555 pl2 := icbarea.First.Line^.Prev;
7556 End;
7557
7558 Result := True;
7559 While (pl1 <> Nil) And (pl1 <> pl2) Do
7560 Begin
7561 S := pl1^.zk^;
7562 If (Scope = fsGlobal) Or (FSelectMode <> smColumnBlock) Then
7563 Begin
7564 If pl1 = icbarea.First.Line
7565 Then FillChar(S[1],icbarea.First.X-1, EmptyChar); {NoANSI}
7566 If pl1 = icbarea.Last.Line
7567 Then FillChar(S[icbarea.Last.X], Length(S)-icbarea.Last.X+1, EmptyChar);
7568 End
7569 Else {Extended Selection And ICB Search}
7570 Begin
7571 FillChar(S[1],icbarea.First.X-1, EmptyChar); {NoANSI}
7572 If Length(S) >= icbarea.Last.X
7573 Then FillChar(S[icbarea.Last.X], Length(S)-icbarea.Last.X+1, EmptyChar);
7574 End;
7575
7576 If opt * [foCaseSensitive] = [] Then S := AnsiUpperCase(S);
7577again:
7578 If direct = fdForward Then pt.X := Pos(Find,S)
7579 Else pt.X := backpos(Find,S);
7580
7581 If opt * [foWordsOnly] <> [] Then CheckWordsOnly(pl1,pt.X,Find);
7582
7583 If pt.X > 0 Then
7584 Begin
7585 pt.Y := _PLine2Index(pl1);
7586 Exit;
7587 End;
7588 If pt.X < 0 Then
7589 Begin
7590 S[Abs(pt.X)] := EmptyChar;
7591 Goto again;
7592 End;
7593
7594 If direct = fdForward Then pl1 := pl1^.Next
7595 Else pl1 := pl1^.Prev;
7596 End;
7597 Result := False;
7598End;
7599
7600
7601Procedure TEditor.FindTextDlg;
7602Begin
7603 cmFindText;
7604End;
7605
7606
7607Function TEditor.FindText(Const Find:String; direct:TFindDirection;
7608 Origin:TFindOrigin; Scope:TFindScope;
7609 opt:TFindOptions):Boolean;
7610Var pt:TEditorPos;
7611 iew:Boolean;
7612Begin
7613 If FindTextPos(Find,direct,Origin,Scope,opt, pt) Then
7614 Begin
7615 (*Undo*)
7616 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
7617 (*Undo*)
7618 FindICB.First.Line := _Index2PLine(pt.Y);
7619 FindICB.First.X := pt.X;
7620 FindICB.Last := FindICB.First;
7621 Inc(FindICB.Last.X,Length(Find));
7622 If direct = fdForward Then pt.X := FindICB.Last.X;
7623 If FLastFind = faIncSearch Then pt.X := FindICB.First.X;
7624
7625 iew := _GotoPosition(pt) Or _ICBExist;
7626 If iew Then InvalidateEditor(0,0)
7627 Else InvalidateWorkLine;
7628 (*Undo*)
7629 LastUndoGroup := ugCursorMove;
7630 (*Undo*)
7631 Result := True;
7632 End
7633 Else
7634 Begin
7635 If FLastFind <> faIncSearch
7636 Then SetErrorMessage(FmtLoadNLSStr(SSearchStringNotFound,[Find])+'.');
7637 Result := False;
7638 End;
7639 FLastFind := faFind;
7640End;
7641
7642
7643Procedure TEditor.ReplaceTextDlg;
7644Begin
7645 cmReplaceText;
7646End;
7647
7648
7649Function TEditor.ReplaceText(Const Find,replace:String; direct:TFindDirection;
7650 Origin:TFindOrigin; Scope:TFindScope; opt:TFindOptions;
7651 Confirm:Boolean; replaceall:Boolean):Boolean;
7652Var Contin:Boolean;
7653 found1:Boolean;
7654 found:Boolean;
7655 Repl:Boolean;
7656 iew:Boolean;
7657 pt,ptsave:TEditorPos;
7658 resp:TMsgDlgReturn;
7659 lastFCX:LongInt;
7660Begin
7661 Result := False;
7662 If ReadOnly Then Exit;
7663 TestAutoSave;
7664 Contin := True;
7665 found1 := False;
7666
7667 While Contin Do
7668 Begin
7669 found := FindTextPos(Find,direct,Origin,Scope,opt, pt);
7670 If found Then
7671 Begin
7672 (*Undo*)
7673 If LastUndoGroup <> ugCursorMove Then _StoreUndoCursor(FUndoList);
7674 (*Undo*)
7675 found1 := True;
7676 ptsave := pt;
7677 FindICB.First.Line := _Index2PLine(pt.Y);
7678 FindICB.First.X := pt.X;
7679 FindICB.Last := FindICB.First;
7680 Inc(FindICB.Last.X,Length(Find));
7681 If direct = fdForward Then pt.X := FindICB.Last.X;
7682
7683 iew := _GotoPosition(pt) Or _ICBExist;
7684 If iew Or Confirm Then InvalidateEditor(0,0)
7685 Else InvalidateWorkLine;
7686 (*Undo*)
7687 LastUndoGroup := ugCursorMove;
7688 (*Undo*)
7689 If Confirm Then
7690 Begin
7691 resp := SetReplaceConfirmMessage;
7692 Repl := False;
7693 Case resp Of
7694 mrYes: Repl := True;
7695 mrCancel: found := False;
7696 End;
7697 End
7698 Else Repl := True;
7699
7700 lastFCX := FFileCursor.X;
7701 If Repl Then
7702 Begin
7703 (*Undo*)
7704 _CopyUndoLines(FActLine,FActLine);
7705 (*Undo*)
7706 _DeleteString(ptsave.X,Length(Find));
7707 If Not _InsertString(ptsave.X,replace) Then Beep(1000,10);
7708
7709 _HorizMove;
7710 FindICB.Last.X := ptsave.X + Length(replace);
7711 If direct = fdForward Then FFileCursor.X := FindICB.Last.X;
7712 If FFileCursor.X > FWinSize.X Then FScrCursor.X := FWinSize.X
7713 Else FScrCursor.X := FFileCursor.X;
7714 lastFCX := FFileCursor.X;
7715
7716 FRedoList.Clear;
7717 If _HorizMove Then
7718 Begin
7719 UpdateLineColorFlag(FActLine);
7720 InvalidateEditor(0,0);
7721 End
7722 Else InvalidateWorkLine;
7723 (*Undo*)
7724 _StoreUndoCursor(FUndoList);
7725 (*Undo*)
7726 End;
7727 End
7728 Else
7729 If Not found1 Then SetErrorMessage(FmtLoadNLSStr(SSearchStringNotFound,[Find])+'.');
7730 Origin := foCursor;
7731 Contin := replaceall And found;
7732
7733 If Contin And (lastFCX > StringLength) Then {prevent endless LOOP}
7734 If FFileCursor.Y < FCountLines Then
7735 Begin
7736 GotoPosition(EditorPos(FFileCursor.Y+1,1));
7737 End;
7738
7739 Application.ProcessMessages;
7740 End;
7741 Result := found1;
7742 FLastFind := faReplace;
7743End;
7744
7745
7746Procedure TEditor.cmFindText;
7747Var Dialog:TFindDialog;
7748Begin
7749 Dialog.Create(Application.MainForm);
7750
7751 Dialog.FindText := FFindReplace.Find;
7752 Dialog.Options := FFindReplace.Options;
7753 Dialog.Origin := FFindReplace.Origin;
7754 Dialog.Scope := FFindReplace.Scope;
7755 Dialog.Direction := FFindReplace.Direction;
7756
7757 Dialog.ShowModal;
7758
7759 If Dialog.ModalResult = cmOk Then
7760 Begin
7761 FFindReplace.Find := Dialog.FindText;
7762 FFindReplace.Options := Dialog.Options;
7763 FFindReplace.Origin := Dialog.Origin;
7764 FFindReplace.Scope := Dialog.Scope;
7765 FFindReplace.Direction := Dialog.Direction;
7766
7767 Dialog.Destroy;
7768 Update;
7769 With FFindReplace Do FindText(Find,Direction,Origin,Scope,Options);
7770 End
7771 Else Dialog.Destroy;
7772End;
7773
7774
7775Procedure TEditor.cmReplaceText;
7776Var Dialog:TReplaceDialog;
7777Begin
7778 Dialog.Create(Application.MainForm);
7779
7780 Dialog.FindText := FFindReplace.Find;
7781 Dialog.ReplaceText := FFindReplace.replace;
7782 Dialog.Options := FFindReplace.Options;
7783 Dialog.Confirm := FFindReplace.Confirm;
7784 Dialog.Origin := FFindReplace.Origin;
7785 Dialog.Scope := FFindReplace.Scope;
7786 Dialog.Direction := FFindReplace.Direction;
7787
7788 Dialog.ShowModal;
7789
7790 If Dialog.ModalResult In [cmOk,cmAll] Then
7791 Begin
7792 FFindReplace.Find := Dialog.FindText;
7793 FFindReplace.replace := Dialog.ReplaceText;
7794 FFindReplace.Options := Dialog.Options;
7795 FFindReplace.Confirm := Dialog.Confirm;
7796 FFindReplace.Origin := Dialog.Origin;
7797 FFindReplace.Scope := Dialog.Scope;
7798 FFindReplace.Direction := Dialog.Direction;
7799 FFindReplace.replall := Dialog.ModalResult = cmAll;
7800
7801 Dialog.Destroy;
7802 Update;
7803 With FFindReplace Do ReplaceText(Find,replace,Direction,Origin,
7804 Scope,Options,Confirm,replall);
7805 End
7806 Else Dialog.Destroy;
7807End;
7808
7809Procedure TEditor.SearchTextAgain;
7810Begin
7811 cmSearchTextAgain;
7812End;
7813
7814Procedure TEditor.cmSearchTextAgain;
7815Begin
7816 If FLastFind = faReplace Then
7817 Begin
7818 With FFindReplace
7819 Do ReplaceText(Find,replace,Direction,foCursor,
7820 Scope,Options,Confirm,replall);
7821 End;
7822
7823 If FLastFind = faFind Then
7824 Begin
7825 With FFindReplace
7826 Do FindText(Find,Direction,foCursor,Scope,Options);
7827 End;
7828End;
7829
7830
7831Procedure TEditor.cmIncrementalSearch;
7832Var FC:TEditorPos;
7833 pp:^TEditorPos;
7834Begin
7835 If IncSearchText <> '' Then
7836 Begin
7837 FC := FFileCursor;
7838 If FindText(IncSearchText,FFindReplace.Direction,foCursor,
7839 fsGlobal,FFindReplace.Options) Then
7840 Begin
7841 New(pp);
7842 pp^ := FC;
7843 IncSearchList.Insert(0,pp);
7844 End
7845 Else
7846 Begin
7847 Delete(IncSearchText,Length(IncSearchText),1);
7848 FLastFind := faIncSearch;
7849 FindText(IncSearchText,FFindReplace.Direction,foCursor,
7850 fsGlobal,FFindReplace.Options);
7851 End;
7852 End
7853 Else
7854 Begin
7855 If FLastFind <> faIncSearch Then FOldCaption := Caption;
7856 _ICBClearICB;
7857 InvalidateEditor(0,0);
7858 IncSearchList.Clear;
7859 End;
7860 SetIncSearchText(LoadNLSStr(SSearch)+': '+ IncSearchText);
7861 FLastFind := faIncSearch;
7862End;
7863
7864
7865Procedure TEditor.SetIncSearchText(S:String);
7866Var I:Integer;
7867 pp:^TEditorPos;
7868Begin
7869 If S = '' Then
7870 Begin
7871 For I := IncSearchList.Count-1 DownTo 0 Do
7872 Begin
7873 pp := IncSearchList.Items[I];
7874 Dispose(pp);
7875 End;
7876 IncSearchList.Clear;
7877 {restore old Caption}
7878 S := FOldCaption;
7879 End;
7880 Caption := S;
7881End;
7882
7883
7884Procedure TEditor.cmRecordMacro;
7885Begin
7886 If FPlaying Then Exit;
7887
7888 If Not FRecording Then
7889 Begin
7890 If FMacroList = Nil Then FMacroList.Create;
7891 FMacroList.Clear;
7892 FRecording := True;
7893 End
7894 Else FRecording := False;
7895End;
7896
7897
7898Procedure TEditor.cmPlayMacro;
7899Var I:LongInt;
7900 scan:TKeyCode;
7901 REP:Byte;
7902Begin
7903 If FPlaying Then Exit;
7904 If FRecording Then Exit;
7905 If FMacroList = Nil Then Exit;
7906
7907 FPlaying := True;
7908 BeginUpdate;
7909 For I := 0 To FMacroList.Count-1 Do
7910 Begin
7911 scan := TKeyCode(FMacroList.Items[I]);
7912 Inc(I);
7913 REP := Byte(FMacroList.Items[I]);
7914 If scan < kb_VK Then CharEvent(Char(scan),REP)
7915 Else ScanEvent(scan,REP);
7916 End;
7917 FPlaying := False;
7918 EndUpdate;
7919End;
7920
7921
7922Procedure TEditor.Undo;
7923Var U:PUndo;
7924 CL:LongInt;
7925 fl,LL:PLine;
7926 FFL,LFL:PLine;
7927 LastType:TUndoGroup;
7928Begin
7929 If ReadOnly Then Exit;
7930 If FUndoList.Count = 0 Then
7931 Begin
7932 UpdateEditorState;
7933 Exit;
7934 End;
7935 _ICBClearMark;
7936
7937 While FUndoList.Count > 0 Do
7938 Begin
7939 TestAutoSave;
7940
7941 U := FUndoList.Last;
7942 If U = Nil Then
7943 Begin
7944 FUndoList.Delete(FUndoList.Count-1); {Delete Last event}
7945 break;
7946 End;
7947 LastType := U^.EventType;
7948
7949 If U^.Memory Then
7950 Begin {save into Redo stack}
7951 fl := _Index2PLine(U^.FrameBegin+1);
7952 If U^.FrameEnd = 0 Then LL := FLastLine
7953 Else LL := _Index2PLine(U^.FrameEnd-1);
7954 CL := _MoveUndoLines(FRedoList,fl,LL);
7955 FFL := fl^.Prev;
7956 If LL <> Nil Then LFL := LL^.Next
7957 Else LFL := FFirstLine;
7958
7959 If U^.Lines > 0 Then
7960 Begin
7961 _Connect(FFL,U^.FirstUndoLine);
7962 _Connect(U^.LastUndoLine,LFL);
7963 End
7964 Else _Connect(FFL,LFL);
7965 SetLineColorFlag(FFL,LFL);
7966
7967 _UpdateLastUndoEvent(FRedoList,_PLine2Index(LFL));
7968 U^.Memory := False; {don't Free the Lines}
7969
7970 Inc(FCountLines,U^.Lines);
7971 Dec(FCountLines,CL);
7972 End
7973 Else _StoreUndoCursor(FRedoList); {only Cursor event}
7974
7975 ICB.First.Line := _Index2PLine(U^.ICBFL);
7976 ICB.First.X := U^.ICBFX;
7977 ICB.Last.Line := _Index2PLine(U^.ICBLL);
7978 ICB.Last.X := U^.ICBLX;
7979 Modified := U^.Modified;
7980 _GotoPosition(U^.FFileCursor);
7981 FUndoList.Delete(FUndoList.Count-1); {Delete Last event}
7982
7983 If LastType <> ugGroup Then
7984 Begin
7985 If FEditOpt * [eoUndoGroups] = [] Then break;
7986 If LastType <> LastUndoGroup Then break;
7987 If LastType = ugNoGroup Then break;
7988 End; {Else group Events everytime}
7989 End;
7990 _ICBSetMark;
7991 InvalidateEditor(0,0);
7992 SetSliderValues;
7993End;
7994
7995
7996Procedure TEditor.Redo;
7997Var U:PUndo;
7998 CL:LongInt;
7999 fl,LL:PLine;
8000 FFL,LFL:PLine;
8001Begin
8002 If ReadOnly Then Exit;
8003 If FRedoList.Count = 0 Then
8004 Begin
8005 UpdateEditorState;
8006 Exit;
8007 End;
8008
8009 U := FRedoList.Last;
8010 If U = Nil Then
8011 Begin
8012 FRedoList.Delete(FRedoList.Count-1); {Delete Last event}
8013 Exit;
8014 End;
8015
8016 _ICBClearMark;
8017 TestAutoSave;
8018
8019 If U^.Memory Then
8020 Begin {save into Undo stack}
8021 fl := _Index2PLine(U^.FrameBegin+1);
8022 If U^.FrameEnd = 0 Then LL := FLastLine
8023 Else LL := _Index2PLine(U^.FrameEnd-1);
8024 CL := _MoveUndoLines(FUndoList,fl,LL);
8025 FFL := fl^.Prev;
8026 If LL <> Nil Then LFL := LL^.Next
8027 Else LFL := FFirstLine;
8028
8029 If U^.Lines > 0 Then
8030 Begin
8031 _Connect(FFL,U^.FirstUndoLine);
8032 _Connect(U^.LastUndoLine,LFL);
8033 End
8034 Else _Connect(FFL,LFL);
8035 SetLineColorFlag(FFL,LFL);
8036
8037 _UpdateLastUndoEvent(FUndoList,_PLine2Index(LFL));
8038 U^.Memory := False; {don't Free the Lines}
8039
8040 Inc(FCountLines,U^.Lines);
8041 Dec(FCountLines,CL);
8042 End
8043 Else _StoreUndoCursor(FUndoList); {only Cursor event}
8044
8045 ICB.First.Line := _Index2PLine(U^.ICBFL);
8046 ICB.First.X := U^.ICBFX;
8047 ICB.Last.Line := _Index2PLine(U^.ICBLL);
8048 ICB.Last.X := U^.ICBLX;
8049 _ICBSetMark;
8050 Modified := U^.Modified;
8051 _GotoPosition(U^.FFileCursor);
8052 FRedoList.Delete(FRedoList.Count-1); {Delete Last event}
8053 InvalidateEditor(0,0);
8054 SetSliderValues;
8055End;
8056
8057
8058Procedure TEditor.ClearUndo;
8059Begin
8060 FUndoList.Clear;
8061End;
8062
8063
8064Procedure TEditor.ClearRedo;
8065Begin
8066 FRedoList.Clear;
8067End;
8068
8069
8070{ drag & drop }
8071
8072Function GetTempFileName:String;
8073Var Hour,Minute,Second,Sec100:Word;
8074 S,dir:String;
8075Begin
8076 If GetTime(Hour,Minute,Second,Sec100) = 0 Then
8077 Begin
8078 S := 'd'+ tostr(Minute)+tostr(Second)+tostr(Sec100) +'.tmp';
8079 End
8080 Else S := 'drag0001.tmp';
8081
8082 dir := GetEnv('TMP');
8083 If dir = '' Then dir := GetEnv('TEMP');
8084 If dir = '' Then
8085 Begin
8086 {$I-}
8087 GetDir(0,dir);
8088 {$I+}
8089 End;
8090 If dir[Length(dir)] <> '\' Then dir := dir + '\';
8091 Result := dir + S;
8092End;
8093
8094
8095Procedure TEditor.CanDrag(X,Y:LongInt;Var Accept:Boolean);
8096Begin
8097 Accept := Selected; {drag only If Selection Is available}
8098 Inherited CanDrag(X,Y,Accept); {call event handler}
8099End;
8100
8101
8102Procedure TEditor.DoStartDrag(Var DragData:TDragDropData);
8103Var P:Pointer;
8104 len:LongInt;
8105 utF:File;
8106 dir,Name,ext:String;
8107Begin
8108 Inherited DoStartDrag(DragData);
8109
8110 If Not _GetEditorBlock(P,len) Then Exit;
8111
8112 FTempFileName := GetTempFileName;
8113 System.Assign(utF,FTempFileName);
8114 {$I-}
8115 Rewrite(utF,1);
8116 If InOutRes <> 0 Then
8117 Begin
8118 FTempFileName := 'drag0001.tmp';
8119 System.Assign(utF,FTempFileName);
8120 Rewrite(utF,1);
8121 End;
8122
8123 If InOutRes = 0 Then
8124 Begin
8125 BlockWrite(utF,P^,len-1); {without #0}
8126 If InOutRes <> 0 Then SetErrorMessage(LoadNLSStr(SErrorWritingTemporaryFile)+': '+ FTempFileName);
8127 System.Close(utF);
8128 End
8129 Else SetErrorMessage(LoadNLSStr(SErrorCreatingTemporaryFile)+': '+ FTempFileName);
8130 {$I+}
8131
8132 FSplit(FTempFileName,dir,Name,ext);
8133 DragData.SourceWindow := Handle;
8134 DragData.SourceType := drtText;
8135 DragData.RenderType := drmFile;
8136 DragData.ContainerName := dir;
8137 DragData.SourceFileName := Name + ext;
8138 DragData.TargetFileName := '';
8139 DragData.SupportedOps := [doCopyable,doMoveable];
8140 DragData.DragOperation := doMove;
8141End;
8142
8143
8144Procedure TEditor.DoEndDrag(target:TObject; X,Y:LongInt);
8145Var utF:File;
8146Begin
8147 Inherited DoEndDrag(target,X,Y);
8148
8149 If target <> Self Then If target<>Nil Then
8150 If LastDragOperation = doMove Then cmICBDeleteBlock;
8151
8152 {Delete temporary File}
8153 System.Assign(utF,FTempFileName);
8154 {$I-}
8155 Erase(utF);
8156 {$I+}
8157 FTempFileName := '';
8158End;
8159
8160
8161Procedure TEditor.DragOver(Source:TObject;X,Y:LongInt;State:TDragState;Var Accept:Boolean);
8162Var ExtDDO:TExternalDragDropObject;
8163 FName:String;
8164 ScreenPos:TEditorPos;
8165 pt:TPoint;
8166 FH:LongInt;
8167Begin
8168 Accept := False;
8169 If ReadOnly Then Exit;
8170
8171 If Source Is TExternalDragDropObject Then
8172 Begin
8173 ExtDDO := TExternalDragDropObject(Source);
8174 If ExtDDO.SupportedOps * [doCopyable,doMoveable] = [] Then Exit;
8175 If ExtDDO.DragOperation In [doLink] Then Exit;
8176 If ExtDDO.RenderType <> drmFile Then Exit;
8177 {drtText abtesten ??}
8178
8179 FName := ExtDDO.ContainerName;
8180 If FName <> '' Then
8181 If FName[Length(FName)] <> '\' Then FName := FName + '\';
8182 FName := FName + ExtDDO.SourceFileName;
8183 If Not FileExists(FName) Then Exit;
8184 End
8185 Else Exit;
8186
8187 Accept := True;
8188 If OnDragOver <> Nil Then OnDragOver(Self,Source,X,Y,State,Accept);
8189 If Not Accept Then Exit;
8190
8191
8192 If State <> dsDragEnter Then {Delete old Insert Mark}
8193 Begin
8194 CreateDragCanvas;
8195 Canvas.DrawInvertRect(FDragRect);
8196 DeleteDragCanvas;
8197 End;
8198
8199 {Get New Position To Insert the File}
8200 ScreenPos := GetCursorFromMouse(Point(X,Y));
8201 If ScreenPos.X > 1 Then Dec(ScreenPos.X);
8202 If ScreenPos.Y + CursorPos.Y - OffsetPos.Y > CountLines
8203 Then ScreenPos.Y := CountLines - (CursorPos.Y - OffsetPos.Y);
8204
8205 pt := GetMouseFromCursor(ScreenPos);
8206 FH := Canvas.FontHeight; {Query here because DragCanvas has no Font}
8207 FDragRect := Rect(pt.X-1,pt.Y,pt.X,pt.Y+FH-1);
8208
8209 If State <> dsDragLeave Then
8210 Begin
8211 CreateDragCanvas;
8212 Canvas.DrawInvertRect(FDragRect);
8213 DeleteDragCanvas;
8214 End;
8215End;
8216
8217
8218Procedure TEditor.DragDrop(Source:TObject;X,Y:LongInt);
8219Var ExtDDO:TExternalDragDropObject;
8220 FName:String;
8221 ScreenPos,FilePos:TEditorPos;
8222 OldPersistent:Boolean;
8223Begin
8224 Inherited DragDrop(Source,X,Y);
8225
8226 If Source Is TExternalDragDropObject Then
8227 Begin
8228 ExtDDO := TExternalDragDropObject(Source);
8229 If ExtDDO.SupportedOps * [doCopyable,doMoveable] = [] Then Exit;
8230 If ExtDDO.DragOperation In [doLink] Then Exit;
8231 If ExtDDO.RenderType <> drmFile Then Exit;
8232
8233 FName := ExtDDO.ContainerName;
8234 If FName <> '' Then
8235 If FName[Length(FName)] <> '\' Then FName := FName + '\';
8236 FName := FName + ExtDDO.SourceFileName;
8237 If Not FileExists(FName) Then Exit;
8238 End
8239 Else Exit;
8240
8241 CreateDragCanvas;
8242 Canvas.DrawInvertRect(FDragRect);
8243 DeleteDragCanvas;
8244
8245 {Get New Position To Insert the File}
8246 ScreenPos := GetCursorFromMouse(Point(X,Y));
8247 If ScreenPos.X > 1 Then Dec(ScreenPos.X);
8248 If ScreenPos.Y + CursorPos.Y - OffsetPos.Y > CountLines
8249 Then ScreenPos.Y := CountLines - (CursorPos.Y - OffsetPos.Y);
8250
8251 BeginUpdate;
8252 OldPersistent := FEditOpt * [eoPersistentBlocks] <> [];
8253 If Not OldPersistent Then Include(FEditOpt, eoPersistentBlocks);
8254
8255 FilePos.X := ScreenPos.X + CursorPos.X - OffsetPos.X;
8256 FilePos.Y := ScreenPos.Y + CursorPos.Y - OffsetPos.Y;
8257 GotoPosition(FilePos);
8258
8259 If ExtDDO.SourceWindow = Handle Then
8260 Begin
8261 Case ExtDDO.DragOperation Of
8262 doCopy: cmICBCopyBlock;
8263 doMove: cmICBMoveBlock;
8264 End;
8265 End
8266 Else
8267 Begin
8268 _ICBClearICB;
8269 InsertFromFile(FName);
8270 End;
8271
8272 If Not OldPersistent Then Exclude(FEditOpt, eoPersistentBlocks);
8273 EndUpdate;
8274 CaptureFocus;
8275End;
8276
8277
8278
8279Begin
8280End.
8281
8282
Note: See TracBrowser for help on using the repository browser.