diff --git a/cvat/apps/engine/static/engine/js/annotationUI.js b/cvat/apps/engine/static/engine/js/annotationUI.js index 58b306c1..1c1471f2 100644 --- a/cvat/apps/engine/static/engine/js/annotationUI.js +++ b/cvat/apps/engine/static/engine/js/annotationUI.js @@ -224,7 +224,7 @@ function buildAnnotationUI(job, shapeData, loadJobEvent) { }), job); new PlayerView(playerModel, playerController, job); - let historyModel = new HistoryModel(playerModel); + let historyModel = new HistoryModel(playerModel, idGenerator); let historyController = new HistoryController(historyModel); new HistoryView(historyController, historyModel); diff --git a/cvat/apps/engine/static/engine/js/history.js b/cvat/apps/engine/static/engine/js/history.js index cca15672..3a05b682 100644 --- a/cvat/apps/engine/static/engine/js/history.js +++ b/cvat/apps/engine/static/engine/js/history.js @@ -14,7 +14,7 @@ "use strict"; class HistoryModel extends Listener { - constructor(playerModel) { + constructor(playerModel, idGenerator) { super('onHistoryUpdate', () => this ); this._deep = 128; @@ -23,10 +23,15 @@ class HistoryModel extends Listener { this._redo_stack = []; this._locked = false; this._player = playerModel; + this._idGenerator = idGenerator; window.cvat.addAction = (name, undo, redo, frame) => this.addAction(name, undo, redo, frame); } + generateId() { + return this._idGenerator.next(); + } + undo() { let frame = window.cvat.player.frames.current; let undo = this._undo_stack.pop(); @@ -42,7 +47,7 @@ class HistoryModel extends Listener { this._player.shift(undo.frame, true); } this._locked = true; - undo.undo(); + undo.undo(this); } catch(err) { this.notify(); @@ -73,7 +78,7 @@ class HistoryModel extends Listener { this._player.shift(redo.frame, true); } this._locked = true; - redo.redo(); + redo.redo(this); } catch(err) { this.notify(); diff --git a/cvat/apps/engine/static/engine/js/shapeBuffer.js b/cvat/apps/engine/static/engine/js/shapeBuffer.js index 15ab15da..bd793dcc 100644 --- a/cvat/apps/engine/static/engine/js/shapeBuffer.js +++ b/cvat/apps/engine/static/engine/js/shapeBuffer.js @@ -157,8 +157,9 @@ class ShapeBufferModel extends Listener { window.cvat.addAction('Paste Object', () => { model.removed = true; model.unsubscribe(this._collection); - }, () => { + }, (self) => { model.subscribe(this._collection); + model.id = self.generateId(); model.removed = false; }, window.cvat.player.frames.current); // End of undo/redo code @@ -247,8 +248,9 @@ class ShapeBufferModel extends Listener { object.removed = true; object.unsubscribe(this._collection); } - }, () => { + }, (self) => { for (let object of addedObjects) { + object.id = self.generateId(); object.removed = false; object.subscribe(this._collection); } diff --git a/cvat/apps/engine/static/engine/js/shapeCollection.js b/cvat/apps/engine/static/engine/js/shapeCollection.js index 7acde4bb..df0cc61a 100644 --- a/cvat/apps/engine/static/engine/js/shapeCollection.js +++ b/cvat/apps/engine/static/engine/js/shapeCollection.js @@ -814,14 +814,16 @@ class ShapeCollectionModel extends Listener { // Undo/redo code let newShapes = this._shapes.slice(-list.length); let originalShape = this._activeShape; - window.cvat.addAction('Split Object', () => { + window.cvat.addAction('Split Object', (self) => { for (let shape of newShapes) { shape.removed = true; shape.unsubscribe(this); } + originalShape.id = self.generateId(); originalShape.removed = false; - }, () => { + }, (self) => { for (let shape of newShapes) { + shape.id = self.generateId(); shape.removed = false; shape.subscribe(this); } diff --git a/cvat/apps/engine/static/engine/js/shapeCreator.js b/cvat/apps/engine/static/engine/js/shapeCreator.js index a93dcc77..bebb7bb1 100644 --- a/cvat/apps/engine/static/engine/js/shapeCreator.js +++ b/cvat/apps/engine/static/engine/js/shapeCreator.js @@ -70,8 +70,9 @@ class ShapeCreatorModel extends Listener { window.cvat.addAction('Draw Object', () => { model.removed = true; model.unsubscribe(this._shapeCollection); - }, () => { + }, (self) => { model.subscribe(this._shapeCollection); + model.id = self.generateId(); model.removed = false; }, window.cvat.player.frames.current); // End of undo/redo code diff --git a/cvat/apps/engine/static/engine/js/shapeMerger.js b/cvat/apps/engine/static/engine/js/shapeMerger.js index 8223be05..cd119366 100644 --- a/cvat/apps/engine/static/engine/js/shapeMerger.js +++ b/cvat/apps/engine/static/engine/js/shapeMerger.js @@ -167,20 +167,22 @@ class ShapeMergerModel extends Listener { let shapes = this._shapesForMerge; // Undo/redo code - window.cvat.addAction('Merge Objects', () => { + window.cvat.addAction('Merge Objects', (self) => { model.unsubscribe(this._collectionModel); model.removed = true; for (let shape of shapes) { + shape.id = self.generateId(); shape.removed = false; shape.subscribe(this._collectionModel); } this._collectionModel.update(); - }, () => { + }, (self) => { for (let shape of shapes) { shape.removed = true; shape.unsubscribe(this._collectionModel); } model.subscribe(this._collectionModel); + model.id = self.generateId(); model.removed = false; }, window.cvat.player.frames.current); // End of undo/redo code diff --git a/cvat/apps/engine/static/engine/js/shapes.js b/cvat/apps/engine/static/engine/js/shapes.js index c273640b..85101f55 100644 --- a/cvat/apps/engine/static/engine/js/shapes.js +++ b/cvat/apps/engine/static/engine/js/shapes.js @@ -476,11 +476,11 @@ class ShapeModel extends Listener { this.removed = true; // Undo/redo code - window.cvat.addAction('Remove Object', () => { + window.cvat.addAction('Remove Object', (self) => { + this.id = self.generateId(); this.removed = false; }, () => { this.removed = true; - }, window.cvat.player.frames.current); // End of undo/redo code } @@ -574,6 +574,10 @@ class ShapeModel extends Listener { return this._id; } + set id(value) { + this._id = value; + } + get frame() { return this._frame; }