[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 395
  • Last Modified:

For Meikl

Hi, Meikl.

You helped me last week with my question titled "Records" by providing me with a sample program.

I am thinking of adapting the program sample you gave so that i can add the parent nodes in myself when required instead of having them fixed inside the program.

I am hoping that you can help me by showing me how i can adapt the program so as to allow for this.

can you help?
0
mi6agent
Asked:
mi6agent
  • 8
  • 7
1 Solution
 
kretzschmarCommented:
well, i would help you, but i don't know yet, what exactly you mean?

do you mean variable parents?

if so, then just add a secondary file with a structure like
ID : Integer;
Name : String[50];

which is read in the inittree-method?

well, could post this evening a sample,
if you mean this

meikl ;-)
0
 
mi6agentAuthor Commented:
Hi Meikl

What i am looking to do is to start with no parents in the treeview and be able to add/delete a parent node to the treeview when i want.  Then i will be able to add a record under the new parent.

I just can't work out a way to be able to do that and be able to save and reload it all back in when i restart the program.

Hope this explains it better for you

0
 
kretzschmarCommented:
well,

sounds like
it could be done,
as i mentioned above

sample follows in ~9 hours

meikl ;-)
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!

 
mi6agentAuthor Commented:
thanks Meikl - i shall wait till it suits you.  

speak to you later.
0
 
kretzschmarCommented:
sorry, got not the time today
(during week is too much todo)

if you are not in hurry, then i post it hopefully tomorrow
otherwise open another q for all

meikl ;-)
0
 
mi6agentAuthor Commented:
That's ok Meikl, i can wait.  I know you will help if you can so i shall wait for you.
0
 
mi6agentAuthor Commented:
thought i would increase the points for you since you are kind enough to help me on this one again.
0
 
kretzschmarCommented:
you do not need to raise the points for me,
have begun yesterday, but not ready yet

this evening it comes :-)

meikl ;-)
0
 
mi6agentAuthor Commented:
Thanks Meikl.  As for the points, your help is worth it.
0
 
kretzschmarCommented:
well, here it comes

well, its already a one file based app,
i've the typ-field in the record to string,
also the combobox is now at the style-property so adjusted,
that u can type in or select an entry->style csDropDown

the inittree method is canceled,
a new method findparent is introduced,
this method looks up, if a given typ alredady exists in the tree,
and returns the node if found.

the insertnode is changed,
it calls now the findparent-method,
if findparent nothing found,
a root node is ceated with given typ
and the comboboxlist is expanded with the new typ-entry.

so it should be now very dynamic,
the root entrys now depends on that what
you type in the combobox

empty rootnodes will disappear after next appstart

unit r_file_tree3_u;

interface

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

Type TheRec = Record  //a record
                LastName  : String[100];
                FirstName : String[100];
                //more attributes could stand here
                Typ      : String[100];
                Deleted  : Boolean;
              end;


type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Panel1: TPanel;
    Edit1: TEdit;
    Edit2: TEdit;
    BInsert: TButton;
    BUpdate: TButton;
    BDelete: TButton;
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure BInsertClick(Sender: TObject);
    procedure BUpdateClick(Sender: TObject);
    procedure BDeleteClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
    procedure FormDestroy(Sender: TObject);
  private
    NodeList : TList;      //Never used
    f : file of TheRec;    // file of this record
    rec : TheRec;   {Buffer} // a memorybuffer for this record
    Currentrecord : LongInt; {FileCursor}  //Points to the current record in the file
    RecordCount : LongInt; {RecordCount} //Holds the amount of records in the file
    Procedure PopulateEdits;
    Procedure PopulateRecord;
    Procedure CleanUpFile_at_Back;  //looks at the last record, if this is deleted, and deletes it
    Procedure CleanUpFile;          //Deletes all records, which are marked for deletion
    Procedure LoadTree;             //adds the level two nodes from files
    Procedure GetRecord(ARecNo : LongInt);  //gets a record
    Procedure UpdateRecord;         //Upsate a Record
    Procedure MarkToDeleteRecord;   //Marks a record for delete
    Procedure InsertNode(AName : String; AType : String; ARecNo : LongInt; DoSelect : Boolean);  //Inserts a Node into the tree
    Procedure AdJustControls(Switch : Boolean);  //Dis-/Enables Buttons
    Procedure InsertRecord;         //Insert a Record
    Function Findparent(AType : String) : TTreeNode;  //Find the Parent by Typ
  public
    { Public-Deklarationen }
  end;



