mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 06:39:31 +01:00 
			
		
		
		
	implemented context help for OI properties
git-svn-id: trunk@8916 -
This commit is contained in:
		
							parent
							
								
									0d5d068a9f
								
							
						
					
					
						commit
						f540eb7d8f
					
				@ -306,13 +306,20 @@ type
 | 
			
		||||
          out 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;
 | 
			
		||||
          const Identifier: string; out NewCode: TCodeBuffer;
 | 
			
		||||
          out NewX, NewY, NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationWithMainUsesSection(Code: TCodeBuffer;
 | 
			
		||||
          const Identifier: string;
 | 
			
		||||
          out NewCode: TCodeBuffer;
 | 
			
		||||
          out NewX, NewY, NewTopLine: integer): Boolean;
 | 
			
		||||
    function FindDeclarationAndOverload(Code: TCodeBuffer; X,Y: integer;
 | 
			
		||||
          var ListOfPCodeXYPosition: TFPList): boolean;
 | 
			
		||||
    function FindMainDeclaration(Code: TCodeBuffer; X,Y: integer;
 | 
			
		||||
          var NewCode: TCodeBuffer;
 | 
			
		||||
          var NewX, NewY, NewTopLine: integer): boolean;
 | 
			
		||||
          out NewCode: TCodeBuffer;
 | 
			
		||||
          out NewX, NewY, NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationOfPropertyPath(Code: TCodeBuffer;
 | 
			
		||||
          const PropertyPath: string; out NewCode: TCodeBuffer;
 | 
			
		||||
          out NewX, NewY, NewTopLine: integer): Boolean;
 | 
			
		||||
 | 
			
		||||
    // get code context
 | 
			
		||||
    function FindCodeContext(Code: TCodeBuffer; X,Y: integer;
 | 
			
		||||
@ -419,6 +426,8 @@ type
 | 
			
		||||
          var FoundInUnits, MissingInUnits, NormalUnits: TStrings): boolean;
 | 
			
		||||
    function CommentUnitsInUsesSections(Code: TCodeBuffer;
 | 
			
		||||
          MissingUnits: TStrings): boolean;
 | 
			
		||||
    function FindUnit(Code: TCodeBuffer;
 | 
			
		||||
                      var AnUnitName, AnUnitInFilename: string): string;
 | 
			
		||||
 | 
			
		||||
    // resources
 | 
			
		||||
    property OnFindDefinePropertyForContext: TOnFindDefinePropertyForContext
 | 
			
		||||
@ -1422,7 +1431,7 @@ begin
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindDeclarationInInterface(Code: TCodeBuffer;
 | 
			
		||||
  const Identifier: string; var NewCode: TCodeBuffer; var NewX, NewY,
 | 
			
		||||
  const Identifier: string; out NewCode: TCodeBuffer; out NewX, NewY,
 | 
			
		||||
  NewTopLine: integer): boolean;
 | 
			
		||||
var
 | 
			
		||||
  NewPos: TCodeXYPosition;
 | 
			
		||||
@ -1451,6 +1460,33 @@ begin
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindDeclarationWithMainUsesSection(Code: TCodeBuffer;
 | 
			
		||||
  const Identifier: string; out NewCode: TCodeBuffer;
 | 
			
		||||
  out NewX, NewY, NewTopLine: integer): Boolean;
 | 
			
		||||
var
 | 
			
		||||
  NewPos: TCodeXYPosition;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  {$IFDEF CTDEBUG}
 | 
			
		||||
  DebugLn('TCodeToolManager.FindDeclarationWithMainUsesSection A ',Code.Filename,' Identifier=',Identifier);
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  if not InitCurCodeTool(Code) then exit;
 | 
			
		||||
  try
 | 
			
		||||
    Result:=FCurCodeTool.FindDeclarationWithMainUsesSection(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.FindDeclarationAndOverload(Code: TCodeBuffer; X,
 | 
			
		||||
  Y: integer; var ListOfPCodeXYPosition: TFPList): boolean;
 | 
			
		||||
var
 | 
			
		||||
@ -1479,7 +1515,7 @@ begin
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindMainDeclaration(Code: TCodeBuffer; X, Y: integer;
 | 
			
		||||
  var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer): boolean;
 | 
			
		||||
  out NewCode: TCodeBuffer; out NewX, NewY, NewTopLine: integer): boolean;
 | 
			
		||||
var
 | 
			
		||||
  CursorPos: TCodeXYPosition;
 | 
			
		||||
  NewPos: TCodeXYPosition;
 | 
			
		||||
