import os import re import sys from pathlib import Path from PySide6.QtCore import QDir, QModelIndex from PySide6.QtGui import QIcon from src.pluginregistry import PluginRegistry from src.plugins.krowlog.Tab import Tab from PySide6.QtWidgets import QVBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QTreeView, \ QFileSystemModel from src.i18n import _ from src.settings.settings import Settings from src.ui.formgrid import FormGrid from src.ui.hbox import HBox class FilesBrowserWidget(Tab): def __init__(self, unique_id: str, title: str, settings: Settings): super(FilesBrowserWidget, self).__init__(unique_id, title) self._settings = settings self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) form = FormGrid(); self.layout.addWidget(form) self._base_dir = QLineEdit(self._initialFolder()) self._base_dir.textChanged.connect(self._base_dir_changed) btn_select_base_dir = QPushButton(QIcon("icons/ionicons/folder-open.svg"), "") btn_select_base_dir.pressed.connect(self._select_base_dir) btn_base_dir_for_current_file = QPushButton(QIcon("icons/myicons/target.svg"), "") btn_base_dir_for_current_file.setToolTip(_("Focus on current file")) btn_base_dir_for_current_file.pressed.connect(self._select_btn_base_dir_for_current_file) form.addRow(QLabel(_("Folder:")), HBox(self._base_dir, btn_select_base_dir, btn_base_dir_for_current_file)) self._filter = QLineEdit(self._settings.get_session("filesBrowser", "filter", fallback="*.log")) self._filter.textChanged.connect(self._filter_changed) form.addRow(QLabel(_("Filter:")), self._filter) self._model = QFileSystemModel() self._model.setRootPath(self._base_dir.text()) self._model.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot | QDir.AllEntries) self._model.setNameFilters(self._get_filters()) self._model.setNameFilterDisables(False) self._view = QTreeView() self._view.setModel(self._model) self._view.setRootIndex(self._model.index(self._base_dir.text())) self._view.hideColumn(2) # hide type column self._view.show() self.layout.addWidget(self._view) self._view.doubleClicked.connect(self._open_file) # icons: /snap/gtk-common-themes/1534/share/icons/ # folder, document, text-css, text-xml, text-x-python # def _open_file(self, index: QModelIndex): file = self._model.filePath(index) if Path(file).is_file(): PluginRegistry.execute_single("open_file", f"{file}") def _select_base_dir(self): dialog = QFileDialog() selected_dir = dialog.getExistingDirectory( caption=_("Open Directory"), dir=self._base_dir.text() ) if selected_dir: self._base_dir.setText(selected_dir) def _select_btn_base_dir_for_current_file(self): dir = self._get_base_dir_for_current_file() self._base_dir.setText(dir) def _filter_changed(self, filter): self._settings.set_session("filesBrowser", "filter", filter) self._model.setNameFilters(self._get_filters()) def _base_dir_changed(self, base_dir): if os.path.isdir(base_dir): self._settings.set_session("filesBrowser", "folder", base_dir) self._model.setRootPath(base_dir) self._view.setRootIndex(self._model.index(base_dir)) def _initialFolder(self) -> str: folder = self._settings.get_session("filesBrowser", "folder", fallback=None) if folder is None or not os.path.isdir(folder): folder = self._get_base_dir_for_current_file() return folder def _get_base_dir_for_current_file(self): current_file = PluginRegistry.execute_single("current_file") folder = os.path.dirname(current_file) if current_file else None if not os.path.isdir(folder): if sys.platform == 'win32' or sys.platform == 'cygwin': folder = "C:\\" else: folder = os.path.join(Path.home()) return folder def _get_filters(self): return re.split(r"[,;\s]+", self._filter.text())