Solved

For mullet_attack

Posted on 2000-05-02
9
119 Views
Last Modified: 2010-04-04
I could figure this out but I don't have time. Would appreciate the help.


Here's what I need:

Code to add a folder. This code must read the selected node (if there is one) and determine if it is a folder or not. If it is a folder, it needs to be placed as a child under the selected folder.

Code to add an item (easy)
As above, if the selected node is a folder, it should be created as a child of this "folder" node.

Hope you don't mind this. As before, all of my points are available for the correct answer.

0
Comment
Question by:Psylord
  • 6
  • 3
9 Comments
 

Author Comment

by:Psylord
Comment Utility
Adjusted points from 25 to 250
0
 
LVL 2

Expert Comment

by:mullet_attack
Comment Utility
Not a problem, but a bit more info needed please.

Add A folder. What if the selected node is not a folder?

Add an item. What if the selected node is not a folder?

Question for you - when you've read in the options etc from the ini file, where do you store the data (if at all), and how do you later relate that data back to the node it belongs to?

0
 

Author Comment

by:Psylord
Comment Utility
Adjusted points from 250 to 320
0
 

Author Comment

by:Psylord
Comment Utility
--Add A folder. What if the selected node is not a folder?

In this case, if the selected item is a site, and the site is a child of a parent node (in a folder), then the new folder would be made a child as well. However, if there is no item selected, the owner would be set to nil.

The same goes for the items (sites).

As for where the data goes when it's read (if you really wanna do this it would be incredible), I have a set of public strings... These strings indicate parameters for connecting to the FTP server. Username, password etc.

The way I had it set up before was, that once a site was clicked, the data:
[Node3] <-- The Account
Option1=Value1 <--Username?
Option2=Value2 <--Password?
(and so on) are displayed in the form's corresponding edits... Displaying the values.

For instance, if I were to click a site,
I have edits set up for:
Site Label, Host address, Username, Password, Port, and notes.

These (as I explained before) are displayed in the click event.

Right now I have those edits set up as read only until an edit button is pressed, at which time (in the future) I will need to enable them, have another "Save" button appear, get the selected node, and when the user is done and hits the save button, the appropriate section will be updated.

Previously, I had it set up so that the appropriate public strings were assigned the the appropriate values from their respective Edit counterparts. :)~

Then, once the node was double clicked, the connect method is called using these public strings as the parameters.

This is getting quite complex. I will continue increasing the points as I recieve them.

Furthermore, you've been such a great help I would have absolutley no problem adding you to the credits section of my app with anything you want there in addition (website addy etc).

Thanks again. Hope this clears things up...

As you can see I check for answrs like every 5 mins (no rush on you). Just very anxious to see what you've come up with. ;)
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 2

Accepted Solution

by:
mullet_attack earned 320 total points
Comment Utility
try this :

a form with :

treeview : TTreeView;
btnSaveTree: TButton;
btnLoadTree: TButton;
btnClearTree: TButton;
btnAddFolder: TButton;
edtFolderName: TEdit;
btnAddSite: TButton;
edtSiteName: TEdit;
Edit1: TEdit;
Edit2: TEdit;

this demo saves the node data in a structure called TNodeInfo, and a pointer to each copy of the structure (one for each node) is stored in the nodes data property. Have a good look at the code, it's mostly the same as before, with added bits (including the buttons you wanted)

unit Unit1;

interface

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

type
  TNodeStyle = (nsFolder, nsSite);
 
  PNodeInfo = ^TNodeInfo;
  TNodeInfo = record
    NodeStyle : TNodeStyle;
    Option1 : string[50];
    Option2 : string[50];
  end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    btnSaveTree: TButton;
    btnLoadTree: TButton;
    btnClearTree: TButton;
    btnAddFolder: TButton;
    edtFolderName: TEdit;
    btnAddSite: TButton;
    edtSiteName: TEdit;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure btnSaveTreeClick(Sender: TObject);
    procedure btnClearTreeClick(Sender: TObject);
    procedure btnLoadTreeClick(Sender: TObject);
    procedure btnAddFolderClick(Sender: TObject);
    procedure btnAddSiteClick(Sender: TObject);
    procedure TreeView1Click(Sender: TObject);
  private
    procedure WriteToIniFile(Node : TTreeNode ; Num : integer);
    function GetNodePath(Node : TTreeNode) : string;
    function GetNumNodes : integer;
    procedure ReadAndCreateNodes(num : integer);
    function CreateNode(Nodename : string) : TTreeNode;
    function FindNode(ParentNode : TTreeNode ; NodeName : string) : TTreeNode;
    function GetFirstNodeName(var NodeName : string) : string;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.btnSaveTreeClick(Sender: TObject);