var
  Form1: TForm1;


implementation

{$R *.DFM}

//open the file
procedure TForm1.FormCreate(Sender: TObject);
var I : Integer;
begin
  assignfile(f,'MyFile3.Dat');  //we will work with this file
  if not(fileexists('MyFile3.Dat')) then  //if this file not exists
    rewrite(f)  //create this file
  else
    reset(f);   //open this file
  CurrentRecord := 0;      //
  RecordCount := fileSize(f);
  LoadTree;
end;

Procedure TForm1.InsertRecord;
begin
  PopulateRecord;
  rec.Deleted := False;
  seek(f,RecordCount);  //goto last record
  write(f,rec);
  inc(RecordCount);
  CurrentRecord := RecordCount;
  InsertNode(rec.LastName,rec.typ,CurrentRecord,True);
end;

procedure TForm1.BInsertClick(Sender: TObject);
begin
  InsertRecord;
end;

procedure TForm1.BUpdateClick(Sender: TObject);
begin
  UpdateRecord;
end;

procedure TForm1.UpdateRecord;
var
  ParentSwap : Boolean;
begin
  if CurrentRecord > 0 then
  begin
    //must we Move the ChildeNode
    ParentSwap := rec.typ <> combobox1.Text;
    PopulateRecord;
    seek(f,CurrentRecord-1);
    write(f,rec);
    If ParentSwap then
    begin
      TreeView1.Selected.Delete;
      InsertNode(rec.LastName,rec.typ,CurrentRecord,True);
    end
    else
      TreeView1.Selected.Text := rec.LastName; //Update NodeText
  end;
end;

Procedure TForm1.MarkToDeleteRecord;
Begin
  rec.deleted := true;
  seek(f,CurrentRecord-1);
  write(f,rec);
  treeview1.selected.Delete;
End;


procedure TForm1.BDeleteClick(Sender: TObject);
begin
  MarkToDeleteRecord;
end;


procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  closefile(f);
end;

Procedure TForm1.AdJustControls(Switch : Boolean);
var I : integer;
begin
  BUpdate.Enabled := Switch;
  BDelete.Enabled := Switch;
  If Not(Switch) then
  begin
    combobox1.ItemIndex := -1;
    edit1.text := '';
    edit2.text := '';
  end;
end;

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin

  If Node.Level > 0 then
  begin
    GetRecord(Integer(node.Data));
    PopulateEdits;
  End;
  AdjustControls(Node.Level > 0);
end;

Procedure TForm1.GetRecord(ARecNo : LongInt);
begin
  If (ARecNo > 0) and (ARecNo <= RecordCount) then
  begin
    try
      seek(f,ARecNo-1);
      read(f,rec);
      CurrentRecord := ARecNo;
    except
      raise;
    end;
  End
  else
    raise exception.create('GetRecord : Recno Out of Bounds');
end;

procedure TForm1.PopulateEdits;
begin
  edit1.text := rec.FirstName;
  edit2.text := rec.LastName;
  //maybe more attributes
  ComboBox1.Text := rec.typ;
end;

procedure TForm1.PopulateRecord;
Begin
  rec.FirstName := edit1.text;
  rec.LastName := edit2.text;
  if comboBox1.Text <> '' then
    rec.Typ := ComboBox1.Text
  else
    raise exception.create('Typ must be set!');
  //maybe more attributes
End;

Procedure TForm1.CleanUpFile_at_Back;
var
  endloop : Boolean;
