def mouseRightButtonPressed(self, obj, event): if self.conn == None: b, p, c, t = [], [], [], [] for i in self.itemAt(event.scenePos(), single=False): if isBlock(i): b.append(i) elif isPort(i): p.append(i) elif isConnection(i): c.append(i) elif isComment(i): t.append(i) item = p.pop() if p else b.pop() if b else c.pop() if c else t.pop( ) if t else None if isBlock(item): self.scene.item = item # self.netlistMenu.clear() # self.addNetlistMenu() self.menuIOBlk.exec_(event.screenPos()) elif isPort(item, ['node', 'ipin', 'opin', 'iopin']): self.scene.item = item self.subMenuPort.exec_(event.screenPos()) elif isConnection(item): self.scene.item = item self.event = event self.subMenuConn.exec_(event.screenPos()) elif isComment(item): self.scene.item = item self.event = event self.subMenuText.exec_(event.screenPos()) else: self.event = event self.subMenuNothing.exec_(event.screenPos())
def mouseReleased(self, obj, event): self.connFromNode = False items = self.scene.selectedItems() for item in items: if isBlock(item) or isPort(item) or isComment(item): item.setPos(gridPos(item.pos())) for thing in item.childItems(): if isPort(thing, 'block'): for conn in thing.connections: conn.update_path()
def pasteAct(self): if self.scene.selection != []: block_tr = dict() port_tr = dict() conn_list = [] dx, dy = 100, 100 for item in self.scene.selection: newitem = None if isinstance(item, Block): b = item.clone(QtCore.QPointF(dx, dy)) b.setSelected(True) block_tr[item.label.text()] = b elif isConnection(item): conn_list.append(item) elif isPort(item, 'pin') or isPort(item, 'node'): newitem = Port(None, self.scene) port_tr[item] = newitem elif isComment(item): newitem = Comment('') self.scene.addItem(newitem) # else: # print ('skipping paste of ', item.toData()) item.setSelected(False) if newitem: data = item.toData() data['x'] += dx data['y'] += dy newitem.fromData(data) newitem.setSelected(True) for c in conn_list: data = c.toData() conn = Connection(None, scene=self.scene) conn.pos[0] = QtCore.QPointF(data['x0'] + dx, data['y0'] + dy) conn.pos[1] = QtCore.QPointF(data['x1'] + dx, data['y1'] + dy) for ix, p in [(0, 'p0'), (1, 'p1')]: if p in data: # translate blocknames (blkname, pinname) = data[p] # update to new blockname if blkname in block_tr: b = block_tr[blkname] conn.attach(ix, b.ports(retDict=True)[pinname]) elif c.port[ix]: port = c.port[ix] if port in port_tr: conn.port[ix] = port_tr[port] conn.update_path()
def attach(self, ix, p): if ix in [0, 1]: if isPort(p): self.pos[ix] = p.scenePos() self.port[ix] = p p.connections.add(self) elif p: self.pos[ix] = p self.port[ix] = None
def sortedItemsAt(self, pos): blocks, ports, nodes, connections, labels = [], [], [], [], [] radius = 4 * DB / self.parent().view.currentscale allitems = self.scene.items( QtCore.QRectF(pos - QtCore.QPointF(radius, radius), QtCore.QSizeF(2 * radius, 2 * radius))) for item in allitems: for cat, test in [(blocks, isBlock), (nodes, isNode), (connections, isConnection), (labels, isTextItem)]: if test(item): cat.append(item) elif isPort(item): # all ports except nodes ports.append(item) return blocks, ports, nodes, connections, labels
def fromData(self, data): self.pos[0] = QtCore.QPointF(data['x0'], data['y0']) self.pos[1] = QtCore.QPointF(data['x1'], data['y1']) if 'p0' in data or 'p1' in data: for item in self.scene().items(): if isPort(item, 'block'): pinname = item.label.text() blkname = item.parent.label.text() if 'p0' in data: if (blkname, pinname) == data['p0']: self.port[0] = item if 'p1' in data: if (blkname, pinname) == data['p1']: self.port[1] = item self.update_pos_from_ports() self.update_path()
def portAddType(self, event): item = self.scene.item if not isPort(item): error('use on nodes/pins') return if item.signalType: dialog = textLineDialog('Signal type: ', 'Signal type', item.signalType.text()) else: dialog = textLineDialog('Signal type: ', 'Signal type') ret = dialog.getLabel() if ret: item.signalType = textItem(ret, anchor=8, parent=item) item.signalType.setBrush(colors['signalType']) font = item.signalType.font() font.setItalic(True) item.signalType.setFont(font)
def moveMouse(self, obj, event): if self.connFromNode: return pos = gridPos(event.scenePos()) item = self.itemAt(pos) if self.conn: self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor) if item and isInPort(item) or isNode(item): if len(item.connections) == 0: self.scene.mainw.view.setCursor(QtCore.Qt.CrossCursor) else: self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor) elif item and isNode(item): if len(item.connections) == 0: self.scene.mainw.view.setCursor(QtCore.Qt.CrossCursor) else: self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor) self.conn.update_path(pos) #return True elif item: if isBlock(item): items = self.scene.selectedItems() for item in items: if isBlock(item): for thing in item.childItems(): if isPort(thing, 'block'): for conn in thing.connections: conn.update_path() #elif isConnection(item): #self.scene.mainw.view.setCursor(QtCore.Qt.PointingHandCursor) elif isOutPort(item): self.scene.mainw.view.setCursor(QtCore.Qt.CrossCursor) elif isNode(item): if item in self.scene.selectedItems(): self.scene.mainw.view.setCursor( QtCore.Qt.PointingHandCursor) else: self.scene.mainw.view.setCursor(QtCore.Qt.CrossCursor) else: self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor)
def toData(self): data = OrderedDict(type='connection') if self.pos[0]: data['x0'] = self.pos[0].x() data['y0'] = self.pos[0].y() if self.pos[1]: data['x1'] = self.pos[1].x() data['y1'] = self.pos[1].y() for ix in [0, 1]: pp = ['p0', 'p1'][ix] if self.port[ix] and isPort(self.port[ix], 'block'): blkname = self.port[ix].parent.label.text() pinname = self.port[ix].label.text() data[pp] = (blkname, pinname) # if self.label: # data['label'] = self.label.text() return data
def diagramToData(self, selection=None): blocks = [] connections = [] nodes = [] comments = [] for block in self.scene.blocks: # force unique names block.setLabel(verbose=True) items = selection if selection else self.scene.items() for item in items: if isBlock(item): blocks.append(d2s(item.toData())) elif isConnection(item): connections.append(d2s(item.toData())) elif isPort(item, tp=['ipin', 'opin', 'iopin', 'node']): nodes.append(d2s(item.toData())) elif isComment(item): comments.append(d2s(item.toData())) return (blocks, connections, nodes, comments)
def mouseDoubleClicked(self, obj, event): pos = gridPos(event.scenePos()) item = self.itemAt(pos, exclude=[isConnection]) if isBlock(item): if 'diagram' in item.getViews(): self.scene.mainw.descend(item) else: views = item.getViews() fname = None if len(views) == 1: viewtype, fname = views.items()[0] elif len(views) > 1: d = selectionDialog(views.keys(), title='Select view') ret = d.getRet() if ret: fname = views[ret] if fname: for tp, (editor, extension) in viewTypes.items(): if fname.endswith(extension): cmd = editor break if cmd: os.system(cmd + " " + fname) else: error( "{} is unkown type\nplease see viewTypes in menu Settings -> Edit settings" .format(source)) return elif isPort(item, tp='ipin opin iopin node'.split()): self.scene.item = item self.portEdit() if self.conn: self.conn.remove() self.conn = None self.scene.mainw.view.setCursor(QtCore.Qt.ArrowCursor) elif isTextItem(item): font, ok = QtWidgets.QFontDialog.getFont(item.font()) if ok: item.setFont(font)
def portEdit(self): item = self.scene.item if not isPort(item): error('not a pin') dd = OrderedDict() dd['Pin_label'] = item.label.text() if item.label else '' options = 'ipin opin iopin node'.split() dd['Pin_type'] = (item.porttype, options) properties = item.properties title = 'Edit Node' if isNode(item) else 'Edit Pin' dialog = propertiesDialog(self.scene.mainw, dd, properties, title=title) dd = dialog.getRet() if dd: item.setType(dd.pop('Pin_type')[0]) item.setLabel(dd.pop('Pin_label')) if dd: item.properties = dd item.setup()
def dataToDiagram(self, blocks, connections, nodes, comments, center=True, undo=False): errors = [] for data in blocks: prop = data['properties'] if 'properties' in data else dict() if 'parameters' in data: #getBlock(libname, blockname, parent=None, scene=None, param=dict(), name=None, flip=False) b = getBlock(data['libname'], data['blockname'], scene=self.scene, param=data['parameters'], properties=prop, errors=errors) else: b = getBlock(data['libname'], data['blockname'], scene=self.scene, properties=prop, errors=errors) if b: b.fromData(data) for item in nodes: pos = QtCore.QPointF(item['x'], item['y']) if self.scene.find_itemAt(pos): print('discarding overlapping node at x={}, y={}'.format( item['x'], item['y'])) else: p = Port(None, self.scene) p.fromData(item) for data in connections: pos = [QtCore.QPointF(data['x0'], data['y0'])] pos.append(QtCore.QPointF(data['x1'], data['y1'])) if pos[0] == pos[1]: print('discarding zero length segment x={}, y={}'.format( data['x0'], data['y0'])) else: conn = Connection(None, self.scene) for ix in [0, 1]: port = self.scene.find_itemAt(pos[ix], exclude=(Block, Connection, textItem)) if isPort(port): conn.attach(ix, port) else: conn.pos[ix] = pos[ix] print('no port at ', pos[ix]) conn.update_path() if 'label' in data: conn.label = textItem(data['label'], anchor=3, parent=conn) conn.label.setPos(conn.pos2.x(), conn.pos2.y()) if 'signalType' in data: conn.signalType = textItem(data['signalType'], anchor=3, parent=conn) conn.signalType.setPos(conn.pos2.x(), conn.pos2.y()) for data in comments: comment = Comment('') comment.fromData(data) self.scene.addItem(comment) if center: self.scene.mainw.view.centerOn(self.scene.getCenter()[0], self.scene.getCenter()[1]) if errors: error('\n'.join(errors))
def convertSymAct(self): selection = self.scene.items(self.scene.selectionArea()) if selection and self.scene.selectedItems(): # blocks, connections, nodes, comments blocks = [] connections = [] nodes = [] comments = [] inp = [] outp = [] inout = [] for item in selection: if isinstance(item, Block): blocks.append(str(item.toData())) elif isConnection(item): connections.append(str(item.toData())) elif isNode(item): nodes.append(str(item.toData())) elif isPort(item, 'pin'): item.pinToPort(inp, outp, inout) elif isComment(item): comments.append(str(item.toData())) dialog = convertSymDialog() ret = dialog.getRet() if ret: name = ret['name'] icon = ret['icon'] if self.library.type == 'symbolView': libname = self.library.tabs.tabText( self.library.tabs.currentIndex()) else: libname = self.library.libraries.currentItem().text() ed, ext = viewTypes['diagram'] views = dict( diagram=os.path.join(libraries.libprefix + libname, name + ext)) if icon: views['icon'] = icon parameters = dict() properties = ret['properties'] data = templates['block'].format(name=name, libname=libname, inp=inp, outp=outp, io=inout, bbox=None, properties=properties, parameters=parameters, views=views) # save block fname = libraries.blockpath(libname, name) with open(fname, 'w+') as f: f.write(str(data)) # save diagram ed, ext = viewTypes['diagram'] fname = strip_ext(fname, '.py') + ext self.saveDiagram(fname, selection) for item in self.scene.selectedItems(): try: item.remove() except: pass # with open(self.path + '/libraries/library_' + libname + '/' + name + '_diagram.py','w+') as f: # f.write("blocks = [" + ",\n ".join(blocks) + "]\n\n" + # "connections = [" + ",\n ".join(connections) + "]\n\n" + # "nodes = [" + ",\n ".join(nodes) + "]\n\n" + # "comments = [" + ",\n ".join(comments) + "]") center = self.scene.getCenter() item = getBlock(libname, name, None, self.scene) item.setPos(center[0], center[1]) if self.library.type == 'symbolView': ix = self.library.tabs.currentIndex() self.library.symbolView() self.library.tabs.setCurrentIndex(ix) else: self.library.listView() self.library.libraries.setCurrentItem( self.library.libraries.findItems( 'symbols', QtCore.Qt.MatchExactly)[0]) else: error('Select what you want to convert')