import json from PySide6.QtCore import QByteArray, QMimeData, QModelIndex, Qt, Signal from PySide6.QtGui import QStandardItem, QStandardItemModel from bedit.core.model import Component from bedit.gui.controllers.document import DocumentController from bedit.gui.graphics.icon_renderer import library_icon from bedit.gui.models.library_repository import LibraryRepository COMPONENT_ROLE = Qt.ItemDataRole.UserRole + 1 COMPONENT_ID_ROLE = Qt.ItemDataRole.UserRole + 2 ITEM_KIND_ROLE = Qt.ItemDataRole.UserRole + 3 COMPONENT_INSTANCE_ROLE = Qt.ItemDataRole.UserRole + 4 COMPONENT_MIME_TYPE = "application/x-bedit-component" class LibraryTreeModel(QStandardItemModel): rebuilt = Signal() def __init__( self, repository: LibraryRepository, controller: DocumentController, parent=None, ) -> None: super().__init__(parent) self.repository = repository self.controller = controller repository.librariesChanged.connect(self.rebuild) self.rebuild() def rebuild(self) -> None: self.clear() self.setHorizontalHeaderLabels(["Libraries"]) for library in self.repository.libraries: root = QStandardItem(library.name) root.setDragEnabled(False) root.setToolTip(library.source_path) for component in library.document.roots.values(): root.appendRow(self._component_item(component)) self.appendRow(root) self.rebuilt.emit() def _component_item(self, component: Component, current: bool = False) -> QStandardItem: item = QStandardItem(component.name) item.setEditable(False) item.setIcon(library_icon(component.icon)) item.setData(component.to_dict(), COMPONENT_ROLE) item.setData(component.id, COMPONENT_ID_ROLE) item.setData("current-component" if current else "library-component", ITEM_KIND_ROLE) item.setData(component, COMPONENT_INSTANCE_ROLE) if component.show_subtree_in_library: for child in component.graph.blocks.values(): item.appendRow(self._component_item(child, current=current)) return item def mimeTypes(self) -> list[str]: # noqa: N802 return [COMPONENT_MIME_TYPE] def mimeData(self, indexes: list[QModelIndex]) -> QMimeData: # noqa: N802 mime_data = QMimeData() for index in indexes: component = index.data(COMPONENT_ROLE) if component: encoded = json.dumps(component).encode("utf-8") mime_data.setData(COMPONENT_MIME_TYPE, QByteArray(encoded)) break return mime_data def supportedDragActions(self): # noqa: N802 return Qt.DropAction.CopyAction class DocumentTreeModel(LibraryTreeModel): def __init__(self, controller: DocumentController, parent=None) -> None: QStandardItemModel.__init__(self, parent) self.controller = controller controller.documentReset.connect(self.rebuild) controller.componentMoved.connect(lambda _component_id, _position: self.rebuild()) controller.connectionAdded.connect(lambda _connection_id: self.rebuild()) controller.connectionRemoved.connect(lambda _connection_id: self.rebuild()) self.rebuild() def rebuild(self) -> None: self.clear() self.setHorizontalHeaderLabels(["Document"]) if self.controller.document is not None: current_root = QStandardItem( str(self.controller.document.metadata.get("name") or "Current Document") ) current_root.setDragEnabled(False) current_root.setData("current-document", ITEM_KIND_ROLE) for component in self.controller.document.roots.values(): current_root.appendRow(self._component_item(component, current=True)) self.appendRow(current_root) self.rebuilt.emit()