mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 07:36:14 +02:00
IDE: implemented using Ancestor component when saving inherited root component, codetools: added flag to search in ancestors for dangling events
git-svn-id: trunk@10046 -
This commit is contained in:
parent
b6f164d0aa
commit
c038401b5b
@ -540,7 +540,8 @@ type
|
|||||||
VarType: shortstring; ErrorOnClassNotFound: boolean): boolean;
|
VarType: shortstring; ErrorOnClassNotFound: boolean): boolean;
|
||||||
function FindDanglingComponentEvents(Code: TCodeBuffer;
|
function FindDanglingComponentEvents(Code: TCodeBuffer;
|
||||||
const AClassName: string;
|
const AClassName: string;
|
||||||
RootComponent: TComponent; ExceptionOnClassNotFound: boolean;
|
RootComponent: TComponent; ExceptionOnClassNotFound,
|
||||||
|
SearchInAncestors: boolean;
|
||||||
out ListOfPInstancePropInfo: TFPList): boolean;
|
out ListOfPInstancePropInfo: TFPList): boolean;
|
||||||
|
|
||||||
// functions for events in the object inspector
|
// functions for events in the object inspector
|
||||||
@ -3571,7 +3572,8 @@ end;
|
|||||||
|
|
||||||
function TCodeToolManager.FindDanglingComponentEvents(Code: TCodeBuffer;
|
function TCodeToolManager.FindDanglingComponentEvents(Code: TCodeBuffer;
|
||||||
const AClassName: string; RootComponent: TComponent;
|
const AClassName: string; RootComponent: TComponent;
|
||||||
ExceptionOnClassNotFound: boolean; out ListOfPInstancePropInfo: TFPList
|
ExceptionOnClassNotFound, SearchInAncestors: boolean;
|
||||||
|
out ListOfPInstancePropInfo: TFPList
|
||||||
): boolean;
|
): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
@ -3582,7 +3584,8 @@ begin
|
|||||||
if not InitCurCodeTool(Code) then exit;
|
if not InitCurCodeTool(Code) then exit;
|
||||||
try
|
try
|
||||||
Result:=FCurCodeTool.FindDanglingComponentEvents(AClassName,RootComponent,
|
Result:=FCurCodeTool.FindDanglingComponentEvents(AClassName,RootComponent,
|
||||||
ExceptionOnClassNotFound,ListOfPInstancePropInfo);
|
ExceptionOnClassNotFound,SearchInAncestors,
|
||||||
|
ListOfPInstancePropInfo);
|
||||||
except
|
except
|
||||||
on e: Exception do Result:=HandleException(e);
|
on e: Exception do Result:=HandleException(e);
|
||||||
end;
|
end;
|
||||||
|
@ -185,10 +185,11 @@ type
|
|||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
function GatherPublishedClassElements(const TheClassName: string;
|
function GatherPublishedClassElements(const TheClassName: string;
|
||||||
ExceptionOnClassNotFound, WithVariables, WithMethods,
|
ExceptionOnClassNotFound, WithVariables, WithMethods,
|
||||||
WithProperties: boolean;
|
WithProperties, WithAncestors: boolean;
|
||||||
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
|
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
|
||||||
function FindDanglingComponentEvents(const TheClassName: string;
|
function FindDanglingComponentEvents(const TheClassName: string;
|
||||||
RootComponent: TComponent; ExceptionOnClassNotFound: boolean;
|
RootComponent: TComponent; ExceptionOnClassNotFound,
|
||||||
|
SearchInAncestors: boolean;
|
||||||
out ListOfPInstancePropInfo: TFPList): boolean;
|
out ListOfPInstancePropInfo: TFPList): boolean;
|
||||||
|
|
||||||
// blocks (e.g. begin..end)
|
// blocks (e.g. begin..end)
|
||||||
@ -4026,15 +4027,71 @@ end;
|
|||||||
|
|
||||||
function TStandardCodeTool.GatherPublishedClassElements(
|
function TStandardCodeTool.GatherPublishedClassElements(
|
||||||
const TheClassName: string;
|
const TheClassName: string;
|
||||||
ExceptionOnClassNotFound, WithVariables, WithMethods, WithProperties: boolean;
|
ExceptionOnClassNotFound, WithVariables, WithMethods, WithProperties,
|
||||||
|
WithAncestors: boolean;
|
||||||
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
|
out TreeOfCodeTreeNodeExtension: TAVLTree): boolean;
|
||||||
|
|
||||||
|
function Add(AFindContext: PFindContext): boolean;
|
||||||
|
var
|
||||||
|
ClassNode: TCodeTreeNode;
|
||||||
|
CurTool: TFindDeclarationTool;
|
||||||
|
SectionNode: TCodeTreeNode;
|
||||||
|
ANode: TCodeTreeNode;
|
||||||
|
CurProcName: String;
|
||||||
|
NewNodeExt: TCodeTreeNodeExtension;
|
||||||
|
CurPropName: String;
|
||||||
|
CurVarName: String;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
ClassNode:=AFindContext^.Node;
|
||||||
|
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) then exit;
|
||||||
|
CurTool:=AFindContext^.Tool;
|
||||||
|
CurTool.BuildSubTreeForClass(ClassNode);
|
||||||
|
SectionNode:=ClassNode.FirstChild;
|
||||||
|
while (SectionNode<>nil) do begin
|
||||||
|
if SectionNode.Desc=ctnClassPublished then begin
|
||||||
|
ANode:=SectionNode.FirstChild;
|
||||||
|
while ANode<>nil do begin
|
||||||
|
if (ANode.Desc=ctnProcedure) and WithMethods then begin
|
||||||
|
CurProcName:=CurTool.ExtractProcName(ANode,[]);
|
||||||
|
//debugln('TStandardCodeTool.GatherPublishedClassElements CurProcName="',CurProcName,'"');
|
||||||
|
NewNodeExt:=NodeExtMemManager.NewNode;
|
||||||
|
with NewNodeExt do begin
|
||||||
|
Node:=ANode;
|
||||||
|
Txt:=CurProcName;
|
||||||
|
end;
|
||||||
|
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
||||||
|
end
|
||||||
|
else if (ANode.Desc=ctnVarDefinition) and WithVariables then begin
|
||||||
|
CurVarName:=CurTool.ExtractDefinitionName(ANode);
|
||||||
|
NewNodeExt:=NodeExtMemManager.NewNode;
|
||||||
|
with NewNodeExt do begin
|
||||||
|
Node:=ANode;
|
||||||
|
Txt:=CurVarName;
|
||||||
|
end;
|
||||||
|
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
||||||
|
end
|
||||||
|
else if (ANode.Desc=ctnProperty) and WithProperties then begin
|
||||||
|
CurPropName:=CurTool.ExtractPropName(ANode,false);
|
||||||
|
NewNodeExt:=NodeExtMemManager.NewNode;
|
||||||
|
with NewNodeExt do begin
|
||||||
|
Node:=ANode;
|
||||||
|
Txt:=CurPropName;
|
||||||
|
end;
|
||||||
|
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
||||||
|
end;
|
||||||
|
ANode:=ANode.NextBrother;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
SectionNode:=SectionNode.NextBrother;
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
ClassNode, SectionNode: TCodeTreeNode;
|
ClassNode: TCodeTreeNode;
|
||||||
ANode: TCodeTreeNode;
|
AncestorList: TFPList;// of PFindContext
|
||||||
CurProcName: String;
|
i: Integer;
|
||||||
NewNodeExt: TCodeTreeNodeExtension;
|
|
||||||
CurVarName: String;
|
|
||||||
CurPropName: String;
|
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
TreeOfCodeTreeNodeExtension:=nil;
|
TreeOfCodeTreeNodeExtension:=nil;
|
||||||
@ -4044,52 +4101,26 @@ begin
|
|||||||
ClassNode:=FindClassNodeInInterface(TheClassName,true,false,
|
ClassNode:=FindClassNodeInInterface(TheClassName,true,false,
|
||||||
ExceptionOnClassNotFound);
|
ExceptionOnClassNotFound);
|
||||||
if ClassNode=nil then exit;
|
if ClassNode=nil then exit;
|
||||||
TreeOfCodeTreeNodeExtension:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
AncestorList:=nil;
|
||||||
BuildSubTreeForClass(ClassNode);
|
try
|
||||||
SectionNode:=ClassNode.FirstChild;
|
if WithAncestors then begin
|
||||||
while (SectionNode<>nil) do begin
|
if not FindClassAndAncestors(ClassNode,AncestorList) then exit;
|
||||||
if SectionNode.Desc=ctnClassPublished then begin
|
end else begin
|
||||||
ANode:=SectionNode.FirstChild;
|
AddFindContext(AncestorList,CreateFindContext(Self,ClassNode));
|
||||||
while ANode<>nil do begin
|
|
||||||
if (ANode.Desc=ctnProcedure) and WithMethods then begin
|
|
||||||
CurProcName:=ExtractProcName(ANode,[]);
|
|
||||||
//debugln('TStandardCodeTool.GatherPublishedClassElements CurProcName="',CurProcName,'"');
|
|
||||||
NewNodeExt:=NodeExtMemManager.NewNode;
|
|
||||||
with NewNodeExt do begin
|
|
||||||
Node:=ANode;
|
|
||||||
Txt:=CurProcName;
|
|
||||||
end;
|
|
||||||
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
|
||||||
end
|
|
||||||
else if (ANode.Desc=ctnVarDefinition) and WithVariables then begin
|
|
||||||
CurVarName:=ExtractDefinitionName(ANode);
|
|
||||||
NewNodeExt:=NodeExtMemManager.NewNode;
|
|
||||||
with NewNodeExt do begin
|
|
||||||
Node:=ANode;
|
|
||||||
Txt:=CurVarName;
|
|
||||||
end;
|
|
||||||
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
|
||||||
end
|
|
||||||
else if (ANode.Desc=ctnProperty) and WithProperties then begin
|
|
||||||
CurPropName:=ExtractPropName(ANode,false);
|
|
||||||
NewNodeExt:=NodeExtMemManager.NewNode;
|
|
||||||
with NewNodeExt do begin
|
|
||||||
Node:=ANode;
|
|
||||||
Txt:=CurPropName;
|
|
||||||
end;
|
|
||||||
TreeOfCodeTreeNodeExtension.Add(NewNodeExt);
|
|
||||||
end;
|
|
||||||
ANode:=ANode.NextBrother;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
SectionNode:=SectionNode.NextBrother;
|
TreeOfCodeTreeNodeExtension:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||||
|
for i:=0 to AncestorList.Count-1 do begin
|
||||||
|
if not Add(PFindContext(AncestorList[i])) then exit;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeListOfPFindContext(AncestorList);
|
||||||
end;
|
end;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TStandardCodeTool.FindDanglingComponentEvents(
|
function TStandardCodeTool.FindDanglingComponentEvents(
|
||||||
const TheClassName: string; RootComponent: TComponent;
|
const TheClassName: string; RootComponent: TComponent;
|
||||||
ExceptionOnClassNotFound: boolean;
|
ExceptionOnClassNotFound, SearchInAncestors: boolean;
|
||||||
out ListOfPInstancePropInfo: TFPList): boolean;
|
out ListOfPInstancePropInfo: TFPList): boolean;
|
||||||
var
|
var
|
||||||
PublishedMethods: TAVLTree;
|
PublishedMethods: TAVLTree;
|
||||||
@ -4165,7 +4196,8 @@ begin
|
|||||||
// search all available published methods
|
// search all available published methods
|
||||||
//debugln('TStandardCodeTool.FindDanglingComponentEvents A ',MainFilename,' ',DbgSName(RootComponent));
|
//debugln('TStandardCodeTool.FindDanglingComponentEvents A ',MainFilename,' ',DbgSName(RootComponent));
|
||||||
Result:=GatherPublishedClassElements(TheClassName,ExceptionOnClassNotFound,
|
Result:=GatherPublishedClassElements(TheClassName,ExceptionOnClassNotFound,
|
||||||
false,true,false,PublishedMethods);
|
false,true,false,SearchInAncestors,
|
||||||
|
PublishedMethods);
|
||||||
if not Result then exit;
|
if not Result then exit;
|
||||||
// go through all components
|
// go through all components
|
||||||
CheckMethodsInComponent(RootComponent);
|
CheckMethodsInComponent(RootComponent);
|
||||||
|
@ -246,7 +246,7 @@ begin
|
|||||||
// find all dangling events
|
// find all dangling events
|
||||||
//debugln('RemoveDanglingEvents A ',PascalBuffer.Filename,' ',DbgSName(RootComponent));
|
//debugln('RemoveDanglingEvents A ',PascalBuffer.Filename,' ',DbgSName(RootComponent));
|
||||||
if not CodeToolBoss.FindDanglingComponentEvents(PascalBuffer,
|
if not CodeToolBoss.FindDanglingComponentEvents(PascalBuffer,
|
||||||
RootComponent.ClassName,RootComponent,false,ListOfPInstancePropInfo)
|
RootComponent.ClassName,RootComponent,false,true,ListOfPInstancePropInfo)
|
||||||
then begin
|
then begin
|
||||||
//debugln('RemoveDanglingEvents Errors in code');
|
//debugln('RemoveDanglingEvents Errors in code');
|
||||||
if OkOnCodeErrors then
|
if OkOnCodeErrors then
|
||||||
|
@ -881,7 +881,7 @@ Begin
|
|||||||
DebugLn(['WARNING: TCustomFormEditor.DeleteComponent freeing orphaned component ',DbgSName(AComponent)]);
|
DebugLn(['WARNING: TCustomFormEditor.DeleteComponent freeing orphaned component ',DbgSName(AComponent)]);
|
||||||
TryFreeComponent(AComponent);
|
TryFreeComponent(AComponent);
|
||||||
end;
|
end;
|
||||||
// if not free, then free the handle to hide it
|
// if not free, then hide it
|
||||||
if (not FreeComponent) and (AComponent is TWinControl) then begin
|
if (not FreeComponent) and (AComponent is TWinControl) then begin
|
||||||
AWinControl:=TWinControl(AComponent);
|
AWinControl:=TWinControl(AComponent);
|
||||||
if AWinControl.HandleAllocated and (AWinControl.Parent=nil) then begin
|
if AWinControl.HandleAllocated and (AWinControl.Parent=nil) then begin
|
||||||
|
33
ide/main.pp
33
ide/main.pp
@ -554,9 +554,9 @@ type
|
|||||||
// methods for 'save unit'
|
// methods for 'save unit'
|
||||||
function DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
|
function DoShowSaveFileAsDialog(AnUnitInfo: TUnitInfo;
|
||||||
var ResourceCode: TCodeBuffer): TModalResult;
|
var ResourceCode: TCodeBuffer): TModalResult;
|
||||||
function DoSaveFileResources(AnUnitInfo: TUnitInfo;
|
function DoSaveUnitComponent(AnUnitInfo: TUnitInfo;
|
||||||
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
||||||
function DoSaveFileResourceToBinStream(AnUnitInfo: TUnitInfo;
|
function DoSaveUnitComponentToBinStream(AnUnitInfo: TUnitInfo;
|
||||||
var BinCompStream: TExtMemoryStream): TModalResult;
|
var BinCompStream: TExtMemoryStream): TModalResult;
|
||||||
function DoRemoveDanglingEvents(AnUnitInfo: TUnitInfo;
|
function DoRemoveDanglingEvents(AnUnitInfo: TUnitInfo;
|
||||||
OkOnCodeErrors: boolean): TModalResult;
|
OkOnCodeErrors: boolean): TModalResult;
|
||||||
@ -592,6 +592,7 @@ type
|
|||||||
Flags: TCloseFlags): TModalResult;
|
Flags: TCloseFlags): TModalResult;
|
||||||
function UnitComponentIsUsed(AnUnitInfo: TUnitInfo;
|
function UnitComponentIsUsed(AnUnitInfo: TUnitInfo;
|
||||||
CheckHasDesigner: boolean): boolean;
|
CheckHasDesigner: boolean): boolean;
|
||||||
|
function GetAncestorUnit(AnUnitInfo: TUnitInfo): TUnitInfo;
|
||||||
|
|
||||||
// methods for creating a project
|
// methods for creating a project
|
||||||
function CreateProjectObject(ProjectDesc,
|
function CreateProjectObject(ProjectDesc,
|
||||||
@ -4027,7 +4028,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
function TMainIDE.DoSaveFileResources(AnUnitInfo: TUnitInfo;
|
function TMainIDE.DoSaveUnitComponent(AnUnitInfo: TUnitInfo;
|
||||||
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
ResourceCode, LFMCode: TCodeBuffer; Flags: TSaveFlags): TModalResult;
|
||||||
var
|
var
|
||||||
ComponentSavingOk: boolean;
|
ComponentSavingOk: boolean;
|
||||||
@ -4038,6 +4039,8 @@ var
|
|||||||
CompResourceCode, LFMFilename, TestFilename, ResTestFilename: string;
|
CompResourceCode, LFMFilename, TestFilename, ResTestFilename: string;
|
||||||
UnitSaveFilename: String;
|
UnitSaveFilename: String;
|
||||||
ADesigner: TDesigner;
|
ADesigner: TDesigner;
|
||||||
|
AncestorUnit: TUnitInfo;
|
||||||
|
AncestorInstance: TComponent;
|
||||||
{$IFDEF TRANSLATESTRING}Grubber:TLRTGrubber;{$ENDIF}
|
{$IFDEF TRANSLATESTRING}Grubber:TLRTGrubber;{$ENDIF}
|
||||||
begin
|
begin
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
@ -4086,7 +4089,13 @@ begin
|
|||||||
Grubber:=TLRTGrubber.Create;
|
Grubber:=TLRTGrubber.Create;
|
||||||
Writer.OnWriteStringProperty:=@Grubber.Grub;
|
Writer.OnWriteStringProperty:=@Grubber.Grub;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Writer.WriteDescendent(AnUnitInfo.Component,nil);
|
AncestorUnit:=GetAncestorUnit(AnUnitInfo);
|
||||||
|
if AncestorUnit<>nil then
|
||||||
|
AncestorInstance:=AncestorUnit.Component
|
||||||
|
else
|
||||||
|
AncestorInstance:=nil;
|
||||||
|
DebugLn(['TMainIDE.DoSaveUnitComponent AncestorInstance=',dbgsName(AncestorInstance)]);
|
||||||
|
Writer.WriteDescendent(AnUnitInfo.Component,AncestorInstance);
|
||||||
if DestroyDriver then Writer.Driver.Free;
|
if DestroyDriver then Writer.Driver.Free;
|
||||||
FreeAndNil(Writer);
|
FreeAndNil(Writer);
|
||||||
AnUnitInfo.ComponentLastBinStreamSize:=BinCompStream.Size;
|
AnUnitInfo.ComponentLastBinStreamSize:=BinCompStream.Size;
|
||||||
@ -4294,7 +4303,7 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMainIDE.DoSaveFileResourceToBinStream(AnUnitInfo: TUnitInfo;
|
function TMainIDE.DoSaveUnitComponentToBinStream(AnUnitInfo: TUnitInfo;
|
||||||
var BinCompStream: TExtMemoryStream): TModalResult;
|
var BinCompStream: TExtMemoryStream): TModalResult;
|
||||||
var
|
var
|
||||||
Writer: TWriter;
|
Writer: TWriter;
|
||||||
@ -4868,7 +4877,7 @@ begin
|
|||||||
OpenFlags,AncestorType,AncestorUnitInfo);
|
OpenFlags,AncestorType,AncestorUnitInfo);
|
||||||
if Result=mrAbort then exit;
|
if Result=mrAbort then exit;
|
||||||
if Result=mrOk then begin
|
if Result=mrOk then begin
|
||||||
Result:=DoSaveFileResourceToBinStream(AncestorUnitInfo,
|
Result:=DoSaveUnitComponentToBinStream(AncestorUnitInfo,
|
||||||
AncestorBinStream);
|
AncestorBinStream);
|
||||||
if Result<>mrOk then exit;
|
if Result<>mrOk then exit;
|
||||||
AncestorBinStream.Position:=0;
|
AncestorBinStream.Position:=0;
|
||||||
@ -4923,6 +4932,8 @@ begin
|
|||||||
NewComponent:=FormEditor1.CreateRawComponentFromStream(BinStream,
|
NewComponent:=FormEditor1.CreateRawComponentFromStream(BinStream,
|
||||||
AncestorType,AncestorBinStream,copy(NewUnitName,1,255),true);
|
AncestorType,AncestorBinStream,copy(NewUnitName,1,255),true);
|
||||||
AnUnitInfo.Component:=NewComponent;
|
AnUnitInfo.Component:=NewComponent;
|
||||||
|
if (AncestorUnitInfo<>nil) then
|
||||||
|
AnUnitInfo.AddRequiresComponentDependency(AncestorUnitInfo);
|
||||||
if NewComponent=nil then begin
|
if NewComponent=nil then begin
|
||||||
// error streaming component -> examine lfm file
|
// error streaming component -> examine lfm file
|
||||||
DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"');
|
DebugLn('ERROR: streaming failed lfm="',LFMBuf.Filename,'"');
|
||||||
@ -5266,6 +5277,14 @@ begin
|
|||||||
exit(true);
|
exit(true);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TMainIDE.GetAncestorUnit(AnUnitInfo: TUnitInfo): TUnitInfo;
|
||||||
|
begin
|
||||||
|
if (AnUnitInfo=nil) or (AnUnitInfo.Component=nil) then
|
||||||
|
Result:=nil
|
||||||
|
else
|
||||||
|
Result:=AnUnitInfo.FindAncestorUnit;
|
||||||
|
end;
|
||||||
|
|
||||||
function TMainIDE.CreateProjectObject(ProjectDesc,
|
function TMainIDE.CreateProjectObject(ProjectDesc,
|
||||||
FallbackProjectDesc: TProjectDescriptor): TProject;
|
FallbackProjectDesc: TProjectDescriptor): TProject;
|
||||||
begin
|
begin
|
||||||
@ -6019,7 +6038,7 @@ begin
|
|||||||
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TMainIDE.DoSaveEditorFile B');{$ENDIF}
|
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TMainIDE.DoSaveEditorFile B');{$ENDIF}
|
||||||
// save resource file and lfm file
|
// save resource file and lfm file
|
||||||
if (ResourceCode<>nil) or (ActiveUnitInfo.Component<>nil) then begin
|
if (ResourceCode<>nil) or (ActiveUnitInfo.Component<>nil) then begin
|
||||||
Result:=DoSaveFileResources(ActiveUnitInfo,ResourceCode,LFMCode,Flags);
|
Result:=DoSaveUnitComponent(ActiveUnitInfo,ResourceCode,LFMCode,Flags);
|
||||||
if Result in [mrIgnore, mrOk] then
|
if Result in [mrIgnore, mrOk] then
|
||||||
Result:=mrCancel
|
Result:=mrCancel
|
||||||
else
|
else
|
||||||
|
171
ide/project.pp
171
ide/project.pp
@ -80,6 +80,37 @@ type
|
|||||||
uilAutoRevertLocked
|
uilAutoRevertLocked
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TUnitCompDependencyList = (
|
||||||
|
ucdlRequires,
|
||||||
|
ucdlUsedBy
|
||||||
|
);
|
||||||
|
|
||||||
|
{ TUnitComponentDependency }
|
||||||
|
|
||||||
|
TUnitComponentDependency = class
|
||||||
|
private
|
||||||
|
FRequiresUnit: TUnitInfo;
|
||||||
|
FUsedByUnit: TUnitInfo;
|
||||||
|
procedure SetRequiresUnit(const AValue: TUnitInfo);
|
||||||
|
procedure SetUsedByUnit(const AValue: TUnitInfo);
|
||||||
|
public
|
||||||
|
NextDependency, PrevDependency:
|
||||||
|
array[TUnitCompDependencyList] of TUnitComponentDependency;
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Clear;
|
||||||
|
function NextUsedByDependency: TUnitComponentDependency;
|
||||||
|
function PrevUsedByDependency: TUnitComponentDependency;
|
||||||
|
function NextRequiresDependency: TUnitComponentDependency;
|
||||||
|
function PrevRequiresDependency: TUnitComponentDependency;
|
||||||
|
procedure AddToList(var FirstDependency: TUnitComponentDependency;
|
||||||
|
ListType: TUnitCompDependencyList);
|
||||||
|
procedure RemoveFromList(var FirstDependency: TUnitComponentDependency;
|
||||||
|
ListType: TUnitCompDependencyList);
|
||||||
|
property RequiresUnit: TUnitInfo read FRequiresUnit write SetRequiresUnit;
|
||||||
|
property UsedByUnit: TUnitInfo read FUsedByUnit write SetUsedByUnit;
|
||||||
|
end;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
{ TUnitInfo }
|
{ TUnitInfo }
|
||||||
@ -105,6 +136,8 @@ type
|
|||||||
fEditorIndex: integer;
|
fEditorIndex: integer;
|
||||||
fFileName: string;
|
fFileName: string;
|
||||||
fFileReadOnly: Boolean;
|
fFileReadOnly: Boolean;
|
||||||
|
FFirstRequiredComponent: TUnitComponentDependency;
|
||||||
|
FFirstUsedByComponent: TUnitComponentDependency;
|
||||||
fHasResources: boolean; // source has resource file
|
fHasResources: boolean; // source has resource file
|
||||||
FIgnoreFileDateOnDiskValid: boolean;
|
FIgnoreFileDateOnDiskValid: boolean;
|
||||||
FIgnoreFileDateOnDisk: longint;
|
FIgnoreFileDateOnDisk: longint;
|
||||||
@ -175,6 +208,7 @@ type
|
|||||||
function WriteUnitSourceToFile(const AFileName: string): TModalResult;
|
function WriteUnitSourceToFile(const AFileName: string): TModalResult;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
procedure ClearModifieds;
|
procedure ClearModifieds;
|
||||||
|
procedure ClearComponentDependencies;
|
||||||
procedure CreateStartCode(Descriptor: TProjectFileDescriptor;
|
procedure CreateStartCode(Descriptor: TProjectFileDescriptor;
|
||||||
const NewUnitName: string);
|
const NewUnitName: string);
|
||||||
procedure DecreaseAutoRevertLock;
|
procedure DecreaseAutoRevertLock;
|
||||||
@ -193,6 +227,11 @@ type
|
|||||||
|
|
||||||
procedure SetSourceText(const SourceText: string); override;
|
procedure SetSourceText(const SourceText: string); override;
|
||||||
function GetSourceText: string; override;
|
function GetSourceText: string; override;
|
||||||
|
|
||||||
|
// component dependencies
|
||||||
|
procedure AddRequiresComponentDependency(RequiredUnit: TUnitInfo);
|
||||||
|
procedure RemoveRequiresComponentDependency(RequiredUnit: TUnitInfo);
|
||||||
|
function FindAncestorUnit: TUnitInfo;
|
||||||
public
|
public
|
||||||
{ Properties }
|
{ Properties }
|
||||||
// Unit lists
|
// Unit lists
|
||||||
@ -225,6 +264,10 @@ type
|
|||||||
read fCustomHighlighter write fCustomHighlighter;
|
read fCustomHighlighter write fCustomHighlighter;
|
||||||
property EditorIndex: integer read fEditorIndex write SetEditorIndex;
|
property EditorIndex: integer read fEditorIndex write SetEditorIndex;
|
||||||
property FileReadOnly: Boolean read fFileReadOnly write SetFileReadOnly;
|
property FileReadOnly: Boolean read fFileReadOnly write SetFileReadOnly;
|
||||||
|
property FirstRequiredComponent: TUnitComponentDependency
|
||||||
|
read FFirstRequiredComponent;
|
||||||
|
property FirstUsedByComponent: TUnitComponentDependency
|
||||||
|
read FFirstUsedByComponent;
|
||||||
property HasResources: boolean read GetHasResources write fHasResources;
|
property HasResources: boolean read GetHasResources write fHasResources;
|
||||||
property Loaded: Boolean read fLoaded write SetLoaded;
|
property Loaded: Boolean read fLoaded write SetLoaded;
|
||||||
property LoadingComponent: boolean read FLoadingComponent write FLoadingComponent;
|
property LoadingComponent: boolean read FLoadingComponent write FLoadingComponent;
|
||||||
@ -755,6 +798,7 @@ end;
|
|||||||
------------------------------------------------------------------------------}
|
------------------------------------------------------------------------------}
|
||||||
destructor TUnitInfo.Destroy;
|
destructor TUnitInfo.Destroy;
|
||||||
begin
|
begin
|
||||||
|
Component:=nil;
|
||||||
Source:=nil;
|
Source:=nil;
|
||||||
FreeAndNil(FBookmarks);
|
FreeAndNil(FBookmarks);
|
||||||
Project:=nil;
|
Project:=nil;
|
||||||
@ -919,6 +963,7 @@ begin
|
|||||||
fUserReadOnly := false;
|
fUserReadOnly := false;
|
||||||
if fSource<>nil then fSource.Clear;
|
if fSource<>nil then fSource.Clear;
|
||||||
Loaded := false;
|
Loaded := false;
|
||||||
|
ClearComponentDependencies;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TUnitInfo.ClearModifieds;
|
procedure TUnitInfo.ClearModifieds;
|
||||||
@ -927,6 +972,12 @@ begin
|
|||||||
SessionModified:=false;
|
SessionModified:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TUnitInfo.ClearComponentDependencies;
|
||||||
|
begin
|
||||||
|
while FFirstRequiredComponent<>nil do FFirstRequiredComponent.Free;
|
||||||
|
while FFirstUsedByComponent<>nil do FFirstUsedByComponent.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------
|
||||||
TUnitInfo SaveToXMLConfig
|
TUnitInfo SaveToXMLConfig
|
||||||
@ -1229,6 +1280,38 @@ begin
|
|||||||
Result:=Source.Source;
|
Result:=Source.Source;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TUnitInfo.AddRequiresComponentDependency(RequiredUnit: TUnitInfo);
|
||||||
|
var
|
||||||
|
ADependency: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
if RequiredUnit=nil then RaiseGDBException('inconsistency');
|
||||||
|
ADependency:=TUnitComponentDependency.Create;
|
||||||
|
ADependency.RequiresUnit:=RequiredUnit;
|
||||||
|
ADependency.UsedByUnit:=Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUnitInfo.RemoveRequiresComponentDependency(RequiredUnit: TUnitInfo);
|
||||||
|
begin
|
||||||
|
RequiredUnit.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitInfo.FindAncestorUnit: TUnitInfo;
|
||||||
|
var
|
||||||
|
Dependency: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
if Component<>nil then begin
|
||||||
|
Dependency:=FirstRequiredComponent;
|
||||||
|
while Dependency<>nil do begin
|
||||||
|
Result:=Dependency.RequiresUnit;
|
||||||
|
if (Result.Component<>nil)
|
||||||
|
and (Component.ClassParent=Result.Component.ClassType) then
|
||||||
|
exit;
|
||||||
|
Dependency:=Dependency.NextRequiresDependency;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
function TUnitInfo.ReadOnly: boolean;
|
function TUnitInfo.ReadOnly: boolean;
|
||||||
begin
|
begin
|
||||||
Result:=UserReadOnly or FileReadOnly;
|
Result:=UserReadOnly or FileReadOnly;
|
||||||
@ -1367,6 +1450,7 @@ begin
|
|||||||
if fComponent=AValue then exit;
|
if fComponent=AValue then exit;
|
||||||
fComponent:=AValue;
|
fComponent:=AValue;
|
||||||
UpdateList(uilWithComponent,fComponent<>nil);
|
UpdateList(uilWithComponent,fComponent<>nil);
|
||||||
|
if fComponent=nil then ClearComponentDependencies;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TUnitInfo.SetIsPartOfProject(const AValue: boolean);
|
procedure TUnitInfo.SetIsPartOfProject(const AValue: boolean);
|
||||||
@ -4504,5 +4588,92 @@ begin
|
|||||||
[ofProjectLoading,ofRegularFile]);
|
[ofProjectLoading,ofRegularFile]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TUnitComponentDependency }
|
||||||
|
|
||||||
|
procedure TUnitComponentDependency.SetRequiresUnit(const AValue: TUnitInfo);
|
||||||
|
begin
|
||||||
|
if FRequiresUnit=AValue then exit;
|
||||||
|
if FRequiresUnit<>nil then
|
||||||
|
RemoveFromList(FRequiresUnit.FFirstUsedByComponent,ucdlUsedBy);
|
||||||
|
FRequiresUnit:=AValue;
|
||||||
|
if FRequiresUnit<>nil then
|
||||||
|
AddToList(FRequiresUnit.FFirstUsedByComponent,ucdlUsedBy);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUnitComponentDependency.SetUsedByUnit(const AValue: TUnitInfo);
|
||||||
|
begin
|
||||||
|
if FUsedByUnit=AValue then exit;
|
||||||
|
if FUsedByUnit<>nil then
|
||||||
|
RemoveFromList(FUsedByUnit.FFirstRequiredComponent,ucdlRequires);
|
||||||
|
FUsedByUnit:=AValue;
|
||||||
|
if FUsedByUnit<>nil then
|
||||||
|
AddToList(FUsedByUnit.FFirstRequiredComponent,ucdlRequires);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TUnitComponentDependency.Create;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TUnitComponentDependency.Destroy;
|
||||||
|
begin
|
||||||
|
RequiresUnit:=nil;
|
||||||
|
UsedByUnit:=nil;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUnitComponentDependency.Clear;
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitComponentDependency.NextUsedByDependency
|
||||||
|
: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
Result:=NextDependency[ucdlUsedBy];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitComponentDependency.PrevUsedByDependency
|
||||||
|
: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
Result:=PrevDependency[ucdlUsedBy];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitComponentDependency.NextRequiresDependency
|
||||||
|
: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
Result:=NextDependency[ucdlRequires];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUnitComponentDependency.PrevRequiresDependency
|
||||||
|
: TUnitComponentDependency;
|
||||||
|
begin
|
||||||
|
Result:=PrevDependency[ucdlRequires];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUnitComponentDependency.AddToList(
|
||||||
|
var FirstDependency: TUnitComponentDependency;
|
||||||
|
ListType: TUnitCompDependencyList);
|
||||||
|
begin
|
||||||
|
NextDependency[ListType]:=FirstDependency;
|
||||||
|
FirstDependency:=Self;
|
||||||
|
PrevDependency[ListType]:=nil;
|
||||||
|
if NextDependency[ListType]<>nil then
|
||||||
|
NextDependency[ListType].PrevDependency[ListType]:=Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUnitComponentDependency.RemoveFromList(
|
||||||
|
var FirstDependency: TUnitComponentDependency;
|
||||||
|
ListType: TUnitCompDependencyList);
|
||||||
|
begin
|
||||||
|
if FirstDependency=Self then FirstDependency:=NextDependency[ListType];
|
||||||
|
if NextDependency[ListType]<>nil then
|
||||||
|
NextDependency[ListType].PrevDependency[ListType]:=PrevDependency[ListType];
|
||||||
|
if PrevDependency[ListType]<>nil then
|
||||||
|
PrevDependency[ListType].NextDependency[ListType]:=NextDependency[ListType];
|
||||||
|
NextDependency[ListType]:=nil;
|
||||||
|
PrevDependency[ListType]:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user