1 unit formmain;
2 
3 {$mode objfpc}{$H+}
4 
5 interface
6 
7 uses
8   Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
9   ExtCtrls, Spin, ComCtrls, Menus, LclIntf, Buttons,
10   EncConv,
11   ATStrings,
12   ATStringProc,
13   ATSynEdit,
14   ATSynEdit_LineParts,
15   ATSynEdit_Carets,
16   ATSynEdit_Bookmarks,
17   ATSynEdit_Gaps,
18   ATSynEdit_CanvasProc,
19   ATSynEdit_Finder,
20   ATSynEdit_Export_HTML,
21   //ATSynEdit_Hotspots,
22   //ATSynEdit_DimRanges,
23   ATSynEdit_Gutter_Decor,
24   ATScrollBar,
25   formkey,
26   formopt,
27   formfind;
28 
29 type
30   { TfmMain }
31   TfmMain = class(TForm)
32     ApplicationProperties1: TApplicationProperties;
33     bFont: TButton;
34     bOpt: TButton;
35     btnStop: TButton;
36     bClearLog: TButton;
37     chkMouseColSelect: TCheckBox;
38     chkSmoothScroll: TCheckBox;
39     chkMinimapTooltip: TCheckBox;
40     chkMouseEn: TCheckBox;
41     chkTabSpaces: TCheckBox;
42     chkNewScroll: TCheckBox;
43     chkMinimapLeft: TCheckBox;
44     chkGutter: TCheckBox;
45     chkMicromap: TCheckBox;
46     chkMinimap: TCheckBox;
47     chkRuler: TCheckBox;
48     chkUnprintEnd: TCheckBox;
49     chkUnprintEndDet: TCheckBox;
50     chkUnprintSp: TCheckBox;
51     chkUnprintVis: TCheckBox;
52     chkWrapIndent: TCheckBox;
53     chkWrapMargin: TRadioButton;
54     chkWrapOff: TRadioButton;
55     chkWrapOn: TRadioButton;
56     edFontsize: TSpinEdit;
57     edMarginFixed: TSpinEdit;
58     edSpaceY: TSpinEdit;
59     edTabsize: TSpinEdit;
60     FontDialog1: TFontDialog;
61     gUnpri: TGroupBox;
62     gWrap: TGroupBox;
63     ImagesDecor: TImageList;
64     LabelScale: TLabel;
65     Label10: TLabel;
66     Label11: TLabel;
67     Label2: TLabel;
68     Label4: TLabel;
69     Label5: TLabel;
70     Label6: TLabel;
71     Label9: TLabel;
72     ListboxLog: TListBox;
73     MainMenu1: TMainMenu;
74     MenuItem1: TMenuItem;
75     MenuItem10: TMenuItem;
76     MenuItem11: TMenuItem;
77     MenuItem13: TMenuItem;
78     mnuTestGutterDecor: TMenuItem;
79     mnuTestGapPanels: TMenuItem;
80     mnuShowPane: TMenuItem;
81     mnuTestGapAdd: TMenuItem;
82     mnuTestGapClear: TMenuItem;
83     mnuTestMarker: TMenuItem;
84     MenuItem5: TMenuItem;
85     mnuFileExit: TMenuItem;
86     MenuItem12: TMenuItem;
87     mnuFileSave: TMenuItem;
88     mnuFileHtml: TMenuItem;
89     mnuFindNext: TMenuItem;
90     mnuFind: TMenuItem;
91     MenuItem9: TMenuItem;
92     mnuTestSyntax: TMenuItem;
93     mnuEnc: TMenuItem;
94     MenuItem2: TMenuItem;
95     mnuHelpMous: TMenuItem;
96     mnuTestConvPos: TMenuItem;
97     MenuItem4: TMenuItem;
98     MenuItem6: TMenuItem;
99     MenuItem7: TMenuItem;
100     MenuItem8: TMenuItem;
101     mnuOpts: TMenuItem;
102     mnuBms: TMenuItem;
103     mnuTestHiliteWww: TMenuItem;
104     mnuTestCaret1: TMenuItem;
105     mnuOptDlg: TMenuItem;
106     mnuTestBookmk: TMenuItem;
107     mnuTestMargins: TMenuItem;
108     mnuFile: TMenuItem;
109     mnuHlp: TMenuItem;
110     mnuFileEnd: TMenuItem;
111     mnuTst: TMenuItem;
112     mnuTestCaret2: TMenuItem;
113     mnuEndWin: TMenuItem;
114     mnuEndUnix: TMenuItem;
115     mnuEndMac: TMenuItem;
116     mnuHelpKey: TMenuItem;
117     mnuFileOpen: TMenuItem;
118     mnuFileSaveAs: TMenuItem;
119     mnuGoto: TMenuItem;
120     OpenDialog1: TOpenDialog;
121     PanelMain: TPanel;
122     PanelRt: TPanel;
123     PopupBookmk: TPopupMenu;
124     PopupFold: TPopupMenu;
125     PopupMinimap: TPopupMenu;
126     PopupMicromap: TPopupMenu;
127     PopupRuler: TPopupMenu;
128     PopupNums: TPopupMenu;
129     progress: TProgressBar;
130     chkWrapWndMargin: TRadioButton;
131     SaveDialog1: TSaveDialog;
132     Status: TStatusBar;
133     StatusMsg: TStatusBar;
134     TimerHint: TTimer;
135     TrackbarScale: TTrackBar;
136     procedure bClearLogClick(Sender: TObject);
137     procedure bGotoClick(Sender: TObject);
138     procedure btnMarkerClick(Sender: TObject);
139     procedure btnStopClick(Sender: TObject);
140     procedure chkMinimapLeftChange(Sender: TObject);
141     procedure chkMinimapTooltipChange(Sender: TObject);
142     procedure chkMouseColSelectChange(Sender: TObject);
143     procedure chkMouseEnChange(Sender: TObject);
144     procedure chkNewScrollChange(Sender: TObject);
145     procedure chkSmoothScrollChange(Sender: TObject);
146     procedure chkTabSpacesChange(Sender: TObject);
147     procedure chkWrapWndMarginChange(Sender: TObject);
148     procedure FinderProgress(Sender: TObject; const ACurPos, AMaxPos: Int64; var AContinue: boolean);
149     procedure MenuItem14Click(Sender: TObject);
150     procedure mnuFileExitClick(Sender: TObject);
151     procedure mnuFileHtmlClick(Sender: TObject);
152     procedure mnuFileOpenClick(Sender: TObject);
153     procedure bFontClick(Sender: TObject);
154     procedure bAddCrtClick(Sender: TObject);
155     procedure mnuFileSaveAsClick(Sender: TObject);
156     procedure bKeymapClick(Sender: TObject);
157     procedure bOptClick(Sender: TObject);
158     procedure mnuFileSaveClick(Sender: TObject);
159     procedure mnuFindClick(Sender: TObject);
160     procedure mnuFindNextClick(Sender: TObject);
161     procedure mnuTestConvPosClick(Sender: TObject);
162     procedure mnuTestGapAddClick(Sender: TObject);
163     procedure mnuTestGapClearClick(Sender: TObject);
164     procedure mnuTestGapPanelsClick(Sender: TObject);
165     procedure mnuTestGutterDecorClick(Sender: TObject);
166     procedure mnuTestSyntaxClick(Sender: TObject);
167     procedure TimerHintTimer(Sender: TObject);
168     procedure TrackbarScaleChange(Sender: TObject);
169     procedure UpdateEnc;
170     procedure mnuHelpMousClick(Sender: TObject);
171     procedure chkGutterChange(Sender: TObject);
172     procedure chkMicromapChange(Sender: TObject);
173     procedure chkMinimapChange(Sender: TObject);
174     procedure mnuBmsClick(Sender: TObject);
175     procedure mnuShowPaneClick(Sender: TObject);
176     procedure chkRulerChange(Sender: TObject);
177     procedure chkUnprintVisChange(Sender: TObject);
178     procedure chkUnprintEndChange(Sender: TObject);
179     procedure chkUnprintEndDetChange(Sender: TObject);
180     procedure chkUnprintSpChange(Sender: TObject);
181     procedure chkWrapMarginChange(Sender: TObject);
182     procedure chkWrapOffChange(Sender: TObject);
183     procedure chkWrapOnChange(Sender: TObject);
184     procedure chkWrapIndentChange(Sender: TObject);
185     procedure edFontsizeChange(Sender: TObject);
186     procedure edMarginFixedChange(Sender: TObject);
187     procedure edSpaceYChange(Sender: TObject);
188     procedure edTabsizeChange(Sender: TObject);
189     procedure FormCreate(Sender: TObject);
190     procedure FormShow(Sender: TObject);
191     procedure mnuEndMacClick(Sender: TObject);
192     procedure mnuEndUnixClick(Sender: TObject);
193     procedure mnuEndWinClick(Sender: TObject);
194     procedure mnuTestHiliteWwwClick(Sender: TObject);
195     procedure mnuLockClick(Sender: TObject);
196     procedure mnuTestBookmkClick(Sender: TObject);
197     procedure mnuTestCaret1Click(Sender: TObject);
198     procedure mnuTestMarginsClick(Sender: TObject);
199     procedure mnuUnlockClick(Sender: TObject);
200   private
201     { private declarations }
202     ed: TATSynEdit;
203     wait: boolean;
204     FFilesDir: string;
205     FFileName: string;
206     FFinder: TATEditorFinder;
207     FFindStopped: boolean;
208     FFindConfirmAll: TModalResult;
209     FFindMarkAll: boolean;
210     ed_gap: TATSynEdit;
211     FGapInitSize: integer;
212     FDecorImage: integer;
213     FCfmPanel: TPanel;
214     FCfmLink: string;
215     procedure ConfirmButtonOkClick(Sender: TObject);
216     procedure ConfirmPanelMouseLeave(Sender: TObject);
217     procedure InitConfirmPanel;
218     procedure DoAddEnc(Sub, SName: string);
219     procedure DoLog(const S: string);
220     procedure EditCalcBookmarkColor(Sender: TObject; ABookmarkKind: integer; var AColor: TColor);
221     procedure EditClickLink(Sender: TObject; const ALink: string);
222     procedure EditHotspotEnter(Sender: TObject; AHotspotIndex: integer);
223     procedure EditHotspotExit(Sender: TObject; AHotspotIndex: integer);
224     procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
225     procedure EditChangeModified(Sender: TObject);
226     procedure EditorGapChange(Sender: TObject);
227     procedure EditorGapDelete(Sender: TObject; ALineIndex: integer);
228     procedure EditStringsChangeBlock(Sender: TObject; const AStartPos,
229       AEndPos: TPoint; AChange: TATBlockChangeKind; ABlock: TStringList);
230     procedure EditClickGap(Sender: TObject; AGapItem: TATGapItem; APos: TPoint);
231     procedure EditStringsChange(Sender: TObject; AChange: TATLineChangeKind; ALineIndex, AItemCount: integer);
EditCalcTabSizenull232     function EditCalcTabSize(Sender: TObject; ALineIndex, APos: integer): integer;
233     procedure FinderConfirmReplace(Sender: TObject; APos1, APos2: TPoint;
234       AForMany: boolean; var AConfirm, AContinue: boolean; var AReplacement: UnicodeString);
235     procedure DoFindError;
236     procedure DoOpen(const fn: string; ADetectEnc: boolean);
237     procedure DoSetEnc(const Str: string);
238     procedure EditChanged(Sender: TObject);
239     procedure EditCaretMoved(Sender: TObject);
240     procedure EditDrawLine(Sender: TObject; C: TCanvas; ALineIndex, AX, AY: integer;
241       const AStr: atString; ACharSize: TATEditorCharSize; constref AExtent: TATIntFixedArray);
242     procedure EditCalcLine(Sender: TObject; var AParts: TATLineParts;
243       ALineIndex, ACharIndex, ALineLen: integer; var AColorAfterEol: TColor);
244     procedure EditScroll(Sender: TObject);
245     procedure EditCommand(Sender: TObject; ACmd{%H-}: integer; AInvoke: TATEditorCommandInvoke; const AText: string; var AHandled: boolean);
246     procedure EditClickGutter(Sender: TObject; ABand, ALine: integer);
247     procedure EditClickMicromap(Sender: TObject; AX, AY: integer);
248     procedure EditDrawBm(Sender: TObject; C: TCanvas; ALineNum{%H-}: integer; const ARect: TRect);
249     procedure EditDrawMicromap(Sender: TObject; C: TCanvas; const ARect: TRect);
250     procedure EditDrawTest(Sender: TObject; C: TCanvas; const ARect: TRect);
251     procedure EditDrawGap(Sender: TObject; C: TCanvas; const ARect: TRect; AGap: TATGapItem);
252     procedure FinderFound(Sender: TObject; APos1, APos2: TPoint);
253     procedure FinderUpdateEditor(AUpdateText: boolean);
254     procedure MenuEncClick(Sender: TObject);
255     procedure MsgStatus(const S: string);
256     procedure ShowBadRegex;
257     procedure UpdateCaption;
258     procedure UpdateGapPanel;
259     procedure UpdateStatus;
260     procedure UpdateChecks;
261   public
262     { public declarations }
263   end;
264 
265 var
266   fmMain: TfmMain;
267 
268 implementation
269 
270 uses
271   Types, Math,
272   LCLType, LCLProc,
273   atsynedit_commands;
274 
275 {$R *.lfm}
276 
277 const
278   cColorBmIco = clMedGray;
279   cBookmarkBgKind = 10;
280 
281 
282 procedure DoPaintGap(C: TCanvas; R: TRect; ALine: integer);
283 begin
284   C.Brush.Color:= clMoneyGreen;
285   C.Pen.Color:= C.Brush.Color;
286   C.FillRect(R);
287   C.Font.Size:= 9;
288   C.Font.Color:= clGray;
289   C.TextOut(R.Left+20, R.Top+1, 'gap for line '+IntToStr(ALine));
290 end;
291 
292 
293 { TfmMain }
294 
295 procedure TfmMain.FormCreate(Sender: TObject);
296 const
297   cGoodFont = 'DejaVu Sans Mono';
298 begin
299   UpdateEnc;
300 
301   FFilesDir:= ExtractFilePath(ExtractFileDir(ExtractFileDir(Application.ExeName)))+'test_files';
302   wait:= true;
303 
304   ed:= TATSynEdit.Create(Self);
305   ed.Parent:= PanelMain;
306   ed.Align:= alClient;
307 
308   {$ifdef windows}
309   ed.Font.Name:= 'Consolas';
310   {$else}
311   ed.Font.Name:= 'Courier New';
312   if Screen.Fonts.IndexOf(cGoodFont)>=0 then
313     ed.Font.Name:= cGoodFont;
314   {$endif}
315 
316   SetLength(ed.Micromap.Columns, 0);
317   ed.Micromap.ColumnAdd(1, 100, clRed);
318   ed.Micromap.ColumnAdd(2, 100, clBlue);
319   ed.Micromap.ColumnAdd(3, 100, clGreen);
320 
321   ed.PopupGutterBm:= PopupBookmk;
322   ed.PopupGutterNum:= PopupNums;
323   ed.PopupGutterFold:= PopupFold;
324   ed.PopupMinimap:= PopupMinimap;
325   ed.PopupMicromap:= PopupMicromap;
326   ed.PopupRuler:= PopupRuler;
327   ed.ImagesGutterDecor:= ImagesDecor;
328 
329   ed.OnChange:= @EditChanged;
330   ed.OnChangeModified:=@EditChangeModified;
331   ed.Strings.OnChangeEx:=@EditStringsChange;
332   ed.Strings.OnChangeBlock:=@EditStringsChangeBlock;
333   ed.Strings.GutterDecor1:= ed.GutterDecor;
334   ed.OnChangeCaretPos:= @EditCaretMoved;
335   ed.OnChangeState:= @EditCaretMoved;
336   ed.OnScroll:=@EditScroll;
337   ed.OnCommand:= @EditCommand;
338   ed.OnClickGutter:= @EditClickGutter;
339   ed.OnClickMicromap:= @EditClickMicromap;
340   ed.OnClickGap:= @EditClickGap;
341   ed.OnClickLink:= @EditClickLink;
342   ed.OnDrawBookmarkIcon:= @EditDrawBm;
343   ed.OnDrawLine:= @EditDrawLine;
344   ed.OnDrawMicromap:= @EditDrawMicromap;
345   ed.OnDrawGap:= @EditDrawGap;
346   ed.OnHotspotEnter:= @EditHotspotEnter;
347   ed.OnHotspotExit:= @EditHotspotExit;
348   ed.OnKeyDown:= @EditKeyDown;
349   ed.OnCalcBookmarkColor:= @EditCalcBookmarkColor;
350   ////ed.OnCalcTabSize:= @EditCalcTabSize;
351 
352   ed.SetFocus;
353 
354   FFinder:= TATEditorFinder.Create;
355   FFinder.Editor:= ed;
356   FFinder.OptRegex:= true;
357   FFinder.OnConfirmReplace:= @FinderConfirmReplace;
358   FFinder.OnProgress:= @FinderProgress;
359   FFinder.OnFound:= @FinderFound;
360 
361   ed_gap:= TATSynEdit.Create(Self);
362   ed_gap.Text:= '(inline editor)';
363   ed_gap.Colors.TextBG:= $80f0f0;
364   ed_gap.OptRulerVisible:= false;
365   ed_gap.OptUnprintedVisible:= false;
366   ed_gap.OptMarginRight:= 2000;
367   ed_gap.OptScrollbarsNew:= ed.OptScrollbarsNew;
368   ed_gap.OptGutterVisible:= false;
369   //ed_gap.Gutter[ed_gap.GutterBandBookmarks].Visible:= false;
370   //ed_gap.Gutter[ed_gap.GutterBandFolding].Visible:= false;
371   //ed_gap.Gutter[ed_gap.GutterBandStates].Visible:= false;
372   ed_gap.Parent:= ed;
373   ed_gap.OnChange:= @EditorGapChange;
374   ed.Gaps.OnDelete:=@EditorGapDelete;
375   ed_gap.Hide;
376 end;
377 
378 procedure TfmMain.FormShow(Sender: TObject);
379 var
380   fn: string;
381 begin
382   if wait then UpdateChecks;
383   wait:= false;
384   ActiveControl:= ed;
385 
386   fn:= FFilesDir+'/all.txt';
387   if FileExists(fn) then
388     DoOpen(fn, true);
389 end;
390 
391 procedure TfmMain.mnuEndMacClick(Sender: TObject);
392 begin
393   ed.Strings.Endings:= cEndMac;
394   ed.Update;
395   UpdateStatus;
396 end;
397 
398 procedure TfmMain.mnuEndUnixClick(Sender: TObject);
399 begin
400   ed.Strings.Endings:= cEndUnix;
401   ed.Update;
402   UpdateStatus;
403 end;
404 
405 procedure TfmMain.mnuEndWinClick(Sender: TObject);
406 begin
407   ed.Strings.Endings:= cEndWin;
408   ed.Update;
409   UpdateStatus;
410 end;
411 
412 procedure TfmMain.mnuTestHiliteWwwClick(Sender: TObject);
413 begin
414   with mnuTestHiliteWww do Checked:= not Checked;
415   ed.Update;
416 end;
417 
418 procedure TfmMain.mnuLockClick(Sender: TObject);
419 begin
420   ed.BeginUpdate;
421 end;
422 
423 procedure TfmMain.mnuTestBookmkClick(Sender: TObject);
424 var
425   NIndex, i: integer;
426   Data: TATBookmarkData;
427 begin
428   FillChar(Data, SizeOf(Data), 0);
429   Data.Kind:= 1;
430   Data.ShowInBookmarkList:= true;
431 
432   for i:= 0 to ed.Strings.Count-1 do
433   begin
434     NIndex:= ed.Strings.Bookmarks.Find(i);
435     if NIndex>=0 then
436       ed.Strings.Bookmarks.Delete(NIndex)
437     else
438     begin
439       Data.LineNum:= i;
440       ed.Strings.Bookmarks.Add(Data);
441     end;
442   end;
443   ed.Update;
444 end;
445 
446 procedure TfmMain.mnuTestCaret1Click(Sender: TObject);
447 var
448   i: integer;
449 begin
450   for i:= 1 to 100 do
451     ed.Carets.Add(0, i);
452   ed.Carets.Sort;
453   ed.Update;
454   UpdateStatus;
455 end;
456 
457 procedure TfmMain.mnuTestMarginsClick(Sender: TObject);
458 var
459   S: string;
460 begin
461   S:= ed.OptMarginString;
462   if InputQuery('Margins', 'space separated ints', S) then
463   begin
464     ed.OptMarginString:= S;
465     ed.Update;
466   end;
467 end;
468 
469 procedure TfmMain.mnuUnlockClick(Sender: TObject);
470 begin
471   ed.EndUpdate;
472 end;
473 
474 
475 procedure TfmMain.EditCaretMoved(Sender: TObject);
476 begin
477   UpdateStatus;
478 end;
479 
480 procedure TfmMain.UpdateStatus;
481 const
482   cEnd: array[TATLineEnds] of string = ('?', 'Win', 'Unix', 'Mac');
483   cOvr: array[boolean] of string = ('-', 'Ovr');
484   cRo: array[boolean] of string = ('-', 'RO');
485   cMod: array[boolean] of string = ('-', 'Mod');
486   cSel: array[boolean] of string = ('-', 'Column');
487 var
488   sPos, sCount: string;
489   i: integer;
490 begin
491   sPos:= '';
492   for i:= 0 to Min(4, ed.Carets.Count-1) do
493     with ed.Carets[i] do
494       sPos:= sPos+Format(' %d:%d', [PosY+1, PosX+1]);
495 
496   sCount:= '';
497   if ed.LastCommandChangedLines>0 then
498     sCount:= Format('%d lines chg', [ed.LastCommandChangedLines]);
499 
500   Status.SimpleText:= Format('Line:Col%s | %s | Carets: %d | Top: %d | %s | %s %s %s %s | Undo: %d, Redo: %d | %s', [
501     sPos,
502     ed.EncodingName,
503     ed.Carets.Count,
504     ed.LineTop+1,
505     cEnd[ed.Strings.Endings],
506     cOvr[ed.ModeOverwrite],
507     cRo[ed.ModeReadOnly],
508     cSel[not ed.IsSelRectEmpty],
509     cMod[ed.Modified],
510     ed.UndoCount,
511     ed.RedoCount,
512     sCount
513     ]);
514 end;
515 
516 procedure TfmMain.UpdateChecks;
517 begin
518   chkGutter.Checked:= ed.OptGutterVisible;
519   chkRuler.Checked:= ed.OptRulerVisible;
520   chkMinimap.Checked:= ed.OptMinimapVisible;
521   chkMinimapLeft.Checked:= ed.OptMinimapAtLeft;
522   chkMicromap.Checked:= ed.OptMicromapVisible;
523   chkTabSpaces.Checked:= ed.OptTabSpaces;
524   chkNewScroll.Checked:= ed.OptScrollbarsNew;
525   edFontsize.Value:= ed.Font.Size;
526   edTabsize.Value:= ed.OptTabSize;
527   edSpaceY.Value:= ed.OptSpacingY;
528   edMarginFixed.Value:= ed.OptMarginRight;
529   case ed.OptWrapMode of
530     cWrapOff: chkWrapOff.Checked:= true;
531     cWrapOn: chkWrapOn.Checked:= true;
532     cWrapAtMargin: chkWrapMargin.Checked:= true;
533   end;
534   chkWrapIndent.Checked:= ed.OptWrapIndented;
535   chkUnprintVis.Checked:= ed.OptUnprintedVisible;
536   chkUnprintSp.Checked:= ed.OptUnprintedSpaces;
537   chkUnprintEnd.Checked:= ed.OptUnprintedEnds;
538   chkUnprintEndDet.Checked:= ed.OptUnprintedEndsDetails;
539 end;
540 
541 procedure TfmMain.EditScroll(Sender: TObject);
542 begin
543   EditCaretMoved(Sender);
544   UpdateGapPanel;
545 end;
546 
547 procedure TfmMain.EditCommand(Sender: TObject; ACmd: integer;
548   AInvoke: TATEditorCommandInvoke; const AText: string; var AHandled: boolean);
549 begin
550   AHandled:= false;
551   {
552   if ACmd=cCommand_KeyTab then
553   begin
554     AHandled:= true;
555     Beep;
556   end;
557   }
558 end;
559 
560 procedure TfmMain.EditClickGutter(Sender: TObject; ABand, ALine: integer);
561 var
562   NIndex: integer;
563   Data: TATBookmarkData;
564 begin
565   if ABand=ed.GutterBandBookmarks then
566   begin
567     NIndex:= ed.Strings.Bookmarks.Find(ALine);
568     if NIndex>=0 then
569       ed.Strings.Bookmarks.Delete(NIndex)
570     else
571     begin
572       FillChar(Data, SizeOf(Data), 0);
573       Data.Kind:= 1;
574       Data.LineNum:= ALine;
575       Data.ShowInBookmarkList:= true;
576       Data.Hint:= StrNew(PChar(Format('Bookmark for line %d', [ALine+1])));
577       ed.Strings.Bookmarks.Add(Data);
578     end;
579     ed.Update;
580   end;
581 end;
582 
583 procedure TfmMain.EditClickMicromap(Sender: TObject; AX, AY: integer);
584 begin
585   Showmessage(Format('Micromap click: %d:%d', [AX, AY]));
586 end;
587 
588 procedure TfmMain.EditDrawBm(Sender: TObject; C: TCanvas; ALineNum: integer;
589   const ARect: TRect);
590 var
591   r: trect;
592   dx: integer;
593 begin
594   r:= arect;
595   if IsRectEmpty(r) then exit;
596   c.brush.color:= cColorBmIco;
597   c.pen.color:= cColorBmIco;
598   inc(r.top, 1);
599   inc(r.left, 4);
600   dx:= r.Height div 2-1;
601   c.Polygon([Point(r.left, r.top), Point(r.left+dx, r.top+dx), Point(r.left, r.top+2*dx)]);
602 end;
603 
604 procedure TfmMain.EditDrawMicromap(Sender: TObject; C: TCanvas; const ARect: TRect);
605 var
606   R: TRect;
607   i: integer;
608 begin
609   for i:= 0 to High(ed.Micromap.Columns) do
610   begin
611     C.Brush.Style:= bsSolid;
612     C.Brush.Color:= ed.Micromap.Columns[i].NColor;
613     R:= ARect;
614     R.Left:= ed.Micromap.Columns[i].NLeft;
615     R.Right:= ed.Micromap.Columns[i].NRight;
616     C.FillRect(R);
617   end;
618 end;
619 
620 procedure TfmMain.EditDrawTest(Sender: TObject; C: TCanvas; const ARect: TRect);
621 begin
622   //Exit;
623   C.Pen.Color:= clred;
624   C.Brush.Style:= bsClear;
625   C.Rectangle(ARect);
626 end;
627 
628 procedure TfmMain.EditDrawGap(Sender: TObject; C: TCanvas; const ARect: TRect;
629   AGap: TATGapItem);
630 begin
631   ////DoPaintGap(C, ARect, AGap.LineIndex);
632 end;
633 
634 procedure TfmMain.mnuFileOpenClick(Sender: TObject);
635 begin
636   with OpenDialog1 do
637   begin
638     InitialDir:= FFilesDir;
639     if not Execute then Exit;
640     DoOpen(FileName, true);
641   end;
642 end;
643 
644 procedure TfmMain.DoOpen(const fn: string; ADetectEnc: boolean);
645 begin
646   Application.ProcessMessages;
647   FFileName:= fn;
648   Progress.Show;
649   Progress.Position:= 0;
650 
651   ed.BeginUpdate;
652   try
653     if ADetectEnc then
654       ed.Strings.EncodingCodepage:= eidUTF8;
655     ed.Strings.EncodingDetect:= ADetectEnc;
656     ed.LoadFromFile(fn);
657     ed.Strings.EncodingDetect:= true;
658   finally
659     ed.EndUpdate;
660   end;
661 
662   //test Bookmarks2
663   ed.BookmarkSetForLine_2(4, cBookmarkBgKind, '', bmadDontDelete, false, 0);
664   ed.BookmarkSetForLine_2(5, cBookmarkBgKind, '', bmadDontDelete, false, 0);
665   ed.BookmarkSetForLine_2(6, cBookmarkBgKind, '', bmadDontDelete, false, 0);
666 
667   Progress.Hide;
668   UpdateCaption;
669 end;
670 
671 procedure TfmMain.UpdateCaption;
672 const
673   cModified: array[boolean] of string = ('', '*');
674 begin
675   Caption:= cModified[ed.Modified]+ExtractFileName(FFileName)+' - Editor';
676 end;
677 
678 procedure TfmMain.EditChanged(Sender: TObject);
679 begin
680   UpdateStatus;
681 end;
682 
683 procedure TfmMain.bGotoClick(Sender: TObject);
684 const
685   NIndentHorz=5;
686   NIndentVert=5;
687 var
688   s: string;
689   n: integer;
690 begin
691   s:= IntToStr(ed.LineTop+1);
692   if not InputQuery('Go to', 'Line:', s) then Exit;
693   if s='' then Exit;
694   n:= StrToIntDef(s, 0)-1;
695   if (n>=0) and (n<ed.Strings.Count) then
696     ed.DoGotoPos(
697       Point(0, n),
698       Point(-1, -1),
699       NIndentHorz,
700       NIndentVert,
701       true,
702       true)
703   else
704     ShowMessage('Incorrect line index: '+s);
705 end;
706 
707 procedure TfmMain.bClearLogClick(Sender: TObject);
708 begin
709   ListboxLog.Items.Clear;
710 end;
711 
712 procedure TfmMain.btnMarkerClick(Sender: TObject);
713 begin
714   if ed.Carets.Count=1 then
715   begin
716     ed.Markers.Add(ed.Carets[0].PosX, ed.Carets[0].PosY);
717     ed.Update;
718   end;
719 end;
720 
721 procedure TfmMain.btnStopClick(Sender: TObject);
722 begin
723   FFindStopped:= true;
724 end;
725 
726 procedure TfmMain.chkMinimapLeftChange(Sender: TObject);
727 begin
728   if wait then Exit;
729   ed.OptMinimapAtLeft:= chkMinimapLeft.Checked;
730   ed.Update;
731 end;
732 
733 procedure TfmMain.chkMinimapTooltipChange(Sender: TObject);
734 begin
735   if wait then Exit;
736   ed.OptMinimapTooltipVisible:= chkMinimapTooltip.Checked;
737 end;
738 
739 procedure TfmMain.chkMouseColSelectChange(Sender: TObject);
740 begin
741   if wait then Exit;
742   ed.OptMouseColumnSelectionWithoutKey:= chkMouseColSelect.Checked;
743 end;
744 
745 procedure TfmMain.chkMouseEnChange(Sender: TObject);
746 begin
747   ed.OptMouseEnableNormalSelection:= chkMouseEn.Checked;
748   ed.OptMouseEnableColumnSelection:= chkMouseEn.Checked;
749   ed.Update;
750 end;
751 
752 procedure TfmMain.chkNewScrollChange(Sender: TObject);
753 begin
754   if wait then Exit;
755   ed.OptScrollbarsNew:= chkNewScroll.Checked;
756   ed.Update;
757 end;
758 
759 procedure TfmMain.chkSmoothScrollChange(Sender: TObject);
760 begin
761   if wait then exit;
762   ed.OptScrollSmooth:= chkSmoothScroll.Checked;
763   ed.Update;
764 end;
765 
766 procedure TfmMain.chkTabSpacesChange(Sender: TObject);
767 begin
768   if wait then exit;
769   ed.OptTabSpaces:= chkTabSpaces.Checked;
770   ed.Update;
771 end;
772 
773 procedure TfmMain.FinderProgress(Sender: TObject; const ACurPos,
774   AMaxPos: Int64; var AContinue: boolean);
775 begin
776   progress.Position:= ACurPos * 100 div AMaxPos;
777   Application.ProcessMessages;
778   if FFindStopped then AContinue:= false;
779 end;
780 
781 procedure TfmMain.MenuItem14Click(Sender: TObject);
782 begin
783 
784 end;
785 
786 procedure TfmMain.mnuFileExitClick(Sender: TObject);
787 begin
788   Close;
789 end;
790 
791 procedure TfmMain.mnuFileHtmlClick(Sender: TObject);
792 var
793   fn: string;
794 begin
795   fn:= GetTempDir+DirectorySeparator+'_export.html';
796   DoEditorExportToHTML(Ed, fn, 'Export test',
797     'Courier New', 12, false,
798     clWhite, clMedGray);
799   if FileExists(fn) then
800     OpenDocument(fn);
801 end;
802 
803 
804 procedure TfmMain.bFontClick(Sender: TObject);
805 begin
806   with FontDialog1 do
807   begin
808     Font:= ed.Font;
809     if Execute then
810     begin
811       ed.Font.Assign(Font);
812       ed.Update;
813     end;
814   end;
815   ed.SetFocus;
816 end;
817 
818 procedure TfmMain.bAddCrtClick(Sender: TObject);
819 var
820   i, j: integer;
821 begin
822   for j:= 1 to 100 do
823     for i:= 1 to 20 do
824       ed.Carets.Add(i*2, j);
825   ed.Carets.Sort;
826   ed.Update;
827   UpdateStatus;
828 end;
829 
830 procedure TfmMain.mnuFileSaveAsClick(Sender: TObject);
831 begin
832   with SaveDialog1 do
833   begin
834     InitialDir:= FFilesDir;
835     FileName:= '';
836     if Execute then
837     begin
838       ed.SaveToFile(FileName);
839       ed.Update;
840     end;
841   end;
842 end;
843 
844 procedure TfmMain.bKeymapClick(Sender: TObject);
845 var
846   Cmd: integer;
847 begin
848   Cmd:= DoCommandDialog(ed);
849   if Cmd>0 then
850   begin
851     ed.DoCommand(Cmd, cInvokeAppPalette);
852     ed.Update;
853   end;
854 end;
855 
856 procedure TfmMain.bOptClick(Sender: TObject);
857 begin
858   DoConfigEditor(ed);
859 
860   wait:= true;
861   chkUnprintVis.Checked:= ed.OptUnprintedVisible;
862   chkUnprintSp.Checked:= ed.OptUnprintedSpaces;
863   chkUnprintEnd.Checked:= ed.OptUnprintedEnds;
864   chkUnprintEndDet.Checked:= ed.OptUnprintedEndsDetails;
865   wait:= false;
866 
867   ed.SetFocus;
868 end;
869 
870 procedure TfmMain.mnuFileSaveClick(Sender: TObject);
871 begin
872   if FFileName='' then exit;
873   ed.SaveToFile(FFileName);
874   ed.Update;
875 end;
876 
877 procedure TfmMain.mnuFindClick(Sender: TObject);
878 var
879   res: TModalResult;
880   cnt: integer;
881   ok, bChanged: boolean;
882 begin
883   with TfmFind.Create(nil) do
884   try
885     edFind.Text:= Utf8Encode(FFinder.StrFind);
886     edRep.Text:= Utf8Encode(FFinder.StrReplace);
887     chkBack.Checked:= FFinder.OptBack;
888     chkCase.Checked:= FFinder.OptCase;
889     chkWords.Checked:= FFinder.OptWords;
890     chkRegex.Checked:= FFinder.OptRegex;
891     chkFromCaret.Checked:= FFinder.OptFromCaret;
892     chkConfirm.Checked:= FFinder.OptConfirmReplace;
893     chkInSel.Enabled:= ed.Carets.IsSelection;
894 
895     res:= ShowModal;
896     if res=mrCancel then Exit;
897     if edFind.Text='' then Exit;
898 
899     FFinder.StrFind:= Utf8Decode(edFind.Text);
900     FFinder.StrReplace:= Utf8Decode(edRep.Text);
901     FFinder.OptBack:= chkBack.Checked;
902     FFinder.OptCase:= chkCase.Checked;
903     FFinder.OptWords:= chkWords.Checked;
904     FFinder.OptRegex:= chkRegex.Checked;
905     FFinder.OptFromCaret:= chkFromCaret.Checked;
906     FFinder.OptConfirmReplace:= chkConfirm.Checked;
907     FFinder.OptInSelection:= chkInSel.Checked;
908 
909     FFindStopped:= false;
910     FFindConfirmAll:= mrNone;
911     FFindMarkAll:= false;
912     btnStop.Show;
913     progress.Show;
914     progress.Position:= 0;
915 
916     ed.Markers.Clear; //support "find first" in selection
917 
918     case res of
919       mrOk: //find
920         begin
921           ok:= FFinder.DoAction_FindOrReplace(false, false, bChanged, true);
922           FinderUpdateEditor(false);
923           if not ok then
924             if FFinder.IsRegexBad then
925               ShowBadRegex
926             else
927               DoFindError;
928         end;
929       mrYes: //replace
930         begin
931           ok:= FFinder.DoAction_FindOrReplace(true, false, bChanged, true);
932           FinderUpdateEditor(true);
933           if not ok then
934             if FFinder.IsRegexBad then
935               ShowBadRegex
936             else
937               DoFindError;
938         end;
939       mrYesToAll: //replace all
940         begin
941           cnt:= FFinder.DoAction_ReplaceAll;
942           FinderUpdateEditor(true);
943           MsgStatus('Replaces made: '+Inttostr(cnt));
944         end;
945       mrIgnore: //count all
946         begin
947           cnt:= FFinder.DoAction_CountAll(false);
948           MsgStatus('Count of "'+FFinder.StrFind+'": '+Inttostr(cnt));
949         end;
950       mrRetry: //mark all
951         begin
952           FFindMarkAll:= true;
953           ed.Markers.Clear;
954           cnt:= FFinder.DoAction_CountAll(true);
955           FFindMarkAll:= false;
956           FinderUpdateEditor(false);
957           MsgStatus('Markers placed: '+Inttostr(cnt));
958         end;
959     end;
960   finally
961     Free;
962   end;
963 
964   btnStop.Hide;
965   progress.Hide;
966 end;
967 
968 procedure TfmMain.mnuFindNextClick(Sender: TObject);
969 var
970   ok, bChanged: boolean;
971 begin
972   if FFinder.StrFind='' then
973   begin
974     mnuFind.Click;
975     Exit
976   end;
977 
978   FFinder.OptFromCaret:= true;
979   ok:= FFinder.DoAction_FindOrReplace(false, false, bChanged, true);
980   FinderUpdateEditor(false);
981   if not ok then DoFindError;
982 end;
983 
984 procedure TfmMain.mnuTestConvPosClick(Sender: TObject);
985 var
986   P: TPoint;
987 begin
988   P:= ed.CaretPosToClientPos(Point(0, ed.Strings.Count{after end-of-file!}));
989   ShowMessage(Format('Client pos (%d, %d)', [P.X, P.Y]));
990 end;
991 
992 procedure TfmMain.mnuTestGapAddClick(Sender: TObject);
993 var
994   Vals: array[0..2] of string;
995   SCaption: string;
996   NLine, NSize: integer;
997   b: TBitmap;
998   f: TCustomForm;
999 begin
1000   Vals[0]:= '2';
1001   Vals[1]:= '60';
1002   Vals[2]:= 'Caption';
1003   if not InputQuery('Add gap (sets last_line_on_top)',
1004     ['Line number', 'Gap size (pixels)', 'If not empty: place the form with caption'],
1005     Vals) then exit;
1006 
1007   NLine:= StrToInt(Vals[0]);
1008   NSize:= StrToInt(Vals[1]);
1009   SCaption:= Vals[2];
1010 
1011   b:= nil;
1012   f:= nil;
1013 
1014   if SCaption<>'' then
1015   begin
1016     f:= TForm.CreateNew(Self, 0);
1017     f.Color:= clGreen;
1018     f.Caption:= SCaption;
1019     with TListbox.Create(f) do
1020     begin
1021       Parent:= f;
1022       Align:= alClient;
1023       BorderSpacing.Around:= 6;
1024       Items.Add('item1');
1025       Items.Add('item2');
1026     end;
1027     f.BorderStyle:= bsNone;
1028     f.Show;
1029   end
1030   else
1031   begin
1032     b:= TBitmap.Create;
1033     b.PixelFormat:= pf24bit;
1034     b.SetSize(500, NSize);
1035     DoPaintGap(b.Canvas, Rect(0, 0, b.Width, b.Height), NLine);
1036   end;
1037 
1038   if not ed.Gaps.Add(NLine-1, NSize, b, f, 0) then
1039   begin
1040     ShowMessage(Format('Not correct line index (%d)', [NLine]));
1041     exit;
1042   end;
1043 
1044   if ed.Gaps.Count=1 then
1045     FGapInitSize:= NSize;
1046 
1047   ed.OptLastLineOnTop:= true;
1048   ed.Update;
1049   UpdateGapPanel;
1050 end;
1051 
1052 procedure TfmMain.mnuTestGapClearClick(Sender: TObject);
1053 begin
1054   ed.Gaps.Clear;
1055   ed.Update;
1056   UpdateGapPanel;
1057 end;
1058 
1059 procedure TfmMain.mnuTestGapPanelsClick(Sender: TObject);
1060 begin
1061   with mnuTestGapPanels do
1062     Checked:= not Checked;
1063   UpdateGapPanel;
1064 end;
1065 
1066 procedure TfmMain.mnuTestGutterDecorClick(Sender: TObject);
1067 var
1068   decor: TATGutterDecorData;
1069   V: array[0..1] of string;
1070   N: integer;
1071 begin
1072   V[0]:= '2';
1073   V[1]:= '*'+Chr(Ord('A')+Random(26));
1074   if not InputQuery('Place gutter decor',
1075     ['Line index:', 'Text (icon if empty):'], V) then exit;
1076 
1077   N:= StrToIntDef(V[0], -1);
1078   if not ed.Strings.IsIndexValid(N) then exit;
1079 
1080   FDecorImage:= (FDecorImage+1) mod ImagesDecor.Count;
1081 
1082   FillChar(decor, SizeOf(decor), 0);
1083   decor.DeleteOnDelLine:= true;
1084   decor.Text:= V[1];
1085   decor.TextItalic:= true;
1086   decor.TextBold:= true;
1087   decor.TextColor:= Random($ffffff);
1088   decor.LineNum:= N;
1089   decor.ImageIndex:= FDecorImage;
1090 
1091   ed.GutterDecor.Add(decor);
1092   ed.Update;
1093 end;
1094 
1095 procedure TfmMain.mnuTestSyntaxClick(Sender: TObject);
1096 begin
1097   mnuTestSyntax.Checked:= not mnuTestSyntax.Checked;
1098   if mnuTestSyntax.Checked then
1099     ed.OnCalcHilite:= @EditCalcLine
1100   else
1101     ed.OnCalcHilite:= nil;
1102   ed.Update;
1103 end;
1104 
1105 procedure TfmMain.TimerHintTimer(Sender: TObject);
1106 begin
1107   TimerHint.Enabled:= false;
1108   StatusMsg.SimpleText:= '';
1109 end;
1110 
1111 procedure TfmMain.TrackbarScaleChange(Sender: TObject);
1112 begin
1113   EditorScalePercents:= TrackbarScale.Position;
1114   ATScrollbarTheme.ScalePercents:= EditorScalePercents;
1115   Ed.Update(true);
1116 end;
1117 
1118 procedure TfmMain.DoSetEnc(const Str: string);
1119 begin
1120   ed.EncodingName:= Str;
1121   if FFileName<>'' then
1122     if Application.Messagebox('Encoding changed in mem. Reload file in this encoding?',
1123       'Editor', MB_OKCANCEL or MB_ICONQUESTION) = id_ok then
1124       DoOpen(FFileName, false);
1125 end;
1126 
1127 procedure TfmMain.DoAddEnc(Sub, SName: string);
1128 var
1129   mi, miSub: TMenuItem;
1130   n: integer;
1131   subEnc: TMenuItem;
1132 begin
1133   subEnc:= mnuEnc;
1134   miSub:= nil;
1135   if Sub<>'' then
1136   begin
1137     n:= subEnc.IndexOfCaption(Sub);
1138     if n<0 then
1139     begin
1140       mi:= TMenuItem.Create(Self);
1141       mi.Caption:= Sub;
1142       subEnc.Add(mi);
1143       n:= subEnc.IndexOfCaption(Sub);
1144     end;
1145     miSub:= subEnc.Items[n]
1146   end;
1147   if miSub=nil then miSub:= subEnc;
1148   mi:= TMenuItem.Create(Self);
1149   mi.Caption:= SName;
1150   mi.OnClick:= @MenuEncClick;
1151   miSub.Add(mi);
1152 end;
1153 
1154 
1155 procedure TfmMain.DoLog(const S: string);
1156 begin
1157   ListboxLog.Items.Add(S);
1158   ListboxLog.ItemIndex:= ListboxLog.Items.Count-1;
1159 end;
1160 
1161 procedure TfmMain.EditCalcBookmarkColor(Sender: TObject; ABookmarkKind: integer; var AColor: TColor);
1162 begin
1163   if ABookmarkKind=cBookmarkBgKind then
1164     AColor:= clYellow;
1165 end;
1166 
1167 procedure TfmMain.EditClickLink(Sender: TObject; const ALink: string);
1168 var
1169   P: TPoint;
1170   bEmail: boolean;
1171 begin
1172   FCfmLink:= ALink;
1173   InitConfirmPanel;
1174 
1175   bEmail:= (Pos('://', ALink)=0) and (Pos('@', ALink)>0);
1176   if bEmail then
1177     FCfmPanel.Caption:= '[send email]'
1178   else
1179     FCfmPanel.Caption:= '[open link]';
1180 
1181   P:= Mouse.CursorPos;
1182   P:= ScreenToClient(P);
1183   FCfmPanel.Parent:= Self;
1184   FCfmPanel.Left:= P.X - FCfmPanel.Width div 2;
1185   FCfmPanel.Top:= P.Y - FCfmPanel.Height div 2;
1186   FCfmPanel.Show;
1187 end;
1188 
1189 procedure TfmMain.EditHotspotEnter(Sender: TObject; AHotspotIndex: integer);
1190 begin
1191   DoLog('OnHotspotEnter: '+IntToStr(AHotspotIndex));
1192 end;
1193 
1194 procedure TfmMain.EditHotspotExit(Sender: TObject; AHotspotIndex: integer);
1195 begin
1196   DoLog('OnHotspotExit: '+IntToStr(AHotspotIndex));
1197 end;
1198 
1199 procedure TfmMain.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
1200 begin
1201   exit;////
1202   DoLog('OnKeyDown, key='+IntToStr(Key));
1203 end;
1204 
1205 procedure TfmMain.EditChangeModified(Sender: TObject);
1206 begin
1207   UpdateCaption;
1208 end;
1209 
1210 procedure TfmMain.EditStringsChangeBlock(Sender: TObject; const AStartPos,
1211   AEndPos: TPoint; AChange: TATBlockChangeKind; ABlock: TStringList);
1212 const
1213   cEvent: array[TATBlockChangeKind] of string = (
1214     'cBlockDeleteLines',
1215     'cBlockInsertLines',
1216     'cBlockDeleteColumn',
1217     'cBlockInsertColumn'
1218     );
1219 begin
1220   DoLog(Format('%s, %d..%d', [
1221     cEvent[AChange],
1222     AStartPos.Y,
1223     AEndPos.Y
1224     ]));
1225 end;
1226 
1227 procedure TfmMain.EditClickGap(Sender: TObject; AGapItem: TATGapItem;
1228   APos: TPoint);
1229 begin
1230   if Assigned(AGapItem) then
1231     MsgStatus(Format('OnClickGap: line %d, pos %d:%d',
1232       [AGapItem.LineIndex+1, APos.X, APos.Y]));
1233 end;
1234 
1235 procedure TfmMain.EditStringsChange(Sender: TObject;
1236   AChange: TATLineChangeKind; ALineIndex, AItemCount: integer);
1237 const
1238   cEvent: array[TATLineChangeKind] of string = (
1239     'cLineChangeEdited',
1240     'cLineChangeAdded',
1241     'cLineChangeDeleted',
1242     'cLineChangeDeletedAll'
1243     );
1244 begin
1245   exit;////
1246   DoLog(Format('%s, line %d', [
1247     cEvent[AChange],
1248     ALineIndex
1249     ]));
1250 end;
1251 
EditCalcTabSizenull1252 function TfmMain.EditCalcTabSize(Sender: TObject; ALineIndex, APos: integer): integer;
1253 begin
1254   if ALineIndex<10 then Result:= 8
1255   else
1256   if ALineIndex<20 then Result:= 2
1257   else
1258     Result:= 4;
1259 end;
1260 
1261 procedure TfmMain.MenuEncClick(Sender: TObject);
1262 begin
1263   DoSetEnc((Sender as TMenuItem).Caption);
1264   UpdateStatus;
1265 end;
1266 
1267 
1268 procedure TfmMain.UpdateEnc;
1269 begin
1270   mnuEnc.Clear;
1271 
1272   DoAddEnc('', cEncNameUtf8_NoBom);
1273   DoAddEnc('', cEncNameUtf8_WithBom);
1274   DoAddEnc('', cEncNameUtf16LE_NoBom);
1275   DoAddEnc('', cEncNameUtf16LE_WithBom);
1276   DoAddEnc('', cEncNameUtf16BE_NoBom);
1277   DoAddEnc('', cEncNameUtf16BE_WithBom);
1278   DoAddEnc('', cEncNameUtf32LE_NoBom);
1279   DoAddEnc('', cEncNameUtf32LE_WithBom);
1280   DoAddEnc('', cEncNameUtf32BE_NoBom);
1281   DoAddEnc('', cEncNameUtf32BE_WithBom);
1282   DoAddEnc('', '-');
1283 
1284   DoAddEnc('Europe', 'CP1250');
1285   DoAddEnc('Europe', 'CP1251');
1286   DoAddEnc('Europe', 'CP1252');
1287   DoAddEnc('Europe', 'CP1253');
1288   DoAddEnc('Europe', 'CP1257');
1289   DoAddEnc('Europe', '-');
1290   DoAddEnc('Europe', 'CP437');
1291   DoAddEnc('Europe', 'CP850');
1292   DoAddEnc('Europe', 'CP852');
1293   DoAddEnc('Europe', 'CP866');
1294   DoAddEnc('Europe', '-');
1295   DoAddEnc('Europe', 'ISO88591');
1296   DoAddEnc('Europe', 'ISO88592');
1297   DoAddEnc('Europe', 'Mac');
1298 
1299   DoAddEnc('Other', 'CP1254');
1300   DoAddEnc('Other', 'CP1255');
1301   DoAddEnc('Other', 'CP1256');
1302 
1303   DoAddEnc('Asian', 'CP874');
1304   DoAddEnc('Asian', 'CP932');
1305   DoAddEnc('Asian', 'CP936');
1306   DoAddEnc('Asian', 'CP949');
1307   DoAddEnc('Asian', 'CP950');
1308   DoAddEnc('Asian', 'CP1258');
1309 end;
1310 
1311 procedure TfmMain.mnuHelpMousClick(Sender: TObject);
1312 const
1313   txt =
1314     'Ctrl+click - add/del caret'#13+
1315     'Ctrl+drag - add caret with selection'#13+
1316     'Ctrl+Shift+click - add carets as column'#13+
1317     #13+
1318     'Alt+drag - column-select (looks weird with wrap, ignores tab-width)'#13+
1319     'drag on line numbers - line-select'#13+
1320     'Shift+wheel - horiz scroll'#13;
1321 begin
1322   Showmessage(txt);
1323 end;
1324 
1325 procedure TfmMain.chkGutterChange(Sender: TObject);
1326 begin
1327   if wait then Exit;
1328   ed.OptGutterVisible:= chkGutter.Checked;
1329   ed.Update;
1330 end;
1331 
1332 procedure TfmMain.chkMicromapChange(Sender: TObject);
1333 begin
1334   if wait then Exit;
1335   ed.OptMicromapVisible:= chkMicromap.Checked;
1336   ed.Update;
1337 end;
1338 
1339 procedure TfmMain.chkMinimapChange(Sender: TObject);
1340 begin
1341   if wait then Exit;
1342   ed.OptMinimapVisible:= chkMinimap.Checked;
1343   ed.Update;
1344 end;
1345 
1346 procedure TfmMain.mnuBmsClick(Sender: TObject);
1347 begin
1348   mnuTestBookmkClick(Self);
1349 end;
1350 
1351 procedure TfmMain.mnuShowPaneClick(Sender: TObject);
1352 begin
1353   with mnuShowPane do
1354   begin
1355     Checked:= not Checked;
1356     PanelRt.Visible:= Checked;
1357   end;
1358 end;
1359 
1360 procedure TfmMain.chkRulerChange(Sender: TObject);
1361 begin
1362   if wait then Exit;
1363   ed.OptRulerVisible:= chkRuler.Checked;
1364   ed.Update;
1365 end;
1366 
1367 procedure TfmMain.chkUnprintVisChange(Sender: TObject);
1368 begin
1369   if wait then Exit;
1370   ed.OptUnprintedVisible:= chkUnprintVis.Checked;
1371   ed.Update;
1372 end;
1373 
1374 procedure TfmMain.chkUnprintEndChange(Sender: TObject);
1375 begin
1376   if wait then Exit;
1377   ed.OptUnprintedEnds:= chkUnprintEnd.Checked;
1378   ed.Update;
1379 end;
1380 
1381 procedure TfmMain.chkUnprintEndDetChange(Sender: TObject);
1382 begin
1383   if wait then Exit;
1384   ed.OptUnprintedEndsDetails:= chkUnprintEndDet.Checked;
1385   ed.Update;
1386 end;
1387 
1388 procedure TfmMain.chkUnprintSpChange(Sender: TObject);
1389 begin
1390   if wait then Exit;
1391   ed.OptUnprintedSpaces:= chkUnprintSp.Checked;
1392   ed.Update;
1393 end;
1394 
1395 procedure TfmMain.chkWrapMarginChange(Sender: TObject);
1396 begin
1397   if wait then Exit;
1398   ed.OptWrapMode:= cWrapAtMargin;
1399 end;
1400 
1401 procedure TfmMain.chkWrapOffChange(Sender: TObject);
1402 begin
1403   if wait then Exit;
1404   ed.OptWrapMode:= cWrapOff;
1405 end;
1406 
1407 procedure TfmMain.chkWrapOnChange(Sender: TObject);
1408 begin
1409   if wait then Exit;
1410   ed.OptWrapMode:= cWrapOn;
1411 end;
1412 
1413 procedure TfmMain.chkWrapWndMarginChange(Sender: TObject);
1414 begin
1415   if wait then Exit;
1416   ed.OptWrapMode:= cWrapAtWindowOrMargin;
1417 end;
1418 
1419 procedure TfmMain.chkWrapIndentChange(Sender: TObject);
1420 begin
1421   if wait then Exit;
1422   ed.OptWrapIndented:= chkWrapIndent.Checked;
1423   ed.Update;
1424 end;
1425 
1426 procedure TfmMain.edFontsizeChange(Sender: TObject);
1427 begin
1428   if wait then Exit;
1429   ed.Font.Size:= edFontsize.Value;
1430   ed.Update(true);
1431 end;
1432 
1433 procedure TfmMain.edMarginFixedChange(Sender: TObject);
1434 begin
1435   if wait then Exit;
1436   ed.OptMarginRight:= edMarginFixed.Value;
1437   ed.Update;
1438 end;
1439 
1440 procedure TfmMain.edSpaceYChange(Sender: TObject);
1441 begin
1442   if wait then Exit;
1443   ed.OptSpacingY:= edSpaceY.Value;
1444   ed.Update;
1445 end;
1446 
1447 procedure TfmMain.edTabsizeChange(Sender: TObject);
1448 begin
1449   if wait then Exit;
1450   ed.OptTabSize:= edTabsize.Value;
1451   ed.Update;
1452 end;
1453 
1454 procedure TfmMain.EditDrawLine(Sender: TObject; C: TCanvas; ALineIndex, AX,
1455   AY: integer; const AStr: atString; ACharSize: TATEditorCharSize; constref AExtent: TATIntFixedArray);
1456 var
1457   X1, X2, Y, i: integer;
1458 begin
1459   if AStr='' then Exit;
1460   if not mnuTestHiliteWww.Checked then Exit;
1461 
1462   C.Pen.Color:= clBlue;
1463   C.Pen.Width:= 2;
1464   C.Pen.EndCap:= pecSquare;
1465 
1466   for i:= 1 to Min(Length(AStr), AExtent.Len) do
1467     if AStr[i]='w' then
1468     begin
1469       X1:= AX;
1470       if i>1 then
1471         Inc(X1, AExtent.Data[i-2]);
1472       X2:= AX+AExtent.Data[i-1];
1473       Y:= AY+ACharSize.Y-1;
1474 
1475       C.Line(X1, Y, X2, Y);
1476     end;
1477 
1478   C.Pen.Width:= 1;
1479 end;
1480 
1481 procedure TfmMain.EditCalcLine(Sender: TObject; var AParts: TATLineParts;
1482   ALineIndex, ACharIndex, ALineLen: integer; var AColorAfterEol: TColor);
1483 var
1484   nlen, npart, noffset: integer;
1485   kind, kindnew: integer;
1486   //
1487   procedure Add;
1488   begin
1489     if npart>High(AParts) then exit;
1490     with AParts[npart] do
1491     begin
1492       ColorBG:= clNone;
1493       case kind of
1494         1: begin
1495              ColorFont:= clblue;
1496            end;
1497         2: begin
1498              ColorFont:= clgreen;
1499              ColorBorder:= clgreen;
1500              BorderDown:= cLineStyleRounded;
1501              BorderUp:= cLineStyleRounded;
1502              BorderLeft:= cLineStyleRounded;
1503              BorderRight:= cLineStyleRounded;
1504              FontStyles:= afsFontBold+afsFontItalic;
1505            end;
1506         3: begin
1507              ColorFont:= clred;
1508              Colorbg:= clyellow;
1509              ColorBorder:= clred;
1510              BorderDown:= cLineStyleWave;
1511              //BorderLeft:= cLineDotted;
1512              //BorderRight:= cLineRounded;
1513              //BorderUp:= cLineRounded;
1514           end;
1515         else
1516           begin
1517             ColorFont:= clgray;
1518           end;
1519       end;
1520       Offset:= noffset;
1521       Len:= nlen;
1522     end;
1523     inc(npart);
1524   end;
1525   //
1526 var
1527   Str: atString;
1528   i: integer;
1529 begin
1530   Str:= Copy(ed.Strings.Lines[ALineIndex], ACharIndex, ALineLen);
1531 
1532   npart:= 0;
1533   noffset:= 0;
1534   nlen:= 1;
1535   kind:= -1;
1536 
1537   for i:= 1 to Length(Str) do
1538   begin
1539     case Str[i] of
1540       'w': kindnew:= 1;
1541       'e': kindnew:= 2;
1542       '0'..'9': kindnew:= 3;
1543       else kindnew:= 0;
1544     end;
1545 
1546     if kindnew=kind then
1547     begin
1548       inc(nlen);
1549       Continue;
1550     end;
1551     if kind>=0 then Add;
1552     kind:= kindnew;
1553     nlen:= 1;
1554     noffset:= i-1;
1555   end;
1556 
1557   Add;
1558 
1559   //test
1560   //AParts[0].Colorbg:= clgreen;
1561   //AParts[1].Colorbg:= clyellow;
1562 end;
1563 
1564 procedure TfmMain.MsgStatus(const S: string);
1565 begin
1566   StatusMsg.SimpleText:= S;
1567   TimerHint.Enabled:= false;
1568   TimerHint.Enabled:= true;
1569 end;
1570 
1571 procedure TfmMain.DoFindError;
1572 begin
1573   MsgStatus('Cannot find: '+FFinder.StrFind);
1574 end;
1575 
1576 procedure TfmMain.FinderConfirmReplace(Sender: TObject; APos1, APos2: TPoint;
1577   AForMany: boolean; var AConfirm, AContinue: boolean;
1578   var AReplacement: UnicodeString);
1579 var
1580   Res: TModalResult;
1581   Buttons: TMsgDlgButtons;
1582 begin
1583   case FFindConfirmAll of
1584     mrYesToAll: begin AConfirm:= true; exit end;
1585     mrNoToAll: begin AConfirm:= false; exit end;
1586   end;
1587 
1588   with Ed.Carets[0] do
1589   begin
1590     PosX:= APos1.X;
1591     PosY:= APos1.Y;
1592     EndX:= APos2.X;
1593     EndY:= APos2.Y;
1594   end;
1595 
1596   Ed.DoCommand(cCommand_ScrollToCaretTop, cInvokeAppInternal);
1597   Ed.Update(true);
1598 
1599   Buttons:= [mbYes, mbNo];
1600   if AForMany then
1601     Buttons:= Buttons+[mbYesToAll, mbNoToAll];
1602   //Str:= Ed.Strings.TextSubstring(APos1.X, APos1.Y, APos2.X, APos2.Y);
1603   Res:= MessageDlg(
1604     'Confirm replace',
1605     'Replace string at line '+Inttostr(APos1.Y+1),
1606     mtConfirmation,
1607     Buttons, '');
1608 
1609   AConfirm:= Res in [mrYes, mrYesToAll];
1610   AContinue:= Res<>mrNoToAll;
1611   if Res in [mrYesToAll, mrNoToAll] then
1612     FFindConfirmAll:= Res;
1613 end;
1614 
1615 
1616 procedure TfmMain.ShowBadRegex;
1617 begin
1618   MessageDlg(
1619     'Incorrect RegEx',
1620     Utf8Encode(FFinder.StrFind)+#10+
1621     FFinder.RegexErrorMsg,
1622     mtError,
1623     [mbOk], ''
1624     );
1625 end;
1626 
1627 procedure TfmMain.FinderUpdateEditor(AUpdateText: boolean);
1628 begin
1629   FFinder.Editor.Update(AUpdateText);
1630   FFinder.Editor.DoGotoCaret(cEdgeTop);
1631   UpdateStatus;
1632 end;
1633 
1634 procedure TfmMain.FinderFound(Sender: TObject; APos1, APos2: TPoint);
1635 begin
1636   if FFindMarkAll then
1637   begin
1638     ed.Markers.Add(APos1.X, APos1.Y, 0, Abs(APos2.X-APos1.X), 0);
1639   end;
1640 end;
1641 
1642 procedure TfmMain.UpdateGapPanel;
1643 var
1644   R: TRect;
1645 begin
1646   if not mnuTestGapPanels.Checked then
1647   begin
1648     ed_gap.Hide;
1649     exit
1650   end;
1651 
1652   if not ed.DoGetGapRect(0, R) then
1653   begin
1654     ed_gap.Hide;
1655     exit
1656   end;
1657 
1658   ed_gap.SetBounds(R.Left, R.Top, R.Width-1, R.Height);
1659   ed_gap.Show;
1660 end;
1661 
1662 procedure TfmMain.EditorGapChange(Sender: TObject);
1663 var
1664   NLines: integer;
1665 begin
1666   NLines:= ed_gap.Strings.Count+1;
1667   ed_gap.Height:= Max(FGapInitSize, NLines*ed_gap.TextCharSize.Y);
1668   ed.Gaps[0].Size:= ed_gap.Height;
1669   ed.Update;
1670 end;
1671 
1672 procedure TfmMain.EditorGapDelete(Sender: TObject; ALineIndex: integer);
1673 begin
1674   //ShowMessage('delete gap '+IntToStr(ALineIndex));
1675 end;
1676 
1677 procedure TfmMain.InitConfirmPanel;
1678 const
1679   cPanelW = 100;
1680   cPanelH = 35;
1681 begin
1682   if FCfmPanel=nil then
1683   begin
1684     FCfmPanel:= TPanel.Create(Self);
1685     FCfmPanel.Caption:= '??';
1686     FCfmPanel.OnMouseLeave:= @ConfirmPanelMouseLeave;
1687     FCfmPanel.Hide;
1688     FCfmPanel.Width:= cPanelW;
1689     FCfmPanel.Height:= cPanelH;
1690     FCfmPanel.OnClick:= @ConfirmButtonOkClick;
1691   end;
1692 end;
1693 
1694 procedure TfmMain.ConfirmButtonOkClick(Sender: TObject);
1695 begin
1696   FCfmPanel.Hide;
1697   EditorOpenLink(FCfmLink);
1698 end;
1699 
1700 procedure TfmMain.ConfirmPanelMouseLeave(Sender: TObject);
1701 begin
1702   FCfmPanel.Hide;
1703 end;
1704 
1705 end.
1706