def undo(self): controller = ControllerManager().getController(self.controllerKey) for itemData in self.data: item = controller.genItemWithData(itemData['node']) pos = QPointF(itemData['node']['pos']['x'], itemData['node']['pos']['y']) self.scene.addItem(item) item.setPos(pos) item.setSelected(True) controller.addNode(item) self.scene.addToCache(item) # 智能恢复边 for itemData in self.data: inEdgesData = itemData['inEdgeData'] outEdgesData = itemData['outEdgeData'] # 恢复入边 for edgeData in inEdgesData: startParent = self.scene.cache.get(edgeData['start'], None) if startParent is None: # 可插入debug信息 continue endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem) # 恢复出边 for edgeData in outEdgesData: endParent = self.scene.cache.get(edgeData['end'], None) if endParent is None: continue startParent = self.scene.cache.get(edgeData['start'], None) startItem = self.scene.findSubItem(startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem)
def redo(self): controller = ControllerManager().getController(self.controllerKey) if type(self.data) == dict: # 从空模板插入一个项目 item = controller.restoreItemFromData(self.data) controller.addNode(item) self.scene.addItem(item) item.setPos(QPointF(self.data['pos']['x'], self.data['pos']['y'])) self.data.update({'id': '%s' % item.uuid}) self.scene.addToCache(item) elif type(self.data) == list: # 来自copy/paste if self.isFirst: # isFirst标识是否是第一次执行redo # 如果是第一次,就是一个粘贴操作,各个item的x,y就是一种相对坐标 # 如果不是第一次,就是执行了undo之后,又执行redo;这时item的x,y就是绝对坐标了。 if self.mousePosition: vsCenterF = QPointF(self.mousePosition[0], self.mousePosition[1]) else: view = self.scene.views()[0] size = view.size() width, height = size.width(), size.height() viewCenter = QPoint(width / 2, height / 2) # 可见中心点映射到场景中的位置 vsCenter = view.mapToScene(viewCenter) vsCenterF = QPointF(vsCenter.x(), vsCenter.y()) vsCenterF = vsCenterF + self.randomOffset() for itemData in self.data: item = controller.genItemWithData(itemData['node']) if self.isFirst: relpos = QPointF(itemData['node']['pos']['x'], itemData['node']['pos']['y']) pos = relpos + vsCenterF else: pos = QPointF(itemData['node']['pos']['x'], itemData['node']['pos']['y']) self.scene.addItem(item) item.setPos(pos) item.setSelected(True) controller.addNode(item) self.scene.addToCache(item) ControllerManager().tracker.trackAdd(item.itemType.typeId) # 智能恢复边 for itemData in self.data: inEdgesData = itemData['inEdgeData'] outEdgesData = itemData['outEdgeData'] # 恢复入边 for edgeData in inEdgesData: startParent = self.scene.cache.get(edgeData['start'], None) if startParent is None: # 可插入debug信息 continue endParent = self.scene.cache.get(edgeData['end'], None) startItem = self.scene.findSubItem( startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem) # 恢复出边 for edgeData in outEdgesData: endParent = self.scene.cache.get(edgeData['end'], None) if endParent is None: continue startParent = self.scene.cache.get(edgeData['start'], None) startItem = self.scene.findSubItem( startParent, edgeData['startItemTypeId']) endItem = self.scene.findSubItem(endParent, edgeData['endItemTypeId']) if startItem is None or endItem is None: continue # 建立边 self.scene.simpleMakeConnection(startItem, endItem) else: print('Error: data type must be dict or list', type(self.data), 'given in', __file__, 'line:', __line__()) self.isFirst = False