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) cbCaseSense: TCheckBox; cbMatchEndBound: TCheckBox; cbMatchStartBound: TCheckBox; cbKeyCase: TCheckBox; cbKeyBoundStart: TCheckBox; cbKeyBoundEnd: TCheckBox; cbSmartSelectBound: TCheckBox; cbGlobalList: TCheckBox; divKeyAdd: TDividerBevel; divKeyRemove: TDividerBevel; divKeyToggle: TDividerBevel; edListName: TEdit; HCenter: 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; lbListName: TLabel; ListMenu: TPopupMenu; MainPanel: TPanel; Notebook1: TNotebook; PageMain: TPage; PageKeys: TPage; Panel1: TPanel; btnKeyAdd: TSpeedButton; btnKeyRemove: TSpeedButton; btnKeyToggle: TSpeedButton; edWordMin: TSpinEdit; edSelectMin: TSpinEdit; SynColorAttrEditor1: TSynColorAttrEditor; ToolBar1: TToolBar; tbSelectList: TToolButton; tbNewList: TToolButton; tbDeleteList: TToolButton; ToolButton2: TToolButton; tbMainPage: TToolButton; tbKeyPage: TToolButton; WordList: TColorStringGrid; procedure edListNameEditingDone(Sender: TObject); procedure edListNameKeyPress(Sender: TObject; var Key: char); procedure KeyEditClicked(Sender: TObject); procedure tbDeleteListClick(Sender: TObject); procedure tbNewListClick(Sender: TObject); procedure tbSelectListClick(Sender: TObject); procedure GeneralCheckBoxChange(Sender: TObject); procedure tbSelectPageClicked(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 DoListSelected(Sender: TObject); 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.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.tbDeleteListClick(Sender: TObject); begin if FUserWords = nil then exit; if WordList.EditorMode then WordList.EditingDone; if IDEMessageDialog(dlgMarkupUserDefinedDelCaption, Format(dlgMarkupUserDefinedDelPrompt, [FUserWords.Name]), mtConfirmation, mbYesNo) = mrNo 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.tbSelectListClick(Sender: TObject); begin tbSelectList.CheckMenuDropdown; 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.tbSelectPageClicked(Sender: TObject); begin if WordList.EditorMode then WordList.EditingDone; if tbMainPage.Down then Notebook1.PageIndex := 0 else Notebook1.PageIndex := 1; 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.DoListSelected(Sender: TObject); begin if WordList.EditorMode then WordList.EditingDone; FSelectedListIdx := TMenuItem(Sender).Tag; UpdateListDisplay; 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 m: TMenuItem; i: Integer; begin ListMenu.Items.Clear; if FUserWordsList.Count > 0 then begin for i := 0 to FUserWordsList.Count - 1 do begin m := TMenuItem.Create(ListMenu); m.Caption := FUserWordsList.Lists[i].Name; m.Tag := i; m.OnClick := @DoListSelected; ListMenu.Items.Add(m); end; end; UpdateListDropDownCaption; end; procedure TEditorMarkupUserDefinedFrame.UpdateListDropDownCaption; begin if FUserWordsList.Count = 0 then begin tbSelectList.Enabled := False; tbSelectList.Caption := dlgMarkupUserDefinedNoLists; end else begin tbSelectList.Enabled := True; if (FSelectedListIdx >= 0) and (FSelectedListIdx < FUserWordsList.Count) then tbSelectList.Caption := FUserWordsList.Lists[FSelectedListIdx].Name else tbSelectList.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; tbNewList.Caption := dlgMarkupUserDefinedListNew; tbDeleteList.Caption := dlgMarkupUserDefinedListDel; lbListName.Caption := dlgMarkupUserDefinedListName; tbMainPage.Caption := dlgMarkupUserDefinedPageMain; tbKeyPage.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; tbDeleteList.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.