""" Левая панель: поиск, выбор корневой папки, дерево подпапок, фильтр избранного и фильтр по тегу. """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QLabel, QLineEdit, QTreeView, QComboBox, QCheckBox ) from PyQt6.QtGui import QFileSystemModel from PyQt6.QtCore import QDir, pyqtSignal from comfy_studio.core.i18n import tr from comfy_studio.ui.widgets.translatable_text_edit import TranslatableLineEdit class LeftPanel(QWidget): search_changed = pyqtSignal(str) root_folder_changed = pyqtSignal(str) filters_changed = pyqtSignal() # избранное / тег def __init__(self, parent=None): super().__init__(parent) self.init_ui() def init_ui(self): layout = QVBoxLayout(self) layout.setContentsMargins(5, 5, 5, 5) self.search_input = TranslatableLineEdit() self.search_input.setPlaceholderText(tr("search_placeholder")) self.search_input.textChanged.connect(self.search_changed.emit) layout.addWidget(self.search_input) # Фильтр избранного self.favorites_check = QCheckBox(tr("filter_favorites")) self.favorites_check.stateChanged.connect(lambda _: self.filters_changed.emit()) layout.addWidget(self.favorites_check) # Фильтр по тегу layout.addWidget(QLabel(tr("filter_tag"))) self.tag_combo = QComboBox() self.tag_combo.addItem(tr("all_tags"), None) self.tag_combo.currentIndexChanged.connect(lambda _: self.filters_changed.emit()) layout.addWidget(self.tag_combo) # Выбор активной корневой директории layout.addWidget(QLabel(tr("active_folder"))) self.folder_selector = QComboBox() self.folder_selector.currentTextChanged.connect(self._on_folder_changed) layout.addWidget(self.folder_selector) layout.addWidget(QLabel(tr("subfolder_tree"))) self.folder_model = QFileSystemModel() self.folder_model.setFilter(QDir.Filter.Dirs | QDir.Filter.NoDotAndDotDot) self.tree_view = QTreeView() self.tree_view.setModel(self.folder_model) self.tree_view.setHeaderHidden(True) for i in range(1, self.folder_model.columnCount()): self.tree_view.setColumnHidden(i, True) layout.addWidget(self.tree_view) # ── Публичные методы ── def set_tracked_folders(self, folders: list): self.folder_selector.blockSignals(True) self.folder_selector.clear() self.folder_selector.addItems(folders) self.folder_selector.blockSignals(False) def set_root_path(self, path: str): self.folder_model.setRootPath(path) self.tree_view.setRootIndex(self.folder_model.index(path)) def update_tags(self, tags: list): """Обновляет список тегов, сохраняя текущий выбор если возможно.""" current = self.tag_combo.currentData() self.tag_combo.blockSignals(True) self.tag_combo.clear() self.tag_combo.addItem(tr("all_tags"), None) for t in tags: self.tag_combo.addItem(t, t) if current in tags: self.tag_combo.setCurrentIndex(tags.index(current) + 1) self.tag_combo.blockSignals(False) def get_filters(self) -> dict: return { "favorites_only": self.favorites_check.isChecked(), "tag": self.tag_combo.currentData(), } def _on_folder_changed(self, path: str): if path: self.set_root_path(path) self.root_folder_changed.emit(path)