56 lines
2.0 KiB
Python
56 lines
2.0 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
from collections.abc import Callable
|
|
|
|
from PySide6.QtCore import QMimeData, QModelIndex, Qt
|
|
|
|
from bedit_core.models import Component
|
|
from bedit_gui.services.component_clipboard import COMPONENTS_MIME
|
|
from bedit_gui.views.models.document_tree_model import DocumentTreeModel
|
|
|
|
PayloadFactory = Callable[[list[Component]], dict]
|
|
|
|
|
|
class LibraryTreeModel(DocumentTreeModel):
|
|
def __init__(self, payload_factory: PayloadFactory) -> None:
|
|
super().__init__(editable=False)
|
|
self._payload_factory = payload_factory
|
|
|
|
def flags(self, index: QModelIndex) -> Qt.ItemFlag:
|
|
flags = super().flags(index)
|
|
if isinstance(self.value(index), Component):
|
|
flags |= Qt.ItemFlag.ItemIsDragEnabled
|
|
return flags
|
|
|
|
def mimeTypes(self) -> list[str]:
|
|
return [COMPONENTS_MIME]
|
|
|
|
def mimeData(self, indexes: list[QModelIndex]) -> QMimeData:
|
|
rows = [index for index in indexes if index.column() == 0 and isinstance(self.value(index), Component)]
|
|
selected = {id(self.value(index)) for index in rows}
|
|
components = []
|
|
added = set()
|
|
for index in rows:
|
|
parent = index.parent()
|
|
if any(id(self.value(parent_index)) in selected for parent_index in self._parents(parent)):
|
|
continue
|
|
component = self.value(index)
|
|
if isinstance(component, Component) and id(component) not in added:
|
|
components.append(component)
|
|
added.add(id(component))
|
|
mime = QMimeData()
|
|
if components:
|
|
mime.setData(COMPONENTS_MIME, json.dumps(self._payload_factory(components)).encode("utf-8"))
|
|
mime.setText("\n".join(component.name for component in components))
|
|
return mime
|
|
|
|
def supportedDragActions(self) -> Qt.DropAction:
|
|
return Qt.DropAction.CopyAction
|
|
|
|
@staticmethod
|
|
def _parents(index: QModelIndex):
|
|
while index.isValid():
|
|
yield index
|
|
index = index.parent()
|