diff --git a/.gitattributes b/.gitattributes index 6673896728..2c078419d8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -74,6 +74,7 @@ ide/idecomp.pp svneol=native#text/pascal ide/include/freebsd/lazconf.inc svneol=native#text/pascal ide/include/linux/lazconf.inc svneol=native#text/pascal ide/include/win32/lazconf.inc svneol=native#text/pascal +ide/keymapping.pp svneol=native#text/pascal ide/lazarus.pp svneol=native#text/pascal ide/lazconf.pp svneol=native#text/pascal ide/lazres.pp svneol=native#text/pascal diff --git a/ide/editoroptions.pp b/ide/editoroptions.pp index 682d8f7e79..e76c48d53e 100644 --- a/ide/editoroptions.pp +++ b/ide/editoroptions.pp @@ -15,6 +15,7 @@ unit editoroptions; - Resizing - SetSynEditSettings - nicer TColorButton + - create LFM file } {$mode objfpc} @@ -33,7 +34,7 @@ uses {$else} mwcustomedit, mwPasSyn, mwHighlighter, {$endif} - XMLCfg, CodeTemplateDialog; + XMLCfg, CodeTemplateDialog, KeyMapping; const AdditionalHiglightAttributes : array[0..4] of string = ( @@ -79,11 +80,14 @@ type fGutterColor:TColor; fGutterWidth:integer; fRightMargin:integer; + fRightMarginColor:TColor; fEditorFont:Ansistring; fEditorFontHeight:integer; fExtraLineSpacing:integer; // Key Mappings options + fKeyMappingScheme:AnsiString; + fKeyMap:TKeyCommandRelationList; // Color options fColorScheme:Ansistring; @@ -119,9 +123,11 @@ type published // general options - property SynEditOptions:TSynEditorOptions read fSynEditOptions write fSynEditOptions - default SYNEDIT_DEFAULT_OPTIONS; - property UndoAfterSave:boolean read fUndoAfterSave write fUndoAfterSave default true; + property SynEditOptions:TSynEditorOptions + read fSynEditOptions write fSynEditOptions + default SYNEDIT_DEFAULT_OPTIONS; + property UndoAfterSave:boolean + read fUndoAfterSave write fUndoAfterSave default true; property DoubleClickLine:boolean read fDoubleClickLine write fDoubleClickLine default false; property FindTextAtCursor:boolean @@ -133,23 +139,30 @@ type property BlockIndent:integer read fBlockIndent write fBlockIndent default 2; property UndoLimit:integer read fUndoLimit write fUndoLimit default 32767; property TabWidths:integer read fTabWidths write fTabWidths default 8; - property SyntaxExtensions:Ansistring read fSyntaxExtensions write fSyntaxExtensions; + property SyntaxExtensions:Ansistring + read fSyntaxExtensions write fSyntaxExtensions; // Display options property VisibleRightMargin:boolean read fVisibleRightMargin write fVisibleRightMargin default true; - property VisibleGutter:boolean read fVisibleGutter write fVisibleGutter default true; + property VisibleGutter:boolean + read fVisibleGutter write fVisibleGutter default true; property ShowLineNumbers:boolean read fShowLineNumbers write fShowLineNumbers default false; property GutterColor:TColor read fGutterColor write fGutterColor default clBtnFace; property GutterWidth:integer read fGutterWidth write fGutterWidth default 30; property RightMargin:integer read fRightMargin write fRightMargin default 80; + property RightMarginColor:integer + read fRightMarginColor write fRightMarginColor default clBtnFace; property EditorFont:Ansistring read fEditorFont write fEditorFont; property EditorFontHeight:integer read fEditorFontHeight write FEditorFontHeight; property ExtraLineSpacing:integer read fExtraLineSpacing write fExtraLineSpacing default 0; // Key Mappings + property KeyMappingScheme:Ansistring + read fKeyMappingScheme write fKeyMappingScheme; + property KeyMap:TKeyCommandRelationList read fKeyMap; // Color options property ColorScheme:Ansistring read fColorScheme write fColorScheme; @@ -242,6 +255,8 @@ type GutterWidthLabel:TLabel; RightMarginComboBox:TComboBox; RightMarginLabel:TLabel; + RightMarginColorButton:TColorButton; + RightMarginColorLabel:TLabel; EditorFontGroupBox:TGroupBox; EditorFontComboBox:TComboBox; EditorFontButton:TButton; @@ -252,7 +267,11 @@ type ExtraLineSpacingComboBox:TComboBox; DisplayPreview:TPreviewEditor; - // Key Mappings options + // Key Mappings + KeyMappingSchemeLabel:TLabel; + KeyMappingSchemeComboBox:TComboBox; + KeyMappingHelpLabel:TLabel; + KeyMappingListBox:TListBox; // Color options ColorSchemeComboBox:TComboBox; @@ -308,6 +327,10 @@ type // display procedure EditorFontButtonClick(Sender:TObject); + // key mapping + procedure KeyMappingListBoxMouseUp(Sender:TObject; + Button:TMouseButton; Shift:TShiftState; X,Y:integer); + // color procedure ColorElementListBoxMouseUp(Sender:TObject; Button:TMouseButton; Shift:TShiftState; X,Y:integer); @@ -339,6 +362,8 @@ type procedure SetupCodeInsightPage; procedure SetComboBoxText(AComboBox:TComboBox;AText:AnsiString); procedure FillCodeTemplateListBox; + function KeyMappingRelationToString(Index:integer):AnsiString; + procedure FillKeyMappingListBox; procedure ShowCurAttribute; procedure FindCurHighlightElement; @@ -420,13 +445,15 @@ begin // set defaults - // general options + // General options fSyntaxExtensions:='pp;inc;lfm;lrs;pas;dpr;dfm;dpk'; // Display options fEditorFont:='courier'; - // Key Mappings options + // Key Mappings + fKeyMappingScheme:='default'; + fKeyMap:=TKeyCommandRelationList.Create; // Color options fColorScheme:='Default'; @@ -525,6 +552,9 @@ begin XMLConfig.GetValue('EditorOptions/Display/GutterWidth',30); fRightMargin:= XMLConfig.GetValue('EditorOptions/Display/RightMargin',80); + fRightMarginColor:= + XMLConfig.GetValue('EditorOptions/Display/VisibleRightMarginColor' + ,clBtnFace); fEditorFont:= XMLConfig.GetValue('EditorOptions/Display/EditorFont','courier'); fEditorFontHeight:= @@ -533,6 +563,10 @@ begin XMLConfig.GetValue('EditorOptions/Display/ExtraLineSpacing',1); // Key Mappings options + fKeyMappingScheme:= + XMLConfig.GetValue('EditorOptions/KeyMapping/Scheme',fKeyMappingScheme); + fKeyMap.LoadFromXMLConfig(XMLConfig + ,'EditorOptions/KeyMapping/'+fKeyMappingScheme+'/'); // Color options fColorScheme:= @@ -618,6 +652,7 @@ begin XMLConfig.GetValue('EditorOptions/Display/GutterColor',fGutterColor); XMLConfig.SetValue('EditorOptions/Display/GutterWidth',fGutterWidth); XMLConfig.SetValue('EditorOptions/Display/RightMargin',fRightMargin); + XMLConfig.SetValue('EditorOptions/Display/RightMarginColor',fRightMarginColor); XMLConfig.SetValue('EditorOptions/Display/EditorFont',fEditorFont); XMLConfig.GetValue('EditorOptions/Display/EditorFontHeight' ,fEditorFontHeight); @@ -625,6 +660,9 @@ begin ,fExtraLineSpacing); // Key Mappings options + XMLConfig.SetValue('EditorOptions/KeyMapping/Scheme',fKeyMappingScheme); + fKeyMap.SaveToXMLConfig( + XMLConfig,'EditorOptions/KeyMapping/'+fKeyMappingScheme+'/'); // Color options XMLConfig.SetValue('EditorOptions/Color/ColorScheme',fColorScheme); @@ -769,7 +807,7 @@ procedure TEditorOptions.GetSynEditSettings(ASynEdit:TSynEdit); begin // general options ASynEdit.Options:=fSynEditOptions; - ASynEdit.TabWidth:=fTabWidths; + ASynEdit.TabWidth:=fBlockIndent; // Display options ASynEdit.Gutter.Visible:=fVisibleGutter; @@ -777,9 +815,14 @@ begin ASynEdit.Gutter.Color:=fGutterColor; ASynEdit.Gutter.Width:=fGutterWidth; ASynEdit.RightEdge:=fRightMargin; + ASynEdit.RightEdgeColor:=fRightMarginColor; ASynEdit.Font.Name:=fEditorFont; ASynEdit.Font.Height:=fEditorFontHeight; ASynEdit.ExtraLineSpacing:=fExtraLineSpacing; + ASynEdit.MaxUndo:=fUndoLimit; + ASynEdit.SelectedColor.ForeGround:=fTextBlockElement.ForeGround; + ASynEdit.SelectedColor.BackGround:=fTextBlockElement.BackGround; + KeyMap.AssignTo(ASynEdit.KeyStrokes); end; procedure TEditorOptions.SetSynEditSettings(ASynEdit:TSynEdit); @@ -798,6 +841,11 @@ begin fEditorFont:=ASynEdit.Font.Name; fEditorFontHeight:=ASynEdit.Font.Height; fExtraLineSpacing:=ASynEdit.ExtraLineSpacing; + fUndoLimit:=ASynEdit.MaxUndo; + fTextBlockElement.ForeGround:=ASynEdit.SelectedColor.ForeGround; + fTextBlockElement.BackGround:=ASynEdit.SelectedColor.BackGround; + + // XXX: KeyMap // XXX: update all checkboxes, comboboxes... end; @@ -898,7 +946,6 @@ begin SetupButtonBar; end; - for a:=Low(PreviewEdits) to High(PreviewEdits) do PreviewEdits[a]:=nil; EditorOpts.GetHighlighterSettings(PreviewPasSyn); @@ -929,15 +976,25 @@ begin EditorOpts.GetSynEditSettings(PreviewEdits[a]); if EditorOpts.UseSyntaxHighlight then Highlighter:=PreviewPasSyn; + EditorOpts.KeyMap.AssignTo(PreviewEdits[a].KeyStrokes); end; end; CodeTemplateCodePreview.Gutter.Visible:=false; + // general options + // display options + // key mappings + // color options + // code insight options + FindCurHighlightElement; FillCodeTemplateListBox; + FillKeyMappingListBox; // with CodeTemplateListBox do // if Items.Count>0 then Selected[0]:=true; // ShowCurCodeTemplate; +writeln('************************* 7'); + end; // general @@ -1091,6 +1148,18 @@ begin end; end; end; + if Sender=RightMarginColorButton then begin + for a:=Low(PreviewEdits) to High(PreviewEdits) do begin + if PreviewEdits[a]<>nil then begin + {$IFDEF NEW_EDITOR_SYNEDIT} + PreviewEdits[a].RightEdgeColor:=RightMarginColorButton.ButtonColor; + PreviewEdits[a].Invalidate; + {$ELSE} + + {$ENDIF} + end; + end; + end; end; procedure TEditorOptionsForm.FontDialogNameToFont(FontDialogName:string;AFont:TFont); @@ -1282,6 +1351,28 @@ begin end; end; +procedure TEditorOptionsForm.KeyMappingListBoxMouseUp(Sender:TObject; + Button:TMouseButton; Shift:TShiftState; X,Y:integer); +var a:integer; +begin + if Button=mbRight then begin + a:=KeyMappingListBox.Items.Count-1; + while (a>=0) and (KeyMappingListBox.Selected[a]=false) do + dec(a); + if a>=0 then begin + if ShowKeyMappingEditForm(a,EditorOpts.KeyMap)=mrOk then begin + // There is a bug in ListBox + //KeyMappingListBox.Items[a]:=KeyMappingRelationToString(a); + // workaround: + FillKeyMappingListBox; + for a:=Low(PreviewEdits) to High(PreviewEdits) do + if PreviewEdits[a]<>nil then + EditorOpts.KeyMap.AssignTo(PreviewEdits[a].KeyStrokes); + end; + end; + end; +end; + procedure TEditorOptionsForm.ColorElementListBoxMouseUp(Sender:TObject; Button:TMouseButton; Shift:TShiftState; X,Y:integer); begin @@ -1347,6 +1438,37 @@ begin end; end; +function TEditorOptionsForm.KeyMappingRelationToString( + Index:integer):AnsiString; +var s:AnsiString; +begin + with EditorOpts.KeyMap.Relations[Index] do begin + Result:=copy(Name,1,37); + SetLength(s,(37-length(Result))*2); + FillChar(s[1],length(s),'.'); + Result:=Result+s; + if (Key1=VK_UNKNOWN) and (Key2=VK_UNKNOWN) then + Result:=Result+'none' + else if (Key2=VK_UNKNOWN) then + Result:=Result+KeyAndShiftStateToStr(Key1,Shift1) + else + Result:=Result+KeyAndShiftStateToStr(Key1,Shift1)+' or '+ + KeyAndShiftStateToStr(Key2,Shift2); + end; +end; + +procedure TEditorOptionsForm.FillKeyMappingListBox; +var a:integer; +begin + with KeyMappingListBox.Items do begin + BeginUpdate; + Clear; + for a:=0 to EditorOpts.KeyMap.Count-1 do + Add(KeyMappingRelationToString(a)); + EndUpdate; + end; +end; + procedure TEditorOptionsForm.ShowCurCodeTemplate; var i,sp,ep:integer; s:ansistring; @@ -1698,7 +1820,6 @@ begin Caption:='Undo after save'; Checked:=EditorOpts.UndoAfterSave; OnClick:=@GeneralCheckBoxOnClick; - Enabled:=false; Show; end; @@ -1713,7 +1834,6 @@ begin Caption:='Double click line'; Checked:=EditorOpts.DoubleClickLine; OnClick:=@GeneralCheckBoxOnClick; - Enabled:=false; Show; end; @@ -1728,7 +1848,6 @@ begin Caption:='Find text at cursor'; Checked:=EditorOpts.FindTextAtCursor; OnClick:=@GeneralCheckBoxOnClick; - Enabled:=false; Show; end; @@ -1757,7 +1876,6 @@ begin Caption:='Create backup files'; Checked:=EditorOpts.CreateBackupFiles; OnClick:=@GeneralCheckBoxOnClick; - Enabled:=false; Show; end; @@ -1807,7 +1925,6 @@ begin Items.Add('512'); Items.EndUpdate; SetComboBoxText(UndoLimitComboBox,IntToStr(EditorOpts.UndoLimit)); - Enabled:=false; OnChange:=@ComboBoxOnChange; OnKeyDown:=@ComboBoxOnKeyDown; OnExit:=@ComboBoxOnExit; @@ -1902,7 +2019,7 @@ begin Top:=5; Left:=5; Width:=MaxX-10; - Height:=105; + Height:=109; Caption:='Margin and gutter'; Show; end; @@ -1954,7 +2071,7 @@ begin Name:='RightMarginComboBox'; Parent:=MarginAndGutterGroupBox; Top:=20; - Left:=150; + Left:=180; Width:=70; Items.BeginUpdate; Items.Add('80'); @@ -1980,12 +2097,37 @@ begin Show; end; + RightMarginColorButton:=TColorButton.Create(Self); + with RightMarginColorButton do begin + Name:='RightMarginColorButton'; + Parent:=MarginAndGutterGroupBox; + Top:=RightMarginComboBox.Top+RightMarginComboBox.Height+20; + Left:=RightMarginComboBox.Left; + Width:=35; + Height:=20; + BorderWidth:=2; + ButtonColor:=EditorOpts.RightMarginColor; + OnColorChanged:=@ColorButtonColorChanged; + Show; + end; + + RightMarginColorLabel:=TLabel.Create(Self); + with RightMarginColorLabel do begin + Name:='RightMarginColorLabel'; + Parent:=MarginAndGutterGroupBox; + Top:=RightMarginComboBox.Top+RightMarginComboBox.Height; + Left:=RightMarginComboBox.Left+2; + Width:=120; + Caption:='Right margin color'; + Show; + end; + GutterWidthComboBox:=TComboBox.Create(Self); with GutterWidthComboBox do begin Name:='GutterWidthComboBox'; Parent:=MarginAndGutterGroupBox; Top:=RightMarginComboBox.Top; - Left:=RightMarginComboBox.Left+RightMarginComboBox.Width+50; + Left:=RightMarginComboBox.Left+RightMarginComboBox.Width+80; Width:=RightMarginComboBox.Width; Height:=RightMarginComboBox.Height; Items.BeginUpdate; @@ -2172,8 +2314,59 @@ begin end; procedure TEditorOptionsForm.SetupKeyMappingsPage; +var MaxX,MaxY:integer; begin + MaxX:=Width-9; + MaxY:=374; + KeyMappingSchemeComboBox:=TComboBox.Create(Self); + with KeyMappingSchemeComboBox do begin + Name:='KeyMappingSchemeComboBox'; + Parent:=MainNoteBook.Page[2]; + Top:=5; + Left:=170; + Width:=100; + Height:=16; + Text:=EditorOpts.KeyMappingScheme; + Enabled:=false; + Show; + end; + + KeyMappingSchemeLabel:=TLabel.Create(Self); + with KeyMappingSchemeLabel do begin + Name:='KeyMappingSchemeLabel'; + Parent:=MainNoteBook.Page[2]; + Top:=5; + Left:=5; + Width:=KeyMappingSchemeComboBox.Left-Left; + Height:=16; + Caption:='Key Mapping Scheme'; + Show; + end; + + KeyMappingHelpLabel:=TLabel.Create(Self); + with KeyMappingHelpLabel do begin + Name:='KeyMappingHelpLabel'; + Parent:=MainNoteBook.Page[2]; + Top:=KeyMappingSchemeComboBox.Top+KeepCaretXCheckBox.Height+10; + Left:=5; + Width:=MaxX-Left-Left; + Height:=16; + Caption:='Hint: right click on the command you want to edit'; + Show; + end; + + KeyMappingListBox:=TListBox.Create(Self); + with KeyMappingListBox do begin + Name:='KeyMappingListBox'; + Parent:=MainNoteBook.Page[2]; + Top:=KeyMappingHelpLabel.Top+KeyMappingHelpLabel.Height+2; + Left:=0; + Width:=MaxX-Left-Left; + Height:=MaxY-Top; + OnMouseUp:=@KeyMappingListBoxMouseUp; + Show; + end; end; procedure TEditorOptionsForm.SetupColorPage; @@ -2417,10 +2610,9 @@ begin Parent:=AutomaticFeaturesGroupBox; Top:=5; Left:=5; - Width:=170; + Width:=200; Caption:='Code completion'; Checked:=EditorOpts.AutoCodeCompletion; - Enabled:=false; Show; end; @@ -2434,7 +2626,6 @@ begin Height:=AutoCodeCompletionCheckBox.Height; Caption:='Code parameters'; Checked:=EditorOpts.AutoCodeParameters; - Enabled:=false; Show; end; @@ -2448,7 +2639,6 @@ begin Height:=AutoCodeCompletionCheckBox.Height; Caption:='Tooltip expression evaluation'; Checked:=EditorOpts.AutoToolTipExprEval; - Enabled:=false; Show; end; @@ -2462,7 +2652,6 @@ begin Height:=AutoCodeCompletionCheckBox.Height; Caption:='Tooltip symbol insight'; Checked:=EditorOpts.AutoToolTipSymbInsight; - Enabled:=false; Show; end; diff --git a/ide/formeditor.pp b/ide/formeditor.pp index a8419f4f4e..d586c79794 100644 --- a/ide/formeditor.pp +++ b/ide/formeditor.pp @@ -39,6 +39,9 @@ type end; +var + FormEditor1 : TFormEditor; + implementation diff --git a/ide/keymapping.pp b/ide/keymapping.pp new file mode 100644 index 0000000000..36723e9d6a --- /dev/null +++ b/ide/keymapping.pp @@ -0,0 +1,737 @@ +unit keymapping; +{ + Author: Mattias Gaertner + + Abstract: + Contains classes to store key-command relationships, can update + TSynEditKeyStrokes and provides a dialog for editing a single + commandkey. + + ToDo: +} + +{$mode objfpc} + +interface + +uses + LCLLinux, + Forms, Classes, SysUtils, Buttons, LResources, StdCtrls, Controls, + SynEdit, SynEditKeyCmds, XMLCfg; + +const + // editor commands constants. see syneditkeycmds.pp for more + ecFind = ecUserFirst+1; + ecFindAgain = ecUserFirst+2; + ecReplace = ecUserFirst+3; + ecFindProcedureDefinition = ecUserFirst+4; + ecFindProcedureMethod = ecUserFirst+5; + ecGotoLineNumber = ecUserFirst+6; + + ecNextEditor = ecUserFirst+7; + ecPrevEditor = ecUserFirst+8; + + ecFirstParent = ecUserFirst+1000; + ecSave = ecFirstParent+1; + ecOpen = ecFirstParent+2; + ecClose = ecFirstParent+3; + + ecJumpToEditor = ecFirstParent+4; + + ecGotoEditor0 = ecUserFirst + 2000; + ecGotoEditor1 = ecGotoEditor0 + 1; + ecGotoEditor2 = ecGotoEditor1 + 1; + ecGotoEditor3 = ecGotoEditor2 + 1; + ecGotoEditor4 = ecGotoEditor3 + 1; + ecGotoEditor5 = ecGotoEditor4 + 1; + ecGotoEditor6 = ecGotoEditor5 + 1; + ecGotoEditor7 = ecGotoEditor6 + 1; + ecGotoEditor8 = ecGotoEditor7 + 1; + ecGotoEditor9 = ecGotoEditor8 + 1; + + +type + //--------------------------------------------------------------------------- + // class for storing the keys for a single command (key-command relationship) + TKeyCommandRelation = class + private + public + Name:ShortString; + Command:TSynEditorCommand; // see the ecXXX constants above + Key1:word; + Shift1:TShiftState; + Key2:word; + Shift2:TShiftState; + constructor Create(AName:ShortString;ACommand:TSynEditorCommand; + AKey1:Word;AShift1:TShiftState;AKey2:Word;AShift2:TShiftState); + end; + + //--------------------------------------------------------------------------- + // class for a list of key - command relations + TKeyCommandRelationList = class + private + FRelations:TList; + function GetRelation(Index:integer):TKeyCommandRelation; + function Add(Name:shortstring;Command:TSynEditorCommand; + Key1:Word; Shift1:TShiftState; + Key2:Word; Shift2:TShiftState):integer; + function ShiftStateToStr(Shift:TShiftState):AnsiString; + public + property Relations[Index:integer]:TKeyCommandRelation read GetRelation; + function Count:integer; + function Find(AKey:Word; AShiftState:TShiftState):TKeyCommandRelation; + function LoadFromXMLConfig(XMLConfig:TXMLConfig; Prefix:AnsiString):boolean; + function SaveToXMLConfig(XMLConfig:TXMLConfig; Prefix:AnsiString):boolean; + procedure AssignTo(ASynEditKeyStrokes:TSynEditKeyStrokes); + constructor Create; + destructor Destroy; override; + end; + + //--------------------------------------------------------------------------- + // form for editing one command - key relationship + TKeyMappingEditForm = class(TForm) + OkButton:TButton; + CancelButton:TButton; + CommandLabel:TLabel; + Key1GroupBox:TGroupBox; + Key1CtrlCheckBox:TCheckBox; + Key1AltCheckBox:TCheckBox; + Key1ShiftCheckBox:TCheckBox; + Key1KeyComboBox:TComboBox; + Key2GroupBox:TGroupBox; + Key2CtrlCheckBox:TCheckBox; + Key2AltCheckBox:TCheckBox; + Key2ShiftCheckBox:TCheckBox; + Key2KeyComboBox:TComboBox; + procedure OkButtonClick(Sender:TObject); + procedure CancelButtonClick(Sender:TObject); + public + constructor Create(AOwner:TComponent); override; + KeyCommandRelationList:TKeyCommandRelationList; + KeyIndex:integer; + end; + +function KeyAndShiftStateToStr(Key:Word; ShiftState:TShiftState):AnsiString; +function ShowKeyMappingEditForm(Index:integer; + AKeyCommandRelationList:TKeyCommandRelationList):TModalResult; + +var KeyMappingEditForm:TKeyMappingEditForm; + + +implementation + + +function ShowKeyMappingEditForm(Index:integer; + AKeyCommandRelationList:TKeyCommandRelationList):TModalResult; +begin + Result:=mrCancel; + if KeyMappingEditForm<>nil then exit; + KeyMappingEditForm:=TKeyMappingEditForm.Create(Application); + with KeyMappingEditForm do + try + KeyCommandRelationList:=AKeyCommandRelationList; + KeyIndex:=Index; + Caption:='Edit Keys'; + with KeyCommandRelationList.Relations[Index] do begin + CommandLabel.Caption:='Command: '+Name; + if Key1<>VK_UNKNOWN then begin + Key1CtrlCheckBox.Checked:=ssCtrl in Shift1; + Key1AltCheckBox.Checked:=ssAlt in Shift1; + Key1ShiftCheckBox.Checked:=ssShift in Shift1; + Key1KeyComboBox.ItemIndex:=Key1KeyComboBox.Items.IndexOf( + KeyAndShiftStateToStr(Key1,[])); + end; + if Key2<>VK_UNKNOWN then begin + Key2CtrlCheckBox.Checked:=ssCtrl in Shift2; + Key2AltCheckBox.Checked:=ssAlt in Shift2; + Key2ShiftCheckBox.Checked:=ssShift in Shift2; + Key2KeyComboBox.ItemIndex:=Key1KeyComboBox.Items.IndexOf( + KeyAndShiftStateToStr(Key2,[])); + end; + end; + Result:=ShowModal; + finally + Free; + KeyMappingEditForm:=nil; + end; +end; + +function KeyAndShiftStateToStr(Key:Word; ShiftState:TShiftState):AnsiString; +begin + Result:=''; + if ssCtrl in ShiftState then Result:=Result+'+Ctrl'; + if ssAlt in ShiftState then Result:=Result+'+Alt'; + if ssShift in ShiftState then Result:=Result+'+Shift'; + if Result<>'' then + Result:=copy(Result,2,length(Result)-1)+'+'; + case Key of + VK_UNKNOWN :Result:=Result+'Unknown'; + VK_LBUTTON :Result:=Result+'Mouse Button Left'; + VK_RBUTTON :Result:=Result+'Mouse Button Right'; + VK_CANCEL :Result:=Result+'Cancel'; + VK_MBUTTON :Result:=Result+'Mouse Button Middle'; + VK_BACK :Result:=Result+'Backspace'; + VK_TAB :Result:=Result+'Tab'; + VK_CLEAR :Result:=Result+'Clear'; + VK_RETURN :Result:=Result+'Return'; + VK_SHIFT :Result:=Result+'Shift'; + VK_CONTROL :Result:=Result+'Control'; + VK_MENU :Result:=Result+'Menu'; + VK_PAUSE :Result:=Result+'Pause'; + VK_CAPITAL :Result:=Result+'Capital'; + VK_KANA :Result:=Result+'Kana'; +// VK_HANGUL :Result:=Result+'Hangul'; + VK_JUNJA :Result:=Result+'Junja'; + VK_FINAL :Result:=Result+'Final'; + VK_HANJA :Result:=Result+'Hanja'; +// VK_KANJI :Result:=Result+'Kanji'; + VK_ESCAPE :Result:=Result+'Escape'; + VK_CONVERT :Result:=Result+'Convert'; + VK_NONCONVERT :Result:=Result+'Nonconvert'; + VK_ACCEPT :Result:=Result+'Accept'; + VK_MODECHANGE :Result:=Result+'Mode Change'; + VK_SPACE :Result:=Result+'Space'; + VK_PRIOR :Result:=Result+'Prior'; + VK_NEXT :Result:=Result+'Next'; + VK_END :Result:=Result+'End'; + VK_HOME :Result:=Result+'Home'; + VK_LEFT :Result:=Result+'Left'; + VK_UP :Result:=Result+'Up'; + VK_RIGHT :Result:=Result+'Right'; + VK_DOWN :Result:=Result+'Down'; + VK_SELECT :Result:=Result+'Select'; + VK_PRINT :Result:=Result+'Print'; + VK_EXECUTE :Result:=Result+'Execute'; + VK_SNAPSHOT :Result:=Result+'Snapshot'; + VK_INSERT :Result:=Result+'Insert'; + VK_DELETE :Result:=Result+'Delete'; + VK_HELP :Result:=Result+'Help'; + VK_0..VK_9 :Result:=Result+IntToStr(Key-VK_0); + VK_A..VK_Z :Result:=Result+chr(ord('A')+Key-VK_A); + VK_LWIN :Result:=Result+'left windows key'; + VK_RWIN :Result:=Result+'right windows key'; + VK_APPS :Result:=Result+'application key'; + VK_NUMPAD0..VK_NUMPAD9:Result:=Result+'Numpad '+IntToStr(Key-VK_NUMPAD0); + VK_MULTIPLY :Result:=Result+'*'; + VK_ADD :Result:=Result+'+'; + VK_SEPARATOR :Result:=Result+'|'; + VK_SUBTRACT :Result:=Result+'-'; + VK_DECIMAL :Result:=Result+'.'; + VK_DIVIDE :Result:=Result+'/'; + VK_F1..VK_F24 :Result:=Result+'F'+IntToStr(Key-VK_F1+1); + VK_NUMLOCK :Result:=Result+'Numlock'; + VK_SCROLL :Result:=Result+'Scroll'; + else + Result:=Result+'Word('''+IntToStr(Key)+''')'; + end; +end; + +{ TKeyMappingEditForm } + +constructor TKeyMappingEditForm.Create(AOwner:TComponent); +var a:integer; + s:AnsiString; +begin + inherited Create(AOwner); + if LazarusResources.Find(ClassName)=nil then begin + Caption:='Edit keys for command'; + Width:=220; + Height:=250; + + OkButton:=TButton.Create(Self); + with OkButton do begin + Name:='OkButton'; + Parent:=Self; + Caption:='Ok'; + Left:=15; + Top:=Self.ClientHeight-Height-15; + Width:=80; + OnClick:=@OkButtonClick; + Show; + end; + + CancelButton:=TButton.Create(Self); + with CancelButton do begin + Name:='CancelButton'; + Parent:=Self; + Caption:='Cancel'; + Left:=125; + Top:=OkButton.Top; + Width:=OkButton.Width; + OnClick:=@CancelButtonClick; + Show; + end; + + CommandLabel:=TLabel.Create(Self); + with CommandLabel do begin + Name:='CommandLabel'; + Parent:=Self; + Caption:='Command'; + Left:=10; + Top:=5; + Width:=Self.ClientWidth-Left-Left-4; + Height:=20; + Show; + end; + + Key1GroupBox:=TGroupBox.Create(Self); + with Key1GroupBox do begin + Name:='Key1GroupBox'; + Parent:=Self; + Caption:='Key 1'; + Left:=5; + Top:=CommandLabel.Top+CommandLabel.Height+8; + Width:=Self.ClientWidth-4-Left-Left; + Height:=80; + Show; + end; + + Key1CtrlCheckBox:=TCheckBox.Create(Self); + with Key1CtrlCheckBox do begin + Name:='Key1CtrlCheckBox'; + Parent:=Key1GroupBox; + Caption:='Ctrl'; + Left:=5; + Top:=2; + Width:=55; + Height:=20; + Show; + end; + + Key1AltCheckBox:=TCheckBox.Create(Self); + with Key1AltCheckBox do begin + Name:='Key1AltCheckBox'; + Parent:=Key1GroupBox; + Caption:='Alt'; + Left:=Key1CtrlCheckBox.Left+Key1CtrlCheckBox.Width+10; + Top:=Key1CtrlCheckBox.Top; + Height:=20; + Width:=Key1CtrlCheckBox.Width; + Show; + end; + + Key1ShiftCheckBox:=TCheckBox.Create(Self); + with Key1ShiftCheckBox do begin + Name:='Key1ShiftCheckBox'; + Parent:=Key1GroupBox; + Caption:='Shift'; + Left:=Key1AltCheckBox.Left+Key1AltCheckBox.Width+10; + Top:=Key1CtrlCheckBox.Top; + Height:=20; + Width:=Key1CtrlCheckBox.Width; + Show; + end; + + Key1KeyComboBox:=TComboBox.Create(Self); + with Key1KeyComboBox do begin + Name:='Key1KeyComboBox'; + Parent:=Key1GroupBox; + Left:=10; + Top:=Key1CtrlCheckBox.Top+Key1CtrlCheckBox.Height+5; + Width:=180; + Items.BeginUpdate; + Items.Add('none'); + for a:=1 to 145 do begin + s:=KeyAndShiftStateToStr(a,[]); + if lowercase(copy(s,1,5))<>'word(' then + Items.Add(s); + end; + Items.EndUpdate; + ItemIndex:=0; + Show; + end; + + Key2GroupBox:=TGroupBox.Create(Self); + with Key2GroupBox do begin + Name:='Key2GroupBox'; + Parent:=Self; + Caption:='Key 2'; + Left:=5; + Top:=Key1GroupBox.Top+Key1GroupBox.Height+8; + Width:=Key1GroupBox.Width; + Height:=80; + Show; + end; + + Key2CtrlCheckBox:=TCheckBox.Create(Self); + with Key2CtrlCheckBox do begin + Name:='Key2CtrlCheckBox'; + Parent:=Key2GroupBox; + Caption:='Ctrl'; + Left:=5; + Top:=2; + Width:=55; + Height:=20; + Show; + end; + + Key2AltCheckBox:=TCheckBox.Create(Self); + with Key2AltCheckBox do begin + Name:='Key2AltCheckBox'; + Parent:=Key2GroupBox; + Caption:='Alt'; + Left:=Key2CtrlCheckBox.Left+Key2CtrlCheckBox.Width+10; + Top:=Key2CtrlCheckBox.Top; + Height:=20; + Width:=Key2CtrlCheckBox.Width; + Show; + end; + + Key2ShiftCheckBox:=TCheckBox.Create(Self); + with Key2ShiftCheckBox do begin + Name:='Key2ShiftCheckBox'; + Parent:=Key2GroupBox; + Caption:='Shift'; + Left:=Key2AltCheckBox.Left+Key2AltCheckBox.Width+10; + Top:=Key2CtrlCheckBox.Top; + Height:=20; + Width:=Key2CtrlCheckBox.Width; + Show; + end; + + Key2KeyComboBox:=TComboBox.Create(Self); + with Key2KeyComboBox do begin + Name:='Key2KeyComboBox'; + Parent:=Key2GroupBox; + Left:=10; + Top:=Key2CtrlCheckBox.Top+Key2CtrlCheckBox.Height+5; + Width:=180; + Items.BeginUpdate; + Items.Add('none'); + for a:=1 to 145 do begin + s:=KeyAndShiftStateToStr(a,[]); + if lowercase(copy(s,1,5))<>'word(' then + Items.Add(s); + end; + Items.EndUpdate; + ItemIndex:=0; + Show; + end; + + end; +end; + +procedure TKeyMappingEditForm.OkButtonClick(Sender:TObject); +var NewKey1,NewKey2,a:integer; + NewShiftState1,NewShiftState2:TShiftState; + s,ACaption,AText:AnsiString; + DummyRelation:TKeyCommandRelation; +begin + NewKey1:=VK_UNKNOWN; + NewShiftState1:=[]; + NewKey2:=VK_UNKNOWN; + NewShiftState2:=[]; + s:=Key1KeyComboBox.Text; + if s<>'none' then + for a:=1 to 145 do + if KeyAndShiftStateToStr(a,[])=s then + NewKey1:=a; + if NewKey1<>VK_UNKNOWN then begin + if Key1CtrlCheckBox.Checked then include(NewShiftState1,ssCtrl); + if Key1AltCheckBox.Checked then include(NewShiftState1,ssAlt); + if Key1ShiftCheckBox.Checked then include(NewShiftState1,ssShift); + end; + DummyRelation:=KeyCommandRelationList.Find(NewKey1,NewShiftState1); + if (DummyRelation<>nil) + and (DummyRelation<>KeyCommandRelationList.Relations[KeyIndex]) then begin + ACaption:='No No No'; + AText:=' The key "'+KeyAndShiftStateToStr(NewKey1,NewShiftState1)+'"' + +' is already connected to "'+DummyRelation.Name+'".'; + Application.MessageBox(PChar(AText),PChar(ACaption),0); + exit; + end; + s:=Key2KeyComboBox.Text; + if s<>'none' then + for a:=1 to 145 do + if KeyAndShiftStateToStr(a,[])=s then + NewKey2:=a; + if (NewKey1=NewKey2) and (NewShiftState1=NewShiftState2) then + NewKey2:=VK_UNKNOWN; + if NewKey2<>VK_UNKNOWN then begin + if Key2CtrlCheckBox.Checked then include(NewShiftState2,ssCtrl); + if Key2AltCheckBox.Checked then include(NewShiftState2,ssAlt); + if Key2ShiftCheckBox.Checked then include(NewShiftState2,ssShift); + end; + DummyRelation:=KeyCommandRelationList.Find(NewKey2,NewShiftState2); + if (DummyRelation<>nil) + and (DummyRelation<>KeyCommandRelationList.Relations[KeyIndex]) then begin + ACaption:='No No No'; + AText:=' The key "'+KeyAndShiftStateToStr(NewKey2,NewShiftState2)+'"' + +' is already connected to "'+DummyRelation.Name+'".'; + Application.MessageBox(PChar(AText),PChar(ACaption),0); + exit; + end; + if NewKey1=VK_UNKNOWN then begin + NewKey1:=NewKey2; + NewShiftState1:=NewShiftState2; + NewKey2:=VK_UNKNOWN; + end; + with KeyCommandRelationList.Relations[KeyIndex] do begin + Key1:=NewKey1; + Shift1:=NewShiftState1; + Key2:=NewKey2; + Shift2:=NewShiftState2; + end; + ModalResult:=mrOk; +end; + +procedure TKeyMappingEditForm.CancelButtonClick(Sender:TObject); +begin + ModalResult:=mrCancel; +end; + + +{ TKeyCommandRelation } + +constructor TKeyCommandRelation.Create(AName:ShortString; + ACommand:TSynEditorCommand; + AKey1:Word;AShift1:TShiftState;AKey2:Word;AShift2:TShiftState); +begin + Name:=AName; + Command:=ACommand; + Key1:=AKey1; + Shift1:=AShift1; + Key2:=AKey2; + Shift2:=AShift2; +end; + +{ TKeyCommandRelationList } + +constructor TKeyCommandRelationList.Create; +begin + inherited Create; + FRelations:=TList.Create; + + // normal synedit commands + Add('Select All',ecSelectAll,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Copy selection to clipboard',ecCopy,VK_C,[ssCtrl],VK_UNKNOWN,[]); + Add('Cut selection to clipboard',ecCut,VK_X,[ssCtrl],VK_UNKNOWN,[]); + Add('Paste clipboard to current position',ecPaste,VK_V,[ssCtrl],VK_UNKNOWN,[]); + Add('Undo',ecUndo,VK_Z,[ssCtrl],VK_UNKNOWN,[]); + Add('Redo',ecRedo,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Normal selection mode',ecNormalSelect,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Column selection mode',ecColumnSelect,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Line selection mode',ecLineSelect,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Go to matching bracket',ecMatchBracket,VK_UNKNOWN,[],VK_UNKNOWN,[]); + Add('Indent block',ecBlockIndent,VK_I,[ssCtrl],VK_UNKNOWN,[]); + Add('Unindent block',ecBlockUnindent,VK_U,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 0',ecGotoMarker0,VK_0,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 1',ecGotoMarker1,VK_1,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 2',ecGotoMarker2,VK_2,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 3',ecGotoMarker3,VK_3,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 4',ecGotoMarker4,VK_4,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 5',ecGotoMarker5,VK_5,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 6',ecGotoMarker6,VK_6,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 7',ecGotoMarker7,VK_7,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 8',ecGotoMarker8,VK_8,[ssCtrl],VK_UNKNOWN,[]); + Add('Go to marker 9',ecGotoMarker9,VK_9,[ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 0',ecSetMarker0,VK_0,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 1',ecSetMarker1,VK_1,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 2',ecSetMarker2,VK_2,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 3',ecSetMarker3,VK_3,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 4',ecSetMarker4,VK_4,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 5',ecSetMarker5,VK_5,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 6',ecSetMarker6,VK_6,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 7',ecSetMarker7,VK_7,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 8',ecSetMarker8,VK_8,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Set marker 9',ecSetMarker9,VK_9,[ssShift,ssCtrl],VK_UNKNOWN,[]); + Add('Code template completion',ecAutoCompletion,VK_J,[ssCtrl],VK_UNKNOWN,[]); + + // user defined commands + Add('Find text',ecFind,VK_F,[SSCtrl],VK_UNKNOWN,[]); + Add('Find text again',ecFindAgain,VK_F3,[],VK_UNKNOWN,[]); + Add('Replace text',ecReplace,VK_R,[SSCtrl],VK_UNKNOWN,[]); + Add('Find procedure definiton',ecFindProcedureDefinition, + VK_UP,[ssShift,SSCtrl],VK_UNKNOWN,[]); + Add('Find procedure method',ecFindProcedureMethod, + VK_DOWN,[ssShift,SSCtrl],VK_UNKNOWN,[]); + Add('Go to line number',ecGotoLineNumber,VK_G,[ssAlt],VK_UNKNOWN,[]); + + Add('Go to next editor',ecNextEditor, VK_S, [ssShift,ssCtrl], VK_UNKNOWN, []); + Add('Go to prior editor',ecPrevEditor, VK_A, [ssShift,ssCtrl], VK_UNKNOWN, []); + + Add('Save',ecSave,VK_S,[ssCtrl],VK_UNKNOWN,[]); + Add('Open',ecOpen,VK_O,[ssCtrl],VK_UNKNOWN,[]); + Add('Close',ecClose,VK_F4,[ssCtrl],VK_UNKNOWN,[]); + + Add('Go to source editor 0',ecGotoEditor0,VK_0,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 1',ecGotoEditor0,VK_1,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 2',ecGotoEditor0,VK_2,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 3',ecGotoEditor0,VK_3,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 4',ecGotoEditor0,VK_4,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 5',ecGotoEditor0,VK_5,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 6',ecGotoEditor0,VK_6,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 7',ecGotoEditor0,VK_7,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 8',ecGotoEditor0,VK_8,[ssAlt],VK_UNKNOWN,[]); + Add('Go to source editor 9',ecGotoEditor0,VK_9,[ssAlt],VK_UNKNOWN,[]); +end; + +destructor TKeyCommandRelationList.Destroy; +var a:integer; +begin + for a:=0 to FRelations.Count-1 do + Relations[a].Free; + FRelations.Free; + inherited Destroy; +end; + +function TKeyCommandRelationList.GetRelation( + Index:integer):TKeyCommandRelation; +begin + if (Index<0) or (Index>=Count) then begin + writeln('[TKeyCommandRelationList.GetRelation] Index out of bounds ' + ,Index,' Count=',Count); + Halt; + end; + Result:= TKeyCommandRelation(FRelations[Index]); +end; + +function TKeyCommandRelationList.Count:integer; +begin + Result:=FRelations.Count; +end; + +function TKeyCommandRelationList.Add(Name:shortstring; + Command:TSynEditorCommand; + Key1:Word; Shift1:TShiftState; Key2:Word; Shift2:TShiftState):integer; +begin + Result:=FRelations.Add(TKeyCommandRelation.Create(Name,Command + ,Key1,Shift1,Key2,Shift2)); +end; + +function TKeyCommandRelationList.LoadFromXMLConfig( + XMLConfig:TXMLConfig; Prefix:AnsiString):boolean; +var a,b,p:integer; + Name:ShortString; + Default,NewValue:AnsiString; + + function ReadNextInt:integer; + begin + Result:=0; + while (p<=length(NewValue)) and (not (NewValue[p] in ['0'..'9'])) + do inc(p); + while (p<=length(NewValue)) and (NewValue[p] in ['0'..'9']) + and (Result<$10000)do begin + Result:=Result*10+ord(NewValue[p])-ord('0'); + inc(p); + end; + end; + + function IntToShiftState(i:integer):TShiftState; + begin + Result:=[]; + if (i and 1)>0 then Include(Result,ssCtrl); + if (i and 2)>0 then Include(Result,ssShift); + if (i and 4)>0 then Include(Result,ssAlt); + end; + +// LoadFromXMLConfig +begin + for a:=0 to FRelations.Count-1 do begin + Name:=lowercase(Relations[a].Name); + for b:=1 to length(Name) do + if Name[b]=' ' then Name[b]:='_'; + with Relations[a] do + Default:=IntToStr(Key1)+','+ShiftStateToStr(Shift1) + +','+IntToStr(Key2)+','+ShiftStateToStr(Shift2); + NewValue:=XMLConfig.GetValue(Prefix+Name,Default); + p:=1; + with Relations[a] do begin + Key1:=ReadNextInt; + Shift1:=IntToShiftState(ReadNextInt); + Key2:=ReadNextInt; + Shift2:=IntToShiftState(ReadNextInt); + end; + end; + Result:=true; +end; + +function TKeyCommandRelationList.SaveToXMLConfig( + XMLConfig:TXMLConfig; Prefix:AnsiString):boolean; +var a,b:integer; + Name:ShortString; + s:AnsiString; +begin + for a:=0 to FRelations.Count-1 do begin + Name:=lowercase(Relations[a].Name); + for b:=1 to length(Name) do + if Name[b]=' ' then Name[b]:='_'; + with Relations[a] do + s:=IntToStr(Key1)+','+ShiftStateToStr(Shift1) + +','+IntToStr(Key2)+','+ShiftStateToStr(Shift2); + XMLConfig.SetValue(Prefix+Name,s); + end; + Result:=true; +end; + +function TKeyCommandRelationList.ShiftStateToStr(Shift:TShiftState):AnsiString; +var i:integer; +begin + i:=0; + if ssCtrl in Shift then inc(i,1); + if ssShift in Shift then inc(i,2); + if ssAlt in Shift then inc(i,4); + Result:=IntToStr(i); +end; + +function TKeyCommandRelationList.Find(AKey:Word; AShiftState:TShiftState + ):TKeyCommandRelation; +var a:integer; +begin + Result:=nil; + if AKey=VK_UNKNOWN then exit; + for a:=0 to FRelations.Count-1 do with Relations[a] do + if ((Key1=AKey) and (Shift1=AShiftState)) + or ((Key2=AKey) and (Shift2=AShiftState)) then begin + Result:=Relations[a]; + exit; + end; +end; + +procedure TKeyCommandRelationList.AssignTo( + ASynEditKeyStrokes:TSynEditKeyStrokes); +var a,b,MaxKeyCnt,KeyCnt:integer; + Key:TSynEditKeyStroke; +begin + for a:=0 to FRelations.Count-1 do begin + if Relations[a].Key1=VK_UNKNOWN then MaxKeyCnt:=0 + else if Relations[a].Key2=VK_UNKNOWN then MaxKeyCnt:=1 + else MaxKeyCnt:=2; + KeyCnt:=1; + b:=0; + while bMaxKeyCnt then begin + ASynEditKeyStrokes[b].Free; + end else if KeyCnt=1 then begin + ASynEditKeyStrokes[b].Key:=Relations[a].Key1; + ASynEditKeyStrokes[b].Shift:=Relations[a].Shift1; + ASynEditKeyStrokes[b].Key2:=VK_UNKNOWN; + ASynEditKeyStrokes[b].Shift2:=[]; + inc(b); + end else if KeyCnt=2 then begin + ASynEditKeyStrokes[b].Key:=Relations[a].Key2; + ASynEditKeyStrokes[b].Shift:=Relations[a].Shift2; + ASynEditKeyStrokes[b].Key2:=VK_UNKNOWN; + ASynEditKeyStrokes[b].Shift2:=[]; + inc(b); + end; + inc(KeyCnt); + end else inc(b); + end; + while KeyCnt<=MaxKeyCnt do begin + Key:=ASynEditKeyStrokes.Add; + Key.Command:=Relations[a].Command; + Key.Key:=Relations[a].Key1; + Key.Shift:=Relations[a].Shift1; + Key.Key2:=VK_UNKNOWN; + Key.Shift2:=[]; + inc(KeyCnt); + end; + end; +end; + +initialization + KeyMappingEditForm:=nil; + +end. diff --git a/ide/main.pp b/ide/main.pp index 7b4b7a8ec3..386892658f 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -200,8 +200,7 @@ const var MainIDE : TMainIDE; - FormEditor1 : TFormEditor; - // this should be moved to FormEditor <... + ObjectInspector1 : TObjectInspector; PropertyEditorHook1 : TPropertyEditorHook; // ...> @@ -1643,6 +1642,10 @@ end. { ============================================================================= $Log$ + Revision 1.55 2001/02/02 14:23:37 lazarus + Start of code completion code. + Shane + Revision 1.54 2001/02/01 16:45:19 lazarus Started the code completion. Shane diff --git a/ide/uniteditor.pp b/ide/uniteditor.pp index 6c0850ad21..c244cec966 100644 --- a/ide/uniteditor.pp +++ b/ide/uniteditor.pp @@ -31,7 +31,7 @@ unit UnitEditor; interface uses - classes, Controls, forms,buttons,comctrls,sysutils,Dialogs,FormEditor,Find_Dlg,EditorOPtions, + classes, Controls, forms,buttons,comctrls,sysutils,Dialogs,FormEditor,Find_Dlg,EditorOPtions,CustomFormEditor,keymapping, {$ifdef NEW_EDITOR_SYNEDIT} SynEdit, SynEditHighlighter, SynHighlighterPas,SynEditAutoComplete, SynEditKeyCmds,SynCompletion, @@ -260,7 +260,7 @@ implementation uses LCLLinux,TypInfo,LResources,Main,LazConf; -const +{const ecFind = ecUserFirst+1; ecFindAgain = ecUserFirst+2; ecFindProcedureDefinition = ecUserFirst+3; @@ -275,7 +275,7 @@ const ecClose = ecFirstParent+3; ecJumpToEditor = ecFirstParent+4; - + } var Editor_Num : Integer; aHighlighter: TSynPasSyn; @@ -842,12 +842,41 @@ Procedure TSourceEditor.ccExecute(Sender : TObject); var scompl : TSynBaseCompletion; S : TStrings; + CompInt : TComponentInterface; + CompName : String; + I : Integer; + propKind : TTypeKind; Begin + CompInt := nil; Writeln('[ccExecute]'); - sCompl := TSynBaseCOmpletion(Sender); + sCompl := TSynBaseCompletion(Sender); S := TStringList.Create; + CompName := sCompl.CurrentString; + if Pos('.',CompName) <> 0 then + CompName := Copy(CompName,1,pos('.',Compname)-1); + CompInt := TComponentInterface(FormEditor1.FindComponentByName(CompName)); + if CompInt = nil then Exit; + + //get all methods + for I := 0 to CompInt.GetPropCount-1 do + Begin + Writeln('I = '+Inttostr(i)); + Writeln('Property Name is '+CompInt.GetPropName(I)); + PropKind := CompInt.GetPropType(i); + case PropKind of + tkMethod : Begin + Writeln('Property type is TKMETHOD'); +// Writeln(' + end; + tkObject : Writeln('Property type is TKObject'); + tkInteger : Writeln('Property type is TKINTEGER'); + tkBool : Writeln('Property type is TKBool'); + end; + end; +{ S.Add('constructor Create(aOwner : TComponent);'); S.Add('OnActivate'); +} sCompl.ItemList := S; End; @@ -873,7 +902,7 @@ Begin Align := alClient; Gutter.Color:=clBlue; AddKey(ecAutoCompletion, word('J'), [ssCtrl], 0, []); - AddKey(ecFind, word('F'), [ssCtrl], 0, []); +{ AddKey(ecFind, word('F'), [ssCtrl], 0, []); AddKey(ecFindAgain, VK_F3, [], 0, []); AddKey(ecFindProcedureDefinition, VK_UP, [ssShift,ssCtrl], 0, []); AddKey(ecFindProcedureMethod, VK_Down, [ssShift,ssCtrl], 0, []); @@ -883,7 +912,7 @@ Begin AddKey(ecSave, word('S'), [ssCtrl], 0, []); AddKey(ecOpen, word('O'), [ssCtrl], 0, []); AddKey(ecClose, VK_F4, [ssCtrl], 0, []); - + } OnStatusChange := @EditorStatusChanged; OnProcessUserCommand := @ProcessUserCommand; Show; diff --git a/lcl/stdctrls.pp b/lcl/stdctrls.pp index 911f051fa6..02622be99f 100644 --- a/lcl/stdctrls.pp +++ b/lcl/stdctrls.pp @@ -293,6 +293,7 @@ type TEdit = class(TCustomEdit) published + property Align; property OnChange; property OnClick; property CharCase; @@ -569,6 +570,10 @@ end. { ============================================================================= $Log$ + Revision 1.13 2001/02/02 14:23:38 lazarus + Start of code completion code. + Shane + Revision 1.12 2001/02/01 16:45:19 lazarus Started the code completion. Shane