@ -1507,6 +1543,33 @@ begin
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindDeclarationOfPropertyPath(Code: TCodeBuffer;
 | 
			
		||||
  const PropertyPath: string; out NewCode: TCodeBuffer; out NewX, NewY,
 | 
			
		||||
  NewTopLine: integer): Boolean;
 | 
			
		||||
var
 | 
			
		||||
  NewPos: TCodeXYPosition;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  {$IFDEF CTDEBUG}
 | 
			
		||||
  DebugLn('TCodeToolManager.FindDeclarationOfPropertyPath A ',Code.Filename,' Path="',PropertyPath,'"');
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  if not InitCurCodeTool(Code) then exit;
 | 
			
		||||
  try
 | 
			
		||||
    Result:=FCurCodeTool.FindDeclarationOfPropertyPath(PropertyPath,
 | 
			
		||||
                                                       NewPos,NewTopLine);
 | 
			
		||||
    if Result then begin
 | 
			
		||||
      NewX:=NewPos.X;
 | 
			
		||||
      NewY:=NewPos.Y;
 | 
			
		||||
      NewCode:=NewPos.Code;
 | 
			
		||||
    end;
 | 
			
		||||
  except
 | 
			
		||||
    on e: Exception do Result:=HandleException(e);
 | 
			
		||||
  end;
 | 
			
		||||
  {$IFDEF CTDEBUG}
 | 
			
		||||
  DebugLn('TCodeToolManager.FindDeclarationOfPropertyPath END ');
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindCodeContext(Code: TCodeBuffer; X, Y: integer; out
 | 
			
		||||
  CodeContexts: TCodeContextInfo): boolean;
 | 
			
		||||
var
 | 
			
		||||
@ -1632,6 +1695,7 @@ begin
 | 
			
		||||
    DebugLn('TCodeToolManager.FindReferences unable to FindMainDeclaration ',IdentifierCode.Filename,' x=',dbgs(x),' y=',dbgs(y));
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  if NewTopLine=0 then ;
 | 
			
		||||
  if not InitCurCodeTool(TargetCode) then exit;
 | 
			
		||||
  CursorPos.X:=NewX;
 | 
			
		||||
  CursorPos.Y:=NewY;
 | 
			
		||||
@ -2744,6 +2808,21 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindUnit(Code: TCodeBuffer; var AnUnitName,
 | 
			
		||||
  AnUnitInFilename: string): string;
 | 
			
		||||
begin
 | 
			
		||||
  Result:='';
 | 
			
		||||
  {$IFDEF CTDEBUG}
 | 
			
		||||
  DebugLn('TCodeToolManager.FindUnit A ',Code.Filename,' TheUnitName="',TheUnitName,'"');
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  if not InitCurCodeTool(Code) then exit;
 | 
			
		||||
  try
 | 
			
		||||
    Result:=FCurCodeTool.FindUnitCaseInsensitive(AnUnitName,AnUnitInFilename);
 | 
			
		||||
  except
 | 
			
		||||
    on e: Exception do HandleException(e);
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCodeToolManager.FindLFMFileName(Code: TCodeBuffer): string;
 | 
			
		||||
var LinkIndex: integer;
 | 
			
		||||
  CurCode: TCodeBuffer;
 | 
			
		||||
 | 
			
		||||
