ideintf: initial implementation of showing collections in the component treeview

git-svn-id: trunk@22903 -
This commit is contained in:
paul 2009-12-01 16:22:52 +00:00
parent a215ac2b7c
commit 27e171ca34

View File

@ -28,7 +28,7 @@ unit ComponentTreeView;
interface interface
uses uses
Classes, SysUtils, LCLProc, AvgLvlTree, Dialogs, Controls, ComCtrls, Classes, SysUtils, TypInfo, LCLProc, AvgLvlTree, Dialogs, Controls, ComCtrls,
ExtCtrls, LResources, ExtCtrls, LResources,
ObjInspStrConsts, PropEdits; ObjInspStrConsts, PropEdits;
@ -78,6 +78,8 @@ type
Added: boolean; Added: boolean;
end; end;
TGetCollectionProc = procedure(AName: String; ACollection: TCollection) of object;
{ TComponentWalker } { TComponentWalker }
TComponentWalker = class TComponentWalker = class
@ -85,12 +87,15 @@ type
FCandidates: TAvgLvlTree; FCandidates: TAvgLvlTree;
FRootComponent: TComponent; FRootComponent: TComponent;
FNode: TTreeNode; FNode: TTreeNode;
protected
procedure GetCollections(AComponent: TComponent; AProc: TGetCollectionProc);
public public
constructor Create( constructor Create(
ATreeView: TComponentTreeView; ACandidates: TAvgLvlTree; ATreeView: TComponentTreeView; ACandidates: TAvgLvlTree;
ARootComponent: TComponent; ANode: TTreeNode); ARootComponent: TComponent; ANode: TTreeNode);
procedure Walk(AComponent: TComponent); procedure Walk(AComponent: TComponent);
procedure AddCollection(AName: String; ACollection: TCollection);
end; end;
TComponentAccessor = class(TComponent); TComponentAccessor = class(TComponent);
@ -109,6 +114,26 @@ end;
{ TComponentWalker } { TComponentWalker }
procedure TComponentWalker.GetCollections(AComponent: TComponent; AProc: TGetCollectionProc);
var
PropList: PPropList;
i, PropCount: Integer;
Obj: TObject;
begin
PropCount := GetPropList(AComponent, PropList);
try
for i := 0 to PropCount - 1 do
if (PropList^[i]^.PropType^.Kind = tkClass) then
begin
Obj := GetObjectProp(AComponent, PropList^[i], TCollection);
if Assigned(Obj) then
AProc(PropList^[i]^.Name, TCollection(Obj));
end;
finally
FreeMem(PropList);
end;
end;
constructor TComponentWalker.Create(ATreeView: TComponentTreeView; constructor TComponentWalker.Create(ATreeView: TComponentTreeView;
ACandidates: TAvgLvlTree; ARootComponent: TComponent; ANode: TTreeNode); ACandidates: TAvgLvlTree; ARootComponent: TComponent; ANode: TTreeNode);
begin begin
@ -126,9 +151,10 @@ var
Root: TComponent; Root: TComponent;
begin begin
if GetLookupRootForComponent(AComponent) <> FRootComponent then Exit; if GetLookupRootForComponent(AComponent) <> FRootComponent then Exit;
AVLNode := FCandidates.FindKey(
AComponent, TListSortCompare(@ComparePersistentWithComponentCandidate)); AVLNode := FCandidates.FindKey(AComponent, TListSortCompare(@ComparePersistentWithComponentCandidate));
if AVLNode = nil then Exit; if AVLNode = nil then Exit;
Candidate := TComponentCandidate(AVLNode.Data); Candidate := TComponentCandidate(AVLNode.Data);
if Candidate.Added then Exit; if Candidate.Added then Exit;
Candidate.Added := True; Candidate.Added := True;
@ -139,17 +165,45 @@ begin
FNode.ImageIndex := FTreeView.GetImageFor(AComponent); FNode.ImageIndex := FTreeView.GetImageFor(AComponent);
FNode.SelectedIndex := FNode.ImageIndex; FNode.SelectedIndex := FNode.ImageIndex;
FNode.MultiSelected := FTreeView.Selection.IndexOf(AComponent) >= 0; FNode.MultiSelected := FTreeView.Selection.IndexOf(AComponent) >= 0;
if (csInline in AComponent.ComponentState) or (AComponent.Owner=nil) then
GetCollections(AComponent, @AddCollection);
if (csInline in AComponent.ComponentState) or (AComponent.Owner = nil) then
Root := AComponent Root := AComponent
else else
Root := AComponent.Owner; Root := AComponent.Owner;
if not ((Root is TControl)
and (csOwnedChildsNotSelectable in TControl(Root).ControlStyle)) if not ((Root is TControl) and (csOwnedChildsNotSelectable in TControl(Root).ControlStyle)) then
then
TComponentAccessor(AComponent).GetChildren(@Walk, Root); TComponentAccessor(AComponent).GetChildren(@Walk, Root);
FNode := OldNode; FNode := OldNode;
FNode.Expanded := True; FNode.Expanded := True;
end; end;
procedure TComponentWalker.AddCollection(AName: String; ACollection: TCollection);
var
CollectionNode, ItemNode: TTreeNode;
i: integer;
Item: TCollectionItem;
begin
CollectionNode := FTreeView.Items.AddChild(FNode, AName);
CollectionNode.Data := ACollection;
CollectionNode.ImageIndex := 4;
CollectionNode.SelectedIndex := CollectionNode.ImageIndex;
CollectionNode.MultiSelected := FTreeView.Selection.IndexOf(ACollection) >= 0;
for i := 0 to ACollection.Count - 1 do
begin
Item := ACollection.Items[i];
ItemNode := FTreeView.Items.AddChild(CollectionNode, Format('%d - %s', [i, Item.ClassName]));
ItemNode.Data := Item;
ItemNode.ImageIndex := 5;
ItemNode.SelectedIndex := ItemNode.ImageIndex;
ItemNode.MultiSelected := FTreeView.Selection.IndexOf(Item) >= 0;
end;
CollectionNode.Expanded := True;
FNode.Expanded := True;
end;
{ TComponentTreeView } { TComponentTreeView }
@ -368,15 +422,17 @@ end;
function TComponentTreeView.GetImageFor(AComponent: TComponent): integer; function TComponentTreeView.GetImageFor(AComponent: TComponent): integer;
begin begin
if Assigned(AComponent) then begin if Assigned(AComponent) then
if (AComponent is TControl) begin
and (csAcceptsControls in TControl(AComponent).ControlStyle) then if (AComponent is TControl) and (csAcceptsControls in TControl(AComponent).ControlStyle) then
Result := 3 Result := 3
else if (AComponent is TControl) then else
if (AComponent is TControl) then
Result := 2 Result := 2
else else
Result := 1; Result := 1;
end else end
else
Result := -1; Result := -1;
end; end;
@ -404,6 +460,8 @@ begin
FImageList.AddLazarusResource('oi_comp'); FImageList.AddLazarusResource('oi_comp');
FImageList.AddLazarusResource('oi_control'); FImageList.AddLazarusResource('oi_control');
FImageList.AddLazarusResource('oi_box'); FImageList.AddLazarusResource('oi_box');
FImageList.AddLazarusResource('oi_collection');
FImageList.AddLazarusResource('oi_item');
Images := FImageList; Images := FImageList;
end; end;
@ -532,9 +590,9 @@ end;
function TComponentTreeView.CreateNodeCaption(APersistent: TPersistent): string; function TComponentTreeView.CreateNodeCaption(APersistent: TPersistent): string;
begin begin
Result:=APersistent.ClassName; Result := APersistent.ClassName;
if APersistent is TComponent then if APersistent is TComponent then
Result:=TComponent(APersistent).Name+': '+Result; Result := TComponent(APersistent).Name + ': ' + Result;
end; end;
initialization initialization