summaryrefslogtreecommitdiff
path: root/apps/X11/VCL/TTreeNode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/X11/VCL/TTreeNode.cpp')
-rw-r--r--apps/X11/VCL/TTreeNode.cpp1003
1 files changed, 1003 insertions, 0 deletions
diff --git a/apps/X11/VCL/TTreeNode.cpp b/apps/X11/VCL/TTreeNode.cpp
new file mode 100644
index 0000000..e50778b
--- /dev/null
+++ b/apps/X11/VCL/TTreeNode.cpp
@@ -0,0 +1,1003 @@
+#include <TTreeNode.h>
+#include <TTreeNodes.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkhbox.h>
+#include <stdio.h>
+
+
+TTreeNode::TTreeNode(TTreeNodes *AOwner) :
+ Text(this, &TTreeNode::getText, &TTreeNode::SetText),
+ StateIndex(this, &TTreeNode::getStateIndex, &TTreeNode::SetStateIndex),
+ ImageIndex(this, &TTreeNode::getImageIndex, &TTreeNode::SetImageIndex),
+ Data(this, &TTreeNode::getData, &TTreeNode::SetData),
+ Parent(this, &TTreeNode::GetParent, 0) {
+ FOwner = AOwner;
+ FStateIndex = 0;
+ FImageIndex = 0;
+}
+
+
+TTreeNode::TTreeNode(const TTreeNode &other) :
+ Text(this, &TTreeNode::getText, &TTreeNode::SetText),
+ StateIndex(this, &TTreeNode::getStateIndex, &TTreeNode::SetStateIndex),
+ ImageIndex(this, &TTreeNode::getImageIndex, &TTreeNode::SetImageIndex),
+ Data(this, &TTreeNode::getData, &TTreeNode::SetData),
+ Parent(this, &TTreeNode::GetParent, 0) {
+ FOwner = other.FOwner;
+ subTreeOwner = other.subTreeOwner;
+ nativeControl = other.nativeControl;
+ FData = other.FData;
+ Text = other.Text;
+ FStateIndex = other.FStateIndex;
+ FImageIndex = other.FImageIndex;
+}
+
+TTreeNode::TTreeNode(TTreeNodes *AOwner, GtkTree *AsubTreeOwner, GtkTreeItem *AnativeControl, string AText, void *Ptr) :
+ Text(this, &TTreeNode::getText, &TTreeNode::SetText),
+ StateIndex(this, &TTreeNode::getStateIndex, &TTreeNode::SetStateIndex),
+ ImageIndex(this, &TTreeNode::getImageIndex, &TTreeNode::SetImageIndex),
+ Data(this, &TTreeNode::getData, &TTreeNode::SetData),
+ Parent(this, &TTreeNode::GetParent, 0) {
+ FOwner = AOwner;
+ subTreeOwner = AsubTreeOwner;
+ nativeControl = AnativeControl;
+ FData = Ptr;
+ Text = AText;
+ FStateIndex = 0;
+ FImageIndex = 0;
+}
+
+
+TTreeNode::~TTreeNode() {
+}
+
+
+/*
+function TTreeNode.GetLastChild: TTreeNode;
+var
+ Node: TTreeNode;
+begin
+ Result := GetFirstChild;
+ if Result <> nil then
+ begin
+ Node := Result;
+ repeat
+ Result := Node;
+ Node := Result.GetNextSibling;
+ until Node = nil;
+ end;
+end;
+*/
+
+/*
+function TTreeNode.GetFirstChild: TTreeNode;
+begin
+ with FOwner do
+ Result := GetNode(TreeView_GetChild(Handle, ItemId));
+end;
+*/
+TTreeNode *TTreeNode::getFirstChild() {
+ GtkWidget *subtree = nativeControl->subtree;
+ if (subtree) {
+ GList *child = g_list_first(GTK_TREE(subtree)->children);
+ return (child) ? FOwner->GetNode(GTK_TREE_ITEM(child->data)) : 0;
+ }
+ return 0;
+}
+
+
+/*
+function TTreeNode.GetNextSibling: TTreeNode;
+begin
+ with FOwner do
+ Result := GetNode(TreeView_GetNextSibling(Handle, ItemId));
+end;
+*/
+TTreeNode *TTreeNode::getNextSibling() {
+ GList *node = g_list_find(GTK_TREE(subTreeOwner)->children, nativeControl);
+ if (node) {
+ node = g_list_next(node);
+ return (node) ? FOwner->GetNode(GTK_TREE_ITEM(node->data)) : 0;
+ }
+ return 0;
+}
+
+
+/*
+procedure TTreeNode.SetText(const S: string);
+var
+ Item: TTVItem;
+begin
+ FText := S;
+ with Item do
+ begin
+ mask := TVIF_TEXT;
+ hItem := ItemId;
+ pszText := LPSTR_TEXTCALLBACK;
+ end;
+ TreeView_SetItem(Handle, Item);
+ if (TreeView.SortType in [stText, stBoth]) and FInTree then
+ begin
+ if (Parent <> nil) then Parent.AlphaSort
+ else TreeView.AlphaSort;
+ end;
+end;
+*/
+
+
+void TTreeNode::SetText(string S) {
+ FText = S;
+ GtkLabel *label;
+ GtkObject *hbox;
+
+ //It's a Bin, so it has one child, which we know to be a
+ // hbox, so get that
+ hbox = GTK_OBJECT(GTK_BIN(nativeControl)->child);
+ label = GTK_LABEL(gtk_object_get_data(hbox, "label1"));
+ gtk_label_set(label, FText.c_str());
+}
+
+
+/*
+function TTreeNode.GetParent: TTreeNode;
+begin
+ with FOwner do
+ Result := GetNode(TreeView_GetParent(Handle, ItemId));
+end;
+*/
+
+TTreeNode *TTreeNode::GetParent() {
+ return FOwner->GetParentNode(this);
+}
+
+
+/*
+procedure TTreeNode.SetStateIndex(Value: Integer);
+var
+ Item: TTVItem;
+begin
+ FStateIndex := Value;
+ if Value >= 0 then Dec(Value);
+ with Item do
+ begin
+ mask := TVIF_STATE or TVIF_HANDLE;
+ stateMask := TVIS_STATEIMAGEMASK;
+ hItem := ItemId;
+ state := IndexToStateImageMask(Value + 1);
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+*/
+
+void TTreeNode::SetStateIndex(int val) {
+ GtkPixmap *itempixmap = 0, *stateImage;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ FStateIndex = val;
+ TCustomImageList *images;
+ GtkObject *hbox;
+ // display appropriate image
+
+ hbox = GTK_OBJECT(GTK_BIN(nativeControl)->child);
+ itempixmap = GTK_PIXMAP(gtk_object_get_data(hbox, "pixmap1"));
+
+ gtk_widget_hide(GTK_WIDGET(itempixmap));
+
+ images = FOwner->FOwner->StateImages;
+
+ if (images) {
+ stateImage = images->GetPixmap(val);
+ if (stateImage) {
+ gtk_pixmap_get(stateImage, &pixmap, &mask);
+ gtk_pixmap_set(itempixmap, pixmap, mask);
+ gtk_widget_show(GTK_WIDGET(itempixmap));
+ }
+
+ }
+}
+
+
+/*
+procedure TTreeNode.SetImageIndex(Value: Integer);
+var
+ Item: TTVItem;
+begin
+ FImageIndex := Value;
+ with Item do
+ begin
+ mask := TVIF_IMAGE or TVIF_HANDLE;
+ hItem := ItemId;
+ iImage := I_IMAGECALLBACK;
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+*/
+
+void TTreeNode::SetImageIndex(int val) {
+ GtkPixmap *itempixmap, *Image;
+ GdkPixmap *pixmap;
+ GdkBitmap *mask;
+ FImageIndex = val;
+ TCustomImageList *images;
+ GtkObject *hbox;
+ // display appropriate image
+
+ hbox = GTK_OBJECT(GTK_BIN(nativeControl)->child);
+ itempixmap = GTK_PIXMAP(gtk_object_get_data(hbox, "pixmap2"));
+
+ gtk_widget_hide(GTK_WIDGET(itempixmap));
+
+ images = FOwner->FOwner->Images;
+
+ if (images) {
+ Image = images->GetPixmap(val);
+ if (Image) {
+ gtk_pixmap_get(Image, &pixmap, &mask);
+ gtk_pixmap_set(itempixmap, pixmap, mask);
+ gtk_widget_show(GTK_WIDGET(itempixmap));
+ }
+ }
+}
+
+
+/*
+procedure TTreeNode.SetData(Value: Pointer);
+begin
+ FData := Value;
+ if (TreeView.SortType in [stData, stBoth]) and Assigned(TreeView.OnCompare)
+ and (not Deleting) and FInTree then
+ begin
+ if Parent <> nil then Parent.AlphaSort
+ else TreeView.AlphaSort;
+ end;
+end;
+*/
+
+void TTreeNode::SetData(void *Value) {
+ FData = Value;
+}
+
+
+/*
+function TTreeNode.GetNext: TTreeNode;
+var
+ NodeID, ParentID: HTreeItem;
+ Handle: HWND;
+begin
+ Handle := FOwner.Handle;
+ NodeID := TreeView_GetChild(Handle, ItemId);
+ if NodeID = nil then NodeID := TreeView_GetNextSibling(Handle, ItemId);
+ ParentID := ItemId;
+ while (NodeID = nil) and (ParentID <> nil) do
+ begin
+ ParentID := TreeView_GetParent(Handle, ParentID);
+ NodeID := TreeView_GetNextSibling(Handle, ParentID);
+ end;
+ Result := FOwner.GetNode(NodeID);
+end;
+*/
+
+TTreeNode *TTreeNode::GetNext() {
+ TTreeNode *parent = this;
+ TTreeNode *next = getFirstChild();
+ if (!next) {
+ next = getNextSibling();
+ while ((!next) && (parent)) {
+ parent = parent->GetParent();
+ if (parent)
+ next = parent->getNextSibling();
+ }
+ }
+
+ return next;
+}
+
+
+/*
+procedure TTreeNode.ExpandItem(Expand: Boolean; Recurse: Boolean);
+var
+ Flag: Integer;
+ Node: TTreeNode;
+begin
+ if Recurse then
+ begin
+ Node := Self;
+ repeat
+ Node.ExpandItem(Expand, False);
+ Node := Node.GetNext;
+ until (Node = nil) or (not Node.HasAsParent(Self));
+ end
+ else begin
+ TreeView.FManualNotify := True;
+ try
+ Flag := 0;
+ if Expand then
+ begin
+ if DoCanExpand(True) then
+ begin
+ Flag := TVE_EXPAND;
+ DoExpand(True);
+ end;
+ end
+ else begin
+ if DoCanExpand(False) then
+ begin
+ Flag := TVE_COLLAPSE;
+ DoExpand(False);
+ end;
+ end;
+ if Flag <> 0 then TreeView_Expand(Handle, ItemId, Flag);
+ finally
+ TreeView.FManualNotify := False;
+ end;
+ end;
+end;
+*/
+
+void TTreeNode::ExpandItem(bool Expand, bool Recurse) {
+ TTreeNode *Node;
+
+ if (Recurse) {
+ Node = this;
+ do {
+ Node->ExpandItem(Expand, false);
+ Node = Node->GetNext();
+ }
+ while ((Node) /*and (Node.HasAsParent(Self)*/);
+ }
+ else {
+ gtk_tree_item_expand(nativeControl);
+
+/*
+ TreeView.FManualNotify := True;
+ try
+ Flag := 0;
+ if Expand then
+ begin
+ if DoCanExpand(True) then
+ begin
+ Flag := TVE_EXPAND;
+ DoExpand(True);
+ end;
+ end
+ else begin
+ if DoCanExpand(False) then
+ begin
+ Flag := TVE_COLLAPSE;
+ DoExpand(False);
+ end;
+ end;
+ if Flag <> 0 then TreeView_Expand(Handle, ItemId, Flag);
+ finally
+ TreeView.FManualNotify := False;
+ end;
+*/
+ }
+}
+
+/*
+procedure TTreeNode.Expand(Recurse: Boolean);
+begin
+ ExpandItem(True, Recurse);
+end;
+*/
+
+void TTreeNode::Expand(bool Recurse) {
+ ExpandItem(true, Recurse);
+}
+
+/*
+
+function DefaultTreeViewSort(Node1, Node2: TTreeNode; lParam: Integer): Integer; stdcall;
+begin
+ with Node1 do
+ if Assigned(TreeView.OnCompare) then
+ TreeView.OnCompare(TreeView, Node1, Node2, lParam, Result)
+ else Result := lstrcmp(PChar(Node1.Text), PChar(Node2.Text));
+end;
+
+procedure TreeViewError(const Msg: string);
+begin
+ raise ETreeViewError.Create(Msg);
+end;
+
+procedure TreeViewErrorFmt(const Msg: string; Format: array of const);
+begin
+ raise ETreeViewError.CreateFmt(Msg, Format);
+end;
+
+constructor TTreeNode.Create(AOwner: TTreeNodes);
+begin
+ inherited Create;
+ FOverlayIndex := -1;
+ FStateIndex := -1;
+ FOwner := AOwner;
+end;
+
+destructor TTreeNode.Destroy;
+var
+ Node: TTreeNode;
+ CheckValue: Integer;
+begin
+ Owner.ClearCache;
+ FDeleting := True;
+ if Owner.Owner.FLastDropTarget = Self then
+ Owner.Owner.FLastDropTarget := nil;
+ Node := Parent;
+ if (Node <> nil) and (not Node.Deleting) then
+ begin
+ if Node.IndexOf(Self) <> -1 then CheckValue := 1
+ else CheckValue := 0;
+ if Node.CompareCount(CheckValue) then
+ begin
+ Expanded := False;
+ Node.HasChildren := False;
+ end;
+ end;
+ if ItemId <> nil then TreeView_DeleteItem(Handle, ItemId);
+ Data := nil;
+ inherited Destroy;
+end;
+
+function TTreeNode.GetHandle: HWND;
+begin
+ Result := TreeView.Handle;
+end;
+
+function TTreeNode.GetTreeView: TCustomTreeView;
+begin
+ Result := Owner.Owner;
+end;
+
+function TTreeNode.HasAsParent(Value: TTreeNode): Boolean;
+begin
+ if Value <> Nil then
+ begin
+ if Parent = nil then Result := False
+ else if Parent = Value then Result := True
+ else Result := Parent.HasAsParent(Value);
+ end
+ else Result := True;
+end;
+
+function TTreeNode.GetState(NodeState: TNodeState): Boolean;
+var
+ Item: TTVItem;
+begin
+ Result := False;
+ with Item do
+ begin
+ mask := TVIF_STATE;
+ hItem := ItemId;
+ if TreeView_GetItem(Handle, Item) then
+ case NodeState of
+ nsCut: Result := (state and TVIS_CUT) <> 0;
+ nsFocused: Result := (state and TVIS_FOCUSED) <> 0;
+ nsSelected: Result := (state and TVIS_SELECTED) <> 0;
+ nsExpanded: Result := (state and TVIS_EXPANDED) <> 0;
+ nsDropHilited: Result := (state and TVIS_DROPHILITED) <> 0;
+ end;
+ end;
+end;
+
+procedure TTreeNode.SetSelectedIndex(Value: Integer);
+var
+ Item: TTVItem;
+begin
+ FSelectedIndex := Value;
+ with Item do
+ begin
+ mask := TVIF_SELECTEDIMAGE or TVIF_HANDLE;
+ hItem := ItemId;
+ iSelectedImage := I_IMAGECALLBACK;
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+
+procedure TTreeNode.SetOverlayIndex(Value: Integer);
+var
+ Item: TTVItem;
+begin
+ FOverlayIndex := Value;
+ with Item do
+ begin
+ mask := TVIF_STATE or TVIF_HANDLE;
+ stateMask := TVIS_OVERLAYMASK;
+ hItem := ItemId;
+ state := IndexToOverlayMask(OverlayIndex + 1);
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+
+function TTreeNode.CompareCount(CompareMe: Integer): Boolean;
+var
+ Count: integer;
+ Node: TTreeNode;
+Begin
+ Count := 0;
+ Result := False;
+ Node := GetFirstChild;
+ while Node <> nil do
+ begin
+ Inc(Count);
+ Node := Node.GetNextChild(Node);
+ if Count > CompareMe then Exit;
+ end;
+ if Count = CompareMe then Result := True;
+end;
+
+function TTreeNode.DoCanExpand(Expand: Boolean): Boolean;
+begin
+ Result := False;
+ if HasChildren then
+ begin
+ if Expand then Result := TreeView.CanExpand(Self)
+ else Result := TreeView.CanCollapse(Self);
+ end;
+end;
+
+procedure TTreeNode.DoExpand(Expand: Boolean);
+begin
+ if HasChildren then
+ begin
+ if Expand then TreeView.Expand(Self)
+ else TreeView.Collapse(Self);
+ end;
+end;
+
+procedure TTreeNode.Collapse(Recurse: Boolean);
+begin
+ ExpandItem(False, Recurse);
+end;
+
+function TTreeNode.GetExpanded: Boolean;
+begin
+ Result := GetState(nsExpanded);
+end;
+
+procedure TTreeNode.SetExpanded(Value: Boolean);
+begin
+ if Value then Expand(False)
+ else Collapse(False);
+end;
+
+function TTreeNode.GetSelected: Boolean;
+begin
+ Result := GetState(nsSelected);
+end;
+
+procedure TTreeNode.SetSelected(Value: Boolean);
+begin
+ if Value then TreeView_SelectItem(Handle, ItemId)
+ else if Selected then TreeView_SelectItem(Handle, nil);
+end;
+
+function TTreeNode.GetCut: Boolean;
+begin
+ Result := GetState(nsCut);
+end;
+
+procedure TTreeNode.SetCut(Value: Boolean);
+var
+ Item: TTVItem;
+ Template: DWORD;
+begin
+ if Value then Template := DWORD(-1)
+ else Template := 0;
+ with Item do
+ begin
+ mask := TVIF_STATE;
+ hItem := ItemId;
+ stateMask := TVIS_CUT;
+ state := stateMask and Template;
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+
+function TTreeNode.GetDropTarget: Boolean;
+begin
+ Result := GetState(nsDropHilited);
+end;
+
+procedure TTreeNode.SetDropTarget(Value: Boolean);
+begin
+ if Value then TreeView_SelectDropTarget(Handle, ItemId)
+ else if DropTarget then TreeView_SelectDropTarget(Handle, nil);
+end;
+
+function TTreeNode.GetChildren: Boolean;
+var
+ Item: TTVItem;
+begin
+ Item.mask := TVIF_CHILDREN;
+ Item.hItem := ItemId;
+ if TreeView_GetItem(Handle, Item) then Result := Item.cChildren > 0
+ else Result := False;
+end;
+
+procedure TTreeNode.SetFocused(Value: Boolean);
+var
+ Item: TTVItem;
+ Template: DWORD;
+begin
+ if Value then Template := DWORD(-1)
+ else Template := 0;
+ with Item do
+ begin
+ mask := TVIF_STATE;
+ hItem := ItemId;
+ stateMask := TVIS_FOCUSED;
+ state := stateMask and Template;
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+
+function TTreeNode.GetFocused: Boolean;
+begin
+ Result := GetState(nsFocused);
+end;
+
+procedure TTreeNode.SetChildren(Value: Boolean);
+var
+ Item: TTVItem;
+begin
+ with Item do
+ begin
+ mask := TVIF_CHILDREN;
+ hItem := ItemId;
+ cChildren := Ord(Value);
+ end;
+ TreeView_SetItem(Handle, Item);
+end;
+
+function TTreeNode.GetPrevSibling: TTreeNode;
+begin
+ with FOwner do
+ Result := GetNode(TreeView_GetPrevSibling(Handle, ItemId));
+end;
+
+function TTreeNode.GetNextVisible: TTreeNode;
+begin
+ if IsVisible then
+ with FOwner do
+ Result := GetNode(TreeView_GetNextVisible(Handle, ItemId))
+ else Result := nil;
+end;
+
+function TTreeNode.GetPrevVisible: TTreeNode;
+begin
+ with FOwner do
+ Result := GetNode(TreeView_GetPrevVisible(Handle, ItemId));
+end;
+
+function TTreeNode.GetNextChild(Value: TTreeNode): TTreeNode;
+begin
+ if Value <> nil then Result := Value.GetNextSibling
+ else Result := nil;
+end;
+
+function TTreeNode.GetPrevChild(Value: TTreeNode): TTreeNode;
+begin
+ if Value <> nil then Result := Value.GetPrevSibling
+ else Result := nil;
+end;
+
+
+function TTreeNode.GetPrev: TTreeNode;
+var
+ Node: TTreeNode;
+begin
+ Result := GetPrevSibling;
+ if Result <> nil then
+ begin
+ Node := Result;
+ repeat
+ Result := Node;
+ Node := Result.GetLastChild;
+ until Node = nil;
+ end else
+ Result := Parent;
+end;
+
+function TTreeNode.GetAbsoluteIndex: Integer;
+var
+ Node: TTreeNode;
+begin
+ if Owner.FNodeCache.CacheNode = Self then
+ Result := Owner.FNodeCache.CacheIndex
+ else begin
+ Result := -1;
+ Node := Self;
+ while Node <> nil do
+ begin
+ Inc(Result);
+ Node := Node.GetPrev;
+ end;
+ end;
+end;
+
+function TTreeNode.GetIndex: Integer;
+var
+ Node: TTreeNode;
+begin
+ Result := -1;
+ Node := Self;
+ while Node <> nil do
+ begin
+ Inc(Result);
+ Node := Node.GetPrevSibling;
+ end;
+end;
+
+function TTreeNode.GetItem(Index: Integer): TTreeNode;
+begin
+ Result := GetFirstChild;
+ while (Result <> nil) and (Index > 0) do
+ begin
+ Result := GetNextChild(Result);
+ Dec(Index);
+ end;
+ if Result = nil then TreeViewError(SListIndexError);
+end;
+
+procedure TTreeNode.SetItem(Index: Integer; Value: TTreeNode);
+begin
+ item[Index].Assign(Value);
+end;
+
+function TTreeNode.IndexOf(Value: TTreeNode): Integer;
+var
+ Node: TTreeNode;
+begin
+ Result := -1;
+ Node := GetFirstChild;
+ while (Node <> nil) do
+ begin
+ Inc(Result);
+ if Node = Value then Break;
+ Node := GetNextChild(Node);
+ end;
+ if Node = nil then Result := -1;
+end;
+
+function TTreeNode.GetCount: Integer;
+var
+ Node: TTreeNode;
+begin
+ Result := 0;
+ Node := GetFirstChild;
+ while Node <> nil do
+ begin
+ Inc(Result);
+ Node := Node.GetNextChild(Node);
+ end;
+end;
+
+procedure TTreeNode.EndEdit(Cancel: Boolean);
+begin
+ TreeView_EndEditLabelNow(Handle, Cancel);
+end;
+
+procedure TTreeNode.InternalMove(ParentNode, Node: TTreeNode;
+ HItem: HTreeItem; AddMode: TAddMode);
+var
+ I: Integer;
+ NodeId: HTreeItem;
+ TreeViewItem: TTVItem;
+ Children: Boolean;
+ IsSelected: Boolean;
+begin
+ Owner.ClearCache;
+ if (AddMode = taInsert) and (Node <> nil) then
+ NodeId := Node.ItemId else
+ NodeId := nil;
+ Children := HasChildren;
+ IsSelected := Selected;
+ if (Parent <> nil) and (Parent.CompareCount(1)) then
+ begin
+ Parent.Expanded := False;
+ Parent.HasChildren := False;
+ end;
+ with TreeViewItem do
+ begin
+ mask := TVIF_PARAM;
+ hItem := ItemId;
+ lParam := 0;
+ end;
+ TreeView_SetItem(Handle, TreeViewItem);
+ with Owner do
+ HItem := AddItem(HItem, NodeId, CreateItem(Self), AddMode);
+ if HItem = nil then
+ raise EOutOfResources.Create(sInsertError);
+ for I := Count - 1 downto 0 do
+ Item[I].InternalMove(Self, nil, HItem, taAddFirst);
+ TreeView_DeleteItem(Handle, ItemId);
+ FItemId := HItem;
+ Assign(Self);
+ HasChildren := Children;
+ Selected := IsSelected;
+end;
+
+procedure TTreeNode.MoveTo(Destination: TTreeNode; Mode: TNodeAttachMode);
+var
+ AddMode: TAddMode;
+ Node: TTreeNode;
+ HItem: HTreeItem;
+ OldOnChanging: TTVChangingEvent;
+ OldOnChange: TTVChangedEvent;
+begin
+ OldOnChanging := TreeView.OnChanging;
+ OldOnChange := TreeView.OnChange;
+ TreeView.OnChanging := nil;
+ TreeView.OnChange := nil;
+ try
+ if (Destination = nil) or not Destination.HasAsParent(Self) then
+ begin
+ AddMode := taAdd;
+ if (Destination <> nil) and not (Mode in [naAddChild, naAddChildFirst]) then
+ Node := Destination.Parent else
+ Node := Destination;
+ case Mode of
+ naAdd,
+ naAddChild: AddMode := taAdd;
+ naAddFirst,
+ naAddChildFirst: AddMode := taAddFirst;
+ naInsert:
+ begin
+ Destination := Destination.GetPrevSibling;
+ if Destination = nil then AddMode := taAddFirst
+ else AddMode := taInsert;
+ end;
+ end;
+ if Node <> nil then
+ HItem := Node.ItemId else
+ HItem := nil;
+ if (Destination <> Self) then
+ InternalMove(Node, Destination, HItem, AddMode);
+ Node := Parent;
+ if Node <> nil then
+ begin
+ Node.HasChildren := True;
+ Node.Expanded := True;
+ end;
+ end;
+ finally
+ TreeView.OnChanging := OldOnChanging;
+ TreeView.OnChange := OldOnChange;
+ end;
+end;
+
+procedure TTreeNode.MakeVisible;
+begin
+ TreeView_EnsureVisible(Handle, ItemId);
+end;
+
+function TTreeNode.GetLevel: Integer;
+var
+ Node: TTreeNode;
+begin
+ Result := 0;
+ Node := Parent;
+ while Node <> nil do
+ begin
+ Inc(Result);
+ Node := Node.Parent;
+ end;
+end;
+
+function TTreeNode.IsNodeVisible: Boolean;
+var
+ Rect: TRect;
+begin
+ Result := TreeView_GetItemRect(Handle, ItemId, Rect, True);
+end;
+
+function TTreeNode.EditText: Boolean;
+begin
+ Result := TreeView_EditLabel(Handle, ItemId) <> 0;
+end;
+
+function TTreeNode.DisplayRect(TextOnly: Boolean): TRect;
+begin
+ FillChar(Result, SizeOf(Result), 0);
+ TreeView_GetItemRect(Handle, ItemId, Result, TextOnly);
+end;
+
+function TTreeNode.AlphaSort: Boolean;
+begin
+ Result := CustomSort(nil, 0);
+end;
+
+function TTreeNode.CustomSort(SortProc: TTVCompare; Data: Longint): Boolean;
+var
+ SortCB: TTVSortCB;
+begin
+ Owner.ClearCache;
+ with SortCB do
+ begin
+ if not Assigned(SortProc) then lpfnCompare := @DefaultTreeViewSort
+ else lpfnCompare := SortProc;
+ hParent := ItemId;
+ lParam := Data;
+ end;
+ Result := TreeView_SortChildrenCB(Handle, SortCB, 0);
+end;
+
+procedure TTreeNode.Delete;
+begin
+ if not Deleting then Free;
+end;
+
+procedure TTreeNode.DeleteChildren;
+begin
+ Owner.ClearCache;
+ TreeView_Expand(TreeView.Handle, ItemID, TVE_COLLAPSE or TVE_COLLAPSERESET);
+ HasChildren := False;
+end;
+
+procedure TTreeNode.Assign(Source: TPersistent);
+var
+ Node: TTreeNode;
+begin
+ Owner.ClearCache;
+ if Source is TTreeNode then
+ begin
+ Node := TTreeNode(Source);
+ Text := Node.Text;
+ Data := Node.Data;
+ ImageIndex := Node.ImageIndex;
+ SelectedIndex := Node.SelectedIndex;
+ StateIndex := Node.StateIndex;
+ OverlayIndex := Node.OverlayIndex;
+ Focused := Node.Focused;
+ DropTarget := Node.DropTarget;
+ Cut := Node.Cut;
+ HasChildren := Node.HasChildren;
+ end
+ else inherited Assign(Source);
+end;
+
+function TTreeNode.IsEqual(Node: TTreeNode): Boolean;
+begin
+ Result := (Text = Node.Text) and (Data = Node.Data);
+end;
+
+procedure TTreeNode.ReadData(Stream: TStream; Info: PNodeInfo);
+var
+ I, Size, ItemCount: Integer;
+begin
+ Owner.ClearCache;
+ Stream.ReadBuffer(Size, SizeOf(Size));
+ Stream.ReadBuffer(Info^, Size);
+ Text := Info^.Text;
+ ImageIndex := Info^.ImageIndex;
+ SelectedIndex := Info^.SelectedIndex;
+ StateIndex := Info^.StateIndex;
+ OverlayIndex := Info^.OverlayIndex;
+ Data := Info^.Data;
+ ItemCount := Info^.Count;
+ for I := 0 to ItemCount - 1 do
+ Owner.AddChild(Self, '').ReadData(Stream, Info);
+end;
+
+procedure TTreeNode.WriteData(Stream: TStream; Info: PNodeInfo);
+var
+ I, Size, L, ItemCount: Integer;
+begin
+ L := Length(Text);
+ if L > 255 then L := 255;
+ Size := SizeOf(TNodeInfo) + L - 255;
+ Info^.Text := Text;
+ Info^.ImageIndex := ImageIndex;
+ Info^.SelectedIndex := SelectedIndex;
+ Info^.OverlayIndex := OverlayIndex;
+ Info^.StateIndex := StateIndex;
+ Info^.Data := Data;
+ ItemCount := Count;
+ Info^.Count := ItemCount;
+ Stream.WriteBuffer(Size, SizeOf(Size));
+ Stream.WriteBuffer(Info^, Size);
+ for I := 0 to ItemCount - 1 do Item[I].WriteData(Stream, Info);
+end;
+
+*/