Board index » cppbuilder » Tree and stream help

Tree and stream help


2004-07-09 01:40:00 AM
cppbuilder94
Can someone help me out with this code if they are familiar with it.
This is my problem, after i load the treeview, i am trying to figure
out how to go through each node and set the expanded property
of the node, so the tree can be in the same state that it was saved
in. I have noticed in the past that you cannot use the expanded
property unless the tree is populated.
Comments below.......
class TConfig
{
public:
virtual ~TConfig() {}
virtual void Load(TStream* Stream) = 0;
virtual void Store(TStream* Stream) = 0;
};
class TNodeData : public TConfig
{
typedef TConfig inherited;
protected:
TTreeNode *fNode;
public:
TNodeData(TTreeNode *ANode);
void Load(TStream* Stream);
void Store(TStream* Stream);
};
class TParentNodeData : public TNodeData
{
typedef TNodeData inherited;
public:
int fTotalItems;
TParentNodeData(TTreeNode *ANode);
void Load(TStream* Stream);
void Store(TStream* Stream);
};
class TChildNodeData : public TNodeData
{
typedef TNodeData inherited;
public:
int fBold;
TList* MessageData;
TChildNodeData(TTreeNode *ANode);
~TChildNodeData();
void ClearMessageData();
void Load(TStream* Stream);
void Store(TStream* Stream);
};
// The message information structure
class TMessageData : public TConfig
{
typedef TConfig inherited;
public:
int fMessageRead;
TMessageData(TList *AMessageList = NULL);
void Load(TStream* Stream);
void Store(TStream* Stream);
};
// Tree is loaded from here
void LoadTreeNodesFromStream(TStream *Stream, TTreeNodes *ATreeNodes)
{
ATreeNodes->BeginUpdate();
try
{
ATreeNodes->Clear();
int count = ReadInteger(Stream);
for(int i = 0; i < count; ++i)
{
TTreeNode *ParentNode = ATreeNodes->Add(NULL, "");
ParentNode->Data = new TParentNodeData(ParentNode);
static_cast<TParentNodeData*>(ParentNode->Data)->Load(Stream);
}
}
__finally
{
ATreeNodes->EndUpdate();
}
}
//--------------------------------------------------------------------
-------
void TParentNodeData::Load(TStream* Stream)
{
// after this line the tree gets loaded one node at a time
inherited::Load(Stream);
---------- Snip ---------------------------
int count = ReadInteger(Stream);
for(int i = 0; i < count; ++i)
{
TTreeNode *Child =
static_cast<TTreeView*>(fNode->TreeView)->Items->AddChild(fNode, "");
Child->Data = new TChildNodeData(Child);
static_cast<TChildNodeData*>(Child->Data)->Load(Stream);
}
}
bool __fastcall ReadBoolean(TStream* Stream)
{
bool result = 0;
Stream->Read(&result, sizeof(result));
return result;
}
//--------------------------------------------------------------------
-------
void TNodeData::Load(TStream* Stream)
{
fNode->Text = ReadCharString(Stream);
fNode->ImageIndex = ReadInteger(Stream);
fNode->SelectedIndex = ReadInteger(Stream);
fNode->Expanded = ReadBoolean(Stream);
}
//--------------------------------------------------------------------
-------
This is the strange part, while its loading the first node and it gets
to the
"fNode->Expanded = ReadBoolean(Stream);" i will trace
into the ReadBoolean() func. The func will return a "true", but when
i look at the value here "fNode->Expanded = ReadBoolean(Stream);"
it says its false, pretty strange i don't get that one at all.
But anyway, after the tree is loaded, how do you go back through all
the nodes while reading the "Expanded" property from the stream
and setting it to the tree nodes? Thats all i want to know.
Greg.
 
 

Re:Tree and stream help

