mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 18:43:50 +02:00
803 lines
25 KiB
ObjectPascal
803 lines
25 KiB
ObjectPascal
unit editor_markup_userdefined;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, sysutils, math,
|
|
// LCL
|
|
LCLType, StdCtrls, ComCtrls, Graphics, EditorOptions, Spin, ExtCtrls,
|
|
Menus, Grids, Controls, Dialogs, Buttons, Forms,
|
|
// LazControls
|
|
DividerBevel,
|
|
// LazUtils
|
|
LazLoggerBase,
|
|
// SynEdit
|
|
SynEditKeyCmds, SynEditMarkupHighAll,
|
|
// IdeIntf
|
|
IDEOptionsIntf, IDEOptEditorIntf, IDECommands, IDEDialogs,
|
|
// IDE
|
|
LazarusIDEStrConsts, SynColorAttribEditor, KeyMapping, KeyMapShortCutDlg,
|
|
editor_keymapping_options;
|
|
|
|
type
|
|
|
|
{ TColorStringGrid }
|
|
|
|
TColorStringGrid = class(TStringGrid)
|
|
private
|
|
FRowFontColor: Array of TColor;
|
|
function GetRowFontColor(AIndex: Integer): TColor;
|
|
function GetUserWordIndex(ARowIndex: Integer): Integer;
|
|
procedure SetRowFontColor(AIndex: Integer; AValue: TColor);
|
|
procedure SetUserWordIndex(ARowIndex: Integer; AValue: Integer);
|
|
protected
|
|
procedure PrepareCanvas(aCol, aRow: Integer; aState: TGridDrawState); override;
|
|
procedure ColRowDeleted(IsColumn: Boolean; index: Integer); override;
|
|
procedure ColRowInserted(IsColumn: boolean; index: integer); override;
|
|
// no exchanged or move
|
|
procedure SizeChanged(OldColCount, OldRowCount: Integer); override;
|
|
procedure DrawTextInCell(aCol, aRow: Integer; aRect: TRect;
|
|
aState: TGridDrawState); override;
|
|
procedure CalcCellExtent(acol, aRow: Integer; var aRect: TRect); override;
|
|
public
|
|
procedure DefaultDrawCell(aCol, aRow: Integer; var aRect: TRect;
|
|
aState: TGridDrawState); override;
|
|
property RowFontColor[AIndex: Integer]: TColor read GetRowFontColor write SetRowFontColor;
|
|
property UserWordIndex[ARowIndex: Integer]: Integer read GetUserWordIndex write SetUserWordIndex;
|
|
end;
|
|
|
|
{ TEditorMarkupUserDefinedFrame }
|
|
|
|
TEditorMarkupUserDefinedFrame = class(TAbstractIDEOptionsEditor)
|
|
btnAdd: TButton;
|
|
btnCopy: TButton;
|
|
btnDelete: TButton;
|
|
cbGroup: TComboBox;
|
|
cbCaseSense: TCheckBox;
|
|
cbMatchEndBound: TCheckBox;
|
|
cbMatchStartBound: TCheckBox;
|
|
cbKeyCase: TCheckBox;
|
|
cbKeyBoundStart: TCheckBox;
|
|
cbKeyBoundEnd: TCheckBox;
|
|
cbSmartSelectBound: TCheckBox;
|
|
cbGlobalList: TCheckBox;
|
|
divEditGroup: TDividerBevel;
|
|
divKeyAdd: TDividerBevel;
|
|
divKeyRemove: TDividerBevel;
|
|
divKeyToggle: TDividerBevel;
|
|
divSelectGroup: TDividerBevel;
|
|
edListName: TEdit;
|
|
HCenter: TLabel;
|
|
lbListName: TLabel;
|
|
lbWordMin: TLabel;
|
|
lbSelectMin: TLabel;
|
|
HQuarter: TLabel;
|
|
lbKeyBoundMinLen: TLabel;
|
|
lbNewKeyOptions: TLabel;
|
|
HCenterKey: TLabel;
|
|
lbKeyAdd1: TLabel;
|
|
lbKeyAdd2: TLabel;
|
|
lbKeyRemove1: TLabel;
|
|
lbKeyRemove2: TLabel;
|
|
lbKeyToggle1: TLabel;
|
|
lbKeyToggle2: TLabel;
|
|
MainPanel: TScrollBox;
|
|
pnlKeys: TPanel;
|
|
pnlMain: TPanel;
|
|
PageControl1: TPageControl;
|
|
Panel1: TPanel;
|
|
btnKeyAdd: TSpeedButton;
|
|
btnKeyRemove: TSpeedButton;
|
|
btnKeyToggle: TSpeedButton;
|
|
edWordMin: TSpinEdit;
|
|
edSelectMin: TSpinEdit;
|
|
SynColorAttrEditor1: TSynColorAttrEditor;
|
|
tabMain: TTabSheet;
|
|
tabKeys: TTabSheet;
|
|
WordList: TColorStringGrid;
|
|
procedure cbGroupChange(Sender: TObject);
|
|
procedure edListNameEditingDone(Sender: TObject);
|
|
procedure edListNameKeyPress(Sender: TObject; var Key: char);
|
|
procedure KeyEditClicked(Sender: TObject);
|
|
procedure PageControl1Change(Sender: TObject);
|
|
procedure tbDeleteListClick(Sender: TObject);
|
|
procedure tbNewListClick(Sender: TObject);
|
|
procedure GeneralCheckBoxChange(Sender: TObject);
|
|
procedure WordListButtonClick(Sender: TObject; {%H-}aCol, aRow: Integer);
|
|
procedure WordListColRowDeleted(Sender: TObject; {%H-}IsColumn: Boolean; {%H-}sIndex,
|
|
{%H-}tIndex: Integer);
|
|
procedure WordListEditingDone(Sender: TObject);
|
|
procedure WordListExit(Sender: TObject);
|
|
procedure WordListKeyUp(Sender: TObject; var {%H-}Key: Word; {%H-}Shift: TShiftState);
|
|
procedure WordListSelection(Sender: TObject; {%H-}aCol, aRow: Integer);
|
|
private
|
|
{ private declarations }
|
|
FGlobalColors: TEditorUserDefinedWordsList;
|
|
FUserWordsList: TEditorUserDefinedWordsList;
|
|
FUserWords: TEditorUserDefinedWords;
|
|
FKeyOptFrame: TEditorKeymappingOptionsFrame;
|
|
FSelectedListIdx: Integer; // In List of Lists
|
|
FSelectedRow: Integer;
|
|
FUpdatingDisplay: Integer;
|
|
procedure CheckDuplicate(AnIndex: Integer);
|
|
procedure MaybeCleanEmptyRow(aRow: Integer);
|
|
procedure UpdateKeys;
|
|
procedure UpdateTermOptions;
|
|
procedure UpdateListDropDownFull;
|
|
procedure UpdateListDropDownCaption;
|
|
procedure UpdateListDisplay(KeepDuplicates: Boolean = False);
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function GetTitle: String; override;
|
|
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
|
|
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
|
|
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
|
|
class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TColorStringGrid }
|
|
|
|
function TColorStringGrid.GetRowFontColor(AIndex: Integer): TColor;
|
|
begin
|
|
assert(AIndex < Length(FRowFontColor), 'GetRowFontColor');
|
|
Result := FRowFontColor[AIndex];
|
|
end;
|
|
|
|
function TColorStringGrid.GetUserWordIndex(ARowIndex: Integer): Integer;
|
|
begin
|
|
Result := PtrInt(Objects[0, ARowIndex])-1;
|
|
end;
|
|
|
|
procedure TColorStringGrid.SetRowFontColor(AIndex: Integer; AValue: TColor);
|
|
begin
|
|
assert(AIndex < Length(FRowFontColor), 'SetRowFontColor');
|
|
if FRowFontColor[AIndex] = AValue then
|
|
exit;
|
|
FRowFontColor[AIndex] := AValue;
|
|
Invalidate;
|
|
end;
|
|
|
|
procedure TColorStringGrid.SetUserWordIndex(ARowIndex: Integer; AValue: Integer
|
|
);
|
|
begin
|
|
Objects[0, ARowIndex] := TObject(PtrInt(AValue + 1));
|
|
end;
|
|
|
|
procedure TColorStringGrid.PrepareCanvas(aCol, aRow: Integer; aState: TGridDrawState);
|
|
begin
|
|
assert(aRow < Length(FRowFontColor));
|
|
inherited PrepareCanvas(aCol, aRow, aState);
|
|
Canvas.Font.Color := FRowFontColor[aRow];
|
|
end;
|
|
|
|
procedure TColorStringGrid.ColRowDeleted(IsColumn: Boolean; index: Integer);
|
|
begin
|
|
inherited ColRowDeleted(IsColumn, index);
|
|
if IsColumn then exit;
|
|
assert(index < Length(FRowFontColor), 'ColRowDeleted');
|
|
if index < Length(FRowFontColor) - 1 then
|
|
move(FRowFontColor[index+1], FRowFontColor[index],
|
|
(Length(FRowFontColor)-index) * SizeOf(TColor));
|
|
SetLength(FRowFontColor, Length(FRowFontColor) - 1);
|
|
end;
|
|
|
|
procedure TColorStringGrid.ColRowInserted(IsColumn: boolean; index: integer);
|
|
begin
|
|
inherited ColRowInserted(IsColumn, index);
|
|
if IsColumn then exit;
|
|
SetLength(FRowFontColor, Length(FRowFontColor) + 1);
|
|
assert(index < Length(FRowFontColor), 'ColRowInserted');
|
|
if index < Length(FRowFontColor) - 1 then
|
|
move(FRowFontColor[index], FRowFontColor[index+1],
|
|
(Length(FRowFontColor)-index) * SizeOf(TColor));
|
|
FRowFontColor[index] := Font.Color;
|
|
end;
|
|
|
|
procedure TColorStringGrid.SizeChanged(OldColCount, OldRowCount: Integer);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
inherited SizeChanged(OldColCount, OldRowCount);
|
|
i := Length(FRowFontColor);
|
|
SetLength(FRowFontColor, RowCount);
|
|
while i < RowCount do begin
|
|
FRowFontColor[i] := Font.Color;
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
procedure TColorStringGrid.DrawTextInCell(aCol, aRow: Integer; aRect: TRect;
|
|
aState: TGridDrawState);
|
|
var
|
|
c: TColor;
|
|
begin
|
|
if (aRow = RowCount - 1) and (Cells[0, aRow] = '') then begin
|
|
c := Canvas.Font.Color;
|
|
Canvas.Font.Color := clGrayText;
|
|
DrawCellText(aCol, aRow, aRect, aState, rsAddNewTerm);
|
|
Canvas.Font.Color := c;
|
|
end
|
|
else
|
|
inherited DrawTextInCell(aCol, aRow, aRect, aState);
|
|
end;
|
|
|
|
procedure TColorStringGrid.CalcCellExtent(acol, aRow: Integer; var aRect: TRect
|
|
);
|
|
var
|
|
dummy: Integer;
|
|
begin
|
|
if (aRow = RowCount - 1) and (acol = 0) then
|
|
ColRowToOffset(True, True, 1, dummy, aRect.Right);
|
|
end;
|
|
|
|
procedure TColorStringGrid.DefaultDrawCell(aCol, aRow: Integer;
|
|
var aRect: TRect; aState: TGridDrawState);
|
|
var
|
|
w, h, x, y: LongInt;
|
|
begin
|
|
if (aRow = RowCount - 1) and (aCol = 1) then
|
|
exit;
|
|
|
|
inherited DefaultDrawCell(aCol, aRow, aRect, aState);
|
|
if aCol = 1 then begin
|
|
Canvas.Pen.Color := clRed;
|
|
Canvas.Pen.Width := 2;
|
|
Canvas.Pen.Style := psSolid;
|
|
w := (aRect.Right - aRect.Left) div 2;
|
|
h := (aRect.Bottom - aRect.Top) div 2;
|
|
x := aRect.Left + w;
|
|
y := aRect.Top + h;
|
|
w := min(w, h) div 2;
|
|
Canvas.Line(x - w, y - w, x + w, y + w);
|
|
Canvas.Line(x - w, y + w, x + w, y - w);
|
|
end;
|
|
end;
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TEditorMarkupUserDefinedFrame }
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.edListNameEditingDone(Sender: TObject);
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
if FUserWords.Name = edListName.Text then
|
|
exit;
|
|
FUserWords.Name := edListName.Text;
|
|
UpdateListDropDownFull;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.cbGroupChange(Sender: TObject);
|
|
begin
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
|
|
FSelectedListIdx := cbGroup.ItemIndex;
|
|
UpdateListDisplay;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.edListNameKeyPress(Sender: TObject; var Key: char);
|
|
begin
|
|
if key in [#10,#13] then edListNameEditingDone(nil);
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.KeyEditClicked(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if FUserWords = nil then exit;
|
|
|
|
i := -1;
|
|
if Sender = btnKeyAdd then
|
|
i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.AddTermCmd as TKeyCommandRelation);
|
|
if Sender = btnKeyRemove then
|
|
i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.RemoveTermCmd as TKeyCommandRelation);
|
|
if Sender = btnKeyToggle then
|
|
i := (FUserWordsList.KeyCommandList as TKeyCommandRelationList).IndexOf(FUserWords.ToggleTermCmd as TKeyCommandRelation);
|
|
|
|
if i < 0 then exit;
|
|
|
|
ShowKeyMappingEditForm(i, (FUserWordsList.KeyCommandList as TKeyCommandRelationList));
|
|
FKeyOptFrame.UpdateTree;
|
|
UpdateKeys;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.PageControl1Change(Sender: TObject);
|
|
begin
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.tbDeleteListClick(Sender: TObject);
|
|
begin
|
|
if FUserWords = nil then exit;
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
|
|
if IDEMessageDialog(dlgMarkupUserDefinedDelCaption,
|
|
Format(dlgMarkupUserDefinedDelPrompt, [FUserWords.Name]),
|
|
mtConfirmation, mbYesNo) <> mrYes
|
|
then
|
|
exit;
|
|
|
|
FUserWordsList.Remove(FUserWords, True);
|
|
FUserWords := nil;
|
|
if FSelectedListIdx > 0 then
|
|
dec(FSelectedListIdx);
|
|
|
|
UpdateListDropDownFull;
|
|
UpdateListDisplay;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.tbNewListClick(Sender: TObject);
|
|
begin
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
|
|
FUserWords := FUserWordsList.Add(dlgMarkupUserDefinedNewName);
|
|
FSelectedListIdx := FUserWordsList.IndexOf(FUserWords);
|
|
UpdateListDropDownFull;
|
|
UpdateListDisplay;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.GeneralCheckBoxChange(Sender: TObject);
|
|
var
|
|
i: PtrInt;
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
|
|
if Sender = cbKeyCase then begin
|
|
FUserWords.KeyAddCase := cbKeyCase.Checked;
|
|
end;
|
|
|
|
if (Sender = cbKeyBoundStart) or (Sender = cbKeyBoundEnd) then begin
|
|
if cbKeyBoundStart.Checked then begin
|
|
if cbKeyBoundEnd.Checked
|
|
then FUserWords.KeyAddTermBounds := soBothBounds
|
|
else FUserWords.KeyAddTermBounds := soBoundsAtStart;
|
|
end
|
|
else begin
|
|
if cbKeyBoundEnd.Checked
|
|
then FUserWords.KeyAddTermBounds := soBoundsAtEnd
|
|
else FUserWords.KeyAddTermBounds := soNoBounds;
|
|
end;
|
|
|
|
cbSmartSelectBound.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
edWordMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
edSelectMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
end;
|
|
|
|
if Sender = cbSmartSelectBound then begin
|
|
FUserWords.KeyAddSelectSmart := cbSmartSelectBound.Checked;
|
|
end;
|
|
|
|
if Sender = edWordMin then begin
|
|
FUserWords.KeyAddWordBoundMaxLen := edWordMin.Value;
|
|
end;
|
|
|
|
if Sender = edSelectMin then begin
|
|
FUserWords.KeyAddSelectBoundMaxLen := edSelectMin.Value;
|
|
end;
|
|
|
|
if Sender = cbGlobalList then
|
|
FUserWords.GlobalList := cbGlobalList.Checked;
|
|
|
|
|
|
// Related to current word
|
|
i := WordList.UserWordIndex[FSelectedRow];
|
|
if (i < 0) or (i >= FUserWords.Count) then
|
|
exit;
|
|
|
|
if Sender = cbCaseSense then begin
|
|
FUserWords.Items[i].MatchCase := cbCaseSense.Checked;
|
|
CheckDuplicate(FSelectedRow);
|
|
end;
|
|
|
|
if (Sender = cbMatchStartBound) or (Sender = cbMatchEndBound) then begin
|
|
if cbMatchStartBound.Checked then begin
|
|
if cbMatchEndBound.Checked
|
|
then FUserWords.Items[i].MatchWordBounds := soBothBounds
|
|
else FUserWords.Items[i].MatchWordBounds := soBoundsAtStart;
|
|
end
|
|
else begin
|
|
if cbMatchEndBound.Checked
|
|
then FUserWords.Items[i].MatchWordBounds := soBoundsAtEnd
|
|
else FUserWords.Items[i].MatchWordBounds := soNoBounds;
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListButtonClick(Sender: TObject;
|
|
aCol, aRow: Integer);
|
|
var
|
|
i: LongInt;
|
|
begin
|
|
if (FUserWords = nil) or (aRow = WordList.RowCount - 1) then
|
|
exit;
|
|
|
|
inc(FUpdatingDisplay);
|
|
try
|
|
i := WordList.UserWordIndex[aRow];
|
|
if (i >= 0) and (i < FUserWords.Count) then begin
|
|
FUserWords.Delete(i);
|
|
i := FSelectedRow;
|
|
UpdateListDisplay(True);
|
|
FSelectedRow := i;
|
|
if (FSelectedRow > aRow) and (FSelectedRow > 0) then
|
|
dec(FSelectedRow);
|
|
WordList.Row := FSelectedRow;
|
|
UpdateTermOptions;
|
|
end;
|
|
finally
|
|
dec(FUpdatingDisplay);
|
|
end;
|
|
UpdateTermOptions;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListColRowDeleted(Sender: TObject;
|
|
IsColumn: Boolean; sIndex, tIndex: Integer);
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
UpdateListDisplay(True);
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListEditingDone(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
|
|
i := WordList.UserWordIndex[FSelectedRow];
|
|
if (i = -1) and (WordList.Cells[0, FSelectedRow] <> '') then begin
|
|
i := FUserWords.Add.Index;
|
|
WordList.UserWordIndex[FSelectedRow] := i;
|
|
WordList.RowCount := WordList.RowCount + 1;
|
|
end;
|
|
|
|
if (i < 0) or (i >= FUserWords.Count) then
|
|
exit;
|
|
|
|
if FUserWords.Items[i].SearchTerm = WordList.Cells[0, FSelectedRow] then
|
|
exit;
|
|
|
|
FUserWords.Items[i].SearchTerm := WordList.Cells[0, FSelectedRow];
|
|
UpdateTermOptions;
|
|
CheckDuplicate(FSelectedRow);
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListExit(Sender: TObject);
|
|
begin
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
MaybeCleanEmptyRow(FSelectedRow);
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListKeyUp(Sender: TObject; var Key: Word;
|
|
Shift: TShiftState);
|
|
var
|
|
i: PtrInt;
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
|
|
i := WordList.UserWordIndex[FSelectedRow];
|
|
if (i = -1) and (WordList.Cells[0, FSelectedRow] <> '') then begin
|
|
// Editing in the newly added cell
|
|
i := FUserWords.Add.Index;
|
|
WordList.UserWordIndex[FSelectedRow] := i;
|
|
WordList.RowCount := WordList.RowCount + 1;
|
|
UpdateTermOptions;
|
|
end;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WordListSelection(Sender: TObject; aCol,
|
|
aRow: Integer);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
|
|
if WordList.EditorMode then
|
|
WordList.EditingDone;
|
|
|
|
i := FSelectedRow;
|
|
FSelectedRow := aRow;
|
|
|
|
MaybeCleanEmptyRow(i);
|
|
UpdateTermOptions;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.CheckDuplicate(AnIndex: Integer);
|
|
|
|
procedure UpdateDupErrors;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
i := 0;
|
|
while (i < FUserWords.Count) do begin
|
|
if (FUserWords.FindSimilarMatchFor(FUserWords[i], 0, i) >= 0) then
|
|
WordList.RowFontColor[i] := clRed
|
|
else
|
|
WordList.RowFontColor[i] := clDefault;
|
|
inc(i);
|
|
end;
|
|
end;
|
|
|
|
var
|
|
j: Integer;
|
|
begin
|
|
if AnIndex < 0 then begin
|
|
UpdateDupErrors;
|
|
exit;
|
|
end;
|
|
|
|
j := FUserWords.FindSimilarMatchFor(FUserWords[AnIndex], 0, AnIndex);
|
|
if (j >= 0) then begin
|
|
if WordList.RowFontColor[FSelectedRow] <> clRed then begin
|
|
UpdateDupErrors;
|
|
IDEMessageDialog(dlgMarkupUserDefinedDuplicate,
|
|
Format(dlgMarkupUserDefinedDuplicateMsg, [FUserWords[AnIndex].SearchTerm]),
|
|
mtConfirmation, [mbOK]);
|
|
end;
|
|
end
|
|
else
|
|
if WordList.RowFontColor[FSelectedRow] <> clDefault then
|
|
UpdateDupErrors;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.MaybeCleanEmptyRow(aRow: Integer);
|
|
var
|
|
i: PtrInt;
|
|
begin
|
|
if (FUpdatingDisplay > 0) or (FUserWords = nil) then exit;
|
|
|
|
inc(FUpdatingDisplay);
|
|
try
|
|
i := WordList.UserWordIndex[aRow];
|
|
if (i < 0) or (i >= FUserWords.Count) then
|
|
exit;
|
|
|
|
if FUserWords.Items[i].SearchTerm = '' then begin
|
|
FUserWords.Delete(i);
|
|
if FSelectedRow > aRow then
|
|
dec(FSelectedRow);
|
|
i := FSelectedRow;
|
|
UpdateListDisplay(True);
|
|
if i >= WordList.RowCount then
|
|
dec(i);
|
|
WordList.Row := i;
|
|
FSelectedRow := i;
|
|
UpdateTermOptions; // WordListSelection
|
|
end;
|
|
|
|
finally
|
|
dec(FUpdatingDisplay);
|
|
end;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.UpdateKeys;
|
|
const
|
|
NoKey: TIDEShortCut = (Key1: VK_UNKNOWN; Shift1: []; Key2: VK_UNKNOWN; Shift2: [];);
|
|
begin
|
|
if (FUserWords = nil) then begin
|
|
lbKeyAdd1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
lbKeyAdd2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
lbKeyRemove1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
lbKeyRemove2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
lbKeyToggle1.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
lbKeyToggle2.Caption := KeyAndShiftStateToEditorKeyString(NoKey);
|
|
exit;
|
|
end;
|
|
|
|
lbKeyAdd1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.AddTermCmd.ShortcutA);
|
|
lbKeyAdd2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.AddTermCmd.ShortcutB);
|
|
lbKeyRemove1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.RemoveTermCmd.ShortcutA);
|
|
lbKeyRemove2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.RemoveTermCmd.ShortcutB);
|
|
lbKeyToggle1.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.ToggleTermCmd.ShortcutA);
|
|
lbKeyToggle2.Caption := KeyAndShiftStateToEditorKeyString(FUserWords.ToggleTermCmd.ShortcutB);
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.UpdateTermOptions;
|
|
var
|
|
i: PtrInt;
|
|
begin
|
|
if (FUserWords = nil) then exit;
|
|
|
|
inc(FUpdatingDisplay);
|
|
try
|
|
i := WordList.UserWordIndex[FSelectedRow];
|
|
cbCaseSense.Enabled := (i >= 0) and (i < FUserWords.Count);
|
|
cbMatchStartBound.Enabled := (i >= 0) and (i < FUserWords.Count);
|
|
cbMatchEndBound.Enabled := (i >= 0) and (i < FUserWords.Count);
|
|
|
|
if (i < 0) or (i >= FUserWords.Count) then begin
|
|
cbCaseSense.Checked := False;
|
|
cbMatchStartBound.Checked := False;
|
|
cbMatchEndBound.Checked := False;
|
|
exit;
|
|
end;
|
|
|
|
cbCaseSense.Checked := FUserWords.Items[i].MatchCase;
|
|
cbMatchStartBound.Checked := FUserWords.Items[i].MatchWordBounds in [soBoundsAtStart, soBothBounds];
|
|
cbMatchEndBound.Checked := FUserWords.Items[i].MatchWordBounds in [soBoundsAtEnd, soBothBounds];
|
|
finally
|
|
dec(FUpdatingDisplay);
|
|
end;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.UpdateListDropDownFull;
|
|
var
|
|
i: Integer;
|
|
begin
|
|
cbGroup.Clear;
|
|
for i := 0 to FUserWordsList.Count - 1 do
|
|
cbGroup.Items.Add(FUserWordsList.Lists[i].Name);
|
|
UpdateListDropDownCaption;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.UpdateListDropDownCaption;
|
|
begin
|
|
if FUserWordsList.Count = 0 then begin
|
|
cbGroup.Enabled := False;
|
|
cbGroup.Caption := dlgMarkupUserDefinedNoLists;
|
|
end
|
|
else begin
|
|
cbGroup.Enabled := True;
|
|
if (FSelectedListIdx >= 0) and (FSelectedListIdx < FUserWordsList.Count) then
|
|
cbGroup.ItemIndex := FSelectedListIdx
|
|
//cbGroup.Caption := FUserWordsList.Lists[FSelectedListIdx].Name
|
|
else
|
|
cbGroup.Caption := dlgMarkupUserDefinedNoListsSel;
|
|
end;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.UpdateListDisplay(KeepDuplicates: Boolean);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
WordList.EditorMode := False;
|
|
inc(FUpdatingDisplay);
|
|
|
|
if (FUserWords <> nil) and not (KeepDuplicates) then
|
|
FUserWords.ClearSimilarMatches;
|
|
|
|
UpdateListDropDownCaption;
|
|
try
|
|
if (FSelectedListIdx < 0) or (FSelectedListIdx >= FUserWordsList.Count) then begin
|
|
FUserWords := nil;
|
|
MainPanel.Enabled := False;
|
|
WordList.RowCount := 0;
|
|
UpdateKeys;
|
|
exit;
|
|
end;
|
|
|
|
FUserWords := FUserWordsList.Lists[FSelectedListIdx];
|
|
MainPanel.Enabled := True;
|
|
edListName.Text := FUserWords.Name;
|
|
SynColorAttrEditor1.CurHighlightElement := FUserWords.ColorAttr;
|
|
WordList.RowCount := FUserWords.Count + 1;
|
|
WordList.Cells[0, 0] := '';
|
|
WordList.UserWordIndex[0] := -1;
|
|
for i := 0 to FUserWords.Count - 1 do begin
|
|
WordList.Cells[0, i] := FUserWords.Items[i].SearchTerm;
|
|
WordList.UserWordIndex[i] := FUserWords.Items[i].Index;
|
|
end;
|
|
WordList.Cells[0, FUserWords.Count] := '';
|
|
WordList.UserWordIndex[FUserWords.Count] := -1;
|
|
FSelectedRow := 0;
|
|
WordList.Col := 0;
|
|
WordList.Row := 0;
|
|
|
|
CheckDuplicate(-1);
|
|
UpdateKeys;
|
|
cbKeyCase.Checked := FUserWords.KeyAddCase;
|
|
cbKeyBoundStart.Checked := FUserWords.KeyAddTermBounds in [soBoundsAtStart, soBothBounds];
|
|
cbKeyBoundEnd.Checked := FUserWords.KeyAddTermBounds in [soBoundsAtEnd, soBothBounds];
|
|
cbSmartSelectBound.Checked := FUserWords.KeyAddSelectSmart;
|
|
cbGlobalList.Checked := FUserWords.GlobalList;
|
|
edWordMin.Value := FUserWords.KeyAddWordBoundMaxLen;
|
|
edSelectMin.Value := FUserWords.KeyAddSelectBoundMaxLen;
|
|
cbSmartSelectBound.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
edWordMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
edSelectMin.Enabled := FUserWords.KeyAddTermBounds <> soNoBounds;
|
|
finally
|
|
dec(FUpdatingDisplay)
|
|
end;
|
|
WordListSelection(nil, 0, 0);
|
|
end;
|
|
|
|
constructor TEditorMarkupUserDefinedFrame.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FUserWordsList := TEditorUserDefinedWordsList.Create;
|
|
FUpdatingDisplay := 0;
|
|
end;
|
|
|
|
destructor TEditorMarkupUserDefinedFrame.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FreeAndNil(FUserWordsList);
|
|
end;
|
|
|
|
function TEditorMarkupUserDefinedFrame.GetTitle: String;
|
|
begin
|
|
Result := dlgMarkupUserDefined;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
|
|
begin
|
|
SynColorAttrEditor1.Setup;
|
|
SynColorAttrEditor1.ShowPrior := True;
|
|
divSelectGroup.Caption := dlgMarkupUserDefinedDivSelect;
|
|
divEditGroup.Caption := dlgMarkupUserDefinedDivEdit;
|
|
btnAdd.Caption := dlgMarkupUserDefinedListNew;
|
|
btnDelete.Caption := dlgMarkupUserDefinedListDel;
|
|
lbListName.Caption := dlgMarkupUserDefinedListName;
|
|
tabMain.Caption := dlgMarkupUserDefinedPageMain;
|
|
tabKeys.Caption := dlgMarkupUserDefinedPageKeys;
|
|
cbCaseSense.Caption := dlgMarkupUserDefinedMatchCase;
|
|
cbMatchStartBound.Caption := dlgMarkupUserDefinedMatchStartBound;
|
|
cbMatchEndBound.Caption := dlgMarkupUserDefinedMatchEndBound;
|
|
divKeyAdd.Caption := dlgMarkupUserDefinedDivKeyAdd;
|
|
divKeyRemove.Caption := dlgMarkupUserDefinedDivKeyRemove;
|
|
divKeyToggle.Caption := dlgMarkupUserDefinedDivKeyToggle;
|
|
|
|
lbNewKeyOptions.Caption := dlgMarkupUserDefinedNewByKeyOpts;
|
|
cbKeyCase.Caption := dlgMarkupUserDefinedMatchCase;
|
|
cbKeyBoundStart.Caption := dlgMarkupUserDefinedMatchStartBound;
|
|
cbKeyBoundEnd.Caption := dlgMarkupUserDefinedMatchEndBound;
|
|
lbKeyBoundMinLen.Caption := dlgMarkupUserDefinedNewByKeyLen;
|
|
lbWordMin.Caption := dlgMarkupUserDefinedNewByKeyLenWord;
|
|
lbSelectMin.Caption := dlgMarkupUserDefinedNewByKeyLenSelect;
|
|
cbSmartSelectBound.Caption := dlgMarkupUserDefinedNewByKeySmartSelect;
|
|
cbGlobalList.Caption := dlgMarkupUserDefinedGlobalList;
|
|
|
|
FKeyOptFrame := TEditorKeymappingOptionsFrame(ADialog.FindEditor(TEditorKeymappingOptionsFrame));
|
|
FUserWordsList.KeyCommandList := FKeyOptFrame.EditingKeyMap;
|
|
edListName.Text := '';
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.ReadSettings(AOptions: TAbstractIDEOptions);
|
|
begin
|
|
FGlobalColors := TEditorOptions(AOptions).UserDefinedColors;
|
|
FSelectedListIdx := 0;
|
|
|
|
FKeyOptFrame.ReadSettings(AOptions);
|
|
|
|
FUserWordsList.Assign(FGlobalColors);
|
|
FSelectedListIdx := 0;
|
|
UpdateListDropDownFull;
|
|
UpdateListDisplay;
|
|
cbGroup.Enabled := FUserWordsList.Count > 0;
|
|
FGlobalColors := nil;
|
|
UpdateKeys;
|
|
end;
|
|
|
|
procedure TEditorMarkupUserDefinedFrame.WriteSettings(AOptions: TAbstractIDEOptions);
|
|
begin
|
|
if FGlobalColors <> nil then
|
|
exit;
|
|
|
|
if FUserWords <> nil then
|
|
FUserWords.ClearSimilarMatches;
|
|
TEditorOptions(AOptions).UserDefinedColors.Assign(FUserWordsList);
|
|
end;
|
|
|
|
class function TEditorMarkupUserDefinedFrame.SupportedOptionsClass: TAbstractIDEOptionsClass;
|
|
begin
|
|
Result := TEditorOptions;
|
|
end;
|
|
|
|
initialization
|
|
RegisterIDEOptionsEditor(GroupEditor, TEditorMarkupUserDefinedFrame,
|
|
EdtOptionsUserDefined, EdtOptionsDisplay);
|
|
end.
|
|
|