mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-13 11:39:13 +02:00
Open unit of component palette component now jumps to declaration
git-svn-id: trunk@5773 -
This commit is contained in:
parent
e603afe3a7
commit
02957fe9b9
@ -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
|
||||
|
@ -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 CenteredTopLine<NewTopLine then
|
||||
NewTopLine:=CenteredTopLine;
|
||||
end;
|
||||
// NewTopLine not above first line of code
|
||||
if NewTopLine<1 then NewTopLine:=1;
|
||||
// make NewTopLine visible
|
||||
if NewTopLine<=NewPos.Y-VisibleEditorLines then begin
|
||||
// NewTopLine is not visible
|
||||
// center or align to bottom
|
||||
if (NewBottomLineCleanPos>NewCleanPos)
|
||||
and (NewBottomLinePos.Y<NewPos.Y+(VisibleEditorLines div 2))
|
||||
then begin
|
||||
// align to bottom
|
||||
NewTopLine:=NewBottomLinePos.Y-VisibleEditorLines+1;
|
||||
end else begin
|
||||
// center
|
||||
NewTopLine:=CenteredTopLine;
|
||||
end;
|
||||
if NewTopLine<1 then NewTopLine:=1;
|
||||
end;
|
||||
end else
|
||||
NewTopLine:=1;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.FindIdentifierInProcContext(
|
||||
ProcContextNode: TCodeTreeNode;
|
||||
Params: TFindDeclarationParams): TIdentifierFoundResult;
|
||||
|
@ -47,8 +47,6 @@ uses
|
||||
|
||||
type
|
||||
TMethodJumpingCodeTool = class(TCodeTemplatesTool)
|
||||
private
|
||||
FAdjustTopLineDueToComment: boolean;
|
||||
protected
|
||||
procedure RemoveCorrespondingProcNodes(Tree1, Tree2: TAVLTree;
|
||||
KeepTree1: boolean);
|
||||
@ -67,13 +65,6 @@ type
|
||||
Attr: TProcHeadAttributes; const UpperClassName: string): TAVLTree;
|
||||
function FindFirstDifferenceNode(SearchForNodes, SearchInNodes: TAVLTree;
|
||||
var DiffTxtPos: integer): TAVLTreeNode;
|
||||
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;
|
||||
function JumpToMethod(const ProcHead: string; Attr: TProcHeadAttributes;
|
||||
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||
IgnoreJumpCentered: boolean): boolean;
|
||||
@ -84,9 +75,6 @@ type
|
||||
function FindSubProcPath(SubProcPath: TStrings; Attr: TProcHeadAttributes;
|
||||
SkipInterface: boolean): TCodeTreeNode;
|
||||
procedure WriteCodeTreeNodeExtTree(ExtTree: TAVLTree);
|
||||
public
|
||||
property AdjustTopLineDueToComment: boolean
|
||||
read FAdjustTopLineDueToComment write FAdjustTopLineDueToComment;
|
||||
end;
|
||||
|
||||
|
||||
@ -885,16 +873,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMethodJumpingCodeTool.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 TMethodJumpingCodeTool.FindNodeInTree(ATree: TAVLTree;
|
||||
const UpperCode: string): TCodeTreeNodeExtension;
|
||||
var cmp: integer;
|
||||
@ -988,71 +966,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMethodJumpingCodeTool.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 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 CenteredTopLine<NewTopLine then
|
||||
NewTopLine:=CenteredTopLine;
|
||||
end;
|
||||
// NewTopLine not above first line of code
|
||||
if NewTopLine<1 then NewTopLine:=1;
|
||||
// make NewTopLine visible
|
||||
if NewTopLine<=NewPos.Y-VisibleEditorLines then begin
|
||||
// NewTopLine is not visible
|
||||
// center or align to bottom
|
||||
if (NewBottomLineCleanPos>NewCleanPos)
|
||||
and (NewBottomLinePos.Y<NewPos.Y+(VisibleEditorLines div 2))
|
||||
then begin
|
||||
// align to bottom
|
||||
NewTopLine:=NewBottomLinePos.Y-VisibleEditorLines+1;
|
||||
end else begin
|
||||
// center
|
||||
NewTopLine:=CenteredTopLine;
|
||||
end;
|
||||
if NewTopLine<1 then NewTopLine:=1;
|
||||
end;
|
||||
end else
|
||||
NewTopLine:=1;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TMethodJumpingCodeTool.JumpToMethod(const ProcHead: string;
|
||||
Attr: TProcHeadAttributes;
|
||||
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||
|
@ -156,7 +156,7 @@ begin
|
||||
if (PkgComponent=nil) or (PkgComponent.PkgFile=nil)
|
||||
or (PkgComponent.PkgFile.LazPackage=nil) then exit;
|
||||
if Assigned(OnOpenUnit) then
|
||||
OnOpenUnit(PkgComponent.PkgFile);
|
||||
OnOpenUnit(PkgComponent);
|
||||
end;
|
||||
|
||||
procedure TComponentPalette.PopupMenuPopup(Sender: TObject);
|
||||
|
30
ide/main.pp
30
ide/main.pp
@ -537,6 +537,8 @@ type
|
||||
function DoOpenEditorFile(AFileName: string; PageIndex: integer;
|
||||
Flags: TOpenFlags): TModalResult; override;
|
||||
function DoOpenFileAtCursor(Sender: TObject): TModalResult;
|
||||
function DoOpenFileAndJumpToIdentifier(const AFilename, AnIdentifier: string;
|
||||
PageIndex: integer; Flags: TOpenFlags): TModalResult; override;
|
||||
function DoSaveAll(Flags: TSaveFlags): TModalResult;
|
||||
function DoOpenMainUnit(ProjectLoading: boolean): TModalResult;
|
||||
function DoRevertMainUnit: TModalResult;
|
||||
@ -677,8 +679,11 @@ type
|
||||
procedure DoGoToPascalBlockStart;
|
||||
procedure DoJumpToGuessedUnclosedBlock(FindNext: boolean);
|
||||
procedure DoJumpToGuessedMisplacedIFDEF(FindNext: boolean);
|
||||
|
||||
procedure DoGotoIncludeDirective;
|
||||
procedure SaveIncludeLinks;
|
||||
|
||||
// tools
|
||||
function DoMakeResourceString: TModalResult;
|
||||
function DoDiff: TModalResult;
|
||||
function DoFindInFiles: TModalResult;
|
||||
@ -5148,6 +5153,28 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMainIDE.DoOpenFileAndJumpToIdentifier(const AFilename,
|
||||
AnIdentifier: string; PageIndex: integer; Flags: TOpenFlags): TModalResult;
|
||||
var
|
||||
ActiveUnitInfo: TUnitInfo;
|
||||
ActiveSrcEdit: TSourceEditor;
|
||||
NewSource: TCodeBuffer;
|
||||
NewX, NewY, NewTopLine: integer;
|
||||
begin
|
||||
Result:=DoOpenEditorFile(AFilename, PageIndex, Flags);
|
||||
if Result<>mrOk 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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user