# HG changeset patch # User windel # Date 1334246613 -7200 # Node ID d8163d2c3779a34eec9bca035b794731b3a7d583 # Parent 6dd7d6a1737cd2159f288f033859b6534635f903 Rework of delete function. diff -r 6dd7d6a1737c -r d8163d2c3779 applications/lab/diagrameditor.py --- a/applications/lab/diagrameditor.py Sun Apr 08 11:28:46 2012 +0200 +++ b/applications/lab/diagrameditor.py Thu Apr 12 18:03:33 2012 +0200 @@ -40,16 +40,20 @@ def setFromPort(self, fromPort): if self.fromPort: self.fromPort.posCallbacks.remove(self.setBeginPos) + self.fromPort.connection = None self.fromPort = fromPort if self.fromPort: + self.fromPort.connection = self self.setBeginPos(fromPort.scenePos()) self.fromPort.posCallbacks.append(self.setBeginPos) def setToPort(self, toPort): if self.toPort: self.toPort.posCallbacks.remove(self.setEndPos) + self.toPort.connection = None self.toPort = toPort if self.toPort: self.setEndPos(toPort.scenePos()) + self.toPort.connection = self self.toPort.posCallbacks.append(self.setEndPos) def releasePorts(self): self.setFromPort(None) @@ -131,10 +135,6 @@ hits = stripHits(ds.items(path)) self.setPath(path) - def delete(self): - editor.diagramScene.removeItem(self) - # Remove position update callbacks: - class ParameterDialog(QDialog): def __init__(self, block, parent = None): super(ParameterDialog, self).__init__(parent) @@ -173,6 +173,7 @@ def __init__(self, name, block, direction): super(PortItem, self).__init__(block) #QRectF(-6,-6,12.0,12.0) + self.connection = None path = QPainterPath() if direction == 'input': d = 5.0 @@ -212,7 +213,8 @@ return value return super(PortItem, self).itemChange(change, value) def mousePressEvent(self, event): - editor.startConnection(self) + if self.direction == 'output': + editor.startConnection(self) class OutputPort(PortItem): # TODO: create a subclass OR make a member porttype @@ -225,15 +227,14 @@ super(HandleItem, self).__init__(QRectF(-4.0,-4.0,8.0,8.0), parent) self.posChangeCallbacks = [] self.setBrush(QBrush(Qt.white)) - self.setFlags(self.ItemIsMovable | self.ItemSendsScenePositionChanges) + self.setFlag(self.ItemSendsScenePositionChanges, True) + self.setFlag(self.ItemIsMovable, True) + #self.setFlag(self.ItemIsSelectable, False) self.setCursor(QCursor(Qt.SizeFDiagCursor)) def itemChange(self, change, value): if change == self.ItemPositionChange: - #value = value.toPointF() x, y = value.x(), value.y() - # TODO: make this a signal? - # This cannot be a signal because this is not a QObject for cb in self.posChangeCallbacks: res = cb(x, y) if res: @@ -259,6 +260,7 @@ self.setPen(QPen(Qt.blue, 2)) self.setBrush(QBrush(Qt.lightGray)) self.setFlags(self.ItemIsSelectable | self.ItemIsMovable) + self.setBoundingRegionGranularity(1) self.setCursor(QCursor(Qt.PointingHandCursor)) self.label = QGraphicsTextItem(name, self) self.name = name @@ -266,13 +268,13 @@ self.sizer = HandleItem(self) self.sizer.posChangeCallbacks.append(self.changeSize) # Connect the callback #self.sizer.setVisible(False) - self.sizer.setFlag(self.sizer.ItemIsSelectable, True) # Inputs and outputs of the block: self.inputs = [] self.outputs = [] # Update size: - self.changeSize(60, 40) + self.sizer.setPos(60, 40) # This is a better resize function + #self.changeSize(60, 40) # TODO: create a wrapper function def editParameters(self): pd = ParameterDialog(self, self.window()) pd.exec_() @@ -291,18 +293,12 @@ def contextMenuEvent(self, event): menu = QMenu() - da = menu.addAction('Delete') - da.triggered.connect(self.delete) pa = menu.addAction('Parameters') pa.triggered.connect(self.editParameters) pa = menu.addAction('Add port') pa.triggered.connect(self.addPort) menu.exec_(event.screenPos()) - def delete(self): - editor.diagramScene.removeItem(self) - # TODO: remove connections - def updateSize(self): rect = self.rect() h, w = rect.height(), rect.width() @@ -344,6 +340,7 @@ class EditorGraphicsView(QGraphicsView): def __init__(self, scene, parent=None): QGraphicsView.__init__(self, scene, parent) + self.setDragMode(QGraphicsView.RubberBandDrag) def dragEnterEvent(self, event): if event.mimeData().hasFormat('component/name'): event.accept() @@ -371,72 +368,11 @@ return mimedata class DiagramScene(QGraphicsScene): + """ Save and load and deletion of item""" def __init__(self, parent=None): super(DiagramScene, self).__init__(parent) - def mouseMoveEvent(self, mouseEvent): - editor.sceneMouseMoveEvent(mouseEvent) - super(DiagramScene, self).mouseMoveEvent(mouseEvent) - def mouseReleaseEvent(self, mouseEvent): - editor.sceneMouseReleaseEvent(mouseEvent) - super(DiagramScene, self).mouseReleaseEvent(mouseEvent) - -class DiagramEditor(QWidget): - def __init__(self, parent=None): - QWidget.__init__(self, parent) - self.setWindowTitle("Diagram editor") - - # Widget layout and child widgets: - self.horizontalLayout = QHBoxLayout(self) - self.libraryBrowserView = QListView(self) - self.libraryBrowserView.setMaximumWidth(160) - self.libraryModel = LibraryModel(self) - self.libraryModel.setColumnCount(1) - # Create an icon with an icon: - pixmap = QPixmap(60, 60) - pixmap.fill() - painter = QPainter(pixmap) - painter.fillRect(10, 10, 40, 40, Qt.blue) - painter.setBrush(Qt.red) - painter.drawEllipse(36, 2, 20, 20) - painter.setBrush(Qt.yellow) - painter.drawEllipse(20, 20, 20, 20) - painter.end() - - # Fill library: - self.libItems = [] - self.libItems.append( QStandardItem(QIcon(pixmap), 'Block') ) - self.libItems.append( QStandardItem(QIcon(pixmap), 'Uber Unit') ) - self.libItems.append( QStandardItem(QIcon(pixmap), 'Device') ) - for i in self.libItems: - self.libraryModel.appendRow(i) - self.libraryBrowserView.setModel(self.libraryModel) - self.libraryBrowserView.setViewMode(self.libraryBrowserView.IconMode) - self.libraryBrowserView.setDragDropMode(self.libraryBrowserView.DragOnly) - - self.diagramScene = DiagramScene(self) - self.diagramView = EditorGraphicsView(self.diagramScene, self) - self.horizontalLayout.addWidget(self.libraryBrowserView) - self.horizontalLayout.addWidget(self.diagramView) - - self.startedConnection = None - fullScreenShortcut = QShortcut(QKeySequence("F11"), self) - fullScreenShortcut.activated.connect(self.toggleFullScreen) - saveShortcut = QShortcut(QKeySequence(QKeySequence.Save), self) - saveShortcut.activated.connect(self.save) - testShortcut = QShortcut(QKeySequence("F12"), self) - testShortcut.activated.connect(self.test) - zoomShortcut = QShortcut(QKeySequence("F8"), self) - zoomShortcut.activated.connect(self.zoomAll) - delShort = QShortcut(QKeySequence.Delete, self) - delShort.activated.connect(self.deleteItem) - - def test(self): - self.diagramView.rotate(11) - def save(self): - self.saveDiagram('diagram2.usd') - def saveDiagram(self, filename): - items = self.diagramScene.items() + items = self.items() blocks = [item for item in items if type(item) is BlockItem] connections = [item for item in items if type(item) is Connection] @@ -493,7 +429,7 @@ h = float(blockElement.getAttribute('height')) name = blockElement.getAttribute('name') block = BlockItem(name) - self.diagramScene.addItem(block) + self.addItem(block) block.setPos(x, y) block.sizer.setPos(w, h) # Load ports: @@ -516,18 +452,94 @@ fromPort = self.findPort(fromBlock, fromPort) toPort = self.findPort(toBlock, toPort) connection = Connection(fromPort, toPort) - self.diagramScene.addItem(connection) - - self.zoomAll() - + self.addItem(connection) def findPort(self, blockname, portname): - items = self.diagramScene.items() + items = self.items() blocks = [item for item in items if type(item) is BlockItem] for block in [b for b in blocks if b.name == blockname]: for port in block.inputs + block.outputs: if port.name == portname: return port + def mouseMoveEvent(self, mouseEvent): + editor.sceneMouseMoveEvent(mouseEvent) + super(DiagramScene, self).mouseMoveEvent(mouseEvent) + def mouseReleaseEvent(self, mouseEvent): + editor.sceneMouseReleaseEvent(mouseEvent) + super(DiagramScene, self).mouseReleaseEvent(mouseEvent) + def deleteItem(self, item=None): + if item: + if type(item) is BlockItem: + for p in item.inputs + item.outputs: + if p.connection: + self.deleteItem(p.connection) + self.removeItem(item) + elif type(item) is Connection: + item.releasePorts() + self.removeItem(item) + else: + # No item was supplied, try to delete all currently selected items: + items = self.selectedItems() + connections = [item for item in items if type(item) is Connection] + blocks = [item for item in items if type(item) is BlockItem] + for item in connections + blocks: + self.deleteItem(item) +class DiagramEditor(QWidget): + def __init__(self, parent=None): + QWidget.__init__(self, parent) + self.setWindowTitle("Diagram editor") + + # Widget layout and child widgets: + self.horizontalLayout = QHBoxLayout(self) + self.libraryBrowserView = QListView(self) + self.libraryBrowserView.setMaximumWidth(160) + self.libraryModel = LibraryModel(self) + self.libraryModel.setColumnCount(1) + # Create an icon with an icon: + pixmap = QPixmap(60, 60) + pixmap.fill() + painter = QPainter(pixmap) + painter.fillRect(10, 10, 40, 40, Qt.blue) + painter.setBrush(Qt.red) + painter.drawEllipse(36, 2, 20, 20) + painter.setBrush(Qt.yellow) + painter.drawEllipse(20, 20, 20, 20) + painter.end() + + # Fill library: + self.libItems = [] + self.libItems.append( QStandardItem(QIcon(pixmap), 'Block') ) + self.libItems.append( QStandardItem(QIcon(pixmap), 'Uber Unit') ) + self.libItems.append( QStandardItem(QIcon(pixmap), 'Device') ) + for i in self.libItems: + self.libraryModel.appendRow(i) + self.libraryBrowserView.setModel(self.libraryModel) + self.libraryBrowserView.setViewMode(self.libraryBrowserView.IconMode) + self.libraryBrowserView.setDragDropMode(self.libraryBrowserView.DragOnly) + + self.diagramScene = DiagramScene(self) + self.loadDiagram = self.diagramScene.loadDiagram + self.diagramView = EditorGraphicsView(self.diagramScene, self) + self.horizontalLayout.addWidget(self.libraryBrowserView) + self.horizontalLayout.addWidget(self.diagramView) + + self.startedConnection = None + fullScreenShortcut = QShortcut(QKeySequence("F11"), self) + fullScreenShortcut.activated.connect(self.toggleFullScreen) + saveShortcut = QShortcut(QKeySequence(QKeySequence.Save), self) + saveShortcut.activated.connect(self.save) + testShortcut = QShortcut(QKeySequence("F12"), self) + testShortcut.activated.connect(self.test) + zoomShortcut = QShortcut(QKeySequence("F8"), self) + zoomShortcut.activated.connect(self.zoomAll) + delShort = QShortcut(QKeySequence.Delete, self) + delShort.activated.connect(self.diagramScene.deleteItem) + + def test(self): + self.diagramView.rotate(30) + self.zoomAll() + def save(self): + self.diagramScene.saveDiagram('diagram2.usd') def toggleFullScreen(self): self.setWindowState(self.windowState() ^ Qt.WindowFullScreen) def startConnection(self, port): @@ -537,15 +549,6 @@ """ zoom to fit all items """ rect = self.diagramScene.itemsBoundingRect() self.diagramView.fitInView(rect, Qt.KeepAspectRatio) - def deleteItem(self): - items = self.diagramScene.selectedItems() - for item in items: - if type(item) is Connection: - item.releasePorts() - item.delete() - if type(item) is Block: - pass - def sceneMouseMoveEvent(self, event): if self.startedConnection: pos = event.scenePos() @@ -559,7 +562,7 @@ self.startedConnection.setToPort(item) self.startedConnection = None return - self.startedConnection.delete() + self.diagramScene.deleteItem(self.startedConnection) del self.startedConnection self.startedConnection = None