From 02957fe9b93413970d4d0c230275b9fe33f5702a Mon Sep 17 00:00:00 2001 From: mattias Date: Thu, 12 Aug 2004 10:50:14 +0000 Subject: [PATCH] Open unit of component palette component now jumps to declaration git-svn-id: trunk@5773 - --- components/codetools/codetoolmanager.pas | 33 +++++ components/codetools/finddeclarationtool.pas | 119 +++++++++++++++++++ components/codetools/methodjumptool.pas | 87 -------------- ide/componentpalette.pas | 2 +- ide/main.pp | 30 +++++ ide/mainbase.pas | 2 +- ide/mainintf.pas | 3 + packager/pkgmanager.pas | 15 ++- 8 files changed, 200 insertions(+), 91 deletions(-) diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index e9640b7e59..85f0e933c8 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -273,6 +273,9 @@ type var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer): boolean; function FindSmartHint(Code: TCodeBuffer; X,Y: integer): string; + function FindDeclarationInInterface(Code: TCodeBuffer; + const Identifier: string; var NewCode: TCodeBuffer; + var NewX, NewY, NewTopLine: integer): boolean; // gather identifiers (i.e. all visible) function GatherIdentifiers(Code: TCodeBuffer; X,Y: integer): boolean; @@ -1158,6 +1161,36 @@ begin {$ENDIF} end; +function TCodeToolManager.FindDeclarationInInterface(Code: TCodeBuffer; + const Identifier: string; var NewCode: TCodeBuffer; var NewX, NewY, + NewTopLine: integer): boolean; +var + NewPos: TCodeXYPosition; +begin + Result:=false; + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.FindDeclarationInInterface A ',Code.Filename,' Identifier=',Identifier); + {$ENDIF} + if not InitCurCodeTool(Code) then exit; + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.FindDeclarationInInterface B ',FCurCodeTool.Scanner<>nil); + {$ENDIF} + try + Result:=FCurCodeTool.FindDeclarationInInterface(Identifier,NewPos, + NewTopLine); + if Result then begin + NewX:=NewPos.X; + NewY:=NewPos.Y; + NewCode:=NewPos.Code; + end; + except + on e: Exception do HandleException(e); + end; + {$IFDEF CTDEBUG} + DebugLn('TCodeToolManager.FindDeclarationInInterface END '); + {$ENDIF} +end; + function TCodeToolManager.GatherIdentifiers(Code: TCodeBuffer; X, Y: integer ): boolean; var diff --git a/components/codetools/finddeclarationtool.pas b/components/codetools/finddeclarationtool.pas index b81b6f371d..d9eeb891ed 100644 --- a/components/codetools/finddeclarationtool.pas +++ b/components/codetools/finddeclarationtool.pas @@ -489,6 +489,7 @@ type TFindDeclarationTool = class(TPascalReaderTool) private + FAdjustTopLineDueToComment: boolean; FInterfaceIdentifierCache: TInterfaceIdentifierCache; FOnFindUsedUnit: TOnFindUsedUnit; FOnGetCodeToolForBuffer: TOnGetCodeToolForBuffer; @@ -647,6 +648,8 @@ type SearchSmartFlags: TFindSmartFlags; var NewTool: TFindDeclarationTool; var NewNode: TCodeTreeNode; var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean; + function FindDeclarationInInterface(const Identifier: string; + var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean; function FindUnitSource(const AnUnitName, AnUnitInFilename: string; ExceptionOnNotFound: boolean): TCodeBuffer; function FindSmartHint(const CursorPos: TCodeXYPosition): string; @@ -654,6 +657,14 @@ type function FindBaseTypeOfNode(Params: TFindDeclarationParams; Node: TCodeTreeNode): TFindContext; + function JumpToNode(ANode: TCodeTreeNode; + var NewPos: TCodeXYPosition; var NewTopLine: integer; + IgnoreJumpCentered: boolean): boolean; + function JumpToCleanPos(NewCleanPos, NewTopLineCleanPos, + NewBottomLineCleanPos: integer; + var NewPos: TCodeXYPosition; var NewTopLine: integer; + IgnoreJumpCentered: boolean): boolean; + property InterfaceIdentifierCache: TInterfaceIdentifierCache read FInterfaceIdentifierCache; property OnGetUnitSourceSearchPath: TOnGetSearchPath @@ -664,6 +675,8 @@ type read FOnGetSrcPathForCompiledUnit write FOnGetSrcPathForCompiledUnit; property OnGetCodeToolForBuffer: TOnGetCodeToolForBuffer read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer; + property AdjustTopLineDueToComment: boolean + read FAdjustTopLineDueToComment write FAdjustTopLineDueToComment; end; function ExprTypeToString(const ExprType: TExpressionType): string; @@ -1086,6 +1099,38 @@ begin end; end; +function TFindDeclarationTool.FindDeclarationInInterface( + const Identifier: string; var NewPos: TCodeXYPosition; var NewTopLine: integer + ): boolean; +var + StartNode: TCodeTreeNode; + SectionNode: TCodeTreeNode; + Node: TCodeTreeNode; +begin + Result:=false; + if Identifier='' then exit; + BuildTree(true); + StartNode:=FindInterfaceNode; + if StartNode=nil then exit; + SectionNode:=StartNode.FirstChild; + if SectionNode=nil then exit; + while SectionNode<>nil do begin + if SectionNode.Desc in AllDefinitionSections then begin + Node:=SectionNode.FirstChild; + while Node<>nil do begin + if Node.Desc in AllIdentifierDefinitions then begin + if CompareSrcIdentifiers(Node.StartPos,PChar(Identifier)) then begin + Result:=JumpToNode(Node,NewPos,NewTopLine,false); + exit; + end; + end; + Node:=Node.NextBrother; + end; + end; + SectionNode:=SectionNode.NextBrother; + end; +end; + function TFindDeclarationTool.FindDeclarationInUsesSection( UsesNode: TCodeTreeNode; CleanPos: integer; var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean; @@ -2720,6 +2765,80 @@ begin {$ENDIF} end; +function TFindDeclarationTool.JumpToNode(ANode: TCodeTreeNode; + var NewPos: TCodeXYPosition; var NewTopLine: integer; + IgnoreJumpCentered: boolean): boolean; +begin + Result:=false; + if (ANode=nil) or (ANode.StartPos<1) then exit; + Result:=JumpToCleanPos(ANode.StartPos,ANode.StartPos,ANode.EndPos, + NewPos,NewTopLine,IgnoreJumpCentered); +end; + +function TFindDeclarationTool.JumpToCleanPos(NewCleanPos, NewTopLineCleanPos, + NewBottomLineCleanPos: integer; var NewPos: TCodeXYPosition; + var NewTopLine: integer; IgnoreJumpCentered: boolean): boolean; +var + CenteredTopLine: integer; + NewTopLinePos: TCodeXYPosition; + NewBottomLinePos: TCodeXYPosition; +begin + Result:=false; + // convert clean position to line, column and code + if not CleanPosToCaret(NewCleanPos,NewPos) then exit; + NewTopLine:=NewPos.Y; + if AdjustTopLineDueToComment then begin + // if there is a comment in front of the top position, it probably belongs + // to the destination code + // -> adjust the topline position, so that the comment is visible + NewTopLineCleanPos:=FindLineEndOrCodeInFrontOfPosition(NewTopLineCleanPos, + false); + if (NewTopLineCleanPos>=1) and (Src[NewTopLineCleanPos] in [#13,#10]) + then begin + inc(NewTopLineCleanPos); + if (Src[NewTopLineCleanPos] in [#10,#13]) + and (Src[NewTopLineCleanPos]<>Src[NewTopLineCleanPos-1]) then + inc(NewTopLineCleanPos); + end; + end; + // convert clean top line position to line, column and code + if not CleanPosToCaret(NewTopLineCleanPos,NewTopLinePos) then exit; + // convert clean bottom line position to line, column and code + NewBottomLinePos:=NewPos; + if (NewBottomLineCleanPos>NewCleanPos) + and (not CleanPosToCaret(NewBottomLineCleanPos,NewBottomLinePos)) then exit; + + if NewTopLinePos.Code=NewPos.Code then begin + // top line position is in the same code as the destination position + NewTopLine:=NewTopLinePos.Y; + CenteredTopLine:=NewPos.Y-VisibleEditorLines div 2; + if JumpCentered and (not IgnoreJumpCentered) then begin + // center the destination position in the source editor + if CenteredTopLineNewCleanPos) + and (NewBottomLinePos.Y adjust the topline position, so that the comment is visible - NewTopLineCleanPos:=FindLineEndOrCodeInFrontOfPosition(NewTopLineCleanPos, - false); - if (NewTopLineCleanPos>=1) and (Src[NewTopLineCleanPos] in [#13,#10]) - then begin - inc(NewTopLineCleanPos); - if (Src[NewTopLineCleanPos] in [#10,#13]) - and (Src[NewTopLineCleanPos]<>Src[NewTopLineCleanPos-1]) then - inc(NewTopLineCleanPos); - end; - end; - // convert clean top line position to line, column and code - if not CleanPosToCaret(NewTopLineCleanPos,NewTopLinePos) then exit; - // convert clea bottom line position to line, column and code - NewBottomLinePos:=NewPos; - if (NewBottomLineCleanPos>NewCleanPos) - and (not CleanPosToCaret(NewBottomLineCleanPos,NewBottomLinePos)) then exit; - - if NewTopLinePos.Code=NewPos.Code then begin - // top line position is in the same code as the destination position - NewTopLine:=NewTopLinePos.Y; - CenteredTopLine:=NewPos.Y-VisibleEditorLines div 2; - if JumpCentered and (not IgnoreJumpCentered) then begin - // center the destination position in the source editor - if CenteredTopLineNewCleanPos) - and (NewBottomLinePos.YmrOk then exit; + Result:=mrCancel; + if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit; + if CodeToolBoss.FindDeclarationInInterface(ActiveUnitInfo.Source, + AnIdentifier,NewSource, NewX, NewY, NewTopLine) + then begin + DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo, + NewSource, NewX, NewY, NewTopLine, true); + Result:=mrOk; + end else + DoJumpToCodeToolBossError; +end; + function TMainIDE.DoNewProject(NewProjectType:TProjectType):TModalResult; var i:integer; Begin @@ -10548,6 +10575,9 @@ end. { ============================================================================= $Log$ + Revision 1.751 2004/08/12 10:50:14 mattias + Open unit of component palette component now jumps to declaration + Revision 1.750 2004/08/09 18:28:16 mattias IDE save toolbutton is now updated on Idle diff --git a/ide/mainbase.pas b/ide/mainbase.pas index 7ed1bb268a..0948db4299 100644 --- a/ide/mainbase.pas +++ b/ide/mainbase.pas @@ -164,7 +164,7 @@ type ActiveUnitInfo: TUnitInfo; NewSource: TCodeBuffer; NewX, NewY, NewTopLine: integer; AddJumpPoint: boolean): TModalResult; virtual; abstract; - + procedure FindInFilesPerDialog(AProject: TProject); override; procedure FindInFiles(AProject: TProject; const FindText: string); override; end; diff --git a/ide/mainintf.pas b/ide/mainintf.pas index 980cbab935..6dc8c6a651 100644 --- a/ide/mainintf.pas +++ b/ide/mainintf.pas @@ -204,6 +204,9 @@ type NewFlags: TNewFlags): TModalResult; virtual; abstract; function DoOpenEditorFile(AFileName:string; PageIndex: integer; Flags: TOpenFlags): TModalResult; virtual; abstract; + function DoOpenFileAndJumpToIdentifier(const AFilename, AnIdentifier: string; + PageIndex: integer; Flags: TOpenFlags): TModalResult; virtual; abstract; + function DoInitProjectRun: TModalResult; virtual; abstract; function DoOpenMacroFile(Sender: TObject; const AFilename: string): TModalResult; virtual; abstract; diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index ca92750ff1..6cff668578 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -283,9 +283,20 @@ begin end; procedure TPkgManager.IDEComponentPaletteOpenUnit(Sender: TObject); +var + PkgComponent: TPkgComponent; begin - if (Sender=nil) or (not (Sender is TPkgFile)) then exit; - MainIDE.DoOpenMacroFile(Self,TPkgFile(Sender).Filename); + if (Sender=nil) then exit; + if (Sender is TPkgFile) then + MainIDE.DoOpenMacroFile(Self,TPkgFile(Sender).Filename) + else if (Sender is TPkgComponent) then begin + PkgComponent:=TPkgComponent(Sender); + if PkgComponent.PkgFile=nil then exit; + MainIDE.DoOpenFileAndJumpToIdentifier( + PkgComponent.PkgFile.Filename,PkgComponent.ComponentClass.ClassName, + -1, // open page somewhere + [ofOnlyIfExists,ofAddToRecent,ofRegularFile,ofConvertMacros]); + end; end; procedure TPkgManager.GetDependencyOwnerDescription(