changeset 54:d8163d2c3779

Rework of delete function.
author windel
date Thu, 12 Apr 2012 18:03:33 +0200
parents 6dd7d6a1737c
children 9414bad225a8
files applications/lab/diagrameditor.py
diffstat 1 files changed, 99 insertions(+), 96 deletions(-) [+]
line wrap: on
line diff
--- 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