"Greg Stantin" < XXXX@XXXXX.COM >wrote in message
Quote
This is the strange part, while its loading the first node
and it gets to the "fNode->Expanded = ReadBoolean(Stream);"
i will trace into the ReadBoolean() func. The func will
return a "true", but when i look at the value here
"fNode->Expanded = ReadBoolean(Stream);" it says
its false, pretty strange i don't get that one at all.
That is because there are no children loaded into the node yet, thus nothing
to expand.
Quote
But anyway, after the tree is loaded, how do you go back
through all the nodes while reading the "Expanded" property
from the stream and setting it to the tree nodes?
You would need to store the streamed Expanded value to a temporary variable
during the actual streaming, and then assign the Expanded property of the
node after the children have actually been streamed.
class TNodeData : public TConfig
{
//...
protected:
bool FLoadExpanded; // <-- add this
//...
};
void TNodeData::Load(TStream* Stream)
{
//...
// change this line:
//fNode->Expanded = ReadBoolean(Stream);
FLoadExpanded = ReadBoolean(Stream);
}
void TParentNodeData::Load(TStream* Stream)
{
inherited::Load(Stream);
//...
for(int i = 0; i < count; ++i)
{
//...
}
fNode->Expanded = FLoadExpanded; // <-- add this
}
An alternative is to change the code a little to store the Expanded value
after the child data rather than before it. That way, children can be
loaded before the Expanded property is then loaded.
class TConfig
{
public:
virtual ~TConfig() {}
virtual void Load(TStream* Stream) = 0;
virtual void Store(TStream* Stream) = 0;
};
class TNodeData : public TConfig
{
typedef TConfig inherited;
protected:
TTreeNode *fNode;
virtual void LoadChildren(TStream* Stream);
virtual void StoreChildren(TStream* Stream);
public:
TNodeData(TTreeNode *ANode);
void Load(TStream* Stream);
void Store(TStream* Stream);
};
class TParentNodeData : public TNodeData
{
typedef TNodeData inherited;
protected:
void LoadChildren(TStream* Stream);
void StoreChildren(TStream* Stream);
public:
int fTotalItems;
TParentNodeData(TTreeNode *ANode);
void Load(TStream* Stream);
void Store(TStream* Stream);
};
class TChildNodeData : public TNodeData
{
typedef TNodeData inherited;
public:
int fBold;
TList* MessageData;
TChildNodeData(TTreeNode *ANode);
~TChildNodeData();
void ClearMessageData();
void Load(TStream* Stream);
void Store(TStream* Stream);
};
class TMessageData : public TConfig
{
typedef TConfig inherited;
public:
int fMessageRead;
TMessageData();
void __fastcall Load(TStream* Stream);
void __fastcall Store(TStream* Stream);
};
int __fastcall ReadInteger(TStream* Stream)
{
int result = 0;
Stream->Read(&result, sizeof(result));
return result;
}
bool __fastcall ReadBoolean(TStream* Stream)
{
bool result = 0;
Stream->Read(&result, sizeof(result));
return result;
}
AnsiString __fastcall ReadCharString(TStream* Stream)
{
int length = ReadInteger(Stream);
AnsiString result;
result.SetLength(length);
Stream->Read(result.c_str(), length);
return result;
}
void __fastcall WriteInteger(TStream* Stream, int Value)
{
Stream->Write(&Value, sizeof(Value));
}
void __fastcall WriteBoolean(TStream* Stream, bool Value)
{
Stream->Write(&Value, sizeof(Value));
}
void __fastcall WriteCharString(TStream* Stream, const String &Str)
{
int length = Str.Length();
WriteInteger(Stream, length);
Stream->Write(Str.c_str(), length);
}
TNodeData::TNodeData(TTreeNode *ANode)
: TConfig(), fNode(ANode)
{
}
void TNodeData::Load(TStream* Stream)
{
fNode->Text = ReadCharString(Stream);
fNode->ImageIndex = ReadInteger(Stream);
LoadChildren(Stream); // <-- load children before Expanded
fNode->Expanded = ReadBoolean(Stream);
}
void TNodeData::LoadChildren(TStream* Stream)
{
// empty in TNodeData, descendants should override it as needed...
}
void TNodeData::Store(TStream* Stream)
{
WriteCharString(Stream, fNode->Text);
WriteInteger(Stream, fNode->ImageIndex);
StoreChildren(Stream); // <-- store children before Expanded
WriteBoolean(Stream, fNode->Expanded);
}
void TNodeData::StoreChildren(TStream* Stream)
{
// empty in TNodeData, descendants should override it as needed...
}
TParentNodeData::TParentNodeData(TTreeNode *ANode)
: TNodeData(ANode)
{
}
void TParentNodeData::Load(TStream* Stream)
{
inherited::Load(Stream);
fTotalItems = ReadInteger(Stream);
}
void TParentNodeData::LoadChildren(TStream* Stream)
{
int count = ReadInteger(Stream);
for(int i = 0; i < count; ++i)
{
TTreeNode *Child =
static_cast<TTreeView*>(fNode->TreeView)->Items->AddChild(fNode, "");
Child->Data = new TChildNodeData(ChildNode);
static_cast<TChildNodeData*>(Child->Data)->Load(Stream);
}
}
void TParentNodeData::Store(TStream* Stream)
{
inherited::Store(Stream);
WriteInteger(Stream, fTotalItems);
}
void TNodeData::StoreChildren(TStream* Stream)
{
WriteInteger(Stream, fNode->Count);
for(int i = 0; i < fNode->Count; ++i)
static_cast<TChildNodeData*>(fNode->Item[i]->Data)->Store(Stream);
}
TChildNodeData::TChildNodeData(TTreeNode *ANode)
: TNodeData(ANode), fBold(0), MessageData(NULL)
{
MessageData = new TList;
}
TChildNodeData::~TChildNodeData()
{
ClearMessageData();
delete MessageData;
}
void TChildNodeData::ClearMessageData()
{
for(int i = 0; i < MessageData->Count; ++i)
delete static_cast<TMessageData*>(MessageData->Items[i]);
MessageData->Clear();
}
void TChildNodeData::Load(TStream* Stream)
{
ClearMessageData();
inherited::Load(Stream);
fBold = ReadInteger(Stream);
int count = ReadInteger(Stream);
for(int i = 0; i < count; ++i)
{
TMessageData *Message = new TMessageData(MessageData);
Data->Load(Stream);
}
}
void TChildNodeData::Store(TStream* Stream)
{
MessageData->Pack();
inherited::Store(Stream);
WriteInteger(Stream, fBold);
WriteInteger(Stream, MessageData->Count);
for(int i = 0; i < MessageData->Count; ++i)
static_cast<TMessageData*>(MessageData->Items[i])->Store(Stream);
}
TMessageData::TMessageData()
: TConfig(), fMessageRead(0)
{
}
void __fastcall TMessageData::Load(TStream* Stream)
{
fMessageRead = ReadInteger(Stream);
}
void __fastcall TMessageData::Store(TStream* Stream)
{
WriteInteger(Stream, fMessageRead);
}
void SaveTreeNodesToStream(TStream *Stream, TTreeNodes *ATreeNodes)
{
int count = 0;
TTreeNode *Node = ATreeNodes->GetFirstNode();
while( Node )
{
++count;
Node = Node->getNextSibling();
}
WriteInteger(Stream, count);
Node = ATreeNodes->GetFirstNode();
while( Node )
{
static_cast<TConfig*>(Node->Data)->Store(Stream);
Node = Node->getNextSibling();
}
}
void LoadTreeNodesFromStream(TStream *Stream, TTreeNodes *ATreeNodes)
{
ATreeNodes->BeginUpdate();
try
{
ATreeNodes->Clear();
int count = ReadInteger(Stream);
for(int i = 0; i < count; ++i)
{
TTreeNode *ParentNode = ATreeNodes->Add(NULL, "");
ParentNode->Data = new TParentNodeData(ParentNode);
static_cast<TParentNodeData*>(ParentNode->Data)->Load(Stream);
}
}
__finally
{
ATreeNodes->EndUpdate();
}
}
Gambit
 

Re:Tree and stream help

Quote
class TNodeData : public TConfig
{
//...
protected:
bool FLoadExpanded; // <-- add this
//...
};
Thanks Gambit, i ended taking the easy way out. I tried using
the code, but i didn't understand some of the missing parts and
what i had to put in there. But this seems to work.
Thanks again.....
Greg
 

{smallsort}

Re:Tree and stream help

"Remy Lebeau (TeamB)" < XXXX@XXXXX.COM >wrote in message
Quote
That is because there are no children loaded
into the node yet, thus nothing to expand.
To clearify on this - the HasChildren property needs to be true in order for
Expand() to do anything. So maybe a simplier solution would be to just
store the HasChildren value into the stream before storing the Expanded
value. That way, HasChildren can be set to true before Expand() is assigned
during loading.
Gambit
 

Re:Tree and stream help

Quote
To clearify on this - the HasChildren property needs to be true in
order for
Expand() to do anything. So maybe a simplier solution would be to
just
store the HasChildren value into the stream before storing the
Expanded
value. That way, HasChildren can be set to true before Expand() is
assigned
during loading.
Okay, i will keep that in mind.