diff applications/lab/diagrameditor.py @ 60:b976546f5a60

Fixed code saving in XML
author windel
date Mon, 30 Apr 2012 17:40:04 +0200
parents f6ea630c4057
children 6fa41208a3a8
line wrap: on
line diff
--- a/applications/lab/diagrameditor.py	Tue Apr 24 08:01:55 2012 +0200
+++ b/applications/lab/diagrameditor.py	Mon Apr 30 17:40:04 2012 +0200
@@ -4,6 +4,7 @@
 from PyQt4.QtCore import *
 import sys
 import xml.dom.minidom as md
+import xml
 
 """
  Author: Windel Bouwman
@@ -45,24 +46,28 @@
       self.setToPort(toPort)
    def mouseDoubleClickEvent(self, event):
       pos = event.scenePos()
-      if len(self.vias) == 0:
-         tidx = 0
+      pts = [self.pos1] + [v.pos() for v in self.vias] + [self.pos2]
+      idx = 0
+      tidx = 0
+      for p1, p2 in zip(pts[0:-1], pts[1:]):
+         l1 = QLineF(p1, p2)
+         l2 = QLineF(p1, pos)
+         l3 = QLineF(pos, p2)
+         d = l2.length() + l3.length() - l1.length()
+         if d < 5:
+            tidx = idx
+         idx += 1
+      self.addHandle(pos, tidx)
+      
+   def addHandle(self, pos, idx=None):
+      hi = HandleItem(self)
+      if idx:
+         self.vias.insert(idx, hi)
       else:
-         pts = [self.pos1] + [v.pos() for v in self.vias] + [self.pos2]
-         idx = 0
-         tidx = 0
-         for p1, p2 in zip(pts[0:-1], pts[1:]):
-            l1 = QLineF(p1, p2)
-            l2 = QLineF(p1, pos)
-            l3 = QLineF(pos, p2)
-            d = l1.length() - l2.length() - l3.length()
-            if d > -3:
-               tidx = idx
-            idx += 1
-      hi = HandleItem(self)
-      self.vias.insert(tidx, hi)
-      def callback(pos):
+         self.vias.append(hi)
+      def callback(p):
          self.updateLineStukken()
+         return p
       hi.posChangeCallbacks.append(callback)
       hi.setPos(pos)
       self.updateLineStukken()
@@ -96,7 +101,8 @@
       self.updateLineStukken()
    def itemChange(self, change, value):
       if change == self.ItemSelectedHasChanged:
-         pass # TODO, do something useful here.
+         for via in self.vias:
+            via.setVisible(value)
       return super(Connection, self).itemChange(change, value)
    def shape(self):
       return self.myshape
@@ -132,10 +138,15 @@
       l.addWidget(QLabel('Name:', self), 0, 0)
       self.nameEdit = QLineEdit(self.block.name)
       l.addWidget(self.nameEdit, 0, 1)
-      l.addWidget(self.button, 1, 0)
+      l.addWidget(QLabel('Code:', self), 1, 0)
+      self.codeEdit = QTextEdit(self)
+      self.codeEdit.setPlainText(self.block.code)
+      l.addWidget(self.codeEdit, 1, 1)
+      l.addWidget(self.button, 2, 0, 1, 2)
       self.button.clicked.connect(self.OK)
    def OK(self):
       self.block.setName(self.nameEdit.text())
+      self.block.code = self.codeEdit.toPlainText()
       self.close()
 
 class PortItem(QGraphicsPathItem):
@@ -165,11 +176,6 @@
       self.setName(name)
       self.posCallbacks = []
       self.setFlag(self.ItemSendsScenePositionChanges, True)
-   def boundingRect(self):
-      rect = super(PortItem, self).boundingRect()
-      dx = 8
-      rect.adjust(-dx, -dx, dx, dx)
-      return rect
    def setName(self, name):
       self.name = name
       self.textItem.setPlainText(name)
@@ -179,7 +185,7 @@
          lx = 3
       else:
          lx = -3 - lw
-      self.textItem.setPos(lx, -lh / 2) # TODO
+      self.textItem.setPos(lx, -lh / 2)
    def itemChange(self, change, value):
       if change == self.ItemScenePositionHasChanged:
          for cb in self.posCallbacks:
@@ -198,18 +204,20 @@
 class HandleItem(QGraphicsEllipseItem):
    """ A handle that can be moved by the mouse """
    def __init__(self, parent=None):
-      dx = 9.0
+      dx = 13.0
       super(HandleItem, self).__init__(QRectF(-0.5*dx,-0.5*dx,dx,dx), parent)
       self.posChangeCallbacks = []
       self.setBrush(QBrush(Qt.white))
       self.setFlag(self.ItemSendsScenePositionChanges, True)
       self.setFlag(self.ItemIsMovable, True)
+      self.setVisible(False)
       self.setCursor(QCursor(Qt.SizeFDiagCursor))
    def mouseMoveEvent(self, event):
       """ Move function without moving the other selected elements """
       p = self.mapToParent(event.pos())
       self.setPos(p)
    def mySetPos(self, p):
+      # TODO: use this instead of itemChange?
       self.setPos(p)
    def itemChange(self, change, value):
       if change == self.ItemPositionChange:
@@ -245,13 +253,14 @@
       self.setPen(QPen(Qt.blue, 2))
       self.setBrush(QBrush(Qt.lightGray))
       self.setFlags(self.ItemIsSelectable | self.ItemIsMovable)
+      self.setFlag(self.ItemSendsScenePositionChanges, True)
       self.setCursor(QCursor(Qt.PointingHandCursor))
       self.label = QGraphicsTextItem(name, self)
       self.name = name
+      self.code = ''
       # Create corner for resize:
       self.sizer = HandleItem(self)
       self.sizer.posChangeCallbacks.append(self.changeSize) # Connect the callback
-      self.sizer.setVisible(False)
       button = QPushButton('+in')
       button.clicked.connect(self.newInputPort)
       self.buttonItemAddInput = QGraphicsProxyWidget(self)
@@ -267,8 +276,7 @@
       self.inputs = []
       self.outputs = []
       # Update size:
-      self.sizer.setPos(60, 40) # This is a better resize function
-      #self.changeSize(60, 40) # TODO: create a wrapper function
+      self.sizer.mySetPos(QPointF(60, 40)) # This is a better resize function
    def editParameters(self):
       pd = ParameterDialog(self, self.window())
       pd.exec_()
@@ -403,6 +411,10 @@
          blockElement.setAttribute("y", str(int(y)))
          blockElement.setAttribute("width", str(int(w)))
          blockElement.setAttribute("height", str(int(h)))
+         codeNode = doc.createCDATASection(block.code)
+         codeElement = doc.createElement('code')
+         codeElement.appendChild(codeNode)
+         blockElement.appendChild(codeElement)
          for inp in block.inputs:
             portElement = doc.createElement("input")
             portElement.setAttribute("name", inp.name)
@@ -422,6 +434,11 @@
          connectionElement.setAttribute("fromPort", fromPort)
          connectionElement.setAttribute("toBlock", toBlock)
          connectionElement.setAttribute("toPort", toPort)
+         for via in connection.vias:
+            viaElement = doc.createElement('via')
+            viaElement.setAttribute('x', str(int(via.x())))
+            viaElement.setAttribute('y', str(int(via.y())))
+            connectionElement.appendChild(viaElement)
          modelElement.appendChild(connectionElement)
       with open(filename, 'w') as f:
          f.write(doc.toprettyxml())
@@ -432,6 +449,9 @@
       except IOError as e:
          print('{0} not found'.format(filename))
          return
+      except xml.parsers.expat.ExpatError as e:
+         print('{0}'.format(e))
+         return
       sysElements = doc.getElementsByTagName('system')
       blockElements = doc.getElementsByTagName('block')
       for sysElement in sysElements:
@@ -446,6 +466,12 @@
             self.addItem(block)
             block.setPos(x, y)
             block.sizer.setPos(w, h)
+            codeElements = blockElement.getElementsByTagName('code')
+            if codeElements:
+               cn = codeElements[0].childNodes
+               cdatas = [cd for cd in cn if type(cd) is md.CDATASection]
+               if len(cdatas) > 0:
+                  block.code = cdatas[0].data
             # Load ports:
             portElements = blockElement.getElementsByTagName('input')
             for portElement in portElements:
@@ -463,9 +489,14 @@
             fromPort = connectionElement.getAttribute('fromPort')
             toBlock = connectionElement.getAttribute('toBlock')
             toPort = connectionElement.getAttribute('toPort')
+            viaElements = connectionElement.getElementsByTagName('via')
             fromPort = self.findPort(fromBlock, fromPort)
             toPort = self.findPort(toBlock, toPort)
             connection = Connection(fromPort, toPort)
+            for viaElement in viaElements:
+               x = int(viaElement.getAttribute('x'))
+               y = int(viaElement.getAttribute('y'))
+               connection.addHandle(QPointF(x, y))
             self.addItem(connection)
    def findPort(self, blockname, portname):
       items = self.items()
@@ -534,8 +565,6 @@
       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()
@@ -586,7 +615,6 @@
       sys.exit(1)
 
    app = QApplication(sys.argv)
-   global editor
    editor = DiagramEditor()
    editor.loadDiagram('diagram2.usd')
    editor.show()