Link to home
Start Free TrialLog in
Avatar of mohfa
mohfa

asked on

treeview and text file

i have a project that uses a treeview and memo and text file so the treeview's nodes and sub-nodes will be loaded from this text file and when clicking ( the event:onchange of each node its data will be read into the memo ) so :

01- how could i load the treeview nodes and sub-nodes from a text file .

02- how could i read each node data into the memo ( the event on change of each node ).

03-i want give each node an ID so that i can update this text file then this treeview will be automatically updated because its nodes are from this text file so i think working with IDs is good idea .
Avatar of kretzschmar
kretzschmar
Flag of Germany image

how looks your textfile, what information is there stored?
Avatar of krypto2000
krypto2000

Yes, what informations are into your textfile ?
Structured like a dataBase ? not structured only words ? explain...
Avatar of mohfa

ASKER

structered like a database , because this text file will be the source of my treeview , it contains words and numbers .

in all : this text file will store my treeview items ( nodes , sub nodes , nodes data  ) so that i can load this treeview items each time the project is launched .
Avatar of mohfa

ASKER

let's say that this textfile is the treeview i mean that it's like saving treeview items ( node , sub-nodes ) to a text file  but here with some modification like the nodes ID ...etc

now i think it's clear !
okay...
I think the best way is to store your data into an XML file.
After, you can load your XML file into a DataSet and then, fill your treeView
in Delphi.NET that's easy to manipulate XML, but in Delphi I never used XML file.
I'm looking for the solution...
I've found a really great function :
   TTreeView.SaveToFile();

I've maked the application :

this is the form definition, juste right click on your form --> view as text
and paste this into :

//------------------------------------------------------------------------------//
object Form1: TForm1
  Left = 192
  Top = 103
  Width = 479
  Height = 319
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object TreeView1: TTreeView
    Left = 10
    Top = 10
    Width = 186
    Height = 241
    Indent = 19
    TabOrder = 0
    Items.Data = {
      020000001F0000000000000000000000FFFFFFFFFFFFFFFF0000000002000000
      064974656D5F30220000000000000000000000FFFFFFFFFFFFFFFF0000000000
      000000097375624974656D5F30220000000000000000000000FFFFFFFFFFFFFF
      FF0000000000000000097375624974656D5F311F0000000000000000000000FF
      FFFFFFFFFFFFFF0000000001000000064974656D5F3122000000000000000000
      0000FFFFFFFFFFFFFFFF0000000000000000097375624974656D5F30}
  end
  object Memo1: TMemo
    Left = 205
    Top = 10
    Width = 251
    Height = 241
    TabOrder = 1
  end
  object btnSave: TButton
    Left = 385
    Top = 262
    Width = 75
    Height = 21
    Caption = '&Save'
    TabOrder = 2
    OnClick = btnSaveClick
  end
  object btnLoad: TButton
    Left = 300
    Top = 262
    Width = 75
    Height = 21
    Caption = '&Load'
    TabOrder = 3
  end
end
//------------------------------------------------------------------------------//

here is the unit file :

//------------------------------------------------------------------------------//
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Memo1: TMemo;
    btnSave: TButton;
    btnLoad: TButton;
    procedure FormShow(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

const
  FILE_NAME = 'C:\tree.txt';

implementation

{$R *.dfm}

procedure synchTreeMemo(trv: TTreeView; mem: TMemo);
var strm: TStream;
begin
   strm := TFileStream.Create(FILE_NAME,fmOpenRead);
   trv.SaveToStream(strm);
   mem.Lines.LoadFromStream(strm);
   strm.Free;
end;

procedure TForm1.FormShow(Sender: TObject);
var strm: TStream;
begin
   if fileExists(FILE_NAME) then
      treeView1.LoadFromFile(FILE_NAME)
   else
      treeView1.SaveToFile(FILE_NAME);
   synchTreeMemo(treeView1,memo1);
end;

procedure TForm1.btnSaveClick(Sender: TObject);
begin
   memo1.Lines.SaveToFile(FILE_NAME);
   treeView1.LoadFromFile(FILE_NAME);
   synchTreeMemo(treeView1,memo1);
end;

end.
//------------------------------------------------------------------------------//

okay...
Note the tree nodes separator is the TAB, but when you type TAB into the memo you set the focus
to the next control, just make CTRL+TAB into the memo and that works !!

I hope it's that you want...
Avatar of mohfa

ASKER

But i need this text file to load the nodes and sub-nodes into the treeview not  in the memo , and this letter (memo )i will use it only to show the nodes data , so please could you give me an exemple on how to load nodes and sub-nodes into the treeview . and the memo to show the nodes data .


thank you all
I have code to this, depending on the format of the file,

I use the virtual tree view from www.delphigems.com

Basicaly what I do is something like (I can provide full code if necessary)

have a file format like

NodeName,NodeValue1,Nodevalue2
>>>|NodeName,NodeValue1,Nodevalue2

where the first node is a root node and then the '>>>|' represents a child node

so when reading the file -
> read line
> count the number of '>>>|' to find the node level
> if the level is equal to the level you are already at then add the node as a sibbling (child of parent) of the last node added
> if it is greater (BY ONE only) then add it as a child of the last node
> if its less then cycle up though the parents of the last node and then add as a sibbling when the levels are equal

the system works well in all the uses I have put it to - if you want a sample App then just say

David
oh as for reading each into a memo.. why not just use the onclick event of the treeview and then just display the selected node in the memo  ? if all the data is loaded into the treeview there is little need to use the text file to load 1 node
Avatar of mohfa

ASKER

yes please could you give me a sample app please
using the delphi treeview or the (better in my opinion) Vitual treeview ?
I'm sorry I'm not english and I think I don't have really understand youjr question...
Waht is for you "nodes-data" ? Please give me an example...
And the memo is just a mirror of the text-file that generate the treeView for you can see what's happend
Gived me some precision please :-)
sorry, I will try to explain it better in the example app

