View Issue Details

IDProjectCategoryView StatusLast Update
0024230LazarusLCLpublic2013-04-27 10:26
ReporterBart BroersmaAssigned ToBart Broersma 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSWindowOS VersionWin7
Product Version1.1 (SVN)Product Buildr40594 
Target VersionFixed in Version1.1 (SVN) 
Summary0024230: ShellTreeView doesn't show root (like Delphi does), which makes root inaccessible
DescriptionWhen I have a TShellTreeView and set it's root to C:\ (on Windows obviously) then the tree looks something like

>devel
>Intel
>Windows

(where > represents the glyph that can be clicked on to expand the node)

The problem is as follows.
When you connect a TShellListView to the ShellTreeView, then when you start the program (nothing is selected in the ShellTreeView) the ShellListView will display all files in the root of the ShellTreeView (as expected).
Now, as soon as the user selects any node in the ShellTreeView, it becomes impossible to get back to the root (as in: like it was when the program started up).

Basically, when I set root to C:\ I would expect the ShellTreeView to look something like:
C:\
  >devel
  >Intel
  >Windows

(The look you get when you open a TSelectDirectoryDlg)
Steps To ReproduceBuild and run attached demo project.
Click on Button1 (this will set the root of the ShellTreeView to whatever is in the Edit1 control, by default C:\)

You will see the files that reside on C:\ in the ShellListView on the right
(see shelltreeview_lazarus01.png)
Now click on any node in the ShellTreeView, it'll look like shelltreeview_lazarus02.png, and from that situation it is impossible to get back to the situation as in shelltreeview_lazarus01.png.

The file shelltreeview_delphi shows how delphi displays the root, so you can get back to it.
TagsNo tags attached.
Fixed in Revisionr40732
LazTarget-
Widgetset
Attached Files
  • shelltreeview_delphi.gif (1,277 bytes)
    shelltreeview_delphi.gif (1,277 bytes)
  • shell.zip (5,840 bytes)
  • shellctrls.diff (2,335 bytes)
    Index: lcl/shellctrls.pas
    ===================================================================
    --- lcl/shellctrls.pas	(revision 40723)
    +++ lcl/shellctrls.pas	(working copy)
    @@ -337,6 +337,8 @@
     end;
     
     procedure TCustomShellTreeView.SetRoot(const AValue: string);
    +var
    +  RootNode: TTreeNode;
     begin
       if FRoot=AValue then exit;
       FRoot:=AValue;
    @@ -344,7 +346,16 @@
       if FRoot = '' then
         PopulateWithBaseFiles()
       else
    -    PopulateTreeNodeWithFiles(nil, AValue);
    +  begin
    +    FRoot := ExpandFileName(FRoot);
    +    //writeln('Adding ChildNode for ',froot);
    +    RootNode := Items.AddChild(nil, AValue);
    +    //writeln('GetPathFromNode(RootNode) = ',GetPathFromNode(RootNode));
    +    RootNode.HasChildren := True;
    +    //PopulateTreeNodeWithFiles(RootNode, AValue);
    +    //writeln('RootNode.Count = ',RootNode.Count);
    +    RootNode.Expand(False);
    +  end;
       if Assigned(ShellListView) then
         ShellListView.Root := FRoot;
     end;
    @@ -600,7 +611,6 @@
       Files := TStringList.Create;
       try
         GetFilesInDir(ANodePath, AllFilesMask, FObjectTypes, Files, FFileSortType);
    -
         Result := Files.Count > 0;
     
         for i := 0 to Files.Count - 1 do
    @@ -631,7 +641,6 @@
     begin
       // avoids crashes in the IDE by not populating during design
       if (csDesigning in ComponentState) then Exit;
    -
       r := GetLogicalDriveStrings(SizeOf(Drives), Drives);
       if r = 0 then Exit;
       if r > SizeOf(Drives) then Exit;
    @@ -681,14 +690,21 @@
       if ANode <> nil then  // Will return the root if nothing is selected (ANode=nil)
       begin
         // Build the path. In the future use ANode.Data instead of ANode.Text
    -    Result := ANode.Text;
    +    if (ANode.Parent = nil) and (GetRootPath <> '') then
    +      Result := ''
    +    else
    +      Result := ANode.Text;
    +    //writeln('GetPathFromNode: Initial Result=',Result);
         while (ANode.Parent <> nil) do
         begin
           ANode := ANode.Parent;
           Result := IncludeTrailingPathDelimiter(ANode.Text) + Result;
    +      //writeln('GetPathFromNode: (Building) Result=',Result);
         end;
       end;
    -  Result := GetRootPath() + Result;    // Include root directory
    +  if not FilenameIsAbsolute(Result) then
    +    Result := GetRootPath() + Result;    // Include root directory
    +  //writeln('GetPathFromNode: Final Result=',Result);
     end;
     
     function TCustomShellTreeView.GetSelectedNodePath: string;
    
    shellctrls.diff (2,335 bytes)

