diff options
Diffstat (limited to 'apps/X11/VCL/TTreeNode.cpp')
-rw-r--r-- | apps/X11/VCL/TTreeNode.cpp | 1003 |
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; + +*/ |