git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.DevExpressVCL@25 05c56307-c608-d34a-929d-697000501d7a
714 lines
20 KiB
ObjectPascal
714 lines
20 KiB
ObjectPascal
|
|
{*******************************************************************}
|
|
{ }
|
|
{ Developer Express Visual Component Library }
|
|
{ Express tree view printed dataset }
|
|
{ }
|
|
{ Copyright (c) 1998-2008 Developer Express Inc. }
|
|
{ ALL RIGHTS RESERVED }
|
|
{ }
|
|
{ The entire contents of this file is protected by U.S. and }
|
|
{ International Copyright Laws. Unauthorized reproduction, }
|
|
{ reverse-engineering, and distribution of all or any portion of }
|
|
{ the code contained in this file is strictly prohibited and may }
|
|
{ result in severe civil and criminal penalties and will be }
|
|
{ prosecuted to the maximum extent possible under the law. }
|
|
{ }
|
|
{ RESTRICTIONS }
|
|
{ }
|
|
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
|
|
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
|
|
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
|
|
{ LICENSED TO DISTRIBUTE THE EXPRESSGRID AND ALL ACCOMPANYING VCL }
|
|
{ CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
|
|
{ }
|
|
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
|
|
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
|
|
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
|
|
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
|
|
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
|
|
{ }
|
|
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
|
|
{ ADDITIONAL RESTRICTIONS. }
|
|
{ }
|
|
{*******************************************************************}
|
|
|
|
unit dxtrprds;
|
|
|
|
{$I cxVer.inc}
|
|
|
|
interface
|
|
|
|
uses Classes, SysUtils, dxmdaset, Windows, DB {$IFDEF DELPHI6}, Variants {$ENDIF};
|
|
|
|
type
|
|
|
|
TdxDBTreePrintData = class;
|
|
|
|
TdxDBTreePrintDataLink = class(TDataLink)
|
|
private
|
|
FPrintData : TdxDBTreePrintData;
|
|
protected
|
|
procedure ActiveChanged; override;
|
|
end;
|
|
|
|
TdxDBTreePrintData = class(TdxMemData)
|
|
private
|
|
FDataLink : TdxDBTreePrintDataLink;
|
|
FKeyFieldName : String;
|
|
FParentFieldName : String;
|
|
FLevelCount : Integer;
|
|
FRootValue : Variant;
|
|
FRootStrValue : String;
|
|
FMaxLevelCount : Integer;
|
|
|
|
function GetTreeDataSource : TDataSource;
|
|
procedure SetTreeDataSource(Value : TDataSource);
|
|
procedure SetKeyFieldName(Value : String);
|
|
procedure SetLevelCount(Value : Integer);
|
|
procedure SetParentFieldName(Value : String);
|
|
procedure SetRootStrValue(Value : String);
|
|
|
|
procedure RefreshStructure;
|
|
protected
|
|
procedure CopyStructure(ASource: TDataSet);
|
|
procedure DoAfterOpen; override;
|
|
|
|
property DataLink : TdxDBTreePrintDataLink read FDataLink;
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure Loaded; override;
|
|
|
|
property MaxLevelCount : Integer read FMaxLevelCount;
|
|
published
|
|
property DataSource read GetTreeDataSource write SetTreeDataSource;
|
|
property KeyField : String read FKeyFieldName write SetKeyFieldName;
|
|
property LevelCount : Integer read FLevelCount write SetLevelCount;
|
|
property ParentField : String read FParentFieldName write SetParentFieldName;
|
|
property RootValue : String read FRootStrValue write SetRootStrValue;
|
|
end;
|
|
|
|
procedure FillDBTreePrintedDataSet(ds1 : TdxDBTreePrintData; ds2 : TDataSet);
|
|
|
|
const
|
|
cDBTreeLevelFieldName = 'dx$level';
|
|
cDBTreeRecNoFieldName = 'dx$recno';
|
|
cDBTreeHasChildrenFieldName = 'dx$haschildren';
|
|
|
|
implementation
|
|
|
|
procedure TdxDBTreePrintDataLink.ActiveChanged;
|
|
begin
|
|
if FPrintData <> nil then
|
|
FPrintData.RefreshStructure;
|
|
end;
|
|
|
|
constructor TdxDBTreePrintData.Create(AOwner : TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
FDataLink := TdxDBTreePrintDataLink.Create;
|
|
FDataLink.FPrintData := self;
|
|
FLevelCount := 0;
|
|
FRootValue := NULL;
|
|
FRootStrValue := '';
|
|
FMaxLevelCount := 0;
|
|
|
|
end;
|
|
|
|
destructor TdxDBTreePrintData.Destroy;
|
|
begin
|
|
FDataLink.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.Loaded;
|
|
begin
|
|
inherited Loaded;
|
|
RefreshStructure;
|
|
end;
|
|
|
|
function TdxDBTreePrintData.GetTreeDataSource : TDataSource;
|
|
begin
|
|
Result := FDataLink.DataSource;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.DoAfterOpen;
|
|
begin
|
|
inherited DoAfterOpen;
|
|
FMaxLevelCount := 0;
|
|
FillDBTreePrintedDataSet(self, FDataLink.DataSet);
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.SetTreeDataSource(Value : TDataSource);
|
|
begin
|
|
if(Value <> FDataLink.DataSource) then begin
|
|
FDataLink.DataSource := Value;
|
|
RefreshStructure;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.SetKeyFieldName(Value : String);
|
|
begin
|
|
if(FKeyFieldName <> Value) then begin
|
|
FKeyFieldName := Value;
|
|
RefreshStructure;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.SetLevelCount(Value : Integer);
|
|
begin
|
|
if(Value < 0) then Value := 0;
|
|
if(FLevelCount <> Value) then begin
|
|
FLevelCount := Value;
|
|
if Not(csLoading in ComponentState) And Active then begin
|
|
Close;
|
|
Open;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.SetParentFieldName(Value : String);
|
|
begin
|
|
if(FParentFieldName <> Value) then begin
|
|
FParentFieldName := Value;
|
|
RefreshStructure;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.SetRootStrValue(Value : String);
|
|
begin
|
|
if(FRootStrValue <> Value) then begin
|
|
FRootStrValue := Value;
|
|
if(FRootStrValue = '') then
|
|
FRootValue := NULL
|
|
else FRootValue := FRootStrValue;
|
|
if Not(csLoading in ComponentState) And Active then begin
|
|
Close;
|
|
Open;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.CopyStructure(ASource: TDataSet);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
CheckInactive;
|
|
for i := FieldCount - 1 downto 0 do
|
|
if Fields[i] <> RecIdField then
|
|
Fields[i].Free;
|
|
|
|
if (ASource = nil) then Exit;
|
|
|
|
FieldDefs := ASource.FieldDefs;
|
|
|
|
for i := 0 to FieldDefs.Count - 1 do begin
|
|
if SupportedFieldType(FieldDefs.Items[i].DataType) then
|
|
FieldDefs.Items[i].CreateField(Self);
|
|
end;
|
|
|
|
for i := 0 to FieldCount - 1 do
|
|
Fields[i].Required := False;
|
|
|
|
FieldDefs.Add(cDBTreeLevelFieldName, ftInteger, 0, False);
|
|
FieldDefs.Items[FieldDefs.Count - 1].CreateField(self);
|
|
FieldDefs.Add(cDBTreeRecNoFieldName, ftInteger, 0, False);
|
|
FieldDefs.Items[FieldDefs.Count - 1].CreateField(self);
|
|
FieldDefs.Add(cDBTreeHasChildrenFieldName, ftBoolean, 0, False);
|
|
FieldDefs.Items[FieldDefs.Count - 1].CreateField(self);
|
|
end;
|
|
|
|
procedure TdxDBTreePrintData.RefreshStructure;
|
|
begin
|
|
if (csLoading in ComponentState) then exit;
|
|
if Active then
|
|
Close;
|
|
if(FDataLink.DataSet <> Nil) and FDataLink.DataSet.Active
|
|
And (FDataLink.DataSet.FindField(FKeyFieldName) <> Nil)
|
|
And (FDataLink.DataSet.FindField(FParentFieldName) <> Nil) then
|
|
CopyStructure(FDataLink.DataSet);
|
|
end;
|
|
|
|
type
|
|
TDBTreePrintedNodes = class;
|
|
|
|
TDBTreePrintedNode = class
|
|
private
|
|
Destroying : Boolean;
|
|
Owner : TDBTreePrintedNodes;
|
|
KeyValue : Variant;
|
|
ParentValue : Variant;
|
|
Level : Integer;
|
|
Parent : TDBTreePrintedNode;
|
|
RecNumber : Integer;
|
|
ChildList : TList;
|
|
|
|
procedure SetChild(Value : TDBTreePrintedNode);
|
|
procedure SetLevel(Value : Integer);
|
|
public
|
|
constructor Create(AOwner : TDBTreePrintedNodes; AKeyValue, AParentValue : Variant);
|
|
destructor Destroy; override;
|
|
function HasAsParent(prNode : TDBTreePrintedNode) : Boolean;
|
|
end;
|
|
|
|
TDBTreePrintedNodes = class
|
|
private
|
|
PrintedDS : TdxDBTreePrintData;
|
|
SourceDS : TDataSet;
|
|
List : TList;
|
|
RootList : TList;
|
|
SortedList : TList;
|
|
protected
|
|
function IndexOf(Value : Variant) : Integer;
|
|
procedure DestroyItems;
|
|
function FindNearest(Value : Variant; Var Index : Integer) : Boolean;
|
|
function GetMaxKeyValue : Variant;
|
|
procedure SortNodes(List : TList);
|
|
procedure UpdateNodes;
|
|
public
|
|
constructor Create(APrintedDS : TdxDBTreePrintData; ASourceDS : TDataSet);
|
|
destructor Destroy; override;
|
|
|
|
procedure CreateStructure;
|
|
end;
|
|
|
|
// Internal methods
|
|
function VarEquals(const V1, V2: Variant): Boolean;
|
|
begin
|
|
Result := False;
|
|
try
|
|
Result := V1 = V2;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
function VarFirstMore(const V1, V2: Variant): Boolean;
|
|
begin
|
|
Result := False;
|
|
try
|
|
Result := V1 >= V2;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
function VarFirstMoreEx(const V1, V2: Variant): Boolean;
|
|
begin
|
|
Result := False;
|
|
try
|
|
Result := V1 > V2;
|
|
except
|
|
end;
|
|
end;
|
|
|
|
{TDBTreePrintedNode}
|
|
constructor TDBTreePrintedNode.Create(AOwner : TDBTreePrintedNodes; AKeyValue, AParentValue : Variant);
|
|
Var
|
|
Index : Integer;
|
|
begin
|
|
Owner := AOwner;
|
|
KeyValue := AKeyValue;
|
|
ParentValue := AParentValue;
|
|
ChildList := Nil;
|
|
RecNumber := Owner.List.Count;
|
|
Owner.FindNearest(KeyValue, Index);
|
|
if(Index < 0) then Index := 0;
|
|
Owner.List.Insert(Index, self);
|
|
Index := Owner.IndexOf(ParentValue);
|
|
Level := 0;
|
|
if(Index > -1) And (TDBTreePrintedNode(Owner.List[Index]) <> self) then
|
|
TDBTreePrintedNode(Owner.List[Index]).SetChild(self)
|
|
else begin
|
|
Parent := Nil;
|
|
Owner.RootList.Add(self);
|
|
end;
|
|
Owner.SortedList.Add(self);
|
|
end;
|
|
|
|
destructor TDBTreePrintedNode.Destroy;
|
|
var
|
|
i : Integer;
|
|
begin
|
|
Destroying := True;
|
|
if(ChildList <> Nil) then
|
|
begin
|
|
for i := 0 to ChildList.Count - 1 do
|
|
TDBTreePrintedNode(ChildList[i]).Parent := Nil;
|
|
ChildList.Free;
|
|
ChildList := nil;
|
|
end;
|
|
if(Parent <> nil) and not Parent.Destroying and (Parent.ChildList <> nil) then
|
|
begin
|
|
Parent.ChildList.Remove(self);
|
|
if(Parent.ChildList.Count = 0) then
|
|
begin
|
|
Parent.ChildList.Free;
|
|
Parent.ChildList := Nil;
|
|
end;
|
|
end;
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TDBTreePrintedNode.SetChild(Value : TDBTreePrintedNode);
|
|
begin
|
|
if(Value = self) then exit;
|
|
if(ChildList = Nil) then
|
|
ChildList := TList.Create;
|
|
ChildList.Add(Value);
|
|
Value.Parent := self;
|
|
Owner.RootList.Remove(Value);
|
|
Value.SetLevel(Level + 1);
|
|
end;
|
|
|
|
procedure TDBTreePrintedNode.SetLevel(Value : Integer);
|
|
Var
|
|
i : Integer;
|
|
begin
|
|
Level := Value;
|
|
if(ChildList <> Nil) then
|
|
for i := 0 to ChildList.Count - 1 do
|
|
TDBTreePrintedNode(ChildList[i]).SetLevel(Level + 1);
|
|
end;
|
|
|
|
function TDBTreePrintedNode.HasAsParent(prNode : TDBTreePrintedNode) : Boolean;
|
|
Var
|
|
Node : TDBTreePrintedNode;
|
|
begin
|
|
Result := False;
|
|
Node := Parent;
|
|
while Node <> Nil do begin
|
|
if(Node = prNode) then begin
|
|
Result := True;
|
|
break;
|
|
end;
|
|
Node := Node.Parent;
|
|
end;
|
|
end;
|
|
|
|
{TDBTreePrintedNodes}
|
|
constructor TDBTreePrintedNodes.Create(APrintedDS : TdxDBTreePrintData; ASourceDS : TDataSet);
|
|
begin
|
|
PrintedDS := APrintedDS;
|
|
SourceDS := ASourceDS;
|
|
List := TList.Create;
|
|
RootList := TList.Create;
|
|
SortedList := TList.Create;
|
|
end;
|
|
|
|
destructor TDBTreePrintedNodes.Destroy;
|
|
begin
|
|
DestroyItems;
|
|
List.Free;
|
|
RootList.Free;
|
|
SortedList.Free;
|
|
end;
|
|
|
|
procedure TDBTreePrintedNodes.DestroyItems;
|
|
Var
|
|
item : TDBTreePrintedNode;
|
|
begin
|
|
while List.Count > 0 do begin
|
|
item := TDBTreePrintedNode(List.Last);
|
|
List.Delete(List.Count - 1);
|
|
item.Free;
|
|
end;
|
|
RootList.Clear;
|
|
end;
|
|
|
|
procedure TDBTreePrintedNodes.CreateStructure;
|
|
Var
|
|
bm : TBookMark;
|
|
i, FRecNumber, NewRecNo : Integer;
|
|
KeyField, ParentField : TField;
|
|
FieldType : TFieldType;
|
|
FieldDes, FieldSrs : TField;
|
|
ListD, ListS : TList;
|
|
begin
|
|
DestroyItems;
|
|
if(PrintedDS <> NIl) And (SourceDS <> NIl) then begin
|
|
KeyField := SourceDS.FindField(PrintedDS.FKeyFieldName);
|
|
ParentField := SourceDS.FindField(PrintedDS.FParentFieldName);
|
|
if (KeyField = Nil) Or (ParentField = Nil) then exit;
|
|
|
|
FieldType := KeyField.DataType;
|
|
with PrintedDS do begin
|
|
if Not VarIsNull(FRootValue) then
|
|
case FieldType of
|
|
ftSmallint: VarCast(FRootValue, FRootValue, varSmallint);
|
|
ftInteger, ftWord, ftAutoInc: VarCast(FRootValue, FRootValue, varInteger);
|
|
ftFloat, ftCurrency: VarCast(FRootValue, FRootValue, varDouble);
|
|
else VarCast(FRootValue, FRootValue, varString);
|
|
end;
|
|
DisableControls;
|
|
end;
|
|
|
|
with SourceDS do begin
|
|
DisableControls;
|
|
bm := GetBookMark;
|
|
First;
|
|
while Not EOF do begin
|
|
TDBTreePrintedNode.Create(self, KeyField.Value, ParentField.Value);
|
|
Next;
|
|
end;
|
|
UpdateNodes;
|
|
First;
|
|
FRecNumber := 1;
|
|
for i := 0 to List.Count - 1 do begin
|
|
PrintedDS.Append;
|
|
PrintedDS.Post;
|
|
end;
|
|
ListD := TList.Create;
|
|
ListS := TList.Create;
|
|
for i := 0 to PrintedDS.FieldCount - 4 do
|
|
begin
|
|
FieldDes := FindField(PrintedDS.Fields[i].FieldName);
|
|
FieldSrs := PrintedDS.FindField(PrintedDS.Fields[i].FieldName);
|
|
if (FieldDes <> nil) and (FieldSrs <> nil) then
|
|
begin
|
|
ListD.Add(FieldDes);
|
|
ListS.Add(FieldSrs);
|
|
end;
|
|
end;
|
|
|
|
while Not EOF do begin
|
|
if (SortedList[FRecNumber - 1] <> Nil) then begin
|
|
NewRecNo := TDBTreePrintedNode(SortedList[FRecNumber - 1]).RecNumber;
|
|
PrintedDS.RecNo := NewRecNo;
|
|
PrintedDS.Edit;
|
|
for i := 0 to ListD.Count - 1 do
|
|
TField(ListS[i]).Assign(TField(ListD[i]));
|
|
PrintedDS.FindField(cDBTreeLevelFieldName).AsInteger := TDBTreePrintedNode(SortedList[FRecNumber - 1]).Level;
|
|
PrintedDS.FindField(cDBTreeRecNoFieldName).AsInteger := TDBTreePrintedNode(SortedList[FRecNumber - 1]).RecNumber;
|
|
if(PrintedDS.FMaxLevelCount < TDBTreePrintedNode(SortedList[FRecNumber - 1]).Level) then
|
|
PrintedDS.FMaxLevelCount := TDBTreePrintedNode(SortedList[FRecNumber - 1]).Level;
|
|
PrintedDS.FindField(cDBTreeHasChildrenFieldName).AsBoolean := TDBTreePrintedNode(SortedList[FRecNumber - 1]).ChildList <> Nil;
|
|
PrintedDS.Post;
|
|
end;
|
|
Next;
|
|
Inc(FRecNumber);
|
|
end;
|
|
GotoBookMark(bm);
|
|
FreeBookMark(bm);
|
|
EnableControls;
|
|
end;
|
|
ListD.Free;
|
|
ListS.Free;
|
|
PrintedDS.First;
|
|
PrintedDS.EnableControls;
|
|
end;
|
|
end;
|
|
|
|
function TDBTreePrintedNodes.IndexOf(Value : Variant) : Integer;
|
|
Var
|
|
i : Integer;
|
|
begin
|
|
if(FindNearest(Value, i)) then
|
|
Result := i
|
|
else Result := -1;
|
|
end;
|
|
|
|
function TDBTreePrintedNodes.FindNearest(Value : Variant; Var Index : Integer) : Boolean;
|
|
var
|
|
Min, Max : LongInt;
|
|
begin
|
|
Result := False;
|
|
if (List.Count = 0) Or VarIsNull(Value)
|
|
Or VarFirstMoreEx( TDBTreePrintedNode(List[0]).KeyValue, Value) then begin
|
|
Index := -1;
|
|
exit;
|
|
end;
|
|
|
|
if VarFirstMoreEx(Value, GetMaxKeyValue) then begin
|
|
Index := List.Count;
|
|
Exit;
|
|
end;
|
|
|
|
Min := 0;
|
|
Max := List.Count - 1;
|
|
|
|
repeat
|
|
if ((Max - Min) = 1) then begin
|
|
if(Min = Index) then Min := Max;
|
|
if(Max = Index) then Max := Min;
|
|
end;
|
|
Index := Min + ((Max - Min) div 2);
|
|
if VarEquals(Value, TDBTreePrintedNode(List[Index]).KeyValue) then break;
|
|
if VarFirstMore(Value, TDBTreePrintedNode(List[Index]).KeyValue) then
|
|
Min := Index
|
|
else Max := Index;
|
|
until (Min = Max);
|
|
if Not VarEquals(Value, TDBTreePrintedNode(List[Index]).KeyValue) then begin
|
|
if (Index < List.Count - 1) And VarFirstMore(Value, TDBTreePrintedNode(List[Index]).KeyValue) then
|
|
Inc(Index);
|
|
end else Result := True;
|
|
end;
|
|
|
|
function TDBTreePrintedNodes.GetMaxKeyValue : Variant;
|
|
begin
|
|
Result := NULL;
|
|
if(List.Count > 0) then begin
|
|
Result := TDBTreePrintedNode(List[List.Count - 1]).KeyValue;
|
|
end;
|
|
end;
|
|
|
|
procedure TDBTreePrintedNodes.UpdateNodes;
|
|
Var
|
|
i, Index, NextValue, OldCount : Integer;
|
|
RootNode, prNode : TDBTreePrintedNode;
|
|
|
|
procedure MakeSortNodes(Node : TDBTreePrintedNode);
|
|
Var
|
|
ii : Integer;
|
|
begin
|
|
if(Node.ChildList <> Nil) then begin
|
|
SortNodes(Node.ChildList);
|
|
for ii := 0 to Node.ChildList.Count - 1 do
|
|
MakeSortNodes(TDBTreePrintedNode(Node.ChildList[ii]));
|
|
end;
|
|
end;
|
|
|
|
procedure SetRecNumber(Node : TDBTreePrintedNode);
|
|
Var
|
|
ii : Integer;
|
|
begin
|
|
if(Node.ChildList <> Nil) then begin
|
|
for ii := 0 to Node.ChildList.Count - 1 do begin
|
|
TDBTreePrintedNode(Node.ChildList[ii]).RecNumber := NextValue;
|
|
Inc(NextValue);
|
|
SetRecNumber(TDBTreePrintedNode(Node.ChildList[ii]));
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure RemoveFromList(Node : TDBTreePrintedNode);
|
|
var
|
|
flag : Integer;
|
|
begin
|
|
if(Node.ChildList <> nil) then
|
|
begin
|
|
flag := 0;
|
|
while (Node.ChildList <> nil) and (Node.ChildList.Count > flag) do
|
|
if(RootNode <> TDBTreePrintedNode(Node.ChildList[flag])) then
|
|
RemoveFromList(TDBTreePrintedNode(Node.ChildList[flag]))
|
|
else Inc(flag);
|
|
end;
|
|
List.Remove(Node);
|
|
SortedList[Node.RecNumber] := Nil;
|
|
Node.Free;
|
|
end;
|
|
|
|
procedure SetParentToNil(AList: TList);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
for I := 0 to AList.Count - 1 do
|
|
TDBTreePrintedNode(AList[I]).Parent := nil;
|
|
end;
|
|
|
|
begin
|
|
i := 0;
|
|
while i < RootList.Count do begin
|
|
Index := IndexOf(TDBTreePrintedNode(RootList[i]).ParentValue);
|
|
OldCount := RootList.Count;
|
|
if(Index > -1)then
|
|
TDBTreePrintedNode(List[Index]).SetChild(TDBTreePrintedNode(RootList[i]));
|
|
if (i < RootList.Count) And (OldCount = RootList.Count)
|
|
And (TDBTreePrintedNode(RootList[i]).Parent = Nil) then
|
|
Inc(i);
|
|
end;
|
|
|
|
if Not VarIsNull(PrintedDS.FRootValue)
|
|
And FindNearest(PrintedDS.FRootValue, Index) then begin
|
|
RootNode := TDBTreePrintedNode(List[Index]);
|
|
RootList.Clear;
|
|
i := 0;
|
|
while (i < List.Count) do begin
|
|
prNode := TDBTreePrintedNode(List[i]);
|
|
if (RootNode <> prNode) And Not (prNode.HasAsParent(RootNode)) then
|
|
RemoveFromList(prNode)
|
|
else Inc(i);
|
|
end;
|
|
RootList.Add(RootNode);
|
|
RootNode.SetLevel(0);
|
|
end;
|
|
|
|
if (PrintedDS.FLevelCount > 0) then begin
|
|
i := 0;
|
|
Index := PrintedDS.FLevelCount - 1;
|
|
while (i < List.Count) do begin
|
|
if(TDBTreePrintedNode(List[i]).Level >= Index) then begin
|
|
prNode := TDBTreePrintedNode(List[i]);
|
|
if (prNode.ChildList <> Nil)then begin
|
|
SetParentToNil(prNode.ChildList);
|
|
prNode.ChildList.Free;
|
|
prNode.ChildList := Nil;
|
|
end;
|
|
if(prNode.Level = Index) then
|
|
Inc(i)
|
|
else begin
|
|
List.Delete(i);
|
|
SortedList[prNode.RecNumber] := Nil;
|
|
prNode.Free;
|
|
end;
|
|
end else Inc(i);
|
|
end;
|
|
end;
|
|
|
|
SortNodes(RootList);
|
|
for i := 0 to RootList.Count - 1 do
|
|
MakeSortNodes(TDBTreePrintedNode(RootList[i]));
|
|
|
|
NextValue := 1;
|
|
for i := 0 to RootList.Count - 1 do begin
|
|
TDBTreePrintedNode(RootList[i]).RecNumber := NextValue;
|
|
Inc(NextValue);
|
|
SetRecNumber(TDBTreePrintedNode(RootList[i]));
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TDBTreePrintedNodes.SortNodes(List : TList);
|
|
|
|
function GetValue(i : Integer) : Integer;
|
|
begin
|
|
Result := TDBTreePrintedNode(List[i]).RecNumber;
|
|
end;
|
|
|
|
procedure Sort(iLo, iHi: Integer);
|
|
var
|
|
Lo, Hi, Mid: Integer;
|
|
begin
|
|
Lo := iLo;
|
|
Hi := iHi;
|
|
Mid := GetValue((Lo + Hi) div 2);
|
|
repeat
|
|
while GetValue(Lo) < Mid do Inc(Lo);
|
|
while GetValue(Hi) > Mid do Dec(Hi);
|
|
if Lo <= Hi then begin
|
|
List.Exchange(Lo, Hi);
|
|
Inc(Lo);
|
|
Dec(Hi);
|
|
end;
|
|
until Lo > Hi;
|
|
if Hi > iLo then Sort(iLo, Hi);
|
|
if Lo < iHi then Sort(Lo, iHi);
|
|
end;
|
|
|
|
begin
|
|
if List.Count > 0 then
|
|
Sort(0, List.Count - 1);
|
|
end;
|
|
|
|
procedure FillDBTreePrintedDataSet(ds1 : TdxDBTreePrintData; ds2 : TDataSet);
|
|
Var
|
|
st : TDBTreePrintedNodes;
|
|
begin
|
|
st := TDBTreePrintedNodes.Create(ds1, ds2);
|
|
st.CreateStructure;
|
|
st.Free;
|
|
end;
|
|
|
|
end.
|
|
|