changeset 49:2b07ab2c0dc4

Added line saving
author windel
date Wed, 04 Apr 2012 07:30:21 +0200
parents a309982ab4d5
children 38ff8e178fe4
files applications/lab/diagrameditor.py
diffstat 1 files changed, 70 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/applications/lab/diagrameditor.py	Tue Mar 27 18:38:29 2012 +0200
+++ b/applications/lab/diagrameditor.py	Wed Apr 04 07:30:21 2012 +0200
@@ -9,23 +9,22 @@
   This script implements a basic diagram editor.
 """
 
-class Connection:
+class Connection(QGraphicsPathItem):
    """
     - fromPort
     - list of line items in between
     - toPort
    """
    def __init__(self, fromPort, toPort):
+      super(Connection, self).__init__()
       self.pos1 = None
       self.pos2 = None
-      self.pathItem = QGraphicsPathItem()
       pen = QPen()
-      pen.setWidth(4)
+      pen.setWidth(2)
       pen.setColor(Qt.blue)
       pen.setCapStyle(Qt.RoundCap)
-      self.pathItem.setPen(pen)
-      #self.pathItem.setFlags(self.pathItem.ItemIsSelectable)
-      editor.diagramScene.addItem(self.pathItem)
+      self.setPen(pen)
+      editor.diagramScene.addItem(self)
       self.setFromPort(fromPort)
       self.setToPort(toPort)
    def setFromPort(self, fromPort):
@@ -65,8 +64,8 @@
       def stripHits(hits):
          """ Helper function that removes object hits """
          hits = [hit for hit in hits if type(hit) is BlockItem]
-         if self.pathItem in hits:
-            hits.remove(self.pathItem)
+         if self in hits:
+            hits.remove(self)
          if self.fromPort in hits:
             hits.remove(self.fromPort)
          if self.toPort in hits:
@@ -112,20 +111,25 @@
       hits = stripHits(ds.items(path))
 
       #print('Items:', hits) 
-      self.pathItem.setPath(path)
+      self.setPath(path)
 
    def delete(self):
-      editor.diagramScene.removeItem(self.pathItem)
+      editor.diagramScene.removeItem(self)
       # Remove position update callbacks:
 
 class ParameterDialog(QDialog):
-   def __init__(self, parent = None):
+   def __init__(self, block, parent = None):
       super(ParameterDialog, self).__init__(parent)
+      self.block = block
       self.button = QPushButton('Ok', self)
-      l = QVBoxLayout(self)
-      l.addWidget(self.button)
+      l = QGridLayout(self)
+      l.addWidget(QLabel('Name:', self), 0, 0)
+      self.nameEdit = QLineEdit(self.block.label.toPlainText())
+      l.addWidget(self.nameEdit, 0, 1)
+      l.addWidget(self.button, 1, 0)
       self.button.clicked.connect(self.OK)
    def OK(self):
+      self.block.label.setPlainText(self.nameEdit.text())
       self.close()
 
 class PortItem(QGraphicsEllipseItem):
@@ -203,20 +207,22 @@
 
       # Inputs and outputs of the block:
       self.inputs = []
-      self.inputs.append( PortItem('a', self) )
-      self.inputs.append( PortItem('b', self) )
-      self.inputs.append( PortItem('c', self) )
+      #self.inputs.append( PortItem('a', self) )
+      #self.inputs.append( PortItem('b', self) )
+      #self.inputs.append( PortItem('c', self) )
       self.outputs = []
-      self.outputs.append( PortItem('y', self) )
+      #self.outputs.append( PortItem('y', self) )
       # Update size:
       self.changeSize(w, h)
    def editParameters(self):
-      pd = ParameterDialog(self.window())
+      pd = ParameterDialog(self, self.window())
       pd.exec_()
    def addInput(self, i):
       self.inputs.append(i)
+      self.updateSize()
    def addOutput(self, o):
       self.outputs.append(o)
+      self.updateSize()
 
    def contextMenuEvent(self, event):
       menu = QMenu()
@@ -230,21 +236,9 @@
       editor.diagramScene.removeItem(self)
       # TODO: remove connections
 
-   def changeSize(self, w, h):
-      """ Resize block function """
-      # Limit the block size:
-      if h < 20:
-         h = 20
-      if w < 40:
-         w = 40
-      self.setRect(0.0, 0.0, w, h)
-      # center label:
-      rect = self.label.boundingRect()
-      lw, lh = rect.width(), rect.height()
-      lx = (w - lw) / 2
-      ly = (h - lh) / 2
-      self.label.setPos(lx, ly)
-      # Update port positions:
+   def updateSize(self):
+      rect = self.rect()
+      h, w = rect.height(), rect.width()
       if len(self.inputs) == 1:
          self.inputs[0].setPos(-4, h / 2)
       elif len(self.inputs) > 1:
@@ -261,6 +255,23 @@
          for outp in self.outputs:
             outp.setPos(w+4, y)
             y += dy
+      
+   def changeSize(self, w, h):
+      """ Resize block function """
+      # Limit the block size:
+      if h < 20:
+         h = 20
+      if w < 40:
+         w = 40
+      self.setRect(0.0, 0.0, w, h)
+      # center label:
+      rect = self.label.boundingRect()
+      lw, lh = rect.width(), rect.height()
+      lx = (w - lw) / 2
+      ly = (h - lh) / 2
+      self.label.setPos(lx, ly)
+      # Update port positions:
+      self.updateSize()
       return w, h
 
 class EditorGraphicsView(QGraphicsView):
@@ -276,9 +287,7 @@
       if event.mimeData().hasFormat('component/name'):
          name = bytes(event.mimeData().data('component/name')).decode()
          b1 = BlockItem(name)
-         print(event.pos())
          b1.setPos(self.mapToScene(event.pos()))
-         print(self.mapToScene(event.pos()))
          self.scene().addItem(b1)
 
 class LibraryModel(QStandardItemModel):
@@ -361,6 +370,7 @@
    def saveDiagram(self, filename):
       items = self.diagramScene.items()
       blocks = [item for item in items if type(item) is BlockItem]
+      connections = [item for item in items if type(item) is Connection]
 
       doc = md.Document()
       modelElement = doc.createElement('system')
@@ -371,10 +381,10 @@
          rect = block.rect()
          w, h = rect.width(), rect.height()
          blockElement.setAttribute("name", block.label.toPlainText())
-         blockElement.setAttribute("x", str(x))
-         blockElement.setAttribute("y", str(y))
-         blockElement.setAttribute("width", str(w))
-         blockElement.setAttribute("height", str(h))
+         blockElement.setAttribute("x", str(int(x)))
+         blockElement.setAttribute("y", str(int(y)))
+         blockElement.setAttribute("width", str(int(w)))
+         blockElement.setAttribute("height", str(int(h)))
          for inp in block.inputs:
             portElement = doc.createElement("input")
             portElement.setAttribute("name", inp.name)
@@ -384,6 +394,18 @@
             portElement.setAttribute("name", outp.name)
             blockElement.appendChild(portElement)
          modelElement.appendChild(blockElement)
+      for connection in connections:
+         print(connection)
+         connectionElement = doc.createElement("connection")
+         fromPort = connection.fromPort.name
+         toPort = connection.toPort.name
+         fromBlock = ""
+         toBlock = ""
+         connectionElement.setAttribute("fromBlock", fromBlock)
+         connectionElement.setAttribute("fromPort", fromPort)
+         connectionElement.setAttribute("toBlock", toBlock)
+         connectionElement.setAttribute("toPort", toPort)
+         modelElement.appendChild(connectionElement)
       with open(filename, 'w') as f:
          f.write(doc.toprettyxml())
          
@@ -408,9 +430,16 @@
             block.setPos(x, y)
             block.sizer.setPos(w, h)
             # Load ports:
-            portElements = blockElement.getElementsByTagName('port')
+            portElements = blockElement.getElementsByTagName('input')
             for portElement in portElements:
-               print(portElement)
+               name = portElement.getAttribute('name')
+               inp = PortItem(name, block)
+               block.addInput(inp)
+            portElements = blockElement.getElementsByTagName('output')
+            for portElement in portElements:
+               name = portElement.getAttribute('name')
+               outp = PortItem(name, block)
+               block.addOutput(outp)
          connectionElements = sysElement.getElementsByTagName('connection')
          for connectionElement in connectionElements:
             print(connectionElement)
@@ -423,7 +452,6 @@
    def zoomAll(self):
       """ zoom to fit all items """
       rect = self.diagramScene.itemsBoundingRect()
-      print(rect)
       self.diagramView.fitInView(rect, Qt.KeepAspectRatio)
    def sceneMouseMoveEvent(self, event):
       if self.startedConnection: