mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-12 04:50:21 +01:00
* Fixed ancestor handling (bug ID 11067)
git-svn-id: trunk@10588 -
This commit is contained in:
parent
9d3d2bba0b
commit
d5eec67b53
@ -1239,7 +1239,7 @@ type
|
|||||||
FDestroyDriver: Boolean;
|
FDestroyDriver: Boolean;
|
||||||
FRootAncestor: TComponent;
|
FRootAncestor: TComponent;
|
||||||
FPropPath: String;
|
FPropPath: String;
|
||||||
FAncestorList: TList;
|
FAncestors: TFPList;
|
||||||
FAncestorPos: Integer;
|
FAncestorPos: Integer;
|
||||||
FChildPos: Integer;
|
FChildPos: Integer;
|
||||||
FOnFindAncestor: TFindAncestorEvent;
|
FOnFindAncestor: TFindAncestorEvent;
|
||||||
@ -1247,11 +1247,14 @@ type
|
|||||||
FOnWriteStringProperty:TReadWriteStringPropertyEvent;
|
FOnWriteStringProperty:TReadWriteStringPropertyEvent;
|
||||||
procedure AddToAncestorList(Component: TComponent);
|
procedure AddToAncestorList(Component: TComponent);
|
||||||
procedure WriteComponentData(Instance: TComponent);
|
procedure WriteComponentData(Instance: TComponent);
|
||||||
|
Procedure DetermineAncestor(Component: TComponent);
|
||||||
|
procedure DoFindAncestor(Component : TComponent);
|
||||||
protected
|
protected
|
||||||
procedure SetRoot(ARoot: TComponent); override;
|
procedure SetRoot(ARoot: TComponent); override;
|
||||||
procedure WriteBinary(AWriteData: TStreamProc);
|
procedure WriteBinary(AWriteData: TStreamProc);
|
||||||
procedure WriteProperty(Instance: TPersistent; PropInfo: Pointer);
|
procedure WriteProperty(Instance: TPersistent; PropInfo: Pointer);
|
||||||
procedure WriteProperties(Instance: TPersistent);
|
procedure WriteProperties(Instance: TPersistent);
|
||||||
|
procedure WriteChildren(Component: TComponent);
|
||||||
function CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectWriter; virtual;
|
function CreateDriver(Stream: TStream; BufSize: Integer): TAbstractObjectWriter; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(ADriver: TAbstractObjectWriter);
|
constructor Create(ADriver: TAbstractObjectWriter);
|
||||||
|
|||||||
@ -402,7 +402,7 @@ end;
|
|||||||
// Used as argument for calls to TComponent.GetChildren:
|
// Used as argument for calls to TComponent.GetChildren:
|
||||||
procedure TWriter.AddToAncestorList(Component: TComponent);
|
procedure TWriter.AddToAncestorList(Component: TComponent);
|
||||||
begin
|
begin
|
||||||
FAncestorList.Add(Component);
|
FAncestors.Add(Component);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWriter.DefineProperty(const Name: String;
|
procedure TWriter.DefineProperty(const Name: String;
|
||||||
@ -495,25 +495,121 @@ begin
|
|||||||
WriteListEnd;
|
WriteListEnd;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TWriter.DetermineAncestor(Component : TComponent);
|
||||||
|
|
||||||
|
Var
|
||||||
|
S : String;
|
||||||
|
I : Integer;
|
||||||
|
C : TComponent;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Should be set only when we write an inherited with children.
|
||||||
|
|
||||||
|
if Not Assigned(FAncestors) then
|
||||||
|
exit;
|
||||||
|
FAncestor:=nil;
|
||||||
|
S:=UpperCase(Component.Name);
|
||||||
|
I:=0;
|
||||||
|
While (FAncestor=Nil) and (I<FAncestors.Count) do
|
||||||
|
begin
|
||||||
|
C:=TComponent(FAncestors[i]);
|
||||||
|
if (S=UpperCase(C.Name)) then
|
||||||
|
FAncestor:=C;
|
||||||
|
Inc(I);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TWriter.DoFindAncestor(Component : TComponent);
|
||||||
|
|
||||||
|
Var
|
||||||
|
C : TComponent;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Assigned(FOnFindAncestor) then
|
||||||
|
if (Ancestor=Nil) or (Ancestor is TComponent) then
|
||||||
|
begin
|
||||||
|
C:=TComponent(Ancestor);
|
||||||
|
FOnFindAncestor(Self,Component,Component.Name,C,FRootAncestor);
|
||||||
|
Ancestor:=C;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TWriter.WriteComponent(Component: TComponent);
|
procedure TWriter.WriteComponent(Component: TComponent);
|
||||||
|
|
||||||
var
|
var
|
||||||
i : integer;
|
i : integer;
|
||||||
|
SA : TPersistent;
|
||||||
|
SR : TComponent;
|
||||||
begin
|
begin
|
||||||
|
SR:=FRoot;
|
||||||
|
SA:=FAncestor;
|
||||||
|
Try
|
||||||
Component.FComponentState:=Component.FComponentState+[csWriting];
|
Component.FComponentState:=Component.FComponentState+[csWriting];
|
||||||
|
Try
|
||||||
|
// Possibly set ancestor.
|
||||||
|
DetermineAncestor(Component);
|
||||||
|
DoFindAncestor(Component); // Mainly for IDE when a parent form had an ancestor renamed...
|
||||||
|
// Will call WriteComponentData.
|
||||||
Component.WriteState(Self);
|
Component.WriteState(Self);
|
||||||
Component.GetChildren(@WriteComponent,Root);
|
|
||||||
FDriver.EndList;
|
FDriver.EndList;
|
||||||
|
Finally
|
||||||
Component.FComponentState:=Component.FComponentState-[csWriting];
|
Component.FComponentState:=Component.FComponentState-[csWriting];
|
||||||
|
end;
|
||||||
|
Finally
|
||||||
|
FAncestor:=SA;
|
||||||
|
FRoot:=SR;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TWriter.WriteChildren(Component : TComponent);
|
||||||
|
|
||||||
|
Var
|
||||||
|
SRoot, SRootA : TComponent;
|
||||||
|
SList : TFPList;
|
||||||
|
begin
|
||||||
|
// Write children list.
|
||||||
|
// While writing children, the ancestor environment must be saved
|
||||||
|
// This is recursive...
|
||||||
|
SRoot:=FRoot;
|
||||||
|
SRootA:=FRootAncestor;
|
||||||
|
SList:=FAncestors;
|
||||||
|
try
|
||||||
|
FAncestors:=Nil;
|
||||||
|
if csInline in Component.ComponentState then
|
||||||
|
FRoot:=Component;
|
||||||
|
if (FAncestor is TComponent) then
|
||||||
|
begin
|
||||||
|
FAncestors:=TFPList.Create;
|
||||||
|
if csInline in TComponent(FAncestor).ComponentState then
|
||||||
|
FRootAncestor := TComponent(FAncestor);
|
||||||
|
TComponent(FAncestor).GetChildren(@AddToAncestorList,FRootAncestor);
|
||||||
|
end;
|
||||||
|
try
|
||||||
|
Component.GetChildren(@WriteComponent, FRoot);
|
||||||
|
Finally
|
||||||
|
FreeAndNil(FAncestors);
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FAncestors:=Slist;
|
||||||
|
FRoot:=SRoot;
|
||||||
|
FRootAncestor:=SRootA;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWriter.WriteComponentData(Instance: TComponent);
|
procedure TWriter.WriteComponentData(Instance: TComponent);
|
||||||
var Dummy: Integer;
|
var Dummy: Integer;
|
||||||
Flags: TFilerFlags;
|
Flags: TFilerFlags;
|
||||||
begin
|
begin
|
||||||
|
Dummy:=0;
|
||||||
Flags := [];
|
Flags := [];
|
||||||
|
If Assigned(FAncestor) then
|
||||||
|
Flags:=[ffInherited];
|
||||||
FDriver.BeginComponent(Instance,Flags, Dummy);
|
FDriver.BeginComponent(Instance,Flags, Dummy);
|
||||||
WriteProperties(Instance);
|
WriteProperties(Instance);
|
||||||
WriteListEnd;
|
WriteListEnd;
|
||||||
|
// Needs special handling of ancestor.
|
||||||
|
If not IgnoreChildren then
|
||||||
|
WriteChildren(Instance);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TWriter.WriteDescendent(ARoot: TComponent; AAncestor: TComponent);
|
procedure TWriter.WriteDescendent(ARoot: TComponent; AAncestor: TComponent);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user