Discussion:
Load TTreeview from memo or text file
(too old to reply)
Marty
2005-09-17 11:37:29 UTC
Permalink
Hi,

I have hacked together some code that almost works correctly at loading
a text file or memo strings into a treeview

the test or memo will contain entries in the format below.


Test
.test1
.test2
Test3
.test4
..test5

the resulting treeview should have a structure of
Test
|
--test1
|
--test2
Test3
|
--test4
|
--test5


The code that I have is

procedure TForm1.LoadTree;

procedure AnalyzeEntry (const entry : string; var cap : string; var
level : integer);
var i, lth : integer;
begin
lth := Length (entry);
i := 1;
while (i <= lth) and (entry [i] = '.') do
inc (i);
Level := i - 1;
cap := Copy(entry,i,MaxInt);
end;

procedure Traverse(aNode: TTreeNode; Alist: tstrings; var ix:
integer;level : integer);
var
last : TTreeNode;
lvl : integer;
tmp,cap : string;
begin
last := aNode;
lvl := Integer (Alist.Objects [ix]);
while (lvl >= level) and (ix < Alist.Count) do
begin
if lvl = level
then begin
tmp := Alist[ix];
cap := Copy(tmp, 1, Pos(':', tmp) - 1);
last := TreeView1.Items.AddChild(aNode, cap);
inc(ix);
end
else begin
if lvl > level
then Traverse(last, Alist, ix, level + 1);
end;
if ix < Alist.Count
then lvl := Integer (Alist.Objects [ix]);
end;
end;

var
aCap : string;
i,aLevel : integer;
lst : tStringList;
begin
lst := tStringList.Create;
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
try
for i := 0 to (Memo1.Lines.Count - 1) do
begin
if Memo1.Lines[i]<>'' then
begin
AnalyzeEntry (Memo1.Lines [i], aCap, aLevel);
lst.AddObject (aCap, tObject (aLevel));
end;
end;
i := 0;
while i < Memo1.Lines.Count do
begin
Traverse(TreeView1.Items.Add(NIL, lst[i]), lst,i,0 );
Inc(i);
end;
finally
lst.Free;
end;
TreeView1.Items.EndUpdate;
end;

How would I make this code fully working and also whats the best way of
doing the reverse i.e building the text file from a treeview into the
format above.


Any help would be apprechiated

regards
Martin B
a***@aol.com
2005-09-17 13:57:26 UTC
Permalink
AFAICS the file format for TTreeView.LoadfromFile is ...

NodeLevel Tabs + NodeText + CR

... for all nodes. Quite similar to your memo contents, except that it
needs tabs instead of full stops. Let Delphi do the hassle of changing
the text into a treeview. I would therefore try ...

var
TVSL : TStringList;
TVNodeStr : string;
FS : TFileStream;
const
Tab = #9;
begin
{create a stringlist to hold the memo lines}
TVSL := TStringList.Create;
TVSL.Assign(MyMemo.Lines);
{check for empty lines}
with TVSL do
for i := Count - 1 downto 0 do
if Strings[i] := '' then
Delete(i);
TVNodeStr := TVSL.Text;
{change full stops to tabs}
for i := 1 to Length(TVNodeStr) do
if TVNodeStr[i] = '.' then
TVNodeStr[i] := Tab;
// I'm not sure if TStringList.Text has CR or CR.LF. If the
// latter then you need to copy TVNodeStr chars to
// another string (or the same) less the LF (#10)
// j := 1;
// for i := 1 to Length(TVNodeStr) do
// if TVNodeStr[i] <> LF then begin
// TVNodeStr[j] := TVNodeStr[i];
// inc(j);
// end;
// SetLength(TVNodeStr, j - 1);
{save string to to filestream & file}
FS := TFileStream.Create('TempFile.dat', fmCreate);
FS.Write(TVNodeStr[1], Length(TVNodeStr));
FS.Free;
{now load the file into treeview}
MyTreeView.Clear
MyTreeView.LoadfromFile('TempFile.dat');

... and similar in reverse (change the tabs to full stops) for moving
the saved TTreeView.SaveToFile to a TMemo.

Alan Lloyd
Chris Cheney
2005-09-17 14:05:18 UTC
Permalink
Post by Marty
Hi,
I have hacked together some code that almost works correctly at loading
a text file or memo strings into a treeview
...
Post by Marty
How would I make this code fully working
You had better say in what way it is not "fully working"!!!
Post by Marty
and also whats the best way of
doing the reverse i.e building the text file from a treeview into the
format above.
"best" is a matter of opinion - one way is:

procedure DoChildNode(Node: TTreeNode; Lines: TStrings);
begin
while Node <> nil do
begin
Lines.Add(StringOfChar('.', Node.Level) + Node.Text);
DoChildNode(Node.GetFirstChild, Lines);
Node := Node.GetNextSibling;
end;
end;

Memo1.Clear;
DoChildNode(TreeView1.Items.GetFirstNode, Memo1.Lines);

Loading...