98 lines
3.9 KiB
Python
98 lines
3.9 KiB
Python
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()
|