Mercurial > lcfOS
comparison python/apps/diagrameditor.py @ 91:7ad4c66dd092
Fixed save function
author | windel |
---|---|
date | Mon, 10 Dec 2012 18:55:40 +0100 |
parents | 4b1892054744 |
children | 0c4bdbf0aead |
comparison
equal
deleted
inserted
replaced
90:499183b99c71 | 91:7ad4c66dd092 |
---|---|
3 from PyQt4.QtGui import * | 3 from PyQt4.QtGui import * |
4 from PyQt4.QtCore import * | 4 from PyQt4.QtCore import * |
5 import sys, json, base64 | 5 import sys, json, base64 |
6 | 6 |
7 from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene | 7 from diagramitems import Connection, ResizeSelectionHandle, Block, DiagramScene |
8 from icons import newicon, saveicon, loadicon | |
8 | 9 |
9 """ | 10 """ |
10 Author: Windel Bouwman | 11 Author: Windel Bouwman |
11 Year: 2012 | 12 Year: 2012 |
12 Description: This script implements a diagram editor. | 13 Description: This script implements a diagram editor. |
13 run with python 3.x as: | 14 run with python 3.x as: |
14 $ python [thisfile.py] | 15 $ python [thisfile.py] |
15 """ | 16 """ |
16 saveicon = b'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\nveAfetNmUUsM6bsAAAAASUVORK5CYII=\n' | |
17 | |
18 loadicon = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACsElEQVR42u2Xf0hTURTHv++ZczlD\n6SeUREVRiRT9gFWM1rbAwr+iYAathPqjMosIQQqJQAhLLDI0CMwflRa1vyQst0oNLKxhCGWR9UfB\nwFCRaqC2vc6d7+1tr/7YnuwW5IEv95y79875vHvP7t4E/GUTpgGmAaL8vaRzpDlx3iuRXpEOkz5N\nFWDhrHR8bL+LtGXLKUqRJcoKyeUk1Q8Fges3gLIKeGlm+1QBHA4rPJ7WxG4eHqLlWoJRcvfJaPHY\nV1LPbwB5Dnja7if+BFUVQEdX7OqETdL48vD+C/DODze5e9iUCmAjgDt6FzJ+m/gG5GyD9OEz1lPY\nqwLQFrQ1JR+Amc0JPO0O941XBbAQQB0nABcBvNACbCGAWk4ABwngpRbATACXEksU7rsJGlnzUSZB\nkEdAbW9lXgnJtx0jAJ8WYCMBnE8MIESFx7+rRQRRLiaPESANmL2EAF6jgaLSCIA9Bx53sZokJpEY\nm4zFzP85BgTn0mUZUL9y7CPpz8CCvAJdA0DrE6D6NnxsLp9UaV2KVfW7Jy8QWcGUyUJhP0piFJA0\nmw6iAn19EAgAmdkICpRw5EEdsjabgXQDYo9gRZENVxVeIJO8Gjqs7y2wxoJ+IXUGxkcHkDrTqC+R\nXrt5D3AVoYU9yJs+L1bnruQLUFJO+34NpxlAc2MVCly7+ALkHQAedSKfAZwq3o/KK2X8ikvUT4ss\nkPyDWMwAtm5ai47uZn4Ag8PAAgvoxxzzGUCGMQ1DI89gMBr4ADymtwHHIXSSa1UOIt/zBqwz5/IB\nqG4Bjl9EDblFCkDN5ZM4csLJB+DoBaDWDTp3cVUBcDntaLx1hg/AzlKgvQc7yH2oAGSbjOg/WwjT\nvMzkFvdT65U34UdgDCtYGP1avoFUSMpK8gKw7q8n9bLgn/pj8n8C/ALihrxpNKi7hQAAAABJRU5E\nrkJggg==\n' | |
19 | |
20 newicon = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADSUlEQVR42r2XO0xaURjHLzYmdXRi\nYXBwdDScJl3djQNLw0TSAR88FR9JU6P4QKMCaTqQdGgXsQQMQXFwcGXhCCG+4iNEo6mDMZL45kK/\n76THUO+9Qi/efskJcm4O3+/+v8f51Al/LBaLmTs6Or43gAkq7eHhoXh2dmZva2v7WusZHf9jZGTE\nPz4+blfjuFwuC6IoCsViUbi8vCwDhM1oNH75V4AAANjUAJRKJeYc183NjXB1dVU+Pj7+CIp+qxlg\neHg44PV6VQHg2z8+PjKAu7s7oampSQAVxL29PUtnZ+eP/waA6/r6WtDr9UyJ09NTcXd319LV1aUI\n8QQwNDQUmJiYqBsA5BcMBgPLC4Q4OTkRt7e3LSaTSRbiCWBwcDAwOTmpOgfQOVSBcHFxIbS0tLB9\nDgH5IGYyGYvZbJZAvAoAOsL4IwTEngGxH9fp2MJnhUJBTKfT5t7e3rAsgMfjYQB4oB4V+OJAuI+A\naGtra6nz8/P3o6OjJQnAwMBAYGpqSjUAh8Aw8JLE3OBqIMTGxgbNZrPE5/MVFQFUe6+A4M5xoWMe\nIg4ASksB+vv761aAG3eKMFwBBFhfX6ebm5sEyl0eAHOgjqvgRSBUA3KAghHouFIAt9vNFNACgIci\nmUxSKEcyNjYmBXC5XK8Wgudvz8OAAJgDigD1lGE155UAsiFwOp2vUgVKzisBZJMQAdR2wlqco62s\nrNBcLkfgzpECOByOuhXg5cc733NLJBIMQLYP2O12BqB0uJrjyk8li8fjdGtri4AfeQAMAUpXayJW\ne2MlANlWbLPZGAB2LPagCoQapZaXl+nOzg6ZmZmRB8CBhANoYTB5U5iQyOzsrDwAjmR4hWpl0WiU\nwpxI5ubmpAAwKLAQ4HWqlUUiEbq/v0/m5+flATAEWiqwtLREDw4OyMLCgjyA1iEIh8P08PCQ+P1+\nKUBPTw8D0DIEi4uL9OjoiASDQSlAd3c3A7i/v9cUAKsgFApJAaxWa2B6etp2e3v71yGlen++X60v\n4EwAAOlUKvUO+oEUoLW19UNfX9/nxsbGhsoOxy+Wl75X2+drdXX1J/zX9AkmI+lU3N7e/hYSxAAT\n0Rs+FdX69rXsA1y5ubn5Vz6fL1Q++w30VO4/0/9IewAAAABJRU5ErkJggg==\n' | |
21 | |
22 def uniqify(name, names): | |
23 newname, i = name, 1 | |
24 while newname in names: newname, i = name + str(i), i + 1 | |
25 return newname | |
26 | |
27 def indent(lines): | 17 def indent(lines): |
28 return [' ' + line for line in lines] | 18 return [' ' + line for line in lines] |
29 | 19 |
30 class ParameterDialog(QDialog): | 20 class ParameterDialog(QDialog): |
31 def __init__(self, block, parent = None): | 21 def __init__(self, block, parent = None): |
53 self._model = None | 43 self._model = None |
54 self.treeView = QTreeView() | 44 self.treeView = QTreeView() |
55 def setDiagram(self, d): | 45 def setDiagram(self, d): |
56 self.setScene(d) | 46 self.setScene(d) |
57 self.delShort.activated.connect(d.deleteItems) | 47 self.delShort.activated.connect(d.deleteItems) |
58 def getModel(self): return self._model | 48 def getModel(self): |
49 return self._model | |
59 def setModel(self, m): | 50 def setModel(self, m): |
60 self._model = m | 51 self._model = m |
61 if m: | 52 if m: |
62 self.treeView.setModel(m) | 53 self.treeView.setModel(m) |
63 self.diagram = m.rootDiagram | 54 self.diagram = m.rootDiagram |
120 if event.mimeData().hasFormat('component/name'): event.accept() | 111 if event.mimeData().hasFormat('component/name'): event.accept() |
121 def dropEvent(self, event): | 112 def dropEvent(self, event): |
122 if event.mimeData().hasFormat('component/name'): | 113 if event.mimeData().hasFormat('component/name'): |
123 name = bytes(event.mimeData().data('component/name')).decode() | 114 name = bytes(event.mimeData().data('component/name')).decode() |
124 pos = self.mapToScene(event.pos()) | 115 pos = self.mapToScene(event.pos()) |
125 self.scene().addNewBlock(pos, name) | 116 s = self.scene() |
117 b = Block(s.uniqify(name)) | |
118 b.setPos(pos) | |
119 s.addItem(b) | |
126 # TODO: do this in a cleaner way: | 120 # TODO: do this in a cleaner way: |
127 self.model.modelReset.emit() | 121 self.model.modelReset.emit() |
128 | 122 |
129 class LibraryModel(QStandardItemModel): | 123 class LibraryModel(QStandardItemModel): |
130 mimeTypes = lambda self: ['component/name'] | 124 mimeTypes = lambda self: ['component/name'] |
142 self.rootDiagram = DiagramScene() | 136 self.rootDiagram = DiagramScene() |
143 self.filename = None | 137 self.filename = None |
144 def setDict(self, d): | 138 def setDict(self, d): |
145 self.rootDiagram.Dict = d | 139 self.rootDiagram.Dict = d |
146 self.modelReset.emit() | 140 self.modelReset.emit() |
147 Dict = property(lambda s: s.rootDiagram.Dict, setDict) | 141 def getDict(self): |
142 return self.rootDiagram.Dict | |
143 Dict = property(getDict, setDict) | |
148 def gencode(self): | 144 def gencode(self): |
149 c = ['def topLevel():'] | 145 c = ['def topLevel():'] |
150 c += indent(self.rootDiagram.gencode()) | 146 c += indent(self.rootDiagram.gencode()) |
151 c.append('print("Running model")') | 147 c.append('print("Running model")') |
152 c.append('topLevel()') | 148 c.append('topLevel()') |
178 return b.name | 174 return b.name |
179 def headerData(self, section, orientation, role): | 175 def headerData(self, section, orientation, role): |
180 if orientation == Qt.Horizontal and role == Qt.DisplayRole: | 176 if orientation == Qt.Horizontal and role == Qt.DisplayRole: |
181 return "Element" | 177 return "Element" |
182 def rowCount(self, parent): | 178 def rowCount(self, parent): |
183 if parent.column() > 0: return 0 | 179 if parent.column() > 0: |
180 return 0 | |
184 if parent.isValid(): | 181 if parent.isValid(): |
185 parent = parent.internalPointer().subModel | 182 block = parent.internalPointer() |
183 if hasattr(block, 'subModel'): | |
184 return len(block.subModel.blocks) | |
185 else: | |
186 return 0 | |
186 else: | 187 else: |
187 parent = self.rootDiagram | 188 return len(self.rootDiagram.blocks) |
188 return len(parent.blocks) | |
189 def columnCount(self, parent): | 189 def columnCount(self, parent): |
190 return 1 | 190 return 1 |
191 | |
192 | 191 |
193 class LibraryWidget(QListView): | 192 class LibraryWidget(QListView): |
194 def __init__(self): | 193 def __init__(self): |
195 super(LibraryWidget, self).__init__(None) | 194 super(LibraryWidget, self).__init__(None) |
196 self.libraryModel = LibraryModel(self) | 195 self.libraryModel = LibraryModel(self) |