which component are you using for your treeview - TTreeview or Tvirtualtreeview  ?
TTreeView...
ok...

here is the code:

Function Tform1.AddNode(Node: TTreenode; AddType: integer; Txt: string): TTreenode;
Begin
   try
      case AddType of
      1: // root
         result:= MyTree.Items.Add(MyTree.TopItem,Txt);
      2: // Sibbling
         result:= MyTree.Items.Add(Node,Txt);
      3: // child
         result:= MyTree.Items.AddChild(Node,Txt);
      end;
   except
      ShowMessage('Error adding node - type: '+inttostr(AddType)+' text:='+Txt);
   end;
end;

procedure Tform1.LoadFile(UseTree: TTreeview; FileName: string);

function  getlevel(MyLine: string): integer; // find out how many >>>| there are in a given string
Begin
   result:= 0;
   While pos('>>>|',MyLine)<>0 do
   Begin
      Result:= result+1;
      delete(MyLine,1,4);
   end;
end;

Function CleanLine(Var Line: string): string;
Begin // Gets stuff out of ''
   Delete(Line,1,Pos('''',Line));
   Delete(Line,Pos('''',Line),100000);
   Result:= Line;
end;

Var
        FileVar: Textfile;
        Line: string;
        Level: integer;
        NewLevel: integer;
        LastNode: TTreenode;
Begin
   assignfile(FileVar,FileName);
   reset(FileVar);

   Level:= 0; // initial level is 0

   UseTree.Items.Clear; ee
   LastNode:= AddNode(MyTree.TopItem,1,'delete it'); // creates first node to be used as base for adding nodes

   while not eof(FileVar) do
   begin
      readln(FileVar,Line); // read line
      NewLevel:= getlevel(Line); // find the level of the node to be added
      Line:= CleanLine(Line); // find the string of the node

      if NewLevel= (Level+1) then // add child
      Begin
         LastNode:= AddNode(LastNode,3,Line);
         Level:= NewLevel;
      end
       else  // if its not a child then it will be a child or on a higher level
      Begin
         if Newlevel= Level then // add sibbling
         Begin
            LastNode:= AddNode(LastNode,2,Line);
         end;

         if NewLevel < Level then
         Begin
            repeat // code moves back up the tree to add nodes
               LastNode:= LastNode.parent;
               Level:= level-1;
            until NewLevel= Level;
            LastNode:= AddNode(LastNode,2,Line);
         end;
      end;
   end;

   UseTree.TopItem.Delete;

   closefile(FileVar);
end;

procedure TForm1.LoaditClick(Sender: TObject);
begin
   LoadFile(MyTree,Getcurrentdir+'\Test1.txt');
end;

-------------------------------------------------------

Alternativly download the source here

www.davidbirch2.com/hidden/EEtree.zip

I hope my comments make sense, if not put a few break points in and you should see how it works, if not then please ask

David
do you have tried my example ?
this is exactly the same as you except the '>>>|' is replaced by a TAB char.

the file is stored here
----------------------------------
const
  FILE_NAME = 'C:\tree.txt';
----------------------------------

but if you want you can delete the memo that work...
what is wrong in my answer mohfa ??
Avatar of mohfa

ASKER

that's really good , but let me suppose that i have a paragraphe in this text file attached to (x) node - that means when i click on this x node i can read this paragraphe into the memo field -  for exemple :
let's suppose that i have a node named ' world ' and a paragraphe explaines the world so when i click on the node ' world ' the paragraphe will appear in to the memo field ...and so on .
---
because i need to assigne eache node a pargraphe and read it in to a memo field that's why i need this memo .

---
usual this is simple

each node has a dataproperty so you can attach your paragraph there due
building the tree content from the file

just define a record or use a tstringlist for this

i'm sure krypto2000 could implement this too (just too less time)

meikl;,-)


ASKER CERTIFIED SOLUTION
Avatar of krypto2000
krypto2000

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just an example sorry :

  Item0
        subItem_0>myDescription
        subItem_1
  Item1
        subItem_0>yourDescription

yeah !
Avatar of mohfa

ASKER

ok my e-mail is :
<< 
email removed

kretzschmar
Page Editor
>>
krypto2000's solution was way better than mine
thx ;-)