Skip to content

Commit

Permalink
FileExplorer Search Support
Browse files Browse the repository at this point in the history
  • Loading branch information
Ceyase committed Jan 26, 2025
1 parent 61eeca8 commit 3135480
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 10 deletions.
20 changes: 14 additions & 6 deletions editors/gm/gm_strings_editor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from PySide6.QtWidgets import QHBoxLayout, QPlainTextEdit
from PySide6.QtWidgets import QHBoxLayout, QPlainTextEdit, QVBoxLayout, QLabel
from .gm_base_editor import BaseEditor
from modules.UML import GameMakerLib as gml

Expand All @@ -10,21 +10,29 @@ def _handle_modify(self):
def init_ui(self):
layout = QHBoxLayout(self)

# 源文本侧布局
source_layout = QVBoxLayout()
source_layout.addWidget(QLabel("源文本"))
self.source_editor = QPlainTextEdit()
try:
self.source_editor.setPlainText(self.source_data.Strings[int(self.id)].Content)
except:
self.source_editor.setPlainText("无法读取源文件")
self.source_editor.setPlainText("无法读取源文本")
self.source_editor.setReadOnly(True)

source_layout.addWidget(self.source_editor)

# 目标文本侧布局
target_layout = QVBoxLayout()
target_layout.addWidget(QLabel("目标文本"))
self.target_editor = QPlainTextEdit()
try:
self.target_editor.setPlainText(self.target_data.Strings[int(self.id)].Content)
except:
self.target_editor.setPlainText("")

layout.addWidget(self.source_editor)
layout.addWidget(self.target_editor)
target_layout.addWidget(self.target_editor)

layout.addLayout(source_layout)
layout.addLayout(target_layout)

self.target_editor.textChanged.connect(self._handle_modify)

Expand Down
2 changes: 1 addition & 1 deletion main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def init_ui(self):
self.file_explorer = FileExplorer()
self.file_explorer.file_double_clicked.connect(self.open_file)
self.menu_bar.file_explorer_action.connect(self.file_explorer.show_or_close)
self.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, self.file_explorer)
self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, self.file_explorer)

# 初始化工具栏
self.tool_bar = MainToolBar()
Expand Down
79 changes: 76 additions & 3 deletions widgets/file_explorer.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,90 @@
from PySide6.QtWidgets import QDockWidget, QTreeWidget, QTreeWidgetItem
from PySide6.QtWidgets import (QDockWidget, QTreeWidget, QTreeWidgetItem,
QLineEdit, QCheckBox, QHBoxLayout, QVBoxLayout, QWidget)
from PySide6.QtCore import Qt, Signal
import os
import re

class FileExplorer(QDockWidget):
file_double_clicked = Signal(str) # 发送相对路径

def __init__(self, parent=None):
super().__init__("文件浏览器", parent)
self.data = [{},{}]

# 创建搜索组件
self.search_line = QLineEdit()
self.search_line.setPlaceholderText("搜索...")
self.regex_checkbox = QCheckBox("正则表达式")

# 创建布局
search_layout = QHBoxLayout()
search_layout.addWidget(self.search_line)
search_layout.addWidget(self.regex_checkbox)

# 创建树部件
self.tree = QTreeWidget()
self.tree.setHeaderLabel("项目文件")
self.tree.itemDoubleClicked.connect(self.on_item_double_clicked)
self.setWidget(self.tree)

# 主容器布局
container = QWidget()
main_layout = QVBoxLayout(container)
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.addLayout(search_layout)
main_layout.addWidget(self.tree)
self.setWidget(container)

# 连接信号
self.search_line.textChanged.connect(self.update_filter)
self.regex_checkbox.stateChanged.connect(self.update_filter)

def update_filter(self):
"""更新树形结构的过滤状态"""
search_text = self.search_line.text()
use_regex = self.regex_checkbox.isChecked()
self.filter_items(search_text, use_regex)

def filter_items(self, text, use_regex):
"""过滤树形结构项"""
try:
pattern = re.compile(text, re.IGNORECASE) if use_regex and text else None
except re.error:
return # 忽略无效的正则表达式

root = self.tree.invisibleRootItem()
for i in range(root.childCount()):
item = root.child(i)
self._filter_item(item, text, pattern, use_regex)

def _filter_item(self, item, text, pattern, use_regex):
"""递归过滤树节点"""
child_visible = False
# 先处理子节点
for i in range(item.childCount()):
child = item.child(i)
if self._filter_item(child, text, pattern, use_regex):
child_visible = True

# 检查当前节点是否匹配
match = False
if not text: # 空搜索字符串显示所有
match = True
else:
item_text = item.text(0)
if use_regex and pattern:
match = bool(pattern.search(item_text))
else:
match = text.lower() in item_text.lower()

# 显示逻辑:自身匹配或子节点可见
is_visible = match or child_visible
item.setHidden(not is_visible)

# 展开匹配的父节点
if is_visible and item.parent():
item.parent().setExpanded(True)

return is_visible

def on_item_double_clicked(self, item):
if not item.childCount():
Expand All @@ -26,6 +99,7 @@ def load_project(self, project_data):

source_dir = project_data['source']
self._populate_tree(self.tree, source_dir, project_data)
self.tree.expandToDepth(1) # 默认展开一级目录

def _populate_tree(self, parent, path, base_data):
for item_name in sorted(os.listdir(path)):
Expand All @@ -51,7 +125,6 @@ def _populate_tree_gm(self, parent, path, base_data):
node = QTreeWidgetItem(pnode)
node.setText(0, str(self.data[0][rel_path].Strings[i]))
node.setData(0, Qt.ItemDataRole.UserRole, f"gm:{rel_path}/GMStrings/{i}")


def show_or_close(self):
if self.isVisible():
Expand Down

0 comments on commit 3135480

Please sign in to comment.