{ *************************************************************************** * * * This source is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This code is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * A copy of the GNU General Public License is available on the World * * Wide Web at . You can also * * obtain it by writing to the Free Software Foundation, * * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. * * * *************************************************************************** } unit editor_general_options; {$mode objfpc}{$H+} interface uses Classes, SysUtils, math, // LCL LCLType, StdCtrls, Controls, Graphics, ImgList, // LazControls DividerBevel, // SynEdit SynEdit, SynHighlighterPas, SynPluginMultiCaret, SynEditTypes, // IdeIntf IDEOptionsIntf, IDEOptEditorIntf, IDEUtils, SrcEditorIntf, // IDE EditorOptions, LazarusIDEStrConsts, SourceMarks; type TPreviewEditor = TSynEdit; { TEditorGeneralOptionsFrame } TEditorGeneralOptionsFrame = class(TAbstractIDEOptionsEditor) CaretScrollGroupDivider: TDividerBevel; CaretMoveClearsSelectionCheckBox: TCheckBox; rbExtraHScrollNone: TRadioButton; rbExtraHScrollPage: TRadioButton; rbExtraHScrollFixed: TRadioButton; SelectAllNoScrollCheckBox: TCheckBox; PersistentCursorNoBlinkCheckBox: TCheckBox; chkMultiCaretColumnMode: TCheckBox; chkMultiCaretMode: TCheckBox; chkMultiCaretDelSkipCr: TCheckBox; MultiCaretGroupDivider: TDividerBevel; MultiCaretOnColumnSelection: TCheckBox; CursorSkipsTabCheckBox: TCheckBox; CaretGroupDivider: TDividerBevel; BlockGroupDivider: TDividerBevel; ScrollGroupDivider: TDividerBevel; UndoGroupDivider: TDividerBevel; EndKeyJumpsToNearestStartCheckBox: TCheckBox; KeepCursorXCheckBox: TCheckBox; CenterLabel:TLabel; OverwriteBlockCheckBox: TCheckBox; PersistentCursorCheckBox: TCheckBox; AlwaysVisibleCursorCheckBox: TCheckBox; CursorSkipsSelectionCheckBox: TCheckBox; HomeKeyJumpsToNearestStartCheckBox: TCheckBox; PersistentBlockCheckBox: TCheckBox; HalfPageScrollCheckBox: TCheckBox; ScrollPastEndFileCheckBox: TCheckBox; CaretPastEndLineCheckBox: TCheckBox; ScrollByOneLessCheckBox: TCheckBox; UndoAfterSaveCheckBox: TCheckBox; GroupUndoCheckBox: TCheckBox; UndoLimitComboBox: TComboBox; UndoLimitLabel: TLabel; chkScrollHint: TCheckBox; procedure AlwaysVisibleCursorCheckBoxChange(Sender: TObject); procedure CaretMoveClearsSelectionCheckBoxChange(Sender: TObject); procedure CursorSkipsSelectionCheckBoxChange(Sender: TObject); procedure CursorSkipsTabCheckBoxChange(Sender: TObject); procedure EndKeyJumpsToNearestStartCheckBoxChange(Sender: TObject); procedure GroupUndoCheckBoxChange(Sender: TObject); procedure HalfPageScrollCheckBoxChange(Sender: TObject); procedure HomeKeyJumpsToNearestStartCheckBoxChange(Sender: TObject); procedure KeepCursorXCheckBoxChange(Sender: TObject); procedure OverwriteBlockCheckBoxChange(Sender: TObject); procedure PersistentBlockCheckBoxChange(Sender: TObject); procedure PersistentCursorCheckBoxChange(Sender: TObject); procedure PersistentCursorNoBlinkCheckBoxChange(Sender: TObject); procedure ScrollByOneLessCheckBoxChange(Sender: TObject); procedure ScrollPastEndFileCheckBoxChange(Sender: TObject); procedure CaretPastEndLineCheckBoxChange(Sender: TObject); private FDialog: TAbstractOptionsEditorDialog; FPasExtendedKeywordsMode: Boolean; FPasStringKeywordMode: TSynPasStringMode; function DefaultBookmarkImages: TCustomImageList; procedure SetExtendedKeywordsMode(const AValue: Boolean); procedure SetStringKeywordMode(const AValue: TSynPasStringMode); protected procedure CreateHandle; override; public PreviewEdits: array of TPreviewEditor; procedure AddPreviewEdit(AEditor: TPreviewEditor); procedure SetPreviewOption(AValue: Boolean; AnOption: TSynEditorOption); overload; procedure SetPreviewOption(AValue: Boolean; AnOption: TSynEditorOption2); overload; procedure UpdatePrevieEdits; constructor Create(AOwner: TComponent); 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; // current previewmode property PasExtendedKeywordsMode: Boolean read FPasExtendedKeywordsMode write SetExtendedKeywordsMode default False; property PasStringKeywordMode: TSynPasStringMode read FPasStringKeywordMode write SetStringKeywordMode default spsmDefault; end; implementation {$R *.lfm} { TEditorGeneralOptionsFrame } function TEditorGeneralOptionsFrame.GetTitle: String; begin Result := lisGeneral; end; procedure TEditorGeneralOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDialog); begin FDialog := ADialog; // undo UndoGroupDivider.Caption := dlgUndoGroupOptions; UndoAfterSaveCheckBox.Caption := dlgUndoAfterSave; GroupUndoCheckBox.Caption := dlgGroupUndo; UndoLimitLabel.Caption := dlgUndoLimit; // scroll ScrollGroupDivider.Caption := dlgScrollGroupOptions; HalfPageScrollCheckBox.Caption := dlgHalfPageScroll; ScrollByOneLessCheckBox.Caption := dlgScrollByOneLess; ScrollPastEndFileCheckBox.Caption := dlgScrollPastEndFile; chkScrollHint.Caption := dlgScrollHint; // caret past eol CaretScrollGroupDivider.Caption := dlgCaretScrollGroupOptions; CaretPastEndLineCheckBox.Caption := dlgScrollPastEndLine; rbExtraHScrollNone.Caption := dlgScrollBarPastEOLNone; rbExtraHScrollPage.Caption := dlgScrollBarPastEOLPage; rbExtraHScrollFixed.Caption := dlgScrollBarPastEOLFixed; // caret + key navigation CaretGroupDivider.Caption := dlgCaretGroupOptions; KeepCursorXCheckBox.Caption := dlgKeepCursorX; PersistentCursorCheckBox.Caption := dlgPersistentCursor; PersistentCursorNoBlinkCheckBox.Caption := dlgPersistentCursorNoBlink; AlwaysVisibleCursorCheckBox.Caption := dlgAlwaysVisibleCursor; CursorSkipsSelectionCheckBox.Caption := dlgCursorSkipsSelection; CaretMoveClearsSelectionCheckBox.Caption := dlgCursorMoveClearsSelection; //dlgCursorMoveClearsSelection CursorSkipsTabCheckBox.Caption := dlgCursorSkipsTab; HomeKeyJumpsToNearestStartCheckBox.Caption := dlgHomeKeyJumpsToNearestStart; EndKeyJumpsToNearestStartCheckBox.Caption := dlgEndKeyJumpsToNearestStart; SelectAllNoScrollCheckBox.Caption := dlgSelectAllNoScroll; // multi caret MultiCaretGroupDivider.Caption := dlgMultiCaretGroupOptions; MultiCaretOnColumnSelection.Caption := dlgMultiCaretOnColumnSelection; chkMultiCaretColumnMode.Caption := dlgMultiCaretColumnMode; chkMultiCaretMode.Caption := dlgMultiCaretMode; chkMultiCaretDelSkipCr.Caption := dlgMultiCaretDelSkipCr; // Block BlockGroupDivider.Caption := dlgBlockGroupOptions; PersistentBlockCheckBox.Caption := dlgPersistentBlock; OverwriteBlockCheckBox.Caption := dlgOverwriteBlock; end; procedure TEditorGeneralOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions); var i: integer; begin with AOptions as TEditorOptions do begin // undo UndoAfterSaveCheckBox.Checked := UndoAfterSave; GroupUndoCheckBox.Checked := eoGroupUndo in SynEditOptions; SetComboBoxText(UndoLimitComboBox, IntToStr(UndoLimit), cstCaseInsensitive); // scroll HalfPageScrollCheckBox.Checked := eoHalfPageScroll in SynEditOptions; ScrollByOneLessCheckBox.Checked := eoScrollByOneLess in SynEditOptions; ScrollPastEndFileCheckBox.Checked := eoScrollPastEoF in SynEditOptions; chkScrollHint.Checked := eoShowScrollHint in SynEditOptions; // caret past eol CaretPastEndLineCheckBox.Checked := eoScrollPastEoL in SynEditOptions; rbExtraHScrollNone.Enabled := CaretPastEndLineCheckBox.Checked; rbExtraHScrollPage.Enabled := CaretPastEndLineCheckBox.Checked; rbExtraHScrollFixed.Enabled := CaretPastEndLineCheckBox.Checked; rbExtraHScrollNone.Checked := ScrollPastEolMode = optScrollNone; rbExtraHScrollPage.Checked := ScrollPastEolMode = optScrollPage; rbExtraHScrollFixed.Checked := ScrollPastEolMode = optScrollFixed; // cursor KeepCursorXCheckBox.Checked := eoKeepCaretX in SynEditOptions; PersistentCursorCheckBox.Checked := eoPersistentCaret in SynEditOptions; PersistentCursorNoBlinkCheckBox.Checked := eoPersistentCaretStopBlink in SynEditOptions2; AlwaysVisibleCursorCheckBox.Checked := eoAlwaysVisibleCaret in SynEditOptions2; CursorSkipsSelectionCheckBox.Checked := eoCaretSkipsSelection in SynEditOptions2; CaretMoveClearsSelectionCheckBox.Checked := eoCaretMoveEndsSelection in SynEditOptions2; CursorSkipsTabCheckBox.Checked := eoCaretSkipTab in SynEditOptions2; HomeKeyJumpsToNearestStartCheckBox.Checked := eoEnhanceHomeKey in SynEditOptions; EndKeyJumpsToNearestStartCheckBox.Checked := eoEnhanceEndKey in SynEditOptions2; MultiCaretOnColumnSelection.Checked := MultiCaretOnColumnSelect; chkMultiCaretColumnMode.Checked := MultiCaretDefaultColumnSelectMode = mcmMoveAllCarets; chkMultiCaretMode.Checked := MultiCaretDefaultMode = mcmMoveAllCarets; chkMultiCaretDelSkipCr.Checked := MultiCaretDeleteSkipLineBreak; SelectAllNoScrollCheckBox.Checked := eoNoScrollOnSelectRange in SynEditOptions2; // block PersistentBlockCheckBox.Checked := eoPersistentBlock in SynEditOptions2; OverwriteBlockCheckBox.Checked := eoOverwriteBlock in SynEditOptions2; for i := Low(PreviewEdits) to High(PreviewEdits) do if PreviewEdits[i] <> nil then GetSynEditPreviewSettings(PreviewEdits[i]); end; end; procedure TEditorGeneralOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions); procedure UpdateOptionFromBool(AValue: Boolean; AnOption: TSynEditorOption); overload; begin if AValue then TEditorOptions(AOptions).SynEditOptions := TEditorOptions(AOptions).SynEditOptions + [AnOption] else TEditorOptions(AOptions).SynEditOptions := TEditorOptions(AOptions).SynEditOptions - [AnOption]; end; procedure UpdateOptionFromBool(AValue: Boolean; AnOption: TSynEditorOption2); overload; begin if AValue then TEditorOptions(AOptions).SynEditOptions2 := TEditorOptions(AOptions).SynEditOptions2 + [AnOption] else TEditorOptions(AOptions).SynEditOptions2 := TEditorOptions(AOptions).SynEditOptions2 - [AnOption]; end; var i: integer; begin with AOptions as TEditorOptions do begin // undo UndoAfterSave := UndoAfterSaveCheckBox.Checked; UpdateOptionFromBool(GroupUndoCheckBox.Checked, eoGroupUndo); i := StrToIntDef(UndoLimitComboBox.Text, 32767); if i < 1 then i := 1; if i > 32767 then i := 32767; UndoLimit := i; // scroll UpdateOptionFromBool(HalfPageScrollCheckBox.Checked, eoHalfPageScroll); UpdateOptionFromBool(ScrollByOneLessCheckBox.Checked, eoScrollByOneLess); UpdateOptionFromBool(ScrollPastEndFileCheckBox.Checked, eoScrollPastEoF); UpdateOptionFromBool(chkScrollHint.Checked, eoShowScrollHint); // caret past eol UpdateOptionFromBool(CaretPastEndLineCheckBox.Checked, eoScrollPastEoL); if rbExtraHScrollNone.Checked then ScrollPastEolMode := optScrollNone; if rbExtraHScrollPage.Checked then ScrollPastEolMode := optScrollPage; if rbExtraHScrollFixed.Checked then ScrollPastEolMode := optScrollFixed; // cursor UpdateOptionFromBool(KeepCursorXCheckBox.Checked, eoKeepCaretX); UpdateOptionFromBool(PersistentCursorCheckBox.Checked, eoPersistentCaret); UpdateOptionFromBool(PersistentCursorNoBlinkCheckBox.Checked, eoPersistentCaretStopBlink); UpdateOptionFromBool(AlwaysVisibleCursorCheckBox.Checked, eoAlwaysVisibleCaret); UpdateOptionFromBool(CursorSkipsSelectionCheckBox.Checked, eoCaretSkipsSelection); UpdateOptionFromBool(CaretMoveClearsSelectionCheckBox.Checked, eoCaretMoveEndsSelection); UpdateOptionFromBool(CursorSkipsTabCheckBox.Checked, eoCaretSkipTab); UpdateOptionFromBool(HomeKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceHomeKey); UpdateOptionFromBool(EndKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceEndKey); MultiCaretOnColumnSelect := MultiCaretOnColumnSelection.Checked; if chkMultiCaretColumnMode.Checked then MultiCaretDefaultColumnSelectMode := mcmMoveAllCarets else MultiCaretDefaultColumnSelectMode := mcmCancelOnCaretMove; if chkMultiCaretMode.Checked then MultiCaretDefaultMode := mcmMoveAllCarets else MultiCaretDefaultMode := mcmCancelOnCaretMove; MultiCaretDeleteSkipLineBreak := chkMultiCaretDelSkipCr.Checked; UpdateOptionFromBool(SelectAllNoScrollCheckBox.Checked, eoNoScrollOnSelectRange); // block UpdateOptionFromBool(PersistentBlockCheckBox.Checked, eoPersistentBlock); UpdateOptionFromBool(OverwriteBlockCheckBox.Checked, eoOverwriteBlock); end; end; class function TEditorGeneralOptionsFrame.SupportedOptionsClass: TAbstractIDEOptionsClass; begin Result := TEditorOptions; end; procedure TEditorGeneralOptionsFrame.SetPreviewOption(AValue: Boolean; AnOption: TSynEditorOption); var a: Integer; begin for a := Low(PreviewEdits) to High(PreviewEdits) do begin if PreviewEdits[a] <> nil then if AValue then PreviewEdits[a].Options := PreviewEdits[a].Options + [AnOption] else PreviewEdits[a].Options := PreviewEdits[a].Options - [AnOption]; end; end; procedure TEditorGeneralOptionsFrame.SetPreviewOption(AValue: Boolean; AnOption: TSynEditorOption2); var a: Integer; begin for a := Low(PreviewEdits) to High(PreviewEdits) do begin if PreviewEdits[a] <> nil then if AValue then PreviewEdits[a].Options2 := PreviewEdits[a].Options2 + [AnOption] else PreviewEdits[a].Options2 := PreviewEdits[a].Options2 - [AnOption]; end; end; procedure TEditorGeneralOptionsFrame.UpdatePrevieEdits; var a: Integer; begin for a := Low(PreviewEdits) to High(PreviewEdits) do if PreviewEdits[a].Highlighter is TSynPasSyn then begin TSynPasSyn(PreviewEdits[a].Highlighter).ExtendedKeywordsMode := PasExtendedKeywordsMode; TSynPasSyn(PreviewEdits[a].Highlighter).StringKeywordMode := PasStringKeywordMode; end; end; procedure TEditorGeneralOptionsFrame.AlwaysVisibleCursorCheckBoxChange( Sender: TObject); begin SetPreviewOption(AlwaysVisibleCursorCheckBox.Checked, eoAlwaysVisibleCaret); end; procedure TEditorGeneralOptionsFrame.CaretMoveClearsSelectionCheckBoxChange( Sender: TObject); begin SetPreviewOption(CaretMoveClearsSelectionCheckBox.Checked, eoCaretMoveEndsSelection); end; procedure TEditorGeneralOptionsFrame.CursorSkipsSelectionCheckBoxChange( Sender: TObject); begin SetPreviewOption(CursorSkipsSelectionCheckBox.Checked, eoCaretSkipsSelection); end; procedure TEditorGeneralOptionsFrame.CursorSkipsTabCheckBoxChange(Sender: TObject); begin SetPreviewOption(CursorSkipsTabCheckBox.Checked, eoCaretSkipTab); end; procedure TEditorGeneralOptionsFrame.EndKeyJumpsToNearestStartCheckBoxChange( Sender: TObject); begin SetPreviewOption(EndKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceEndKey); end; procedure TEditorGeneralOptionsFrame.GroupUndoCheckBoxChange(Sender: TObject); begin SetPreviewOption(GroupUndoCheckBox.Checked, eoGroupUndo); end; procedure TEditorGeneralOptionsFrame.HalfPageScrollCheckBoxChange( Sender: TObject); begin SetPreviewOption(HalfPageScrollCheckBox.Checked, eoHalfPageScroll); end; procedure TEditorGeneralOptionsFrame.HomeKeyJumpsToNearestStartCheckBoxChange( Sender: TObject); begin SetPreviewOption(HomeKeyJumpsToNearestStartCheckBox.Checked, eoEnhanceHomeKey); end; procedure TEditorGeneralOptionsFrame.KeepCursorXCheckBoxChange(Sender: TObject); begin SetPreviewOption(KeepCursorXCheckBox.Checked, eoKeepCaretX); end; procedure TEditorGeneralOptionsFrame.OverwriteBlockCheckBoxChange(Sender: TObject); begin SetPreviewOption(KeepCursorXCheckBox.Checked, eoOverwriteBlock); end; procedure TEditorGeneralOptionsFrame.PersistentBlockCheckBoxChange(Sender: TObject); begin SetPreviewOption(PersistentBlockCheckBox.Checked, eoPersistentBlock); end; procedure TEditorGeneralOptionsFrame.PersistentCursorCheckBoxChange( Sender: TObject); begin SetPreviewOption(PersistentCursorCheckBox.Checked, eoPersistentCaret); end; procedure TEditorGeneralOptionsFrame.PersistentCursorNoBlinkCheckBoxChange( Sender: TObject); begin SetPreviewOption(PersistentCursorNoBlinkCheckBox.Checked, eoPersistentCaretStopBlink); end; procedure TEditorGeneralOptionsFrame.ScrollByOneLessCheckBoxChange( Sender: TObject); begin SetPreviewOption(ScrollByOneLessCheckBox.Checked, eoScrollByOneLess); end; procedure TEditorGeneralOptionsFrame.ScrollPastEndFileCheckBoxChange( Sender: TObject); begin SetPreviewOption(ScrollPastEndFileCheckBox.Checked, eoScrollPastEoF); end; procedure TEditorGeneralOptionsFrame.CaretPastEndLineCheckBoxChange( Sender: TObject); begin SetPreviewOption(CaretPastEndLineCheckBox.Checked, eoScrollPastEolAutoCaret); SetPreviewOption(CaretPastEndLineCheckBox.Checked and rbExtraHScrollPage.Checked, eoScrollPastEolAddPage); SetPreviewOption(CaretPastEndLineCheckBox.Checked and rbExtraHScrollFixed.Checked, eoScrollPastEoL); rbExtraHScrollNone.Enabled := CaretPastEndLineCheckBox.Checked; rbExtraHScrollPage.Enabled := CaretPastEndLineCheckBox.Checked; rbExtraHScrollFixed.Enabled := CaretPastEndLineCheckBox.Checked; end; function TEditorGeneralOptionsFrame.DefaultBookmarkImages: TCustomImageList; begin Result := SourceEditorMarks.ImgList; end; procedure TEditorGeneralOptionsFrame.SetExtendedKeywordsMode(const AValue: Boolean); begin if FPasExtendedKeywordsMode = AValue then exit; FPasExtendedKeywordsMode := AValue; UpdatePrevieEdits; end; procedure TEditorGeneralOptionsFrame.SetStringKeywordMode(const AValue: TSynPasStringMode); begin if FPasStringKeywordMode = AValue then exit; FPasStringKeywordMode := AValue; UpdatePrevieEdits; end; procedure TEditorGeneralOptionsFrame.CreateHandle; var i, w: Integer; c: TControl; begin inherited; w := 150; for i := 0 to ControlCount - 1 do begin c := Controls[i]; if not (c is TCheckBox) then Continue; w := Max(w, Canvas.TextExtent(c.Caption).cx); end; Constraints.MinWidth := 2 * w + 60; end; procedure TEditorGeneralOptionsFrame.AddPreviewEdit(AEditor: TPreviewEditor); begin SetLength(PreviewEdits, Length(PreviewEdits) + 1); PreviewEdits[Length(PreviewEdits)-1] := AEditor; if AEditor.BookMarkOptions.BookmarkImages = nil then AEditor.BookMarkOptions.BookmarkImages := DefaultBookmarkImages; end; constructor TEditorGeneralOptionsFrame.Create(AOwner: TComponent); begin inherited Create(AOwner); PreviewEdits := nil; if EditorOpts <> nil then begin FPasExtendedKeywordsMode := EditorOpts.PasExtendedKeywordsMode; FPasStringKeywordMode := EditorOpts.PasStringKeywordMode; end; end; initialization RegisterIDEOptionsEditor(GroupEditor, TEditorGeneralOptionsFrame, EdtOptionsGeneral); end.