var
  t : integer;
  aNode : TTreeNode;
begin
  for t := 0 to Treeview1.items.Count -1 do
    WriteToIniFile(TreeView1.items[t], t);
end;

function TForm1.GetNodePath(Node: TTreeNode): string;
// get the full path of a node, and return as string like 'node1~node2~node3'
var
  tempNode : TTreeNode;
begin
  tempNode := Node;
  result := '';
  with tempNode as TTreeNode do
    begin
      while tempNode.AbsoluteIndex <> 0 do
        begin
          result := '~' + tempnode.text + result;
          tempNode := tempNode.Parent;
        end;
      result := tempnode.text + result;
    end;
end;

procedure TForm1.WriteToIniFile(Node: TTreeNode; Num : integer);
// write each nodes path and data to the inifile
var
 IniFile : TIniFile;
begin
  with Node as TTreeNode do
    begin
      try
        IniFile := TIniFile.create('MyNodes.ini');
        IniFile.WriteString('Nodes', 'Node' + IntToStr(num),GetNodePath(Node));
        IniFile.WriteInteger('Nodes', 'NumNodes',Num);
        IniFile.WriteInteger('Node' + IntToStr(num),'Style',ord(PNodeInfo(Data)^.NodeStyle));
        IniFile.WriteString('Node' + IntToStr(num),'Option1',PNodeInfo(Data)^.Option1);
        IniFile.WriteString('Node' + IntToStr(num),'Option2',PNodeInfo(Data)^.Option2);
      finally
        IniFile.free;
      end;
    end;
end;

procedure TForm1.btnClearTreeClick(Sender: TObject);
begin
  treeview1.items.clear;
end;

procedure TForm1.btnLoadTreeClick(Sender: TObject);
// read all nodes from the inifile
var
  NumNodes : integer;
  t : integer;
begin
  NumNodes := GetNumNodes;
  for t := 0 to NumNodes do
    ReadAndCreateNodes(t);
end;

function TForm1.GetNumNodes: integer;
var
  IniFile : TIniFile;
begin
  result := 0;
  try
    IniFile := TIniFile.create('MyNodes.ini');
    result := IniFile.ReadInteger('Nodes', 'NumNodes', 0);
  finally
    IniFile.free;
  end;
end;

procedure TForm1.ReadAndCreateNodes(num: integer);
// read each entry from the inifile and create each node
var
  IniFile : TIniFile;
  NodeName : string;
  NodeOption : string;
  Node : TTreeNode;
begin
  try
    IniFile := TIniFile.create('MyNodes.ini');
    NodeName := IniFile.ReadString('Nodes', 'Node' + IntToStr(num), '');
    Node := CreateNode(NodeName);
    PNodeInfo(Node.data)^.NodeStyle := TNodeStyle(IniFile.ReadInteger('Node' + IntToStr(num),'Style', 0));
    PNodeInfo(Node.data)^.Option1 := IniFile.ReadString('Node' + IntToStr(num),'Option1', '');
    PNodeInfo(Node.data)^.Option2 := IniFile.ReadString('Node' + IntToStr(num),'Option2', '');
  finally
    IniFile.free;
  end;
end;

function TForm1.CreateNode(Nodename: string): TTreeNode;
// create the nodes at the proper place, based on it's fullpath in NodeName
var
  temp : string;
  NodeText : string;
  FoundNode : TTreeNode;
  ParentNode : TTreeNode;
  NodeInfo : PNodeInfo;
begin
  temp := NodeName;
  ParentNode := nil;
  while temp <> '' do
    begin
      NodeText := GetFirstNodeName(temp);
      FoundNode := FindNode(ParentNode,NodeText);
      if FoundNode = nil then
        begin
          New(NodeInfo);
          ParentNode := TreeView1.items.AddChildObject(ParentNode,NodeText,NodeInfo);
        end
      else
        ParentNode := FoundNode;
    end;
  result := ParentNode;
end;

function TForm1.FindNode(ParentNode : TTreeNode ; NodeName: string): TTreeNode;
// find a particular node by name, checking the parent is the correct one
// this allows sub nodes to have the same name (different parents)
var
  t : integer;
