If you type a folder's path in a file dialog, expand it

This commit is contained in:
Isaiah Odhner 2023-06-22 02:37:45 -04:00
parent d0385556d1
commit 14475154b9
2 changed files with 37 additions and 16 deletions

View File

@ -19,22 +19,17 @@ class EnhancedDirectoryTree(DirectoryTree):
self.scroll_to_region(region, animate=False, top=True)
self.set_timer(0.01, scroll_node_to_top)
def _hook_node_add(self, node: TreeNode[DirEntry], remaining_parts: tuple[str]) -> None:
# print("_hook_node_add", node, remaining_parts)
def _expand_matching_child(self, node: TreeNode[DirEntry], remaining_parts: tuple[str]) -> None:
"""Hooks into DirectoryTree's add method, and expands the child node matching the next path part, recursively.
Once the last part of the path is reached, it scrolls to and selects the node.
"""
# print("_expand_matching_child", node, remaining_parts)
orig_add = node.add
_hook_node_add = self._hook_node_add
_expand_matching_child = self._expand_matching_child
_add_to_load_queue = self._add_to_load_queue
_go_to_node = self._go_to_node
def add(
self: TreeNode[DirEntry],
label: TextType,
data: DirEntry | None = None,
*,
expand: bool = False,
allow_expand: bool = True,
) -> TreeNode[DirEntry]:
node = orig_add(label, data, expand=expand, allow_expand=allow_expand)
# print("add", node, node.data)
def expand_if_match(node: TreeNode[DirEntry]) -> None:
if node.data:
# print(f"comparing node.data.path.parts[-1] {node.data.path.parts[-1]!r} with remaining_parts[0] {remaining_parts[0]!r}")
if node.data.path.parts[-1] == remaining_parts[0]:
@ -42,7 +37,7 @@ class EnhancedDirectoryTree(DirectoryTree):
if node.data.path.is_dir():
sliced_parts = remaining_parts[1:]
# print("recursing with sliced_parts", sliced_parts)
_hook_node_add(node, sliced_parts) # type: ignore
_expand_matching_child(node, sliced_parts) # type: ignore
_add_to_load_queue(node)
# else:
# print("Found a file, not as last part of path:", node.data.path, "remaining_parts:", remaining_parts)
@ -54,8 +49,26 @@ class EnhancedDirectoryTree(DirectoryTree):
# but for File > New, File > Open, it should expand the current directory.
if node.data.path.is_dir():
_add_to_load_queue(node)
def add(
self: TreeNode[DirEntry],
label: TextType,
data: DirEntry | None = None,
*,
expand: bool = False,
allow_expand: bool = True,
) -> TreeNode[DirEntry]:
node = orig_add(label, data, expand=expand, allow_expand=allow_expand)
# print("add", node, node.data)
expand_if_match(node)
# Note: The hook is left indefinitely.
# It may be worth some consideration as to whether this could pose any problems.
# However, we can't just reset to orig_add here since it would only handle the first added node.
return node
# Hook the add method to handle new nodes.
node.add = add.__get__(node, type(node))
# Also expand children of the node already loaded.
for child in node.children:
expand_if_match(child)
def expand_to_path(self, target_path: str | Path) -> None:
"""Expand the directory tree to the target path, loading any directories as needed."""
@ -70,5 +83,5 @@ class EnhancedDirectoryTree(DirectoryTree):
# - Maybe this method should return the node if it was found.
# - Definitely want to figure out how to avoid the timers.
self._hook_node_add(self.root, target_path.parts[1:])
self._expand_matching_child(self.root, target_path.parts[1:])

View File

@ -64,7 +64,15 @@ class FileDialogWindow(DialogWindow):
if os.path.splitext(file_path)[1] == "":
file_path += self._auto_add_default_extension
# TODO: if directory, just navigate to it in the directory tree
# if it's a directory, just navigate to it in the directory tree
if os.path.isdir(file_path):
# self._directory_tree_selected_path = file_path
# self._selected_file_path = file_path
# self._expand_directory_tree()
tree = self.content.query_one(EnhancedDirectoryTree)
tree.expand_to_path(file_path)
return
self.handle_selected_file_path(file_path)
def on_mount(self) -> None: