Forum > LCL

[SOLVED] FindNodeWithTextPath();

(1/2) > >>

petevick:
To select a node in a ShellTreeView I have been walking through the nodes using a given path, this is ok unless there are duplicate folders, for example there are these two paths, C:\Users\username\Documents\ and C:\Users\username\OneDrive\Documents\Folder1, both Documents folders are found, but I want the second one that contains Folder1, an error occurs because the first empty Documents folder is found first.
I came across the following....

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---ShellTreeView.Selected:=ShellTreeView.Items.FindNodeWithTextPath(PathString);...but this does not select the PathString.
I also came across this post by Mike.Cornflake https://forum.lazarus.freepascal.org/index.php/topic,18856.msg106774.html#msg106774 and https://forum.lazarus.freepascal.org/index.php/topic,18856.msg106844.html#msg106844 in which he notes the problem of unique node names. It seems that I'd be better off looking at Mike.Cornflakes code as there seems to be very little information on how FindNodeWithTextPath() is used. I also need anyting I do to be cross platform, Linux and Windows.

petevick:
I should have added this, it's the code I use for waling through the ShellTreeView at the moment...

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TBrowser.ExpFolder(aPath:String);var  aPart:String = '';  str:Integer = 0;  fin:Integer = 1;begin  while (fin <> Length(aPath)) and (aPath<>'') do  begin    fin:=fin+1;    if (Copy(aPath, fin, 1) = PathDelim) and (aPath > '')  then    begin      aPart:=Copy(aPath, str, fin-str);      aPart:=ExcludeTrailingPathDelimiter(aPart);      aPart:=ExcludeLeadingPathDelimiter(aPart);      myTreeView.Selected := myTreeView.Items.FindNodeWithText(aPart);      if fin < Length(aPath) then begin        myTreeView.Selected.Expanded:=True;      str:=fin+1;      end;    end;  end;end; 

wp:
I don't know if this really is the problem. The more severe issue is that in my ShellTreeView it does not even find a node when its parent is not expanded. This is because the ShellTreeView knows only the expanded nodes; the collapsed nodes are not populated for better performance. Another complication - for windows - is that the FindNodeWithTextPath is a method of TCustomTreeView which does not make the assumption that its nodes are related to the file structure and thus separates them by a forward slash...

Please test the following function which splits the path at the path delimiters (of the OS) and, going from top-level downward, expands the nodes already found:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function FindNodeWithPath(ATreeView: TShellTreeView; PathString: String): TTreeNode;var  s: String;begin  Result := nil;  for s in PathString.Split(PathDelim) do  begin    if Result = nil then      Result := ATreeView.Items.FindTopLvlNode(s)    else    begin      Result.Expanded := true;      Result := Result.FindNode(s);    end;  end;end;
[EDIT]
Just committed an updated version of TCustomTreeView/TShellTreeView to Laz-main in which
- the path delimiter of the OS is used to separate nodes in the treeview path
- the nodes found along the path are expanded so that the search can continue with the collapsed nodes
- path elements are compared in a case-insensitive way on Windows.

So, the method FindNodeWithTextPath should work for TShellTreeView now, too.

petevick:
Hi wp. It works great in Windows but fails in Linux unfortunatly. I've stepped through the code and variable s is returning the split parts of the path correctly but it always returns Nil so the browser opens with no node expanded. I can't see for the life of what the difference is between Windows and Linux.

wp:
Ah - my code makes the top-level path element to an empty string in Linux while it should be '/'. Please check this one:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function FindNodeWithPath(ATreeView: TShellTreeView; TextPath: String): TTreeNode;var  s: String;begin  Result := nil;  for s in TextPath.Split(PathDelim) do  begin    if (Result = nil) then    begin      if s = '' then Result := ATreeView.Items.FindTopLvlNode('/')      else Result := ATreeView.Items.FindTopLvlNode(s);    end    else    begin      Result.Expanded := true;      Result := Result.FindNode(s);    end;  end;end;
Got to fix this in Laz-main as well...

Navigation

[0] Message Index

[#] Next page

Go to full version