Activities

Bart Broersma

2013-04-05 10:48

developer  

Bart Broersma

2013-04-05 10:48

developer  

Bart Broersma

2013-04-05 10:48

developer  

shelltreeview_delphi.gif (1,277 bytes)
shelltreeview_delphi.gif (1,277 bytes)

Bart Broersma

2013-04-07 12:24

developer  

shell.zip (5,840 bytes)

Bart Broersma

2013-04-07 12:25

developer  

shellctrls.diff (2,335 bytes)
Index: lcl/shellctrls.pas
===================================================================
--- lcl/shellctrls.pas	(revision 40723)
+++ lcl/shellctrls.pas	(working copy)
@@ -337,6 +337,8 @@
 end;
 
 procedure TCustomShellTreeView.SetRoot(const AValue: string);
+var
+  RootNode: TTreeNode;
 begin
   if FRoot=AValue then exit;
   FRoot:=AValue;
@@ -344,7 +346,16 @@
   if FRoot = '' then
     PopulateWithBaseFiles()
   else
-    PopulateTreeNodeWithFiles(nil, AValue);
+  begin
+    FRoot := ExpandFileName(FRoot);
+    //writeln('Adding ChildNode for ',froot);
+    RootNode := Items.AddChild(nil, AValue);
+    //writeln('GetPathFromNode(RootNode) = ',GetPathFromNode(RootNode));
+    RootNode.HasChildren := True;
+    //PopulateTreeNodeWithFiles(RootNode, AValue);
+    //writeln('RootNode.Count = ',RootNode.Count);
+    RootNode.Expand(False);
+  end;
   if Assigned(ShellListView) then
     ShellListView.Root := FRoot;
 end;
@@ -600,7 +611,6 @@
   Files := TStringList.Create;
   try
     GetFilesInDir(ANodePath, AllFilesMask, FObjectTypes, Files, FFileSortType);
-
     Result := Files.Count > 0;
 
     for i := 0 to Files.Count - 1 do
@@ -631,7 +641,6 @@
 begin
   // avoids crashes in the IDE by not populating during design
   if (csDesigning in ComponentState) then Exit;
-
   r := GetLogicalDriveStrings(SizeOf(Drives), Drives);
   if r = 0 then Exit;
   if r > SizeOf(Drives) then Exit;
@@ -681,14 +690,21 @@
   if ANode <> nil then  // Will return the root if nothing is selected (ANode=nil)
   begin
     // Build the path. In the future use ANode.Data instead of ANode.Text
-    Result := ANode.Text;
+    if (ANode.Parent = nil) and (GetRootPath <> '') then
+      Result := ''
+    else
+      Result := ANode.Text;
+    //writeln('GetPathFromNode: Initial Result=',Result);
     while (ANode.Parent <> nil) do
     begin
       ANode := ANode.Parent;
       Result := IncludeTrailingPathDelimiter(ANode.Text) + Result;
+      //writeln('GetPathFromNode: (Building) Result=',Result);
     end;
   end;
-  Result := GetRootPath() + Result;    // Include root directory
+  if not FilenameIsAbsolute(Result) then
+    Result := GetRootPath() + Result;    // Include root directory
+  //writeln('GetPathFromNode: Final Result=',Result);
 end;
 
 function TCustomShellTreeView.GetSelectedNodePath: string;
shellctrls.diff (2,335 bytes)

Issue History

Date Modified Username Field Change
2013-04-05 10:47 Bart Broersma New Issue
2013-04-05 10:47 Bart Broersma File Added: shell.zip
2013-04-05 10:48 Bart Broersma File Added: shelltreeview_lazarus01.png
2013-04-05 10:48 Bart Broersma File Added: shelltreeview_lazarus02.png
2013-04-05 10:48 Bart Broersma File Added: shelltreeview_delphi.gif
2013-04-07 12:23 Bart Broersma File Deleted: shell.zip
2013-04-07 12:24 Bart Broersma File Added: shell.zip
2013-04-07 12:25 Bart Broersma File Added: shellctrls.diff
2013-04-07 12:59 Bart Broersma Fixed in Revision => r40732
2013-04-07 12:59 Bart Broersma Status new => resolved
2013-04-07 12:59 Bart Broersma Fixed in Version => 1.1 (SVN)
2013-04-07 12:59 Bart Broersma Resolution open => fixed
2013-04-07 12:59 Bart Broersma Assigned To => Bart Broersma
2013-04-27 10:26 Bart Broersma Status resolved => closed