@ -682,16 +682,29 @@ type
 | 
			
		||||
      var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationInInterface(const Identifier: string;
 | 
			
		||||
      var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationWithMainUsesSection(const Identifier: string;
 | 
			
		||||
      var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationOfPropertyPath(const PropertyPath: string;
 | 
			
		||||
      var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
 | 
			
		||||
    function FindDeclarationNodeInInterface(const Identifier: string;
 | 
			
		||||
      BuildTheTree: Boolean): TCodeTreeNode;
 | 
			
		||||
 | 
			
		||||
    function FindMainUsesSection: TCodeTreeNode;
 | 
			
		||||
    function FindImplementationUsesSection: TCodeTreeNode;
 | 
			
		||||
 | 
			
		||||
    function FindUnitSource(const AnUnitName,
 | 
			
		||||
      AnUnitInFilename: string; ExceptionOnNotFound: boolean): TCodeBuffer;
 | 
			
		||||
    function FindUnitCaseInsensitive(var AnUnitName,
 | 
			
		||||
                                     AnUnitInFilename: string): string;
 | 
			
		||||
    procedure GatherUnitAndSrcPath(var UnitPath, SrcPath: string);
 | 
			
		||||
    function SearchUnitInUnitLinks(const TheUnitName: string): string;
 | 
			
		||||
    
 | 
			
		||||
    function FindSmartHint(const CursorPos: TCodeXYPosition): string;
 | 
			
		||||
    
 | 
			
		||||
    function BaseTypeOfNodeHasSubIdents(ANode: TCodeTreeNode): boolean;
 | 
			
		||||
    function FindBaseTypeOfNode(Params: TFindDeclarationParams;
 | 
			
		||||
      Node: TCodeTreeNode): TFindContext;
 | 
			
		||||
      
 | 
			
		||||
    function FindDeclarationAndOverload(const CursorPos: TCodeXYPosition;
 | 
			
		||||
      out ListOfPCodeXYPosition: TFPList): boolean;
 | 
			
		||||
    function FindClassAndAncestors(ClassNode: TCodeTreeNode;
 | 
			
		||||
@ -700,6 +713,7 @@ type
 | 
			
		||||
      var ListOfPFindContext: TFPList): boolean;
 | 
			
		||||
    function FindReferences(const CursorPos: TCodeXYPosition;
 | 
			
		||||
      SkipComments: boolean; out ListOfPCodeXYPosition: TFPList): boolean;
 | 
			
		||||
      
 | 
			
		||||
    function CleanPosIsDeclarationIdentifier(CleanPos: integer;
 | 
			
		||||
                                 Node: TCodeTreeNode): boolean;
 | 
			
		||||
    function FindCodeContext(const CursorPos: TCodeXYPosition;
 | 
			
		||||
@ -715,17 +729,17 @@ type
 | 
			
		||||
    function NodeIsForwardDeclaration(Node: TCodeTreeNode): boolean;
 | 
			
		||||
 | 
			
		||||
    property InterfaceIdentifierCache: TInterfaceIdentifierCache
 | 
			
		||||
      read FInterfaceIdentifierCache;
 | 
			
		||||
                                                 read FInterfaceIdentifierCache;
 | 
			
		||||
    property OnGetUnitSourceSearchPath: TOnGetSearchPath
 | 
			
		||||
      read FOnGetUnitSourceSearchPath write FOnGetUnitSourceSearchPath;
 | 
			
		||||
               read FOnGetUnitSourceSearchPath write FOnGetUnitSourceSearchPath;
 | 
			
		||||
    property OnFindUsedUnit: TOnFindUsedUnit
 | 
			
		||||
      read FOnFindUsedUnit write FOnFindUsedUnit;
 | 
			
		||||
                                     read FOnFindUsedUnit write FOnFindUsedUnit;
 | 
			
		||||
    property OnGetSrcPathForCompiledUnit: TOnGetSrcPathForCompiledUnit
 | 
			
		||||
      read FOnGetSrcPathForCompiledUnit write FOnGetSrcPathForCompiledUnit;
 | 
			
		||||
           read FOnGetSrcPathForCompiledUnit write FOnGetSrcPathForCompiledUnit;
 | 
			
		||||
    property OnGetCodeToolForBuffer: TOnGetCodeToolForBuffer
 | 
			
		||||
      read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer;
 | 
			
		||||
                     read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer;
 | 
			
		||||
    property AdjustTopLineDueToComment: boolean
 | 
			
		||||
        read FAdjustTopLineDueToComment write FAdjustTopLineDueToComment;
 | 
			
		||||
               read FAdjustTopLineDueToComment write FAdjustTopLineDueToComment;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
function ExprTypeToString(const ExprType: TExpressionType): string;
 | 
			
		||||
@ -1307,6 +1321,123 @@ end;
 | 
			
		||||
function TFindDeclarationTool.FindDeclarationInInterface(
 | 
			
		||||
  const Identifier: string; var NewPos: TCodeXYPosition; var NewTopLine: integer
 | 
			
		||||
  ): boolean;
 | 
			
		||||
var
 | 
			
		||||
  Node: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  if Identifier='' then exit;
 | 
			
		||||
  Node:=FindDeclarationNodeInInterface(Identifier,true);
 | 
			
		||||
  if Node<>nil then
 | 
			
		||||
    Result:=JumpToNode(Node,NewPos,NewTopLine,false);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindDeclarationWithMainUsesSection(
 | 
			
		||||
  const Identifier: string; var NewPos: TCodeXYPosition; var NewTopLine: integer
 | 
			
		||||
  ): boolean;
 | 
			
		||||
var
 | 
			
		||||
  UsesNode: TCodeTreeNode;
 | 
			
		||||
  Params: TFindDeclarationParams;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  if Identifier='' then exit;
 | 
			
		||||
  BuildTree(false);
 | 
			
		||||
  UsesNode:=FindMainUsesSection;
 | 
			
		||||
  if UsesNode=nil then exit;
 | 
			
		||||
 | 
			
		||||
  Params:=TFindDeclarationParams.Create;
 | 
			
		||||
  try
 | 
			
		||||
    Params.Flags:=[fdfExceptionOnNotFound];
 | 
			
		||||
    Params.SetIdentifier(Self,PChar(Identifier),nil);
 | 
			
		||||
    if FindIdentifierInUsesSection(UsesNode,Params) then begin
 | 
			
		||||
      if Params.NewNode=nil then exit;
 | 
			
		||||
      Result:=Params.NewCodeTool.JumpToNode(Params.NewNode,NewPos,
 | 
			
		||||
                                            NewTopLine,false);
 | 
			
		||||
    end;
 | 
			
		||||
  finally
 | 
			
		||||
    Params.Free;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindDeclarationOfPropertyPath(
 | 
			
		||||
  const PropertyPath: string; var NewPos: TCodeXYPosition;
 | 
			
		||||
  var NewTopLine: integer): boolean;
 | 
			
		||||
// example: PropertyPath='TForm1.Font.Color'
 | 
			
		||||
var
 | 
			
		||||
  StartPos: Integer;
 | 
			
		||||
 | 
			
		||||
  function GetNextIdentifier: string;
 | 
			
		||||
  var
 | 
			
		||||
    EndPos: LongInt;
 | 
			
		||||
  begin
 | 
			
		||||
    EndPos:=StartPos;
 | 
			
		||||
    while (EndPos<=length(PropertyPath)) and (IsIdentChar[PropertyPath[EndPos]])
 | 
			
		||||
    do inc(EndPos);
 | 
			
		||||
    if (EndPos<=length(PropertyPath)) and (PropertyPath[EndPos]<>'.') then
 | 
			
		||||
      Result:=''
 | 
			
		||||
    else begin
 | 
			
		||||
      Result:=copy(PropertyPath,StartPos,EndPos-StartPos);
 | 
			
		||||
      StartPos:=EndPos+1;
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
  
 | 
			
		||||
var
 | 
			
		||||
  Params: TFindDeclarationParams;
 | 
			
		||||
  Identifier: String;
 | 
			
		||||
  IsLastProperty: Boolean;
 | 
			
		||||
  Context: TFindContext;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  //DebugLn('TFindDeclarationTool.FindDeclarationOfPropertyPath PropertyPath="',PropertyPath,'"');
 | 
			
		||||
  if PropertyPath='' then exit;
 | 
			
		||||
  BuildTree(false);
 | 
			
		||||
 | 
			
		||||
  // first search the class in the interface
 | 
			
		||||
  StartPos:=1;
 | 
			
		||||
  Identifier:=GetNextIdentifier;
 | 
			
		||||
  if Identifier='' then exit;
 | 
			
		||||
  Context.Tool:=Self;
 | 
			
		||||
  Context.Node:=FindDeclarationNodeInInterface(Identifier,true);
 | 
			
		||||
  if Context.Node=nil then exit;
 | 
			
		||||
  Context.Node:=FindTypeNodeOfDefinition(Context.Node);
 | 
			
		||||
  if Context.Node=nil then exit;
 | 
			
		||||
  Params:=TFindDeclarationParams.Create;
 | 
			
		||||
  try
 | 
			
		||||
    // then search the properties
 | 
			
		||||
    repeat
 | 
			
		||||
      //DebugLn('TFindDeclarationTool.FindDeclarationOfPropertyPath ',Context.Node.DescAsString);
 | 
			
		||||
      if (not (Context.Node.Desc in [ctnClass,ctnClassInterface,ctnRecordType]))
 | 
			
		||||
      then
 | 
			
		||||
        exit;
 | 
			
		||||
      Params.Flags:=[fdfExceptionOnNotFound,fdfSearchInAncestors];
 | 
			
		||||
      Identifier:=GetNextIdentifier;
 | 
			
		||||
      //DebugLn('TFindDeclarationTool.FindDeclarationOfPropertyPath Identifier="',identifier,'"');
 | 
			
		||||
      if Identifier='' then exit;
 | 
			
		||||
      Params.SetIdentifier(Self,PChar(Identifier),nil);
 | 
			
		||||
      Params.ContextNode:=Context.Node;
 | 
			
		||||
      IsLastProperty:=StartPos>length(PropertyPath);
 | 
			
		||||
      if IsLastProperty then
 | 
			
		||||
        Params.Flags:=Params.Flags+[fdfFindVariable]
 | 
			
		||||
      else
 | 
			
		||||
        Params.Flags:=Params.Flags-[fdfFindVariable]+[fdfFunctionResult];
 | 
			
		||||
      if not Context.Tool.FindIdentifierInContext(Params) then exit;
 | 
			
		||||
      Context.Tool:=Params.NewCodeTool;
 | 
			
		||||
      Context.Node:=Params.NewNode;
 | 
			
		||||
      if Context.Node=nil then exit;
 | 
			
		||||
      if IsLastProperty then begin
 | 
			
		||||
        Result:=Context.Tool.JumpToNode(Context.Node,NewPos,NewTopLine,false);
 | 
			
		||||
        break;
 | 
			
		||||
      end else begin
 | 
			
		||||
        Context:=Context.Tool.FindBaseTypeOfNode(Params,Context.Node);
 | 
			
		||||
        if Context.Node=nil then exit;
 | 
			
		||||
      end;
 | 
			
		||||
     until false;
 | 
			
		||||
  finally
 | 
			
		||||
    Params.Free;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindDeclarationNodeInInterface(
 | 
			
		||||
  const Identifier: string; BuildTheTree: Boolean): TCodeTreeNode;
 | 
			
		||||
var
 | 
			
		||||
  StartNode: TCodeTreeNode;
 | 
			
		||||
  SectionNode: TCodeTreeNode;
 | 
			
		||||
@ -1315,10 +1446,14 @@ var
 | 
			
		||||
  CurNodeIsForwardDeclaration: Boolean;
 | 
			
		||||
  BestNode: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  Result:=nil;
 | 
			
		||||
  if Identifier='' then exit;
 | 
			
		||||
  BuildTree(true);
 | 
			
		||||
  StartNode:=FindInterfaceNode;
 | 
			
		||||
  if BuildTheTree then BuildTree(true);
 | 
			
		||||
  if Tree.Root=nil then exit;
 | 
			
		||||
  if Tree.Root.Desc=ctnUnit then
 | 
			
		||||
    StartNode:=FindInterfaceNode
 | 
			
		||||
  else
 | 
			
		||||
    StartNode:=Tree.Root;
 | 
			
		||||
  if StartNode=nil then exit;
 | 
			
		||||
  SectionNode:=StartNode.FirstChild;
 | 
			
		||||
  if SectionNode=nil then exit;
 | 
			
		||||
@ -1342,8 +1477,32 @@ begin
 | 
			
		||||
    end;
 | 
			
		||||
    SectionNode:=SectionNode.NextBrother;
 | 
			
		||||
  end;
 | 
			
		||||
  if BestNode<>nil then
 | 
			
		||||
    Result:=JumpToNode(BestNode,NewPos,NewTopLine,false);
 | 
			
		||||
  Result:=BestNode;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindMainUsesSection: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=Tree.Root;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  if Result.Desc=ctnUnit then begin
 | 
			
		||||
    Result:=Result.NextBrother;
 | 
			
		||||
    if Result=nil then exit;
 | 
			
		||||
  end;
 | 
			
		||||
  Result:=Result.FirstChild;
 | 
			
		||||
  if (Result=nil) then exit;
 | 
			
		||||
  if (Result.Desc<>ctnUsesSection) then Result:=nil;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindImplementationUsesSection: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=Tree.Root;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  while (Result<>nil) and (Result.Desc<>ctnImplementation) do
 | 
			
		||||
    Result:=Result.NextBrother;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  Result:=Result.FirstChild;
 | 
			
		||||
  if (Result=nil) then exit;
 | 
			
		||||
  if (Result.Desc<>ctnUsesSection) then Result:=nil;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TFindDeclarationTool.FindDeclarationInUsesSection(
 | 
			
		||||
 | 
			
		||||
@ -84,8 +84,6 @@ type
 | 
			
		||||
          var NamePos, InPos: TAtomPosition): boolean;
 | 
			
		||||
    function FindUnitInAllUsesSections(const UpperUnitName: string;
 | 
			
		||||
          var NamePos, InPos: TAtomPosition): boolean;
 | 
			
		||||
    function FindMainUsesSection: TCodeTreeNode;
 | 
			
		||||
    function FindImplementationUsesSection: TCodeTreeNode;
 | 
			
		||||
    function RenameUsedUnit(const OldUpperUnitName, NewUnitName,
 | 
			
		||||
          NewUnitInFile: string;
 | 
			
		||||
          SourceChangeCache: TSourceChangeCache): boolean;
 | 
			
		||||
@ -413,31 +411,6 @@ begin
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TStandardCodeTool.FindMainUsesSection: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=Tree.Root;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  if Result.Desc=ctnUnit then begin
 | 
			
		||||
    Result:=Result.NextBrother;
 | 
			
		||||
    if Result=nil then exit;
 | 
			
		||||
  end;
 | 
			
		||||
  Result:=Result.FirstChild;
 | 
			
		||||
  if (Result=nil) then exit;
 | 
			
		||||
  if (Result.Desc<>ctnUsesSection) then Result:=nil;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TStandardCodeTool.FindImplementationUsesSection: TCodeTreeNode;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=Tree.Root;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  while (Result<>nil) and (Result.Desc<>ctnImplementation) do
 | 
			
		||||
    Result:=Result.NextBrother;
 | 
			
		||||
  if Result=nil then exit;
 | 
			
		||||
  Result:=Result.FirstChild;
 | 
			
		||||
  if (Result=nil) then exit;
 | 
			
		||||
  if (Result.Desc<>ctnUsesSection) then Result:=nil;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TStandardCodeTool.RenameUsedUnit(const OldUpperUnitName,
 | 
			
		||||
  NewUnitName, NewUnitInFile: string;
 | 
			
		||||
  SourceChangeCache: TSourceChangeCache): boolean;
 | 
			
		||||
 | 
			
		||||
@ -23,9 +23,11 @@ unit ObjInspExt;
 | 
			
		||||
interface
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  Classes, SysUtils, ObjectInspector, Forms, Controls, Buttons, StdCtrls,
 | 
			
		||||
  ExtCtrls, Dialogs, LCLProc,
 | 
			
		||||
  FileUtil, LazConf, ConfigStorage, LazarusIDEStrConsts;
 | 
			
		||||
  Classes, SysUtils, LCLProc, Forms, Controls, Buttons, StdCtrls, TypInfo,
 | 
			
		||||
  ExtCtrls, Dialogs, Menus,
 | 
			
		||||
  CodeToolManager, CodeCache,
 | 
			
		||||
  LazIDEIntf, ProjectIntf, ObjectInspector, PropEdits,
 | 
			
		||||
  DialogProcs, FileUtil, LazConf, ConfigStorage, LazarusIDEStrConsts;
 | 
			
		||||
  
 | 
			
		||||
type
 | 
			
		||||
  { TOIAddRemoveFavouriteDlg }
 | 
			
		||||
@ -67,6 +69,9 @@ function LoadOIFavouriteProperties: TOIFavouriteProperties;
 | 
			
		||||
procedure SaveOIFavouriteProperties(Favourites: TOIFavouriteProperties);
 | 
			
		||||
function GetOIFavouriteConfigFilename: string;
 | 
			
		||||
 | 
			
		||||
function FindDeclarationOfOIProperty(AnInspector: TObjectInspector;
 | 
			
		||||
  Row: TOIPropertyGridRow; out Code: TCodeBuffer; out Caret: TPoint): Boolean;
 | 
			
		||||
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
function CreateDefaultOIFavouriteProperties: TOIFavouriteProperties;
 | 
			
		||||
@ -81,7 +86,7 @@ begin
 | 
			
		||||
  // TControl
 | 
			
		||||
  Add(TComponent,'Name');
 | 
			
		||||
  Add(TControl,'Anchors');
 | 
			
		||||
  Add(TControl,'Caption');
 | 
			
		||||
  Add(TComponent,'Caption');
 | 
			
		||||
  Add(TControl,'OnClick');
 | 
			
		||||
  // miscellaneous
 | 
			
		||||
  Add(TCustomGroupBox,'Align');
 | 
			
		||||
@ -184,6 +189,67 @@ begin
 | 
			
		||||
  Result:=AppendPathDelim(GetPrimaryConfigPath)+DefaultOIFavouriteConfigFilename;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function FindDeclarationOfOIProperty(AnInspector: TObjectInspector;
 | 
			
		||||
  Row: TOIPropertyGridRow; out Code: TCodeBuffer; out Caret: TPoint): Boolean;
 | 
			
		||||
var
 | 
			
		||||
  PropPath: String;
 | 
			
		||||
  LookupRoot: TPersistent;
 | 
			
		||||
  AFile: TLazProjectFile;
 | 
			
		||||
  NewCode: TCodeBuffer;
 | 
			
		||||
  NewX, NewY, NewTopLine: integer;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=false;
 | 
			
		||||
  Code:=nil;
 | 
			
		||||
  Caret:=Point(0,0);
 | 
			
		||||
  if AnInspector=nil then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty AnInspector=nil');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  if Row=nil then
 | 
			
		||||
    Row:=AnInspector.GetActivePropertyRow;
 | 
			
		||||
  if Row=nil then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty Row=nil');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  // get the unit filename of the LookupRoot
 | 
			
		||||
  if AnInspector.PropertyEditorHook=nil then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty AnInspector.PropertyEditorHook=nil');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  LookupRoot:=AnInspector.PropertyEditorHook.LookupRoot;
 | 
			
		||||
  if not (LookupRoot is TComponent) then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty not (LookupRoot is TComponent)');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  AFile:=LazarusIDE.GetProjectFileWithRootComponent(TComponent(LookupRoot));
 | 
			
		||||
  if AFile=nil then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty AFile=nil');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  if not LazarusIDE.BeginCodeTools then begin
 | 
			
		||||
    DebugLn('FindDeclarationOfOIProperty not LazarusIDE.BeginCodeTools');
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  Code:=nil;
 | 
			
		||||
  if LoadCodeBuffer(Code,AFile.Filename,[])<>mrOk then begin
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  // create the property search path
 | 
			
		||||
  PropPath:=LookupRoot.ClassName+'.'+
 | 
			
		||||
            AnInspector.GetActivePropertyGrid.PropertyPath(Row);
 | 
			
		||||
  // find the property declaration
 | 
			
		||||
  if not CodeToolBoss.FindDeclarationOfPropertyPath(Code,PropPath,NewCode,
 | 
			
		||||
    NewX,NewY,NewTopLine) then
 | 
			
		||||
  begin
 | 
			
		||||
    LazarusIDE.DoJumpToCodeToolBossError;
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  Code:=NewCode;
 | 
			
		||||
  Caret:=Point(NewX,NewY);
 | 
			
		||||
  DebugLn('FindDeclarationOfOIProperty SUCCESS ',Code.Filename,' ',dbgs(Caret));
 | 
			
		||||
  Result:=true;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TOIAddRemoveFavouriteDlg }
 | 
			
		||||
 | 
			
		||||
procedure TOIAddRemoveFavouriteDlg.OkButtonClick(Sender: TObject);
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ uses
 | 
			
		||||
  PropEdits, ObjectInspector, FormEditingIntf, ProjectIntf,
 | 
			
		||||
  HelpIntf, HelpHTML, HelpFPDoc, MacroIntf, IDEWindowIntf, MsgIntf, LazIDEIntf,
 | 
			
		||||
  LazarusIDEStrConsts, TransferMacros, DialogProcs, IDEOptionDefs,
 | 
			
		||||
  EnvironmentOpts, AboutFrm, MsgView, Project, PackageDefs, MainBar,
 | 
			
		||||
  ObjInspExt, EnvironmentOpts, AboutFrm, MsgView, Project, PackageDefs, MainBar,
 | 
			
		||||
  OutputFilter, HelpOptions, MainIntf, LazConf, ExtCtrls, LResources,
 | 
			
		||||
  Interfaces;
 | 
			
		||||
 | 
			
		||||
@ -621,30 +621,16 @@ end;
 | 
			
		||||
procedure THelpManager.ShowHelpForObjectInspector(Sender: TObject);
 | 
			
		||||
var
 | 
			
		||||
  AnInspector: TObjectInspector;
 | 
			
		||||
  Row: TOIPropertyGridRow;
 | 
			
		||||
  LookupRoot: TPersistent;
 | 
			
		||||
  AFile: TLazProjectFile;
 | 
			
		||||
  Code: TCodeBuffer;
 | 
			
		||||
  Caret: TPoint;
 | 
			
		||||
  ErrMsg: string;
 | 
			
		||||
begin
 | 
			
		||||
  DebugLn('THelpManager.ShowHelpForObjectInspector ',dbgsName(Sender));
 | 
			
		||||
  if Sender=nil then Sender:=ObjectInspector1;
 | 
			
		||||
  if Sender is TObjectInspector then begin
 | 
			
		||||
    AnInspector:=TObjectInspector(Sender);
 | 
			
		||||
    Row:=AnInspector.GetActivePropertyRow;
 | 
			
		||||
    if Row=nil then begin
 | 
			
		||||
      // TODO: show help about object inspector
 | 
			
		||||
      DebugLn('THelpManager.ShowHelpForObjectInspector TODO: show help about object inspector');
 | 
			
		||||
    end else begin
 | 
			
		||||
      // find unit of LookupRoot
 | 
			
		||||
      if AnInspector.PropertyEditorHook=nil then exit;
 | 
			
		||||
      LookupRoot:=AnInspector.PropertyEditorHook.LookupRoot;
 | 
			
		||||
      if not (LookupRoot is TComponent) then exit;
 | 
			
		||||
      AFile:=LazarusIDE.GetProjectFileWithRootComponent(TComponent(LookupRoot));
 | 
			
		||||
      if AFile=nil then exit;
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
      if Row.Editor=nil then exit;
 | 
			
		||||
      if Row.Editor.GetPropInfo=nil then exit;
 | 
			
		||||
      
 | 
			
		||||
    if FindDeclarationOfOIProperty(AnInspector,nil,Code,Caret) then begin
 | 
			
		||||
      ShowHelpForSourcePosition(Code.Filename,Caret,ErrMsg);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -402,6 +402,7 @@ type
 | 
			
		||||
    function GridHeight: integer;
 | 
			
		||||
    function MouseToIndex(y: integer; MustExist: boolean):integer;
 | 
			
		||||
    function PropertyPath(Index: integer):string;
 | 
			
		||||
    function PropertyPath(Row: TOIPropertyGridRow):string;
 | 
			
		||||
    function TopMax: integer;
 | 
			
		||||
    procedure BuildPropertyList;
 | 
			
		||||
    procedure Clear;
 | 
			
		||||
@ -978,17 +979,25 @@ begin
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TOICustomPropertyGrid.PropertyPath(Index:integer):string;
 | 
			
		||||
var CurRow:TOIPropertyGridRow;
 | 
			
		||||
begin
 | 
			
		||||
  if (Index>=0) and (Index<FRows.Count) then begin
 | 
			
		||||
    CurRow:=Rows[Index];
 | 
			
		||||
    Result:=CurRow.Name;
 | 
			
		||||
    CurRow:=CurRow.Parent;
 | 
			
		||||
    while CurRow<>nil do begin
 | 
			
		||||
      Result:=CurRow.Name+'.'+Result;
 | 
			
		||||
      CurRow:=CurRow.Parent;
 | 
			
		||||
    end;
 | 
			
		||||
  end else Result:='';
 | 
			
		||||
    Result:=PropertyPath(Rows[Index]);
 | 
			
		||||
  end else
 | 
			
		||||
    Result:='';
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TOICustomPropertyGrid.PropertyPath(Row: TOIPropertyGridRow): string;
 | 
			
		||||
begin
 | 
			
		||||
  if Row=nil then begin
 | 
			
		||||
    Result:='';
 | 
			
		||||
    exit;
 | 
			
		||||
  end;
 | 
			
		||||
  Result:=Row.Name;
 | 
			
		||||
  Row:=Row.Parent;
 | 
			
		||||
  while Row<>nil do begin
 | 
			
		||||
    Result:=Row.Name+'.'+Result;
 | 
			
		||||
    Row:=Row.Parent;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TOICustomPropertyGrid.GetRowByPath(
 | 
			
		||||
 | 
			
		||||
@ -297,6 +297,7 @@ type
 | 
			
		||||
    function GetAttributes: TPropertyAttributes; virtual;
 | 
			
		||||
    function IsReadOnly: boolean; virtual;
 | 
			
		||||
    function GetComponent(Index: Integer): TPersistent;// for Delphi compatibility
 | 
			
		||||
    function GetUnitName(Index: Integer): string;
 | 
			
		||||
    function GetEditLimit: Integer; virtual;
 | 
			
		||||
    function GetName: shortstring; virtual;
 | 
			
		||||
    procedure GetProperties(Proc: TGetPropEditProc); virtual;
 | 
			
		||||
@ -2034,6 +2035,11 @@ begin
 | 
			
		||||
  Result:=FPropList^[Index].Instance;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TPropertyEditor.GetUnitName(Index: Integer): string;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=GetClassUnitName(GetComponent(Index).ClassType);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TPropertyEditor.GetFloatValue:Extended;
 | 
			
		||||
begin
 | 
			
		||||
  Result:=GetFloatValueAt(0);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user