1 unit editor_markup_userdefined;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, sysutils, math,
9 // LCL
10 LCLType, StdCtrls, ComCtrls, Graphics, EditorOptions, Spin, ExtCtrls,
11 Menus, Grids, Controls, Dialogs, Buttons, Forms,
12 // LazControls
13 DividerBevel,
14 // LazUtils
15 LazLoggerBase,
16 // SynEdit
17 SynEditKeyCmds, SynEditMarkupHighAll,
18 // IdeIntf
19 IDEOptionsIntf, IDEOptEditorIntf, IDECommands, IDEDialogs,
20 // IDE
21 LazarusIDEStrConsts, SynColorAttribEditor, KeyMapping, KeyMapShortCutDlg,
22 editor_keymapping_options;
23
24 type
25
26 { TColorStringGrid }
27
28 TColorStringGrid = class(TStringGrid)
29 private
30 FRowFontColor: Array of TColor;
GetRowFontColornull31 function GetRowFontColor(AIndex: Integer): TColor;
GetUserWordIndexnull32 function GetUserWordIndex(ARowIndex: Integer): Integer;
33 procedure SetRowFontColor(AIndex: Integer; AValue: TColor);
34 procedure SetUserWordIndex(ARowIndex: Integer; AValue: Integer);
35 protected
36 procedure PrepareCanvas(aCol, aRow: Integer; aState: TGridDrawState); override;
37 procedure ColRowDeleted(IsColumn: Boolean; index: Integer); override;
38 procedure ColRowInserted(IsColumn: boolean; index: integer); override;
39 // no exchanged or move
40 procedure SizeChanged(OldColCount, OldRowCount: Integer); override;
41 procedure DrawTextInCell(aCol, aRow: Integer; aRect: TRect;
42 aState: TGridDrawState); override;
43 procedure CalcCellExtent(acol, aRow: Integer; var aRect: TRect); override;
44 public
45 procedure DefaultDrawCell(aCol, aRow: Integer; var aRect: TRect;
46 aState: TGridDrawState); override;
47 property RowFontColor[AIndex: Integer]: TColor read GetRowFontColor write SetRowFontColor;
48 property UserWordIndex[ARowIndex: Integer]: Integer read GetUserWordIndex write SetUserWordIndex;
49 end;
50
51 { TEditorMarkupUserDefinedFrame }
52
53 TEditorMarkupUserDefinedFrame = class(TAbstractIDEOptionsEditor)
54 cbCaseSense: TCheckBox;
55 cbMatchEndBound: TCheckBox;
56 cbMatchStartBound: TCheckBox;
57 cbKeyCase: TCheckBox;
58 cbKeyBoundStart: TCheckBox;
59 cbKeyBoundEnd: TCheckBox;
60 cbSmartSelectBound: TCheckBox;
61 cbGlobalList: TCheckBox;
62 divKeyAdd: TDividerBevel;
63 divKeyRemove: TDividerBevel;
64 divKeyToggle: TDividerBevel;
65 edListName: TEdit;
66 HCenter: TLabel;
67 lbWordMin: TLabel;
68 lbSelectMin: TLabel;
69 HQuarter: TLabel;
70 lbKeyBoundMinLen: TLabel;
71 lbNewKeyOptions: TLabel;
72 HCenterKey: TLabel;
73 lbKeyAdd1: TLabel;
74 lbKeyAdd2: TLabel;
75 lbKeyRemove1: TLabel;
76 lbKeyRemove2: TLabel;
77 lbKeyToggle1: TLabel;
78 lbKeyToggle2: TLabel;
79 lbListName: TLabel;
80 ListMenu: TPopupMenu;
81 MainPanel: TPanel;
82 Notebook1: TNotebook;
83 PageMain: TPage;
84 PageKeys: TPage;
85 Panel1: TPanel;
86 btnKeyAdd: TSpeedButton;
87 btnKeyRemove: TSpeedButton;
88 btnKeyToggle: TSpeedButton;
89 edWordMin: TSpinEdit;
90 edSelectMin: TSpinEdit;
91 SynColorAttrEditor1: TSynColorAttrEditor;
92 ToolBar1: TToolBar;
93 tbSelectList: TToolButton;
94 tbNewList: TToolButton;
95 tbDeleteList: TToolButton;
96 ToolButton2: TToolButton;
97 tbMainPage: TToolButton;
98 tbKeyPage: TToolButton;
99 WordList: TColorStringGrid;
100 procedure edListNameEditingDone(Sender: TObject);
101 procedure edListNameKeyPress(Sender: TObject; var Key: char);
102 procedure KeyEditClicked(Sender: TObject);
103 procedure tbDeleteListClick(Sender: TObject);
104 procedure tbNewListClick(Sender: TObject);
105 procedure tbSelectListClick(Sender: TObject);
106 procedure GeneralCheckBoxChange(Sender: TObject);
107 procedure tbSelectPageClicked(Sender: TObject);
108 procedure WordListButtonClick(Sender: TObject; {%H-}aCol, aRow: Integer);
109 procedure WordListColRowDeleted(Sender: TObject; {%H-}IsColumn: Boolean; {%H-}sIndex,
110 {%H-}tIndex: Integer);
111 procedure WordListEditingDone(Sender: TObject);
112 procedure WordListExit(Sender: TObject);
113 procedure WordListKeyUp(Sender: TObject; var {%H-}Key: Word; {%H-}Shift: TShiftState);
114 procedure WordListSelection(Sender: TObject; {%H-}aCol, aRow: Integer);
115 private
116 { private declarations }
117 FGlobalColors: TEditorUserDefinedWordsList;
118 FUserWordsList: TEditorUserDefinedWordsList;
119 FUserWords: TEditorUserDefinedWords;
120 FKeyOptFrame: TEditorKeymappingOptionsFrame;
121 FSelectedListIdx: Integer; // In List of Lists
122 FSelectedRow: Integer;
123 FUpdatingDisplay: Integer;
124 procedure CheckDuplicate(AnIndex: Integer);
125 procedure DoListSelected(Sender: TObject);
126 procedure MaybeCleanEmptyRow(aRow: Integer);
127 procedure UpdateKeys;
128 procedure UpdateTermOptions;
129 procedure UpdateListDropDownFull;
130 procedure UpdateListDropDownCaption;
131 procedure UpdateListDisplay(KeepDuplicates: Boolean = False);
132 public
133 constructor Create(AOwner: TComponent); override;
134 destructor Destroy; override;
GetTitlenull135 function GetTitle: String; override;
136 procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
137 procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
138 procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
SupportedOptionsClassnull139 class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
140 end;
141
142 implementation
143
144 { TColorStringGrid }
145
GetRowFontColornull146 function TColorStringGrid.GetRowFontColor(AIndex: Integer): TColor;
147 begin
148 assert(AIndex < Length(FRowFontColor), 'GetRowFontColor');
149 Result := FRowFontColor[AIndex];
150 end;
151
TColorStringGrid.GetUserWordIndexnull152 function TColorStringGrid.GetUserWordIndex(ARowIndex: Integer): Integer;
153 begin
154 Result := PtrInt(Objects[0, ARowIndex])-1;
155 end;
156
157 procedure TColorStringGrid.SetRowFontColor(AIndex: Integer; AValue: TColor);
158 begin
159 assert(AIndex < Length(FRowFontColor), 'SetRowFontColor');
160 if FRowFontColor[AIndex] = AValue then
161 exit;
162 FRowFontColor[AIndex] := AValue;
163 Invalidate;
164 end;
165
166 procedure TColorStringGrid.SetUserWordIndex(ARowIndex: Integer; AValue: Integer
167 );
168 begin
169 Objects[0, ARowIndex] := TObject(PtrInt(AValue + 1));
170 end;
171
172 procedure TColorStringGrid.PrepareCanvas(aCol, aRow: Integer; aState: TGridDrawState);
173 begin
174 assert(aRow < Length(FRowFontColor));
175 inherited PrepareCanvas(aCol, aRow, aState);
176 Canvas.Font.Color := FRowFontColor[aRow];
177 end;
178
179 procedure TColorStringGrid.ColRowDeleted(IsColumn: Boolean; index: Integer);
180 begin
181 inherited ColRowDeleted(IsColumn, index);
182 if IsColumn then exit;
183 assert(index < Length(FRowFontColor), 'ColRowDeleted');
184 if index < Length(FRowFontColor) - 1 then
185 move(FRowFontColor[index+1], FRowFontColor[index],
186 (Length(FRowFontColor)-index) * SizeOf(TColor));
187 SetLength(FRowFontColor, Length(FRowFontColor) - 1);
188 end;
189
190 procedure TColorStringGrid.ColRowInserted(IsColumn: boolean; index: integer);
191 begin
192 inherited ColRowInserted(IsColumn, index);
193 if IsColumn then exit;
194 SetLength(FRowFontColor, Length(FRowFontColor) + 1);
195 assert(index < Length(FRowFontColor), 'ColRowInserted');
196 if index < Length(FRowFontColor) - 1 then
197 move(FRowFontColor[index], FRowFontColor[index+1],
198 (Length(FRowFontColor)-index) * SizeOf(TColor));
199 FRowFontColor[index] := Font.Color;
200 end;
201
202 procedure TColorStringGrid.SizeChanged(OldColCount, OldRowCount: Integer);
203 var
204 i: Integer;
205 begin
206 inherited SizeChanged(OldColCount, OldRowCount);
207 i := Length(FRowFontColor);
208 SetLength(FRowFontColor, RowCount);
209 while i < RowCount do begin
210 FRowFontColor[i] := Font.Color;
211 inc(i);
212 end;
213 end;
214
215 procedure TColorStringGrid.DrawTextInCell(aCol, aRow: Integer; aRect: TRect;
216 aState: TGridDrawState);
217 var
218 c: TColor;
219 begin
220 if (aRow = RowCount - 1) and (Cells[0, aRow] = '') then begin
221 c := Canvas.Font.Color;
222 Canvas.Font.Color := clGrayText;
223 DrawCellText(aCol, aRow, aRect, aState, rsAddNewTerm);
224 Canvas.Font.Color := c;
225 end
226 else
227 inherited DrawTextInCell(aCol, aRow, aRect, aState);
228 end;
229
230 procedure TColorStringGrid.CalcCellExtent(acol, aRow: Integer; var aRect: TRect
231 );
232 var
233 dummy: Integer;
234 begin
235 if (aRow = RowCount - 1) and (acol = 0) then
236 ColRowToOffset(True, True, 1, dummy, aRect.Right);
237 end;
238
239 procedure TColorStringGrid.DefaultDrawCell(aCol, aRow: Integer;
240 var aRect: TRect; aState: TGridDrawState);
241 var
242 w, h, x, y: LongInt;
243 begin
244 if (aRow = RowCount - 1) and (aCol = 1) then
245 exit;
246
247 inherited DefaultDrawCell(aCol, aRow, aRect, aState);
248 if aCol = 1 then begin
249 Canvas.Pen.Color := clRed;
250 Canvas.Pen.Width := 2;
251 Canvas.Pen.Style := psSolid;
252 w := (aRect.Right - aRect.Left) div 2;
253 h := (aRect.Bottom - aRect.Top) div 2;
254 x := aRect.Left + w;
255 y := aRect.Top + h;
256 w := min(w, h) div 2;
257 Canvas.Line(x - w, y - w, x + w, y + w);
258 Canvas.Line(x - w, y + w, x + w, y - w);
259 end;
260 end;
261
262 {$R *.lfm}
263
264 { TEditorMarkupUserDefinedFrame }
265
266 procedure TEditorMarkupUserDefinedFrame.edListNameEditingDone(Sender: TObject);
267 begin
268 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
269 if FUserWords.Name = edListName.Text then
270 exit;
271 FUserWords.Name := edListName.Text;
272 UpdateListDropDownFull;
273 end;
274
275 procedure TEditorMarkupUserDefinedFrame.edListNameKeyPress(Sender: TObject; var Key: char);
276 begin
277 if key in [#10,#13] then edListNameEditingDone(nil);
278 end;
279
280 procedure TEditorMarkupUserDefinedFrame.KeyEditClicked(Sender: TObject);
281 var
282 i: Integer;
283 begin
284 if FUserWords = nil then exit;
285
286 i := -1;
287 if Sender = btnKeyAdd then
288 i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.AddTermCmd as TKeyCommandRelation);
289 if Sender = btnKeyRemove then
290 i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.RemoveTermCmd as TKeyCommandRelation);
291 if Sender = btnKeyToggle then
292 i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.ToggleTermCmd as TKeyCommandRelation);
293
294 if i < 0 then exit;
295
296 ShowKeyMappingEditForm(i, (FUserWordsList.KeyCommandList as TKeyCommandRelationList));
297 FKeyOptFrame.UpdateTree;
298 UpdateKeys;
299 end;
300
301 procedure TEditorMarkupUserDefinedFrame.tbDeleteListClick(Sender: TObject);
302 begin
303 if FUserWords = nil then exit;
304 if WordList.EditorMode then
305 WordList.EditingDone;
306
307 if IDEMessageDialog(dlgMarkupUserDefinedDelCaption,
308 Format(dlgMarkupUserDefinedDelPrompt, [FUserWords.Name]),
309 mtConfirmation, mbYesNo) = mrNo
310 then
311 exit;
312
313 FUserWordsList.Remove(FUserWords, True);
314 FUserWords := nil;
315 if FSelectedListIdx > 0 then
316 dec(FSelectedListIdx);
317
318 UpdateListDropDownFull;
319 UpdateListDisplay;
320 end;
321
322 procedure TEditorMarkupUserDefinedFrame.tbNewListClick(Sender: TObject);
323 begin
324 if WordList.EditorMode then
325 WordList.EditingDone;
326
327 FUserWords := FUserWordsList.Add(dlgMarkupUserDefinedNewName);
328 FSelectedListIdx := FUserWordsList.IndexOf(FUserWords);
329 UpdateListDropDownFull;
330 UpdateListDisplay;
331 end;
332
333 procedure TEditorMarkupUserDefinedFrame.tbSelectListClick(Sender: TObject);
334 begin
335 tbSelectList.CheckMenuDropdown;
336 end;
337
338 procedure TEditorMarkupUserDefinedFrame.GeneralCheckBoxChange(Sender: TObject);
339 var
340 i: PtrInt;
341 begin
342 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
343
344 if WordList.EditorMode then
345 WordList.EditingDone;
346
347 if Sender = cbKeyCase then begin
348 FUserWords.KeyAddCase := cbKeyCase.Checked;
349 end;
350
351 if (Sender = cbKeyBoundStart) or (Sender = cbKeyBoundEnd) then begin
352 if cbKeyBoundStart.Checked then begin
353 if cbKeyBoundEnd.Checked
354 then FUserWords.KeyAddTermBounds := soBothBounds
355 else FUserWords.KeyAddTermBounds := soBoundsAtStart;
356 end
357 else begin
358 if cbKeyBoundEnd.Checked
359 then FUserWords.KeyAddTermBounds := soBoundsAtEnd
360 else FUserWords.KeyAddTermBounds := soNoBounds;
361 end;
362
363 cbSmartSelectBound.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
364 edWordMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
365 edSelectMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
366 end;
367
368 if Sender = cbSmartSelectBound then begin
369 FUserWords.KeyAddSelectSmart := cbSmartSelectBound.Checked;
370 end;
371
372 if Sender = edWordMin then begin
373 FUserWords.KeyAddWordBoundMaxLen := edWordMin.Value;
374 end;
375
376 if Sender = edSelectMin then begin
377 FUserWords.KeyAddSelectBoundMaxLen := edSelectMin.Value;
378 end;
379
380 if Sender = cbGlobalList then
381 FUserWords.GlobalList := cbGlobalList.Checked;
382
383
384 // Related to current word
385 i := WordList.UserWordIndex[FSelectedRow];
386 if (i < 0) or (i >= FUserWords.Count) then
387 exit;
388
389 if Sender = cbCaseSense then begin
390 FUserWords.Items[i].MatchCase := cbCaseSense.Checked;
391 CheckDuplicate(FSelectedRow);
392 end;
393
394 if (Sender = cbMatchStartBound) or (Sender = cbMatchEndBound) then begin
395 if cbMatchStartBound.Checked then begin
396 if cbMatchEndBound.Checked
397 then FUserWords.Items[i].MatchWordBounds := soBothBounds
398 else FUserWords.Items[i].MatchWordBounds := soBoundsAtStart;
399 end
400 else begin
401 if cbMatchEndBound.Checked
402 then FUserWords.Items[i].MatchWordBounds := soBoundsAtEnd
403 else FUserWords.Items[i].MatchWordBounds := soNoBounds;
404 end;
405 end;
406
407 end;
408
409 procedure TEditorMarkupUserDefinedFrame.tbSelectPageClicked(Sender: TObject);
410 begin
411 if WordList.EditorMode then
412 WordList.EditingDone;
413
414 if tbMainPage.Down then
415 Notebook1.PageIndex := 0
416 else
417 Notebook1.PageIndex := 1;
418 end;
419
420 procedure TEditorMarkupUserDefinedFrame.WordListButtonClick(Sender: TObject;
421 aCol, aRow: Integer);
422 var
423 i: LongInt;
424 begin
425 if (FUserWords = nil) or (aRow = WordList.RowCount - 1) then
426 exit;
427
428 inc(FUpdatingDisplay);
429 try
430 i := WordList.UserWordIndex[aRow];
431 if (i >= 0) and (i < FUserWords.Count) then begin
432 FUserWords.Delete(i);
433 i := FSelectedRow;
434 UpdateListDisplay(True);
435 FSelectedRow := i;
436 if (FSelectedRow > aRow) and (FSelectedRow > 0) then
437 dec(FSelectedRow);
438 WordList.Row := FSelectedRow;
439 UpdateTermOptions;
440 end;
441 finally
442 dec(FUpdatingDisplay);
443 end;
444 UpdateTermOptions;
445 end;
446
447 procedure TEditorMarkupUserDefinedFrame.WordListColRowDeleted(Sender: TObject;
448 IsColumn: Boolean; sIndex, tIndex: Integer);
449 begin
450 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
451 UpdateListDisplay(True);
452 end;
453
454 procedure TEditorMarkupUserDefinedFrame.WordListEditingDone(Sender: TObject);
455 var
456 i: Integer;
457 begin
458 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
459
460 i := WordList.UserWordIndex[FSelectedRow];
461 if (i = -1) and (WordList.Cells[0, FSelectedRow] <> '') then begin
462 i := FUserWords.Add.Index;
463 WordList.UserWordIndex[FSelectedRow] := i;
464 WordList.RowCount := WordList.RowCount + 1;
465 end;
466
467 if (i < 0) or (i >= FUserWords.Count) then
468 exit;
469
470 if FUserWords.Items[i].SearchTerm = WordList.Cells[0, FSelectedRow] then
471 exit;
472
473 FUserWords.Items[i].SearchTerm := WordList.Cells[0, FSelectedRow];
474 UpdateTermOptions;
475 CheckDuplicate(FSelectedRow);
476 end;
477
478 procedure TEditorMarkupUserDefinedFrame.WordListExit(Sender: TObject);
479 begin
480 if WordList.EditorMode then
481 WordList.EditingDone;
482 MaybeCleanEmptyRow(FSelectedRow);
483 end;
484
485 procedure TEditorMarkupUserDefinedFrame.WordListKeyUp(Sender: TObject; var Key: Word;
486 Shift: TShiftState);
487 var
488 i: PtrInt;
489 begin
490 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
491
492 i := WordList.UserWordIndex[FSelectedRow];
493 if (i = -1) and (WordList.Cells[0, FSelectedRow] <> '') then begin
494 // Editing in the newly added cell
495 i := FUserWords.Add.Index;
496 WordList.UserWordIndex[FSelectedRow] := i;
497 WordList.RowCount := WordList.RowCount + 1;
498 UpdateTermOptions;
499 end;
500 end;
501
502 procedure TEditorMarkupUserDefinedFrame.WordListSelection(Sender: TObject; aCol,
503 aRow: Integer);
504 var
505 i: Integer;
506 begin
507 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
508
509 if WordList.EditorMode then
510 WordList.EditingDone;
511
512 i := FSelectedRow;
513 FSelectedRow := aRow;
514
515 MaybeCleanEmptyRow(i);
516 UpdateTermOptions;
517 end;
518
519 procedure TEditorMarkupUserDefinedFrame.CheckDuplicate(AnIndex: Integer);
520
521 procedure UpdateDupErrors;
522 var
523 i: Integer;
524 begin
525 i := 0;
526 while (i < FUserWords.Count) do begin
527 if (FUserWords.FindSimilarMatchFor(FUserWords[i], 0, i) >= 0) then
528 WordList.RowFontColor[i] := clRed
529 else
530 WordList.RowFontColor[i] := clDefault;
531 inc(i);
532 end;
533 end;
534
535 var
536 j: Integer;
537 begin
538 if AnIndex < 0 then begin
539 UpdateDupErrors;
540 exit;
541 end;
542
543 j := FUserWords.FindSimilarMatchFor(FUserWords[AnIndex], 0, AnIndex);
544 if (j >= 0) then begin
545 if WordList.RowFontColor[FSelectedRow] <> clRed then begin
546 UpdateDupErrors;
547 IDEMessageDialog(dlgMarkupUserDefinedDuplicate,
548 Format(dlgMarkupUserDefinedDuplicateMsg, [FUserWords[AnIndex].SearchTerm]),
549 mtConfirmation, [mbOK]);
550 end;
551 end
552 else
553 if WordList.RowFontColor[FSelectedRow] <> clDefault then
554 UpdateDupErrors;
555 end;
556
557 procedure TEditorMarkupUserDefinedFrame.DoListSelected(Sender: TObject);
558 begin
559 if WordList.EditorMode then
560 WordList.EditingDone;
561
562 FSelectedListIdx := TMenuItem(Sender).Tag;
563 UpdateListDisplay;
564 end;
565
566 procedure TEditorMarkupUserDefinedFrame.MaybeCleanEmptyRow(aRow: Integer);
567 var
568 i: PtrInt;
569 begin
570 if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
571
572 inc(FUpdatingDisplay);
573 try
574 i := WordList.UserWordIndex[aRow];
575 if (i < 0) or (i >= FUserWords.Count) then
576 exit;
577
578 if FUserWords.Items[i].SearchTerm = '' then begin
579 FUserWords.Delete(i);
580 if FSelectedRow > aRow then
581 dec(FSelectedRow);
582 i := FSelectedRow;
583 UpdateListDisplay(True);
584 if i >= WordList.RowCount then
585 dec(i);
586 WordList.Row := i;
587 FSelectedRow := i;
588 UpdateTermOptions; // WordListSelection
589 end;
590
591 finally
592 dec(FUpdatingDisplay);
593 end;
594 end;
595
596 procedure TEditorMarkupUserDefinedFrame.UpdateKeys;
597 const
598 NoKey: TIDEShortCut = (Key1: VK_UNKNOWN; Shift1: []; Key2: VK_UNKNOWN; Shift2: [];);
599 begin
600 if (FUserWords = nil) then begin
601 lbKeyAdd1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
602 lbKeyAdd2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
603 lbKeyRemove1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
604 lbKeyRemove2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
605 lbKeyToggle1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
606 lbKeyToggle2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
607 exit;
608 end;
609
610 lbKeyAdd1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.AddTermCmd.ShortcutA);
611 lbKeyAdd2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.AddTermCmd.ShortcutB);
612 lbKeyRemove1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.RemoveTermCmd.ShortcutA);
613 lbKeyRemove2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.RemoveTermCmd.ShortcutB);
614 lbKeyToggle1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.ToggleTermCmd.ShortcutA);
615 lbKeyToggle2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.ToggleTermCmd.ShortcutB);
616 end;
617
618 procedure TEditorMarkupUserDefinedFrame.UpdateTermOptions;
619 var
620 i: PtrInt;
621 begin
622 if (FUserWords = nil) then exit;
623
624 inc(FUpdatingDisplay);
625 try
626 i := WordList.UserWordIndex[FSelectedRow];
627 cbCaseSense.Enabled := (i >= 0) and (i < FUserWords.Count);
628 cbMatchStartBound.Enabled := (i >= 0) and (i < FUserWords.Count);
629 cbMatchEndBound.Enabled := (i >= 0) and (i < FUserWords.Count);
630
631 if (i < 0) or (i >= FUserWords.Count) then begin
632 cbCaseSense.Checked := False;
633 cbMatchStartBound.Checked := False;
634 cbMatchEndBound.Checked := False;
635 exit;
636 end;
637
638 cbCaseSense.Checked := FUserWords.Items[i].MatchCase;
639 cbMatchStartBound.Checked := FUserWords.Items[i].MatchWordBounds in [soBoundsAtStart, soBothBounds];
640 cbMatchEndBound.Checked := FUserWords.Items[i].MatchWordBounds in [soBoundsAtEnd, soBothBounds];
641 finally
642 dec(FUpdatingDisplay);
643 end;
644 end;
645
646 procedure TEditorMarkupUserDefinedFrame.UpdateListDropDownFull;
647 var
648 m: TMenuItem;
649 i: Integer;
650 begin
651 ListMenu.Items.Clear;
652 if FUserWordsList.Count > 0 then begin
653 for i := 0 to FUserWordsList.Count - 1 do begin
654 m := TMenuItem.Create(ListMenu);
655 m.Caption := FUserWordsList.Lists[i].Name;
656 m.Tag := i;
657 m.OnClick := @DoListSelected;
658 ListMenu.Items.Add(m);
659 end;
660 end;
661 UpdateListDropDownCaption;
662 end;
663
664 procedure TEditorMarkupUserDefinedFrame.UpdateListDropDownCaption;
665 begin
666 if FUserWordsList.Count = 0 then begin
667 tbSelectList.Enabled := False;
668 tbSelectList.Caption := dlgMarkupUserDefinedNoLists;
669 end
670 else begin
671 tbSelectList.Enabled := True;
672 if (FSelectedListIdx >= 0) and (FSelectedListIdx < FUserWordsList.Count) then
673 tbSelectList.Caption := FUserWordsList.Lists[FSelectedListIdx].Name
674 else
675 tbSelectList.Caption := dlgMarkupUserDefinedNoListsSel;
676 end;
677 end;
678
679 procedure TEditorMarkupUserDefinedFrame.UpdateListDisplay(KeepDuplicates: Boolean);
680 var
681 i: Integer;
682 begin
683 WordList.EditorMode := False;
684 inc(FUpdatingDisplay);
685
686 if (FUserWords <> nil) and not (KeepDuplicates) then
687 FUserWords.ClearSimilarMatches;
688
689 UpdateListDropDownCaption;
690 try
691 if (FSelectedListIdx < 0) or (FSelectedListIdx >= FUserWordsList.Count) then begin
692 FUserWords := nil;
693 MainPanel.Enabled := False;
694 WordList.RowCount := 0;
695 UpdateKeys;
696 exit;
697 end;
698
699 FUserWords := FUserWordsList.Lists[FSelectedListIdx];
700 MainPanel.Enabled := True;
701 edListName.Text := FUserWords.Name;
702 SynColorAttrEditor1.CurHighlightElement := FUserWords.ColorAttr;
703 WordList.RowCount := FUserWords.Count + 1;
704 WordList.Cells[0, 0] := '';
705 WordList.UserWordIndex[0] := -1;
706 for i := 0 to FUserWords.Count - 1 do begin
707 WordList.Cells[0, i] := FUserWords.Items[i].SearchTerm;
708 WordList.UserWordIndex[i] := FUserWords.Items[i].Index;
709 end;
710 WordList.Cells[0, FUserWords.Count] := '';
711 WordList.UserWordIndex[FUserWords.Count] := -1;
712 FSelectedRow := 0;
713 WordList.Col := 0;
714 WordList.Row := 0;
715
716 CheckDuplicate(-1);
717 UpdateKeys;
718 cbKeyCase.Checked := FUserWords.KeyAddCase;
719 cbKeyBoundStart.Checked := FUserWords.KeyAddTermBounds in [soBoundsAtStart, soBothBounds];
720 cbKeyBoundEnd.Checked := FUserWords.KeyAddTermBounds in [soBoundsAtEnd, soBothBounds];
721 cbSmartSelectBound.Checked := FUserWords.KeyAddSelectSmart;
722 cbGlobalList.Checked := FUserWords.GlobalList;
723 edWordMin.Value := FUserWords.KeyAddWordBoundMaxLen;
724 edSelectMin.Value := FUserWords.KeyAddSelectBoundMaxLen;
725 cbSmartSelectBound.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
726 edWordMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
727 edSelectMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
728 finally
729 dec(FUpdatingDisplay)
730 end;
731 WordListSelection(nil, 0, 0);
732 end;
733
734 constructor TEditorMarkupUserDefinedFrame.Create(AOwner: TComponent);
735 begin
736 inherited Create(AOwner);
737 FUserWordsList := TEditorUserDefinedWordsList.Create;
738 FUpdatingDisplay := 0;
739 end;
740
741 destructor TEditorMarkupUserDefinedFrame.Destroy;
742 begin
743 inherited Destroy;
744 FreeAndNil(FUserWordsList);
745 end;
746
TEditorMarkupUserDefinedFrame.GetTitlenull747 function TEditorMarkupUserDefinedFrame.GetTitle: String;
748 begin
749 Result := dlgMarkupUserDefined;
750 end;
751
752 procedure TEditorMarkupUserDefinedFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
753 begin
754 SynColorAttrEditor1.Setup;
755 SynColorAttrEditor1.ShowPrior := True;
756 tbNewList.Caption := dlgMarkupUserDefinedListNew;
757 tbDeleteList.Caption := dlgMarkupUserDefinedListDel;
758 lbListName.Caption := dlgMarkupUserDefinedListName;
759 tbMainPage.Caption := dlgMarkupUserDefinedPageMain;
760 tbKeyPage.Caption := dlgMarkupUserDefinedPageKeys;
761 cbCaseSense.Caption := dlgMarkupUserDefinedMatchCase;
762 cbMatchStartBound.Caption := dlgMarkupUserDefinedMatchStartBound;
763 cbMatchEndBound.Caption := dlgMarkupUserDefinedMatchEndBound;
764 divKeyAdd.Caption := dlgMarkupUserDefinedDivKeyAdd;
765 divKeyRemove.Caption := dlgMarkupUserDefinedDivKeyRemove;
766 divKeyToggle.Caption := dlgMarkupUserDefinedDivKeyToggle;
767
768 lbNewKeyOptions.Caption := dlgMarkupUserDefinedNewByKeyOpts;
769 cbKeyCase.Caption := dlgMarkupUserDefinedMatchCase;
770 cbKeyBoundStart.Caption := dlgMarkupUserDefinedMatchStartBound;
771 cbKeyBoundEnd.Caption := dlgMarkupUserDefinedMatchEndBound;
772 lbKeyBoundMinLen.Caption := dlgMarkupUserDefinedNewByKeyLen;
773 lbWordMin.Caption := dlgMarkupUserDefinedNewByKeyLenWord;
774 lbSelectMin.Caption := dlgMarkupUserDefinedNewByKeyLenSelect;
775 cbSmartSelectBound.Caption := dlgMarkupUserDefinedNewByKeySmartSelect;
776 cbGlobalList.Caption := dlgMarkupUserDefinedGlobalList;
777
778 FKeyOptFrame := TEditorKeymappingOptionsFrame(ADialog.FindEditor(TEditorKeymappingOptionsFrame));
779 FUserWordsList.KeyCommandList := FKeyOptFrame.EditingKeyMap;
780 edListName.Text := '';
781 end;
782
783 procedure TEditorMarkupUserDefinedFrame.ReadSettings(AOptions: TAbstractIDEOptions);
784 begin
785 FGlobalColors := TEditorOptions(AOptions).UserDefinedColors;
786 FSelectedListIdx := 0;
787
788 FKeyOptFrame.ReadSettings(AOptions);
789
790 FUserWordsList.Assign(FGlobalColors);
791 FSelectedListIdx := 0;
792 UpdateListDropDownFull;
793 UpdateListDisplay;
794 tbDeleteList.Enabled := FUserWordsList.Count > 0;
795 FGlobalColors := nil;
796 UpdateKeys;
797 end;
798
799 procedure TEditorMarkupUserDefinedFrame.WriteSettings(AOptions: TAbstractIDEOptions);
800 begin
801 if FGlobalColors <> nil then
802 exit;
803
804 if FUserWords <> nil then
805 FUserWords.ClearSimilarMatches;
806 TEditorOptions(AOptions).UserDefinedColors.Assign(FUserWordsList);
807 end;
808
TEditorMarkupUserDefinedFrame.SupportedOptionsClassnull809 class function TEditorMarkupUserDefinedFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
810 begin
811 Result := TEditorOptions;
812 end;
813
814 initialization
815 RegisterIDEOptionsEditor(GroupEditor, TEditorMarkupUserDefinedFrame,
816 EdtOptionsUserDefined, EdtOptionsDisplay);
817 end.
818
819