diff --git a/components/ideintf/idecommands.pas b/components/ideintf/idecommands.pas index ee3ad3a73b..f2d0e5593a 100644 --- a/components/ideintf/idecommands.pas +++ b/components/ideintf/idecommands.pas @@ -80,6 +80,8 @@ const ecJumpToImplementation = ecFirstLazarus + 27; ecJumpToImplementationUses= ecFirstLazarus + 28; ecJumpToInitialization = ecFirstLazarus + 29; + ecJumpToProcedureHeader = ecFirstLazarus + 30; + ecJumpToProcedureBegin = ecFirstLazarus + 31; // edit selection ecSelectionUpperCase = ecFirstLazarus + 50; diff --git a/components/ideintf/menuintf.pas b/components/ideintf/menuintf.pas index cbc1047010..002aa6bc4c 100644 --- a/components/ideintf/menuintf.pas +++ b/components/ideintf/menuintf.pas @@ -1920,12 +1920,9 @@ begin end; procedure TIDEMenuCommand.SetVisible(const AValue: Boolean); -var - xBtn: TIDEToolButton; begin inherited SetVisible(AValue); - for xBtn in ToolButtons do - xBtn.Visible := AValue; + //do not set visible for tool buttons, you usually only want to hide menu item and keep tool buttons visible end; procedure TIDEMenuCommand.ToolButtonAdded(const aBtn: TIDEToolButton); diff --git a/ide/keymapping.pp b/ide/keymapping.pp index d4c41b6f0c..50b8a25f2a 100644 --- a/ide/keymapping.pp +++ b/ide/keymapping.pp @@ -555,6 +555,8 @@ begin ecJumpToImplementation : Result:= lisMenuJumpToImplementation; ecJumpToImplementationUses: Result:= lisMenuJumpToImplementationUses; ecJumpToInitialization : Result:= lisMenuJumpToInitialization; + ecJumpToProcedureHeader : Result:= lisMenuJumpToProcedureHeader; + ecJumpToProcedureBegin : Result:= lisMenuJumpToProcedureBegin; ecOpenFileAtCursor : Result:= srkmecOpenFileAtCursor; ecProcedureList : Result:= lisPListProcedureList; @@ -2769,6 +2771,8 @@ begin AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation); AddDefault(C, 'Jump to Implementation uses', lisMenuJumpToImplementationUses, ecJumpToImplementationUses); AddDefault(C, 'Jump to Initialization', lisMenuJumpToInitialization, ecJumpToInitialization); + AddDefault(C, 'Jump to Procedure header', lisMenuJumpToProcedureHeader, ecJumpToProcedureHeader); + AddDefault(C, 'Jump to Procedure begin', lisMenuJumpToProcedureBegin, ecJumpToProcedureBegin); AddDefault(C, 'Show abstract methods', srkmecShowAbstractMethods, ecShowAbstractMethods); AddDefault(C, 'Remove empty methods', srkmecRemoveEmptyMethods, ecRemoveEmptyMethods); AddDefault(C, 'Remove unused units', srkmecRemoveUnusedUnits, ecRemoveUnusedUnits); diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 2a65b56f00..331df5b082 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -389,6 +389,8 @@ resourcestring lisMenuJumpToImplementation = 'Jump to Implementation'; lisMenuJumpToImplementationUses = 'Jump to Implementation uses'; lisMenuJumpToInitialization = 'Jump to Initialization'; + lisMenuJumpToProcedureHeader = 'Jump to Procedure header'; + lisMenuJumpToProcedureBegin = 'Jump to Procedure begin'; lisMenuViewUnits = 'Units ...'; lisMenuViewForms = 'Forms ...'; lisMenuViewUnitDependencies = 'Unit Dependencies'; diff --git a/ide/main.pp b/ide/main.pp index cf0be28a95..13afbf7ab6 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -2101,6 +2101,8 @@ begin MainIDEBar.itmJumpToImplementation.OnClick := @SourceEditorManager.JumpToImplementationClicked; MainIDEBar.itmJumpToImplementationUses.OnClick := @SourceEditorManager.JumpToImplementationUsesClicked; MainIDEBar.itmJumpToInitialization.OnClick := @SourceEditorManager.JumpToInitializationClicked; + MainIDEBar.itmJumpToProcedureHeader.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked; + MainIDEBar.itmJumpToProcedureBegin.OnClick := @SourceEditorManager.JumpToProcedureBeginClicked; MainIDEBar.itmFindBlockStart.OnClick:=@mnuSearchFindBlockStart; MainIDEBar.itmFindBlockOtherEnd.OnClick:=@mnuSearchFindBlockOtherEnd; MainIDEBar.itmFindDeclaration.OnClick:=@mnuSearchFindDeclaration; diff --git a/ide/mainbar.pas b/ide/mainbar.pas index bce74ab1e2..008aa7af29 100644 --- a/ide/mainbar.pas +++ b/ide/mainbar.pas @@ -146,6 +146,8 @@ type itmJumpToImplementation: TIDEMenuCommand; itmJumpToImplementationUses: TIDEMenuCommand; itmJumpToInitialization: TIDEMenuCommand; + itmJumpToProcedureHeader: TIDEMenuCommand; + itmJumpToProcedureBegin: TIDEMenuCommand; //itmBookmarks: TIDEMenuSection; itmSetFreeBookmark: TIDEMenuCommand; itmJumpToNextBookmark: TIDEMenuCommand; diff --git a/ide/mainbase.pas b/ide/mainbase.pas index 81e183fc2a..644240e09b 100644 --- a/ide/mainbase.pas +++ b/ide/mainbase.pas @@ -1084,6 +1084,12 @@ begin CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses'); CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization'); + ParentMI:=itmJumpings; + CreateMenuItem(ParentMI,itmJumpToProcedureHeader,'itmJumpToProcedureHeader',lisMenuJumpToProcedureHeader, 'menu_jumpto_procedureheader'); + CreateMenuItem(ParentMI,itmJumpToProcedureBegin,'itmJumpToProcedureBegin',lisMenuJumpToProcedureBegin, 'menu_jumpto_procedurebegin'); + itmJumpToProcedureHeader.Visible := False; + itmJumpToProcedureBegin.Visible := False; + CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks'); ParentMI:=itmBookmarks; @@ -1542,6 +1548,8 @@ begin itmJumpToImplementationUses.ToolButtonClass:=TJumpToSectionToolButton; itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization); itmJumpToInitialization.ToolButtonClass:=TJumpToSectionToolButton; + itmJumpToProcedureHeader.Command:=GetCommand(ecJumpToProcedureHeader); + itmJumpToProcedureBegin.Command:=GetCommand(ecJumpToProcedureBegin); itmFindBlockOtherEnd.Command:=GetCommand(ecFindBlockOtherEnd); itmFindBlockStart.Command:=GetCommand(ecFindBlockStart); itmFindDeclaration.Command:=GetCommand(ecFindDeclaration); diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 643aaea4ea..bbb8d46764 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -948,6 +948,7 @@ type jmpInterface, jmpInterfaceUses, jmpImplementation, jmpImplementationUses, jmpInitialization); + TJumpToProcedureType = (jmpHeader, jmpBegin); { TSourceEditorManager } (* Reintroduce all Methods with the final types *) @@ -1025,12 +1026,16 @@ type public procedure BookMarkNextClicked(Sender: TObject); procedure BookMarkPrevClicked(Sender: TObject); + procedure JumpToPos(FileName: string; Pos: TCodeXYPosition; TopLine: Integer); procedure JumpToSection(JumpType: TJumpToSectionType); procedure JumpToInterfaceClicked(Sender: TObject); procedure JumpToInterfaceUsesClicked(Sender: TObject); procedure JumpToImplementationClicked(Sender: TObject); procedure JumpToImplementationUsesClicked(Sender: TObject); procedure JumpToInitializationClicked(Sender: TObject); + procedure JumpToProcedure(const JumpType: TJumpToProcedureType); + procedure JumpToProcedureHeaderClicked(Sender: TObject); + procedure JumpToProcedureBeginClicked(Sender: TObject); protected // macros function MacroFuncCol(const {%H-}s:string; const {%H-}Data: PtrInt; @@ -9637,6 +9642,77 @@ begin JumpToSection(jmpInterfaceUses); end; +procedure TSourceEditorManager.JumpToPos(FileName: string; + Pos: TCodeXYPosition; TopLine: Integer); +begin + if (LazarusIDE.DoOpenFileAndJumpToPos(Filename + ,Point(Pos.X,Pos.Y), TopLine, -1,-1 + ,[ofRegularFile,ofUseCache]) = mrOk) + then + ActiveEditor.EditorControl.SetFocus; +end; + +procedure TSourceEditorManager.JumpToProcedure( + const JumpType: TJumpToProcedureType); +const + cJumpNames: array[TJumpToProcedureType] of string = ( + 'procedure header', 'procedure begin'); +var + SrcEditor: TSourceEditorInterface; + ProcNode: TCodeTreeNode; + Tool: TCodeTool; + CleanPos: integer; + NewPos: TCodeXYPosition; + NewTopLine: integer; + JumpFound: Boolean; +begin + if not LazarusIDE.BeginCodeTools then Exit; //==> + + SrcEditor := SourceEditorManagerIntf.ActiveEditor; + if not Assigned(SrcEditor) then Exit; //==> + + if CodeToolBoss.Explore(SrcEditor.CodeToolsBuffer as TCodeBuffer, Tool, false, false) then + begin + if Tool.CaretToCleanPos( + CodeXYPosition(SrcEditor.CursorTextXY.X, SrcEditor.CursorTextXY.Y, SrcEditor.CodeToolsBuffer as TCodeBuffer), + CleanPos) <> 0 + then + Exit; + ProcNode := Tool.FindDeepestNodeAtPos(CleanPos{%H-},true); + while (ProcNode <> nil) and (ProcNode.Desc <> ctnProcedure) do + ProcNode := ProcNode.Parent; + + if (ProcNode <> nil) and (ProcNode.Desc = ctnProcedure) then + begin + if JumpType = jmpBegin then + JumpFound := Tool.FindJumpPointInProcNode(ProcNode, NewPos, NewTopLine) + else + JumpFound := Tool.JumpToCleanPos(ProcNode.StartPos, ProcNode.StartPos, ProcNode.EndPos, NewPos, NewTopLine, True); + end else + JumpFound := False; + + if JumpFound then + JumpToPos(NewPos.Code.Filename, NewPos, NewTopLine) + else + begin + CodeToolBoss.SetError(nil, 0, 0, Format(lisCannotFind, [cJumpNames[JumpType]])); + LazarusIDE.DoJumpToCodeToolBossError; + end; + end + else + LazarusIDE.DoJumpToCodeToolBossError; +end; + +procedure TSourceEditorManager.JumpToProcedureBeginClicked(Sender: TObject); +begin + JumpToProcedure(jmpBegin); +end; + +procedure TSourceEditorManager.JumpToProcedureHeaderClicked(Sender: TObject); +begin + JumpToProcedure(jmpHeader); +end; + procedure TSourceEditorManager.JumpToSection(JumpType: TJumpToSectionType); const cJumpNames: array[TJumpToSectionType] of string = ( @@ -9677,19 +9753,14 @@ begin Node := Tool.FindRootNode(ctnEndPoint); end; end; - if (Node <> nil) then - begin - NewTopLine := 0; - NewCodePos := CleanCodeXYPosition; - if Tool.CleanPosToCaretAndTopLine(Node.StartPos, NewCodePos, NewTopLine) - and (LazarusIDE.DoOpenFileAndJumpToPos(NewCodePos.Code.Filename - ,Point(NewCodePos.X,NewCodePos.Y), NewTopLine, -1,-1 - ,[ofRegularFile,ofUseCache]) = mrOk) - then - ActiveEditor.EditorControl.SetFocus; - end + + if (Node <> nil) and Tool.CleanPosToCaretAndTopLine(Node.StartPos, NewCodePos, NewTopLine) then + JumpToPos(NewCodePos.Code.Filename, NewCodePos, NewTopLine) else - ShowMessage(Format(lisCannotFind, [cJumpNames[JumpType]])); + begin + CodeToolBoss.SetError(nil, 0, 0, Format(lisCannotFind, [cJumpNames[JumpType]])); + LazarusIDE.DoJumpToCodeToolBossError; + end; end else LazarusIDE.DoJumpToCodeToolBossError; diff --git a/images/laz_images.res b/images/laz_images.res index 6c1b32d601..3c40d3f4f7 100644 Binary files a/images/laz_images.res and b/images/laz_images.res differ diff --git a/images/laz_images_list.txt b/images/laz_images_list.txt index 6a78dbf4d0..acb25178b5 100644 --- a/images/laz_images_list.txt +++ b/images/laz_images_list.txt @@ -94,6 +94,8 @@ menu/menu_jumpto_interfaceuses.png menu/menu_jumpto_implementation.png menu/menu_jumpto_implementationuses.png menu/menu_jumpto_initialization.png +menu/menu_jumpto_procedureheader.png +menu/menu_jumpto_procedurebegin.png menu/menu_search_next_bookmark.png menu/menu_search_openfile_atcursor.png menu/menu_search_previous_bookmark.png