Forum > LCL

TTreeView: an example and a question

(1/2) > >>

moit:
I've been trying to come grips with populating a TTreeView with directories and came up with the following example based on the example here.

As a testcase, it recursively lists out the dirs in my Music folder. I'm on Ubuntu 9.04 using Lazarus v0.9.26.2-2beta. I wanted to include the example here because I wasn't able to find a Linux-friendly example elsewhere.


--- Code: ---unit Unit1;

{ based on http://stackoverflow.com/questions/1967359/populate-a-ttreeview-with-directory-tree-and-filtering }

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ComCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    populateButton: TButton;
    closeButton: TButton;
    dirTree: TTreeView;
    procedure closeButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure populateButtonClick(Sender: TObject);
  private
    { private declarations }
    procedure PopulateDirTree();
    procedure AddDirectories(theNode: TTreeNode; inPath: String);
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.closeButtonClick(Sender: TObject);
begin
  Close();
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  //self.PopulateDirTree();
end;

procedure TForm1.populateButtonClick(Sender: TObject);
begin
  self.PopulateDirTree();
end;

procedure TForm1.PopulateDirTree();
var
  searchRec : TSearchRec;
  FileAttrs : Integer;
  theRootDir : String;
  theRootNode : TTreeNode;
  aNode : TTreeNode;
begin
  FileAttrs := faDirectory;     // Only care about directories
  theRootDir:=GetUserDir()+'Music';
  // TODO: catch dir-not-found
  DirTree.Items.Clear;
  theRootNode := DirTree.Items.AddFirst(nil,theRootDir);
  if FindFirst(theRootDir + DirectorySeparator + '*', FileAttrs, searchRec) = 0 then
  begin
    repeat
      if (searchRec.Name = '.') or (searchRec.Name = '..') then
        continue;
      if (searchRec.Attr and faVolumeID) = faVolumeID then
        continue; // nothing useful to do with volume IDs
      if (searchRec.Attr and faHidden) = faHidden then
        continue; // honor the OS "hidden" setting ... doesn't seem to work in Linux
      {$IFDEF UNIX}
      { kludge to filter out hidden files on UNIXy systems }
      if searchRec.Name[1] = '.' then
        continue;
      {$ENDIF}
      if (searchRec.Attr and FileAttrs) = FileAttrs then              { we've found a directory! }
      begin
        aNode := dirTree.Items.AddChild(theRootNode,searchRec.name);  { add it as a node to the tree }
        AddDirectories(aNode,theRootDir+DirectorySeparator+searchRec.Name);  { and add its subdirs as children }
      end;
    until FindNext(searchRec) <> 0;
    FindClose(searchRec);
  end;
  dirTree.FullExpand();
end;

procedure TForm1.AddDirectories(theNode: TTreeNode; inPath: String);
var
  searchRec : TSearchRec;
  FileAttrs : Integer;
  theNewNode : TTreeNode;
begin
  FileAttrs := faDirectory;     // Only care about directories
  if FindFirst(inPath + DirectorySeparator + '*', FileAttrs, searchRec) = 0 then
  begin
    repeat
      //if  ((searchRec.Attr and FileAttrs) = searchRec.Attr) and (copy(searchRec.Name,1,1) <> '.') then
      if (searchRec.Name = '.') or (searchRec.Name = '..') then
        continue;
      if (searchRec.Attr and faHidden) = faHidden then
        continue; // honor the OS "hidden" setting ... doesn't seem to work in Linux
      {$IFDEF UNIX}
      { kludge to filter out hidden files on UNIX-y systems }
      if searchRec.Name[1] = '.' then
        continue;
      {$ENDIF}
      if  ((searchRec.Attr and FileAttrs) = FileAttrs) then            { we've found a directory! }
      begin
        theNewNode := dirTree.Items.AddChild(theNode,searchRec.name);  { add it as a node to the tree }
        self.AddDirectories(theNewNode,inPath+DirectorySeparator+searchRec.Name);  { and add its subdirs as children }
      end;
    until FindNext(searchRec) <> 0;
    FindClose(searchRec);
  end;
end;

initialization
  {$I unit1.lrs}

end.

--- End code ---

I've only been using Lazarus for a few weeks, so please be gentle.

My question regards sorting. What is magical incantation required to get TTreeViews to give sorted results? I've tried setting the dirView's sorted property to all the available options in the Options Inspector, but none of them seem to make any difference. Is this a bug, or am I just not getting it?

-M

moit:

--- Quote from: moit on June 15, 2010, 06:09:29 pm ---What is magical incantation required to get TTreeViews to give sorted results?

--- End quote ---

I think I answered my own question:


--- Code: ---dirTree.AlphaSort();
--- End code ---

Apparently, TTreeViews are not automatically sorted -- I suspect because of performance concerns.

theo:
There is also a TShellTreeView in the Misc tab.

moit:

--- Quote from: theo on June 16, 2010, 03:20:03 am ---There is also a TShellTreeView in the Misc tab.

--- End quote ---

So there is! I'll give that a go next.

moit:
Please pardon my stupid, but how do you set the root of a TShellTreeView? I can't seem to find documentation on it and the autocompletion isn't suggesting anything useful.

-M

Navigation

[0] Message Index

[#] Next page

Go to full version