401
procedure TTreeNode.SetIndex(const AValue: Integer);
403
procedure RaiseMissingTreeNodes;
405
TreeViewError('TTreeNode.SetIndex missing Owner');
412
if OldIndex=AValue then exit;
413
if Parent=nil then begin
414
// moving a top level node
415
if Owner=nil then RaiseMissingTreeNodes;
417
MoveTo(Owner.GetFirstNode,naInsert)
418
else if AValue<OldIndex then
419
MoveTo(Owner.TopLvlItems[AValue-1],naInsertBehind)
421
MoveTo(Owner.TopLvlItems[AValue],naInsertBehind);
423
// moving a normal node
425
MoveTo(Parent.GetFirstChild,naInsert)
426
else if AValue<OldIndex then
427
MoveTo(Parent.Items[AValue-1],naInsertBehind)
429
MoveTo(Parent.Items[AValue],naInsertBehind);
403
433
procedure TTreeNode.SetSelectedIndex(AValue: Integer);
405
435
if FSelectedIndex = AValue then exit;
1087
1139
if ANode<>nil then DbgOut(' ANode.Text=',ANode.Text);
1092
if AddMode in [taAdd, taAddFirst] then
1094
else begin // taInsert
1096
TreeNodeError('TTreeNode.InternalMove AddMode=taInsert but ANode=nil');
1097
FParent:=ANode.Parent;
1098
FPrevBrother:=ANode.FPrevBrother;
1099
FNextBrother:=ANode;
1101
if FParent<>nil then begin
1102
FParent.HasChildren:=true;
1103
if (FParent.FCount=FParent.FCapacity) then begin
1104
// grow FParent.FItems
1105
if FParent.FCapacity=0 then
1106
FParent.FCapacity:=5
1108
FParent.FCapacity:=FParent.FCapacity shl 1;
1109
NewParentItemSize:=SizeOf(Pointer)*FParent.FCapacity;
1110
if FParent.FItems=nil then
1111
GetMem(FParent.FItems,NewParentItemSize)
1113
ReAllocMem(FParent.FItems,NewParentItemSize);
1115
inc(FParent.FCount);
1116
// calculate new Index
1118
taAdd: NewIndex:=FParent.Count-1;
1119
taAddFirst: NewIndex:=0;
1122
NewIndex:=ANode.Index;
1124
// move next siblings
1125
for i:=FParent.FCount-1 downto NewIndex+1 do
1126
FParent.FItems[i]:=FParent.FItems[i-1];
1127
// insert this node to parent's items
1128
FParent.FItems[NewIndex]:=Self;
1129
// set Next and Prev sibling
1131
FPrevBrother:=FParent.FItems[NewIndex-1]
1134
if NewIndex<FParent.Count-1 then
1135
FNextBrother:=FParent.FItems[NewIndex+1]
1138
// update total node count of all parents
1139
HigherNode:=FParent;
1140
while HigherNode<>nil do begin
1141
inc(HigherNode.FSubTreeCount,FSubTreeCount);
1142
HigherNode:=HigherNode.Parent;
1144
//if TreeNodes<>nil then inc(TreeNodes.FCount,FSubTreeCount);
1146
// add as top level node
1150
// add as last top level node
1151
if Owner<>nil then begin
1152
FPrevBrother:=Owner.GetLastNode;
1153
Owner.MoveTopLvlNode(-1,Owner.FTopLvlCount,Self);
1158
// add as first top level node = root node
1159
if Owner<>nil then begin
1160
FNextBrother:=Owner.GetFirstNode;
1161
Owner.MoveTopLvlNode(-1,0,Self);
1166
// insert node in front of ANode
1167
//DebugLn('[TTreeNode.InternalMove] ANode.Index=',ANode.Index,' ANode=',DbgS(ANode));
1168
FNextBrother:=ANode;
1169
FPrevBrother:=ANode.GetPrevSibling;
1170
if Owner<>nil then begin
1171
Owner.MoveTopLvlNode(-1,ANode.Index,Self);
1176
// connect Next and Prev sibling
1177
if FPrevBrother<>nil then FPrevBrother.FNextBrother:=Self;
1178
if FNextBrother<>nil then FNextBrother.FPrevBrother:=Self;
1179
if Owner.Owner<>nil then
1180
Owner.Owner.FStates:=Owner.Owner.FStates+[tvsMaxRightNeedsUpdate,
1181
tvsTopsNeedsUpdate,tvsTopItemNeedsUpdate,tvsBottomItemNeedsUpdate];
1142
if TreeView<>nil then TreeView.BeginUpdate;
1144
WasSelected:=Selected;
1147
if AddMode in [taAdd, taAddFirst] then
1149
else begin // taInsert
1151
TreeNodeError('TTreeNode.InternalMove AddMode=taInsert but ANode=nil');
1152
FParent:=ANode.Parent;
1153
FPrevBrother:=ANode.FPrevBrother;
1154
FNextBrother:=ANode;
1156
if FParent<>nil then begin
1157
FParent.HasChildren:=true;
1158
if (FParent.FCount=FParent.FCapacity) then begin
1159
// grow FParent.FItems
1160
if FParent.FCapacity=0 then
1161
FParent.FCapacity:=5
1163
FParent.FCapacity:=FParent.FCapacity shl 1;
1164
NewParentItemSize:=SizeOf(Pointer)*FParent.FCapacity;
1165
if FParent.FItems=nil then
1166
GetMem(FParent.FItems,NewParentItemSize)
1168
ReAllocMem(FParent.FItems,NewParentItemSize);
1170
inc(FParent.FCount);
1171
// calculate new Index
1173
taAdd: NewIndex:=FParent.Count-1;
1174
taAddFirst: NewIndex:=0;
1177
NewIndex:=ANode.Index;
1179
// move next siblings
1180
for i:=FParent.FCount-1 downto NewIndex+1 do begin
1181
FParent.FItems[i]:=FParent.FItems[i-1];
1182
FParent.FItems[i].FIndex:=i;
1184
// insert this node to parent's items
1185
FParent.FItems[NewIndex]:=Self;
1187
// set Next and Prev sibling
1189
FPrevBrother:=FParent.FItems[NewIndex-1]
1192
if NewIndex<FParent.Count-1 then
1193
FNextBrother:=FParent.FItems[NewIndex+1]
1196
// update total node count of all parents
1197
HigherNode:=FParent;
1198
while HigherNode<>nil do begin
1199
inc(HigherNode.FSubTreeCount,FSubTreeCount);
1200
HigherNode:=HigherNode.Parent;
1202
//if TreeNodes<>nil then inc(TreeNodes.FCount,FSubTreeCount);
1204
// add as top level node
1208
// add as last top level node
1209
if Owner<>nil then begin
1210
FPrevBrother:=Owner.GetLastNode;
1211
Owner.MoveTopLvlNode(-1,Owner.FTopLvlCount,Self);
1216
// add as first top level node = root node
1217
if Owner<>nil then begin
1218
FNextBrother:=Owner.GetFirstNode;
1219
Owner.MoveTopLvlNode(-1,0,Self);
1224
// insert node in front of ANode
1225
//DebugLn('[TTreeNode.InternalMove] ANode.Index=',ANode.Index,' ANode=',DbgS(ANode));
1226
FNextBrother:=ANode;
1227
FPrevBrother:=ANode.GetPrevSibling;
1228
if Owner<>nil then begin
1229
Owner.MoveTopLvlNode(-1,ANode.Index,Self);
1234
// connect Next and Prev sibling
1235
if FPrevBrother<>nil then FPrevBrother.FNextBrother:=Self;
1236
if FNextBrother<>nil then FNextBrother.FPrevBrother:=Self;
1237
if Owner.Owner<>nil then
1238
Owner.Owner.FStates:=Owner.Owner.FStates+[tvsMaxRightNeedsUpdate,
1239
tvsTopsNeedsUpdate,tvsTopItemNeedsUpdate,tvsBottomItemNeedsUpdate];
1240
// re-add to multiselection list
1241
if MultiSelected then
1242
BindToMultiSelected;
1246
if TreeView<>nil then TreeView.EndUpdate;
1183
1249
{$IFDEF TREEVIEW_DEBUG}
1184
1250
DbgOut('[TTreeNode.InternalMove] END Self=',DbgS(Self),' Self.Text=',Text
1293
1317
if (TreeView<>nil) and (not (tvoAllowMultiselect in TreeView.Options)) then
1295
1319
if (TreeView<>nil) then TreeView.LockSelectionChangeEvent;
1296
FirstNode:=GetPrevSibling;
1297
while (FirstNode<>nil) and (not FirstNode.MultiSelected) do
1298
FirstNode:=FirstNode.GetPrevSibling;
1299
if FirstNode=nil then FirstNode:=Self;
1300
LastNode:=GetNextSibling;
1301
while (LastNode<>nil) and (not LastNode.MultiSelected) do
1302
LastNode:=LastNode.GetNextSibling;
1303
if LastNode=nil then LastNode:=Self;
1305
while ANode<>nil do begin
1306
ANode.MultiSelected:=true;
1307
if ANode=LastNode then break;
1308
ANode:=ANode.GetNextSibling;
1321
FirstNode:=GetPrevSibling;
1322
while (FirstNode<>nil) and (not FirstNode.MultiSelected) do
1323
FirstNode:=FirstNode.GetPrevSibling;
1324
if FirstNode=nil then FirstNode:=Self;
1325
LastNode:=GetNextSibling;
1326
while (LastNode<>nil) and (not LastNode.MultiSelected) do
1327
LastNode:=LastNode.GetNextSibling;
1328
if LastNode=nil then LastNode:=Self;
1330
while ANode<>nil do begin
1331
ANode.MultiSelected:=true;
1332
if ANode=LastNode then break;
1333
ANode:=ANode.GetNextSibling;
1336
if (TreeView<>nil) then TreeView.UnlockSelectionChangeEvent;
1310
if (TreeView<>nil) then TreeView.UnlockSelectionChangeEvent;
1313
1340
procedure TTreeNode.MakeVisible;
1597
1616
if FOwner<>nil then begin
1599
if FCapacity<0 then RaiseGDBException('');
1600
if FCapacity<FCount then RaiseGDBException('');
1601
if FCount<0 then RaiseGDBException('');
1602
if FHeight<0 then RaiseGDBException('');
1603
if (FItems<>nil) and (FCapacity<=0) then RaiseGDBException('');
1604
if (FCapacity>0) and (FItems=nil) then RaiseGDBException('');
1619
RaiseGDBException('');
1620
if FCapacity<FCount then
1621
RaiseGDBException('');
1623
RaiseGDBException('');
1625
RaiseGDBException('');
1626
if (FItems<>nil) and (FCapacity<=0) then
1627
RaiseGDBException('');
1628
if (FCapacity>0) and (FItems=nil) then
1629
RaiseGDBException('');
1605
1630
if (FNextBrother<>nil) and (FNextBrother.FPrevBrother<>Self) then
1606
1631
RaiseGDBException('');
1607
1632
if (FPrevBrother<>nil) and (FPrevBrother.FNextBrother<>Self) then
1608
1633
RaiseGDBException('');
1634
if (FNextMultiSelected<>nil) and (FNextMultiSelected.FPrevMultiSelected<>Self) then
1635
RaiseGDBException('');
1636
if (FPrevMultiSelected<>nil) and (FPrevMultiSelected.FNextMultiSelected<>Self) then
1637
RaiseGDBException('');
1638
if MultiSelected then begin
1639
Node1:=TreeView.GetFirstMultiSelected;
1640
while (Node1<>nil) and (Node1<>Self) do Node1:=Node1.FNextMultiSelected;
1642
RaiseGDBException('');
1644
if Selected and (TreeView<>nil) and (tvoAllowMultiselect in TreeView.Options)
1645
and (not MultiSelected) then
1646
RaiseGDBException('');// selected, but not multiselected
1609
1648
// check childs
1610
1649
RealSubTreeCount:=1;
1611
1650
for i:=0 to FCount-1 do begin
1612
1651
if (Items[i]=nil) then RaiseGDBException('');
1613
if (i=0) and (Items[i].FPrevBrother<>nil) then RaiseGDBException('');
1614
if (i>0) and (Items[i].FPrevBrother=nil) then RaiseGDBException('');
1615
if (i>0) and (Items[i].FPrevBrother<>Items[i-1]) then RaiseGDBException('');
1616
if (i<FCount-1) and (Items[i].FNextBrother=nil) then
1617
RaiseGDBException('');
1618
if (i<FCount-1) and (Items[i].FNextBrother<>Items[i+1]) then
1619
RaiseGDBException('');
1620
if (i=FCount-1) and (Items[i].FNextBrother<>nil) then
1621
RaiseGDBException('');
1622
if Items[i].FParent<>Self then RaiseGDBException('');
1623
Items[i].ConsistencyCheck;
1624
inc(RealSubTreeCount,Items[i].SubTreeCount);
1653
if Node1.FParent<>Self then RaiseGDBException('');
1654
if (i=0) and (Node1.FPrevBrother<>nil) then
1655
RaiseGDBException('');
1656
if (i>0) and (Node1.FPrevBrother=nil) then
1657
RaiseGDBException('');
1658
if (i>0) and (Node1.FPrevBrother<>Items[i-1]) then
1659
RaiseGDBException('');
1660
if (i<FCount-1) and (Node1.FNextBrother=nil) then
1661
RaiseGDBException('');
1662
if (i<FCount-1) and (Node1.FNextBrother<>Items[i+1]) then
1663
RaiseGDBException('');
1664
if (i=FCount-1) and (Node1.FNextBrother<>nil) then
1665
RaiseGDBException('');
1666
if Node1.FIndex<>i then
1667
RaiseGDBException('');
1668
Node1.ConsistencyCheck;
1669
inc(RealSubTreeCount,Node1.SubTreeCount);
1626
1671
if FParent<>nil then begin
1627
1672
if FParent.IndexOf(Self)<0 then RaiseGDBException('');
1697
1740
GetLastNode.Delete;
1700
procedure TTreeNodes.ClearMultiSelection;
1743
procedure TTreeNodes.ClearMultiSelection(ClearSelected: boolean = false);
1702
1745
ANode, OldNode: TTreeNode;
1704
1747
if Owner<>nil then Owner.LockSelectionChangeEvent;
1705
ANode:=FFirstMultiSelected;
1706
while ANode<>nil do begin
1708
ANode:=ANode.GetNextMultiSelected;
1709
OldNode.MultiSelected:=false;
1711
if Owner<>nil then Owner.UnlockSelectionChangeEvent;
1749
ANode:=FFirstMultiSelected;
1750
while ANode<>nil do begin
1752
ANode:=ANode.GetNextMultiSelected;
1753
OldNode.MultiSelected:=false;
1755
if ClearSelected then
1756
Owner.Selected:=nil;
1758
if Owner<>nil then Owner.UnlockSelectionChangeEvent;
1762
procedure TTreeNodes.SelectOnlyThis(Node: TTreeNode);
1764
if Owner<>nil then Owner.LockSelectionChangeEvent;
1766
ClearMultiSelection(true);
1767
Node.Selected:=true;
1769
if Owner<>nil then Owner.UnlockSelectionChangeEvent;
1714
1773
function TTreeNodes.IsMultiSelection: boolean;
1915
1974
Result:=Result.GetNextSibling;
1977
function TTreeNodes.FindNodeWithText(const NodeText: string): TTreeNode;
1979
Result:=GetFirstNode;
1980
while (Result<>nil) and (Result.Text<>NodeText) do
1981
Result:=Result.GetNext;
1984
function TTreeNodes.FindNodeWithData(const NodeData: Pointer): TTreeNode;
1986
Result:=GetFirstNode;
1987
while (Result<>nil) and (Result.Data<>NodeData) do
1988
Result:=Result.GetNext;
1918
1991
function TTreeNodes.GetNodeFromIndex(Index: Integer): TTreeNode;
1919
1992
// find node with absolute index in ALL nodes (even collapsed)
1994
procedure RaiseIndexOutOfBounds;
1996
TreeNodeError('TTreeNodes.GetNodeFromIndex Index '+IntToStr(Index)
1997
+' out of bounds (Count='+IntToStr(FCount)+')');
2000
procedure RaiseSubTreeCount0;
2003
'TTreeNodes.GetNodeFromIndex: Consistency error - SubTreeCount=0');
2006
procedure RaiseSubTreeCountTooBig;
2009
'TTreeNodes.GetNodeFromIndex: Consistency error - invalid SubTreeCount');
2012
procedure RaiseCountTooBig;
2015
'TTreeNodes.GetNodeFromIndex: Consistency Error - Count too big');
1923
2021
if (Index < 0) or (Index >= FCount) then
1924
TreeNodeError('TTreeNodes.GetNodeFromIndex Index '+IntToStr(Index)
1925
+' out of bounds (Count='+IntToStr(FCount)+')');
2022
RaiseIndexOutOfBounds;
1926
2023
if (FNodeCache.CacheNode <> nil) and (Abs(FNodeCache.CacheIndex - Index) <= 1)
1928
2025
with FNodeCache do
2284
2394
if (FTopLvlCount<0) then
2285
2395
RaiseGDBException('');
2286
2396
for i:=0 to FTopLvlCount-1 do begin
2287
if (i=0) and (FTopLvlItems[i].FPrevBrother<>nil) then
2288
RaiseGDBException('');
2289
if (i>0) and (FTopLvlItems[i].FPrevBrother<>FTopLvlItems[i-1]) then
2290
RaiseGDBException('');
2291
if (i<FTopLvlCount-1) and (FTopLvlItems[i].FNextBrother<>FTopLvlItems[i+1])
2397
Node:=FTopLvlItems[i];
2398
if (i=0) and (Node.FPrevBrother<>nil) then
2399
RaiseGDBException('');
2400
if (i>0) and (Node.FPrevBrother<>FTopLvlItems[i-1]) then
2401
RaiseGDBException('');
2402
if (i<FTopLvlCount-1) and (Node.FNextBrother<>FTopLvlItems[i+1])
2293
2404
DebugLn(' CONSISTENCY i=%d FTopLvlCount=%d FTopLvlItems[i]=%p FTopLvlItems[i].FNextBrother=%p FTopLvlItems[i+1]=%p',
2294
[i, FTopLvlCount, Pointer(FTopLvlItems[i]), Pointer(FTopLvlItems[i].FNextBrother), Pointer(FTopLvlItems[i+1])]);
2405
[i, FTopLvlCount, Pointer(Node), Pointer(Node.FNextBrother), Pointer(FTopLvlItems[i+1])]);
2295
2406
RaiseGDBException('');
2297
if (i=FTopLvlCount-1) and (FTopLvlItems[i].FNextBrother<>nil) then
2408
if (i=FTopLvlCount-1) and (Node.FNextBrother<>nil) then
2409
RaiseGDBException('');
2410
if Node.FIndex<>i then
2298
2411
RaiseGDBException('');
2300
2413
if FNodeCache.CacheNode<>nil then begin