begin
  if RecordCount > 0 then
  begin
    endloop := False;
    while (not endloop) and (RecordCount > 0) do
    begin
      getrecord(RecordCount);
      if rec.Deleted then
      begin
        seek(f,RecordCount-1);
        truncate(f);
        dec(RecordCount);
      end
      else endloop := true;
    end;
  end;
end;

Procedure TForm1.CleanUpFile;
var
  tmpCurrentRecord : Integer;
Begin
  If RecordCount > 0 then
  begin
    tmpCurrentRecord := 1;
    CleanUpFile_at_Back;  //be sure the last record isn't deleted
    while tmpCurrentRecord < RecordCount do
    begin
      GetRecord(tmpCurrentRecord);
      if rec.Deleted then
      begin
        GetRecord(RecordCount);  //swap records
        seek(f,tmpCurrentRecord-1);
        write(f,rec);
        seek(f,RecordCount-1);
        truncate(f);         //snip
        dec(RecordCount);
        CleanUpFile_at_Back; //be sure the new last record isn't deleted
      end;
      inc(tmpCurrentRecord);
    end;
  end;
  CloseFile(f);  //force physically write
  reset(f);
  CurrentRecord := 0;  //reinit
  If (filesize(f) = RecordCount) then
    RecordCount := FileSize(f)
  else
    raise exception.Create('CleanUp : Something goes wrong');
end;

Function TForm1.Findparent(AType : String) : TTreeNode;
begin
  Result := TreeView1.Items.GetFirstNode;
  While (Result <> NIL) and (Result.Text <> AType) do
    Result := Result.GetNextSibling;
end;


procedure TForm1.InsertNode(AName : String;
                            AType : String;
                            ARecNo : LongInt;
                            DoSelect : Boolean);
var
  ANode : TTreeNode;
  AIndex : Integer;
Begin
  //Search the parentnode
  ANode := FindParent(AType);
  If Anode = Nil then  //Not found
  begin
    Anode := TreeView1.Items.Add(NIL,AType); //Add RootEntry
    ComboBox1.Items.Add(AType);              //Expand Combo
  end;
  ANode := TreeView1.Items.AddChild(ANode,AName); //Create Node
  ANode.Data := Pointer(ARecNo);  //Store recordposition
  If DoSelect Then
  begin
    TreeView1.Selected := ANode;  //Select Node
    ANode.MakeVisible;
  end;
end;

procedure TForm1.LoadTree;
Begin
  CleanUpFile;   //Delete all marked physically
  CurrentRecord := 0;    //load From Beginning
  seek(f,CurrentRecord);
  While not eof(f) do
  begin
    Read(f,rec);
    inc(CurrentRecord);
    InsertNode(rec.LastName,rec.typ,CurrentRecord,False);
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  NodeList.Free; //free the list of RootNodes
end;

end.

hope this helps
ask if something unclear

meikl ;-)
0
 
mi6agentAuthor Commented:
Thanks Meikl, you did it again!  I wish i was as good as you at doing all of this.

One question though, what exactly is the purpose of "ParentSwap" i can't seem to figure out what it does.
0
 
kretzschmarCommented:
hi

well if you change the typ-field of a record, then the record-entry must change to another parentnode

for ex.
you have a record AName, which has the typ friend

friend
|-AName
|-AName2
workers
|-Aname3

you change the type to best friend and update the record,
the result will be then in the tree

friend
|-AName2
best friend
|-AName
workers
|-AName3

parentswap indicates, that the type has changed and introduce a node move to the other parent which matches the changed type via the insertnode-method

meikl ;-)
0
 
mi6agentAuthor Commented:
thanks meikl, i think i understand it a bit better now.

as i said, you are a genius and thank you very much for your help in all of this.

0
 
mi6agentAuthor Commented:
again, i give and excellent grade for an excellent answer and an excellent guy that took the time to help.

thanks.
0
 
kretzschmarCommented:
no no, i'm not a genius

well glad you like it
you a very generous with your points, thnaks :-)

good luck again

meikl ;-)
0

Featured Post

Technology Partners: 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!

  • 8
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now