begin
  for t := 0 to Treeview1.items.count -1 do
    if ((TTreenode(treeview1.items[t]).text = NodeName) and
     (TTreenode(treeview1.items[t]).HasAsParent(ParentNode))) then
      begin
        result := treeview1.items[t];
        exit;
      end;
  result := nil;
end;

function TForm1.GetFirstNodeName(var NodeName: string): string;
// returns the first node name from the fullpath, and also removes
// the first node name from the full path
// eg enter with Node1~Node2~Node3, and exit with result := Node1 and
// NodeName := Node2~Node3
begin
  if pos('~',NodeName) > 0 then
    begin
      result := Copy(NodeName,1,Pos('~',NodeName)-1);
      NodeName := Copy(NodeName,Pos('~',NodeName) + 1, length(NodeName) - Pos('~',NodeName));
    end
  else
    begin
      result := NodeName;
      NodeName := '';
    end;
end;

procedure TForm1.btnAddFolderClick(Sender: TObject);
var
  ParentNode : TTreeNode;
  NodeInfo : PNodeInfo;
begin
  if edtFolderName.text <> '' then
    begin
      New(NodeInfo);
      NodeInfo^.NodeStyle := nsFolder;
      NodeInfo^.Option1 := 'some folder text';
      NodeInfo^.Option2:= 'more folder text';
      ParentNode := Treeview1.selected;
      if ParentNode <> nil then
        if PNodeInfo(ParentNode.Data)^.NodeStyle = nsSite then
           ParentNode := ParentNode.parent;
      Treeview1.Items.AddChildObjectFirst(ParentNode,edtFolderName.text,NodeInfo);
    end;
end;

procedure TForm1.btnAddSiteClick(Sender: TObject);
var
  ParentNode : TTreeNode;
  NodeInfo : PNodeInfo;
begin
  if edtSiteName.text <> '' then
    begin
      New(NodeInfo);
      NodeInfo^.NodeStyle := nsSite;
      NodeInfo^.Option1 := 'some site text';
      NodeInfo^.Option2:= 'some more site text';
      ParentNode := Treeview1.selected;
      if ParentNode <> nil then
        if PNodeInfo(ParentNode.Data)^.NodeStyle = nsSite then
           ParentNode := ParentNode.parent;
      Treeview1.Items.AddChildObjectFirst(treeview1.selected,edtSiteName.text,NodeInfo);
    end;
end;

procedure TForm1.TreeView1Click(Sender: TObject);
begin
  with treeview1 do
    begin
      if selected = nil then exit;
      case PNodeInfo(selected.data)^.NodeStyle of
        nsFolder:
          begin
            edit1.text := PNodeInfo(Selected.data)^.option1;
            edit2.text := '';
          end;
        nsSite:
          begin
            edit2.text := PNodeInfo(Selected.data)^.option1;
            edit1.text := '';
          end;
       end;  
    end;
end;

end.
0
 

Author Comment

by:Psylord
Comment Utility
Working with the code...

A couple things are a bit wrong already, but I'll get back to you on them...
0
 

Author Comment

by:Psylord
Comment Utility
It's looking up... Still working with it... Got the sites adding correctly... I've got it set up so there is a "New Site" button, then there's a "Save Site" button. I think it's better this way... One problem I've noticed is that with an empty treeview, when I add a site, the first site is added as a parent node. This shouldn't happen (if you wanna comment on this that's cool). Additionally, Sites are able to be added as childeren of sites (with your code) this is also incorrect and needs to be changed. Comments?

(New Site is sent to back when it's clicked this sends save site to the front, which when clicked is sent to back again!). :)

-Psylord
0
 
LVL 2

Expert Comment

by:mullet_attack
Comment Utility
personally I would add a popup menu to the treeview, with items like 'new folder', 'new site' etc enabled depending on what you clicked on, ie folder or site. that way a user can't add a site without a folder as parent. The above code is more to show how to store additional info in the data property of nodes, rather than a complete solution (you still have to do most of the work yourself. Most of my answers are like this, I try to make the person think more about what they are doing, rather than just do it for them. It's the old "teach a man to fish..." thing.)
0
 

Author Comment

by:Psylord
Comment Utility
I can appreciate that. :)

I do in fact have a popup menu... But I wish to have buttons as well... I'll work through it. I appreciate all the time youv'e put into this.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
This video discusses moving either the default database or any database to a new volume.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

743 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now