|
@@ -29,6 +29,7 @@ class Canvas(QtWidgets.QWidget):
|
|
|
edgeSelected = QtCore.Signal(bool, object)
|
|
|
vertexSelected = QtCore.Signal(bool)
|
|
|
|
|
|
+ CREATE, EDIT = 0, 1
|
|
|
CREATE, EDIT = 0, 1
|
|
|
|
|
|
# polygon, rectangle, line, or point
|
|
@@ -45,6 +46,7 @@ class Canvas(QtWidgets.QWidget):
|
|
|
self.double_click
|
|
|
)
|
|
|
)
|
|
|
+ self.num_backups = kwargs.pop("num_backups", 10)
|
|
|
super(Canvas, self).__init__(*args, **kwargs)
|
|
|
# Initialise local state.
|
|
|
self.mode = self.EDIT
|
|
@@ -111,26 +113,35 @@ class Canvas(QtWidgets.QWidget):
|
|
|
shapesBackup = []
|
|
|
for shape in self.shapes:
|
|
|
shapesBackup.append(shape.copy())
|
|
|
- if len(self.shapesBackups) >= 10:
|
|
|
- self.shapesBackups = self.shapesBackups[-9:]
|
|
|
+ if len(self.shapesBackups) > self.num_backups:
|
|
|
+ self.shapesBackups = self.shapesBackups[-self.num_backups - 1 :]
|
|
|
self.shapesBackups.append(shapesBackup)
|
|
|
|
|
|
@property
|
|
|
def isShapeRestorable(self):
|
|
|
+ # We save the state AFTER each edit (not before) so for an
|
|
|
+ # edit to be undoable, we expect the CURRENT and the PREVIOUS state
|
|
|
+ # to be in the undo stack.
|
|
|
if len(self.shapesBackups) < 2:
|
|
|
return False
|
|
|
return True
|
|
|
|
|
|
def restoreShape(self):
|
|
|
+ # This does _part_ of the job of restoring shapes.
|
|
|
+ # The complete process is also done in app.py::undoShapeEdit
|
|
|
+ # and app.py::loadShapes and our own Canvas::loadShapes function.
|
|
|
if not self.isShapeRestorable:
|
|
|
return
|
|
|
self.shapesBackups.pop() # latest
|
|
|
+
|
|
|
+ # The application will eventually call Canvas.loadShapes which will
|
|
|
+ # push this right back onto the stack.
|
|
|
shapesBackup = self.shapesBackups.pop()
|
|
|
self.shapes = shapesBackup
|
|
|
self.selectedShapes = []
|
|
|
for shape in self.shapes:
|
|
|
shape.selected = False
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def enterEvent(self, ev):
|
|
|
self.overrideCursor(self._cursor)
|
|
@@ -423,7 +434,7 @@ class Canvas(QtWidgets.QWidget):
|
|
|
# Only hide other shapes if there is a current selection.
|
|
|
# Otherwise the user will not be able to select a shape.
|
|
|
self.setHiding(True)
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def setHiding(self, enable=True):
|
|
|
self._hideBackround = self.hideBackround if enable else False
|
|
@@ -756,13 +767,13 @@ class Canvas(QtWidgets.QWidget):
|
|
|
else:
|
|
|
self.current = None
|
|
|
self.drawingPolygon.emit(False)
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def loadPixmap(self, pixmap, clear_shapes=True):
|
|
|
self.pixmap = pixmap
|
|
|
if clear_shapes:
|
|
|
self.shapes = []
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def loadShapes(self, shapes, replace=True):
|
|
|
if replace:
|
|
@@ -774,11 +785,11 @@ class Canvas(QtWidgets.QWidget):
|
|
|
self.hShape = None
|
|
|
self.hVertex = None
|
|
|
self.hEdge = None
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def setShapeVisible(self, shape, value):
|
|
|
self.visible[shape] = value
|
|
|
- self.repaint()
|
|
|
+ self.update()
|
|
|
|
|
|
def overrideCursor(self, cursor):
|
|
|
self.restoreCursor()
|