Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

treeview and text file

Posted on 2004-10-22
28
Medium Priority
?
742 Views
Last Modified: 2010-04-05
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 .
0
Comment
Question by:mohfa
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 6
  • 6
  • +1
28 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12378807
how looks your textfile, what information is there stored?
0
 

Expert Comment

by:krypto2000
ID: 12378925
Yes, what informations are into your textfile ?
Structured like a dataBase ? not structured only words ? explain...
0
 

Author Comment

by:mohfa
ID: 12380569
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 .
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:mohfa
ID: 12380610
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 !
0
 

Expert Comment

by:krypto2000
ID: 12380666
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...
0
 

Expert Comment

by:krypto2000
ID: 12381283
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...
0
 

Author Comment

by:mohfa
ID: 12388102
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
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12388895
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
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12388901
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
0
 

Author Comment

by:mohfa
ID: 12391794
yes please could you give me a sample app please
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12392056
using the delphi treeview or the (better in my opinion) Vitual treeview ?
0
 

Expert Comment

by:krypto2000
ID: 12397833
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 :-)
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12398120
sorry, I will try to explain it better in the example app

which component are you using for your treeview - TTreeview or Tvirtualtreeview  ?
0
 

Expert Comment

by:krypto2000
ID: 12398133
TTreeView...
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 12399486
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
0
 

Expert Comment

by:krypto2000
ID: 12399694
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 ??
0
 

Author Comment

by:mohfa
ID: 12418939
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 .

---
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12418970
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;,-)


0
 

Accepted Solution

by:
krypto2000 earned 1000 total points
ID: 12419754
Hello,

I have look for the itemdata property but the problem is that is only a pointer and not "real data" so when I saveToFile there don't save...

So I have maked a new little application, it work like this :
   
   when you open the application, you can see the tree. If file exists it load from file, else create new file. okay.
   when you click on an item, in the edit you can see the description if exists. if not, you can add it.
   for adding description to item, switch to edit mode (there is a checkBox) and then, click on the item you want to add description,
   and you can see the item caption in the edit. Then, just add a delimiter (i have choose ">" you can change) and write your description after.
   Now, return to normal mode, click on the item and you can see the description in the edit !!!

   I hope that is that you want ;-)

   (that would be great if you have an e-mail where I can send to you the application because I am at work and the fu*** firewall block anything, no ftp possible)

//----------------------------------- FORM1 ----------------------------------------//
object Form1: TForm1
  Left = 192
  Top = 103
  Width = 292
  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
  OnCreate = FormCreate
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object TreeView1: TTreeView
    Left = 10
    Top = 10
    Width = 261
    Height = 241
    HideSelection = False
    Indent = 19
    TabOrder = 0
    OnClick = TreeView1Click
    OnCustomDrawItem = TreeView1CustomDrawItem
    Items.Data = {
      020000001F0000000000000000000000FFFFFFFFFFFFFFFF0000000002000000
      064974656D5F30220000000000000000000000FFFFFFFFFFFFFFFF0000000000
      000000097375624974656D5F30220000000000000000000000FFFFFFFFFFFFFF
      FF0000000000000000097375624974656D5F311F0000000000000000000000FF
      FFFFFFFFFFFFFF0000000001000000064974656D5F3122000000000000000000
      0000FFFFFFFFFFFFFFFF0000000000000000097375624974656D5F30}
  end
  object Edit1: TEdit
    Left = 10
    Top = 260
    Width = 186
    Height = 21
    TabOrder = 1
    OnChange = Edit1Change
  end
  object CheckBox1: TCheckBox
    Left = 205
    Top = 263
    Width = 71
    Height = 17
    Caption = 'Edit mode'
    TabOrder = 2
    OnClick = CheckBox1Click
  end
end
//-------------------------------------------------------------------------------------//

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

interface

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

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Edit1: TEdit;
    CheckBox1: TCheckBox;
    procedure FormShow(Sender: TObject);
    procedure TreeView1CustomDrawItem(Sender: TCustomTreeView;
      Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);
    procedure TreeView1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure CheckBox1Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Desc: TStringList;

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


implementation

{$R *.dfm}

procedure resetDesc(Desc: TStrings);
var i: integer;
begin
   Desc.Clear;
   for i := 0 to Form1.treeView1.Items.Count do
       Desc.Add('');
end;

procedure fileToTree(trv: TTreeView);
begin
   trv.LoadFromFile(FILE_NAME);
   trv.FullExpand;
end;

procedure treeToFile(trv: TTreeView);
begin
   trv.FullExpand;
   trv.SaveToFile(FILE_NAME);
end;

procedure TForm1.FormShow(Sender: TObject);
var strm: TStream; i: integer;
begin
   if fileExists(FILE_NAME) then
      fileToTree(TreeView1)
   else
      treeToFile(TreeView1);
   resetDesc(Desc);
end;

procedure TForm1.TreeView1CustomDrawItem(Sender: TCustomTreeView;
  Node: TTreeNode; State: TCustomDrawState; var DefaultDraw: Boolean);

function getDesc(s:string): string;
begin
  if pos(DELIMITER,s) > 0 then
     result := rightStr(s,length(s) - pos(DELIMITER,s))
else result := s;
end;

function getCaption(s:string): string;
begin
  if pos(DELIMITER,s) > 0 then begin
     result := leftStr(s,pos(DELIMITER,s)-1);
     Desc[Node.AbsoluteIndex] := getDesc(s);
     end
else result := s;
end;

begin
if not CheckBox1.Checked then
   Node.Text := getCaption(Node.Text);
end;

procedure TForm1.TreeView1Click(Sender: TObject);
begin
   if (treeView1.Selected <> nil) then
   if not CheckBox1.Checked then
      Edit1.Text := Desc[TreeView1.Selected.AbsoluteIndex]
   else
      Edit1.Text := TreeView1.Selected.Text;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   Desc := TStringList.Create;
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
   resetDesc(Desc);
   fileToTree(TreeView1);
   Edit1.Clear;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
   if treeView1.Selected <> nil then
      if CheckBox1.Checked then
         begin
         TreeView1.Selected.Text := Edit1.Text;
         treeToFile(TreeView1);
         end;
end;

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

Expert Comment

by:krypto2000
ID: 12419771
Just an example sorry :

  Item0
        subItem_0>myDescription
        subItem_1
  Item1
        subItem_0>yourDescription

yeah !
0
 

Author Comment

by:mohfa
ID: 12419960
ok my e-mail is :
<< 
email removed

kretzschmar
Page Editor
>>
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 12420067
0
 
LVL 7

Expert Comment

by:DavidBirch2dotCom
ID: 13344298
krypto2000's solution was way better than mine
0
 

Expert Comment

by:krypto2000
ID: 13458569
thx ;-)
0

Featured Post

What’s Wrong with Your Cloud Strategy ?

Even as many CIOs are embracing a cloud-first strategy, the reality is that moving to the cloud is a lengthy process and the end-state is likely to be a blend of multiple clouds—public and private. Learn why multicloud solutions matter in this webinar by Nimble Storage.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question