From f9a74a9f02043c77764cff1e647c41098df3abb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Fri, 28 Nov 2025 15:05:21 -0500 Subject: [PATCH 1/9] Add per user undo and redo stacks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 298 +++++++++++------- 1 file changed, 185 insertions(+), 113 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index db6f88626..71a89983c 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -396,9 +396,15 @@ class: AnnotateMinorMode : MinorMode "%s.frame:%d.order" % (node, frame); } - method: frameOrderRedoStackName (string; string node, int frame) + + method: frameUserUndoStackName (string; string node, int frame) + { + "%s.frame:%d.undo_%s" % (node, frame, encodedName(_user)); + } + + method: frameUserRedoStackName (string; string node, int frame) { - "%s.frame:%d.redo" % (node, frame); + "%s.frame:%d.redo_%s" % (node, frame, encodedName(_user)); } method: updateFrameDependentState (void;) @@ -459,18 +465,19 @@ class: AnnotateMinorMode : MinorMode int mode=RenderOverMode, int debug=0) { - let n = newUniqueName(node, "pen", frame), - colorName = "%s.color" % n, - widthName = "%s.width" % n, - brushName = "%s.brush" % n, - debugName = "%s.debug" % n, - joinName = "%s.join" % n, - capName = "%s.cap" % n, - pointsName = "%s.points" % n, - splatName = "%s.splat" % n, + let n = newUniqueName(node, "pen", frame), + colorName = "%s.color" % n, + widthName = "%s.width" % n, + brushName = "%s.brush" % n, + debugName = "%s.debug" % n, + joinName = "%s.join" % n, + capName = "%s.cap" % n, + pointsName = "%s.points" % n, + splatName = "%s.splat" % n, startFrameName = "%s.startFrame" % n, - durationName = "%s.duration" % n, - orderName = frameOrderName(node, frame); + durationName = "%s.duration" % n, + orderName = frameOrderName(node, frame), + undoName = frameUserUndoStackName(node, frame); beginCompoundStateChange(); newProperty(colorName, FloatType, 4); @@ -514,16 +521,21 @@ class: AnnotateMinorMode : MinorMode setIntProperty(startFrameName, int[] {startFrame}, true); setIntProperty(durationName, int[] {duration}, true); - try + let stroke = n.split(".").back(); + + if (!propertyExists(orderName)) { - propertyInfo(orderName); + newProperty(orderName, StringType, 1); } - catch (...) + + insertStringProperty(orderName, string[] {stroke}); + + if (!propertyExists(undoName)) { - newProperty(orderName, StringType, 1); + newProperty(undoName, StringType, 1); } - insertStringProperty(orderName, string[] {n.split(".").back()}); + insertStringProperty(undoName, string[] {stroke}); endCompoundStateChange(); return n; @@ -575,20 +587,21 @@ class: AnnotateMinorMode : MinorMode int mode=RenderOverMode, int debug=0) { - let n = newUniqueName(node, "text", frame), - colorName = "%s.color" % n, - sizeName = "%s.size" % n, - scaleName = "%s.scale" % n, - spacingName = "%s.spacing" % n, - rotName = "%s.rotation" % n, - fontName = "%s.font" % n, - textName = "%s.text" % n, - originName = "%s.origin" % n, - posName = "%s.position" % n, - debugName = "%s.debug" % n, + let n = newUniqueName(node, "text", frame), + colorName = "%s.color" % n, + sizeName = "%s.size" % n, + scaleName = "%s.scale" % n, + spacingName = "%s.spacing" % n, + rotName = "%s.rotation" % n, + fontName = "%s.font" % n, + textName = "%s.text" % n, + originName = "%s.origin" % n, + posName = "%s.position" % n, + debugName = "%s.debug" % n, startFrameName = "%s.startFrame" % n, - durationName = "%s.duration" % n, - orderName = frameOrderName(node, frame); + durationName = "%s.duration" % n, + orderName = frameOrderName(node, frame), + undoName = frameUserUndoStackName(node, frame); beginCompoundStateChange(); newProperty(posName, FloatType, 2); @@ -621,16 +634,21 @@ class: AnnotateMinorMode : MinorMode setIntProperty(startFrameName, int[] {startFrame}, true); setIntProperty(durationName, int[] {duration}, true); - try + let stroke = n.split(".").back(); + + if (!propertyExists(orderName)) { - propertyInfo(orderName); + newProperty(orderName, StringType, 1); } - catch (...) + + insertStringProperty(orderName, string[] {stroke}); + + if (!propertyExists(undoName)) { - newProperty(orderName, StringType, 1); + newProperty(undoName, StringType, 1); } - insertStringProperty(orderName, string[] {n.split(".").back()}); + insertStringProperty(undoName, string[] {stroke}); endCompoundStateChange(); return n; @@ -648,9 +666,8 @@ class: AnnotateMinorMode : MinorMode method: saveAnnotation (void; string description) { let comp = "annotation:%d" % nextAnnotationID(), - f = frame(), - orderName = frameOrderName(_currentNode, f), - redoName = frameOrderRedoStackName(_currentNode, f), + frame = frame(), + orderName = frameOrderName(_currentNode, frame), orderArray = getStringProperty(orderName), propName = _currentNode + "." + comp + ".order", descName = _currentNode + "." + comp + ".description"; @@ -1088,16 +1105,23 @@ class: AnnotateMinorMode : MinorMode runtime.gc.enable(); _currentDrawObject = nil; - let f = _currentNodeInfo.frame, - rprop= frameOrderRedoStackName(_currentNode, f); + let frame = _currentNodeInfo.frame; + let redoProperty = frameUserRedoStackName(_currentNode, frame); + + if (propertyExists(redoProperty) && propertyInfo(redoProperty).size > 0) + { + for_each (c; getStringProperty(redoProperty)) + { + deleteStroke(_currentNode, c); + } + setStringProperty(redoProperty, string[](), true); + } - if (propertyExists(rprop) && propertyInfo(rprop).size > 0) + if (_syncWholeStrokes) { - for_each (c; getStringProperty(rprop)) deleteStroke(_currentNode, c); - setStringProperty(rprop, string[](), true); + endCompoundStateChange(); } - if (_syncWholeStrokes) endCompoundStateChange(); undoRedoUpdate(); redraw(); } @@ -1408,111 +1432,161 @@ class: AnnotateMinorMode : MinorMode method: undoRedoUpdate (void;) { - let f = _currentNodeInfo.frame, - uprop = frameOrderName(_currentNode, f), - rprop= frameOrderRedoStackName(_currentNode, f), - playing = isPlaying(); + let frame = _currentNodeInfo.frame; + let undoProperty = frameUserUndoStackName(_currentNode, frame); + let redoProperty = frameUserRedoStackName(_currentNode, frame); + let playing = isPlaying(); _undoAct.setEnabled(!playing && - propertyExists(uprop) && - propertyInfo(uprop).size > 0); + propertyExists(undoProperty) && + propertyInfo(undoProperty).size > 0); _redoAct.setEnabled(!playing && - propertyExists(rprop) && - propertyInfo(rprop).size > 0); + propertyExists(redoProperty) && + propertyInfo(redoProperty).size > 0); } - method: undoPaint (void; int frame) + method: undoPaint (void;) { - let f = _currentNodeInfo.frame, - upropName = frameOrderName(_currentNode, f), - rpropName = frameOrderRedoStackName(_currentNode, f); + let frame = _currentNodeInfo.frame; + let orderProperty = frameOrderName(_currentNode, frame); + let undoProperty = frameUserUndoStackName(_currentNode, frame); + let redoProperty = frameUserRedoStackName(_currentNode, frame); - if (propertyExists(upropName)) + if (propertyExists(undoProperty)) { - if (!propertyExists(rpropName)) newProperty(rpropName, StringType, 1); + if (!propertyExists(redoProperty)) + { + newProperty(redoProperty, StringType, 1); + } - let u = getStringProperty(upropName), - r = getStringProperty(rpropName); + let undo = getStringProperty(undoProperty); + let redo = getStringProperty(redoProperty); + let order = getStringProperty(orderProperty); - r.push_back(u.back()); - u.resize(u.size()-1); + let stroke = undo.back(); + redo.push_back(stroke); + undo.resize(undo.size()-1); - setStringProperty(upropName, u, true); - setStringProperty(rpropName, r, true); + for_index(i; order) + { + if (order[i] == stroke) + { + order.erase(i, 1); + break; + } + } + + beginCompoundStateChange(); + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + endCompoundStateChange(); } } - method: redoPaint (void; int frame) + method: redoPaint (void;) { - let f = _currentNodeInfo.frame, - upropName = frameOrderName(_currentNode, f), - rpropName = frameOrderRedoStackName(_currentNode, f); + let frame = _currentNodeInfo.frame; + let orderProperty = frameOrderName(_currentNode, frame); + let undoProperty = frameUserUndoStackName(_currentNode, frame); + let redoProperty = frameUserRedoStackName(_currentNode, frame); - if (propertyExists(rpropName)) + if (propertyExists(redoProperty)) { - if (!propertyExists(upropName)) newProperty(upropName, StringType, 1); + if (!propertyExists(undoProperty)) + { + newProperty(undoProperty, StringType, 1); + } - let u = getStringProperty(upropName), - r = getStringProperty(rpropName); + let undo = getStringProperty(undoProperty); + let redo = getStringProperty(redoProperty); + let order = getStringProperty(orderProperty); int startIndex = -1; int endIndex = -1; - for (int i = 0; i < r.size(); i++) + for (int i = 0; i < redo.size(); i++) { - if (r[i] == "start") + if (redo[i] == "start") { startIndex = i; } - if (r[i] == "end") + if (redo[i] == "end") { endIndex = i; } } - if (r.size() >= 3 && startIndex != -1 && endIndex != -1) + string[] strokes; + + if (redo.size() >= 3 && startIndex != -1 && endIndex != -1) { for (int i = startIndex + 1; i < endIndex; i++) { - u.push_back(r[i]); + let stroke = redo[i]; + strokes.push_back(stroke); + undo.push_back(stroke); } - r.erase(startIndex, endIndex - startIndex + 1); + redo.erase(startIndex, endIndex - startIndex + 1); } else { - u.push_back(r.back()); - r.resize(r.size() - 1); + let stroke = redo.back(); + strokes.push_back(stroke); + undo.push_back(stroke); + redo.resize(redo.size() - 1); + } + + + for_each(stroke; strokes) + { + order.push_back(stroke); } - setStringProperty(upropName, u, true); - setStringProperty(rpropName, r, true); + beginCompoundStateChange(); + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + endCompoundStateChange(); } } method: clearPaint (void; string node, int frame) { - let upropName = frameOrderName(node, frame); - let rpropName = frameOrderRedoStackName(node, frame); + let orderProperty = frameOrderName(node, frame); + let undoProperty = frameUserUndoStackName(node, frame); + let redoProperty = frameUserRedoStackName(node, frame); - if (propertyExists(upropName)) + if (propertyExists(undoProperty)) { - if (!propertyExists(rpropName)) newProperty(rpropName, StringType, 1); + if (!propertyExists(redoProperty)) + { + newProperty(redoProperty, StringType, 1); + } - let u = getStringProperty(upropName), - r = getStringProperty(rpropName); + let undo = getStringProperty(undoProperty); + let redo = getStringProperty(redoProperty); + let order = getStringProperty(orderProperty); - if (u.size() > 0) + if (undo.size() > 0) { - r.push_back("start"); - for (int i = 0; i < u.size(); i++) - r.push_back(u[i]); - r.push_back("end"); - u.clear(); + redo.push_back("start"); + for_each(stroke; undo) + { + redo.push_back(stroke); + } + redo.push_back("end"); + + undo.clear(); + order.clear(); } - setStringProperty(upropName, u, true); - setStringProperty(rpropName, r, true); + beginCompoundStateChange(); + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + endCompoundStateChange(); } } @@ -1638,7 +1712,7 @@ class: AnnotateMinorMode : MinorMode method: undoSlot (void; bool checked) { - undoPaint(sourceFrame(frame())); + undoPaint(); updateFrameDependentState(); redraw(); } @@ -1678,7 +1752,7 @@ class: AnnotateMinorMode : MinorMode method: redoSlot (void; bool checked) { - redoPaint(sourceFrame(frame())); + redoPaint(); updateFrameDependentState(); redraw(); } @@ -1696,13 +1770,12 @@ class: AnnotateMinorMode : MinorMode method: keyUndoEvent (void; Event event) { - let f = _currentNodeInfo.frame, - uprop = frameOrderName(_currentNode, f), - rprop= frameOrderRedoStackName(_currentNode, f), - playing = isPlaying(); + let frame = _currentNodeInfo.frame; + let undoStackProp = frameUserUndoStackName(_currentNode, frame); + let playing = isPlaying(); - if (!playing && propertyExists(uprop) && - propertyInfo(uprop).size > 0) + if (!playing && propertyExists(undoStackProp) && + propertyInfo(undoStackProp).size > 0) { undoSlot(true); } @@ -1710,13 +1783,12 @@ class: AnnotateMinorMode : MinorMode method: keyRedoEvent (void; Event event) { - let f = _currentNodeInfo.frame, - uprop = frameOrderName(_currentNode, f), - rprop= frameOrderRedoStackName(_currentNode, f), - playing = isPlaying(); + let frame = _currentNodeInfo.frame; + let redoStackProp = frameUserRedoStackName(_currentNode, frame); + let playing = isPlaying(); - if (!playing && propertyExists(rprop) && - propertyInfo(rprop).size > 0) + if (!playing && propertyExists(redoStackProp) && + propertyInfo(redoStackProp).size > 0) { redoSlot(true); } @@ -1733,14 +1805,14 @@ class: AnnotateMinorMode : MinorMode { if isSessionEmpty() || _currentNode eq nil then DisabledMenuState - else propOnState(frameOrderName(_currentNode, _currentNodeInfo.frame)); + else propOnState(frameUserUndoStackName(_currentNode, _currentNodeInfo.frame)); } method: redoState (int;) { if isSessionEmpty() || _currentNode eq nil then DisabledMenuState - else propOnState(frameOrderRedoStackName(_currentNode, _currentNodeInfo.frame)); + else propOnState(frameUserRedoStackName(_currentNode, _currentNodeInfo.frame)); } method: nextPrevState (int;) From 96c75b70bdb0ea16a48efa74e3d45a8f5016337b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Mon, 1 Dec 2025 13:02:29 -0500 Subject: [PATCH 2/9] Update clear state based on order stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- src/plugins/rv-packages/annotate/annotate_mode.mu | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index 71a89983c..2783ea3f1 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -1432,9 +1432,18 @@ class: AnnotateMinorMode : MinorMode method: undoRedoUpdate (void;) { + if (_currentNode eq nil) + { + _undoAct.setEnabled(false); + _redoAct.setEnabled(false); + _clearAct.setEnabled(false); + return; + } + let frame = _currentNodeInfo.frame; let undoProperty = frameUserUndoStackName(_currentNode, frame); let redoProperty = frameUserRedoStackName(_currentNode, frame); + let orderProperty = frameOrderName(_currentNode, frame); let playing = isPlaying(); _undoAct.setEnabled(!playing && @@ -1444,6 +1453,10 @@ class: AnnotateMinorMode : MinorMode _redoAct.setEnabled(!playing && propertyExists(redoProperty) && propertyInfo(redoProperty).size > 0); + + _clearAct.setEnabled(!playing && + propertyExists(orderProperty) && + propertyInfo(orderProperty).size > 0); } method: undoPaint (void;) @@ -2797,6 +2810,7 @@ class: AnnotateMinorMode : MinorMode { updateCurrentNode(); updateToolAvailability(); + undoRedoUpdate(); if (commands.isEventCategoryEnabled("annotate_category")) { From 92976e1ff900b7f0ef98cbfaa0cebd7df6c7f532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Thu, 4 Dec 2025 10:29:43 -0500 Subject: [PATCH 3/9] Refactor undo paint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 158 ++++++++++++++---- 1 file changed, 128 insertions(+), 30 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index 2783ea3f1..3d45441d6 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -396,15 +396,17 @@ class: AnnotateMinorMode : MinorMode "%s.frame:%d.order" % (node, frame); } - method: frameUserUndoStackName (string; string node, int frame) { - "%s.frame:%d.undo_%s" % (node, frame, encodedName(_user)); + "%s.frame:%d.undo_%s_%d" % (node, frame, encodedName(_user), _processId); } method: frameUserRedoStackName (string; string node, int frame) { - "%s.frame:%d.redo_%s" % (node, frame, encodedName(_user)); + method: undoClearAllFramesActionName (string;) + { + "%s.paint.undoClearAllFrames_%s_%d" % (viewNode(), encodedName(_user), _processId); + } } method: updateFrameDependentState (void;) @@ -1461,41 +1463,128 @@ class: AnnotateMinorMode : MinorMode method: undoPaint (void;) { - let frame = _currentNodeInfo.frame; - let orderProperty = frameOrderName(_currentNode, frame); - let undoProperty = frameUserUndoStackName(_currentNode, frame); - let redoProperty = frameUserRedoStackName(_currentNode, frame); - - if (propertyExists(undoProperty)) + let clearAllUndoProperty = undoClearAllFramesActionName(); + let clearAllRedoProperty = redoClearAllFramesActionName(); + + if (propertyExists(clearAllUndoProperty) && propertyInfo(clearAllUndoProperty).size > 0) { - if (!propertyExists(redoProperty)) + let clearAllUndo = getStringProperty(clearAllUndoProperty); + + // clearAllUndo format: ["clearAllFrames", "node1", "stroke1", "node2", "stroke2"] + if (clearAllUndo.size() > 1 && clearAllUndo[0] == "clearAllFrames") { - newProperty(redoProperty, StringType, 1); - } + beginCompoundStateChange(); + + for (int i = 1; i < clearAllUndo.size(); i += 2) + { + let node = clearAllUndo[i]; + let stroke = clearAllUndo[i + 1]; - let undo = getStringProperty(undoProperty); - let redo = getStringProperty(redoProperty); - let order = getStringProperty(orderProperty); + let parts = stroke.split(":"); // Stroke format: type:id:frame:user_processId + let frame = int(parts[2]); + + let orderName = frameOrderName(node, frame); + + if (!propertyExists(orderName)) + { + newProperty(orderName, StringType, 1); + } + + insertStringProperty(orderName, string[] {stroke}); + } - let stroke = undo.back(); - redo.push_back(stroke); - undo.resize(undo.size()-1); + if (!propertyExists(clearAllRedoProperty)) + { + newProperty(clearAllRedoProperty, StringType, 1); + } + setStringProperty(clearAllRedoProperty, clearAllUndo, true); + + deleteProperty(clearAllUndoProperty); + + endCompoundStateChange(); + return; + } + } - for_index(i; order) + let frame = _currentNodeInfo.frame; + let undoProperty = frameUserUndoStackName(_currentNode, frame); + let redoProperty = frameUserRedoStackName(_currentNode, frame); + let orderProperty = frameOrderName(_currentNode, frame); + + if (!propertyExists(undoProperty) || propertyInfo(undoProperty).size == 0) + { + return; + } + + if (!propertyExists(redoProperty)) + { + newProperty(redoProperty, StringType, 1); + } + + let undo = getStringProperty(undoProperty); + let redo = getStringProperty(redoProperty); + let order = getStringProperty(orderProperty); + + let action = undo.back(); + undo.resize(undo.size() - 1); + + if (action == "create") + { + if (undo.size() > 0) { - if (order[i] == stroke) + let stroke = undo.back(); + undo.resize(undo.size() - 1); + + for_index(i; order) { - order.erase(i, 1); - break; + if (order[i] == stroke) + { + order.erase(i, 1); + break; + } } + + redo.push_back(stroke); + redo.push_back("create"); } + } + else if (action == "clearAll") + { + if (undo.size() > 0) + { + let strokeCount = undo.back(); + undo.resize(undo.size() - 1); + let count = int(strokeCount); + + string[] strokes; + for (int i = 0; i < count; i++) + { + if (undo.size() > 0) + { + strokes.push_back(undo.back()); + undo.resize(undo.size() - 1); + } + } - beginCompoundStateChange(); - setStringProperty(undoProperty, undo, true); - setStringProperty(redoProperty, redo, true); - setStringProperty(orderProperty, order, true); - endCompoundStateChange(); + for_each(stroke; strokes) + { + order.push_back(stroke); + } + + for_each(stroke; strokes) + { + redo.push_back(stroke); + } + redo.push_back(strokeCount); + redo.push_back("clearAll"); + } } + + beginCompoundStateChange(); + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + endCompoundStateChange(); } method: redoPaint (void;) @@ -1816,9 +1905,18 @@ class: AnnotateMinorMode : MinorMode method: undoState (int;) { - if isSessionEmpty() || _currentNode eq nil - then DisabledMenuState - else propOnState(frameUserUndoStackName(_currentNode, _currentNodeInfo.frame)); + if (isSessionEmpty() || _currentNode eq nil) + { + return DisabledMenuState; + } + + let clearAllUndoProperty = undoClearAllFramesActionName(); + if (propertyExists(clearAllUndoProperty) && propertyInfo(clearAllUndoProperty).size > 0) + { + return UncheckedMenuState; + } + + return propOnState(frameUserUndoStackName(_currentNode, _currentNodeInfo.frame)); } method: redoState (int;) From 4fbe8df725f2c0fb3761dd378634fa1070bd2313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Thu, 4 Dec 2025 10:31:33 -0500 Subject: [PATCH 4/9] Refactor redo paint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 199 +++++++++++++----- 1 file changed, 147 insertions(+), 52 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index 3d45441d6..3bf7fcd5b 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -403,10 +403,17 @@ class: AnnotateMinorMode : MinorMode method: frameUserRedoStackName (string; string node, int frame) { + "%s.frame:%d.redo_%s_%d" % (node, frame, encodedName(_user), _processId); + } + method: undoClearAllFramesActionName (string;) { "%s.paint.undoClearAllFrames_%s_%d" % (viewNode(), encodedName(_user), _processId); } + + method: redoClearAllFramesActionName (string;) + { + "%s.paint.redoClearAllFrames_%s_%d" % (viewNode(), encodedName(_user), _processId); } method: updateFrameDependentState (void;) @@ -537,7 +544,13 @@ class: AnnotateMinorMode : MinorMode newProperty(undoName, StringType, 1); } - insertStringProperty(undoName, string[] {stroke}); + insertStringProperty(undoName, string[] {stroke, "create"}); + + let redoName = frameUserRedoStackName(node, frame); + if (propertyExists(redoName)) + { + setStringProperty(redoName, string[] {}, true); + } endCompoundStateChange(); return n; @@ -650,7 +663,13 @@ class: AnnotateMinorMode : MinorMode newProperty(undoName, StringType, 1); } - insertStringProperty(undoName, string[] {stroke}); + insertStringProperty(undoName, string[] {stroke, "create"}); + + let redoName = frameUserRedoStackName(node, frame); + if (propertyExists(redoName)) + { + setStringProperty(redoName, string[] {}, true); + } endCompoundStateChange(); return n; @@ -1589,68 +1608,135 @@ class: AnnotateMinorMode : MinorMode method: redoPaint (void;) { - let frame = _currentNodeInfo.frame; - let orderProperty = frameOrderName(_currentNode, frame); - let undoProperty = frameUserUndoStackName(_currentNode, frame); - let redoProperty = frameUserRedoStackName(_currentNode, frame); + let clearAllUndoName = undoClearAllFramesActionName(); + let clearAllRedoName = redoClearAllFramesActionName(); - if (propertyExists(redoProperty)) + if (propertyExists(clearAllRedoName) && propertyInfo(clearAllRedoName).size > 0) { - if (!propertyExists(undoProperty)) - { - newProperty(undoProperty, StringType, 1); - } + let clearAllRedo = getStringProperty(clearAllRedoName); - let undo = getStringProperty(undoProperty); - let redo = getStringProperty(redoProperty); - let order = getStringProperty(orderProperty); - - int startIndex = -1; - int endIndex = -1; - - for (int i = 0; i < redo.size(); i++) + // clearAllRedo format: ["clearAllFrames", "node1", "stroke1", "node2", "stroke2"] + if (clearAllRedo.size() > 1 && clearAllRedo[0] == "clearAllFrames") { - if (redo[i] == "start") - { - startIndex = i; - } - if (redo[i] == "end") + beginCompoundStateChange(); + + for (int i = 1; i < clearAllRedo.size(); i += 2) { - endIndex = i; - } - } - - string[] strokes; + let node = clearAllRedo[i]; + let stroke = clearAllRedo[i + 1]; + + let parts = stroke.split(":"); // Stroke format: type:id:frame:user_processId + let frame = int(parts[2]); - if (redo.size() >= 3 && startIndex != -1 && endIndex != -1) - { - for (int i = startIndex + 1; i < endIndex; i++) + let orderName = frameOrderName(node, frame); + if (propertyExists(orderName)) + { + let order = getStringProperty(orderName); + for_index(index; order) + { + if (order[index] == stroke) + { + order.erase(index, 1); + break; + } + } + setStringProperty(orderName, order, true); + } + } + + if (!propertyExists(clearAllUndoName)) { - let stroke = redo[i]; - strokes.push_back(stroke); - undo.push_back(stroke); + newProperty(clearAllUndoName, StringType, 1); } - redo.erase(startIndex, endIndex - startIndex + 1); + setStringProperty(clearAllUndoName, clearAllRedo, true); + + deleteProperty(clearAllRedoName); + + endCompoundStateChange(); + return; } - else + } + + let frame = _currentNodeInfo.frame; + let undoProperty = frameUserUndoStackName(_currentNode, frame); + let redoProperty = frameUserRedoStackName(_currentNode, frame); + let orderProperty = frameOrderName(_currentNode, frame); + + if (!propertyExists(redoProperty) || propertyInfo(redoProperty).size == 0) + { + return; + } + + if (!propertyExists(undoProperty)) + { + newProperty(undoProperty, StringType, 1); + } + + let undo = getStringProperty(undoProperty); + let redo = getStringProperty(redoProperty); + let order = getStringProperty(orderProperty); + + let action = redo.back(); + redo.resize(redo.size() - 1); + + if (action == "create") + { + if (redo.size() > 0) { let stroke = redo.back(); - strokes.push_back(stroke); - undo.push_back(stroke); redo.resize(redo.size() - 1); + + order.push_back(stroke); + + undo.push_back(stroke); + undo.push_back("create"); } - - - for_each(stroke; strokes) + } + else if (action == "clearAll") + { + if (redo.size() > 0) { - order.push_back(stroke); + let countStr = redo.back(); + redo.resize(redo.size() - 1); + let count = int(countStr); + + string[] strokes; + for (int i = 0; i < count; i++) + { + if (redo.size() > 0) + { + strokes.push_back(redo.back()); + redo.resize(redo.size() - 1); + } + } + + for_each(stroke; strokes) + { + for_index(i; order) + { + if (order[i] == stroke) + { + order.erase(i, 1); + break; + } + } + } + + for_each(stroke; strokes) + { + undo.push_back(stroke); + } + undo.push_back(countStr); + undo.push_back("clearAll"); } - - beginCompoundStateChange(); - setStringProperty(undoProperty, undo, true); - setStringProperty(redoProperty, redo, true); - setStringProperty(orderProperty, order, true); - endCompoundStateChange(); + } + + beginCompoundStateChange(); + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + endCompoundStateChange(); + } } } @@ -1921,9 +2007,18 @@ class: AnnotateMinorMode : MinorMode method: redoState (int;) { - if isSessionEmpty() || _currentNode eq nil - then DisabledMenuState - else propOnState(frameUserRedoStackName(_currentNode, _currentNodeInfo.frame)); + if (isSessionEmpty() || _currentNode eq nil) + { + return DisabledMenuState; + } + + let clearAllRedoProprety = redoClearAllFramesActionName(); + if (propertyExists(clearAllRedoProprety) && propertyInfo(clearAllRedoProprety).size > 0) + { + return UncheckedMenuState; + } + + return propOnState(frameUserRedoStackName(_currentNode, _currentNodeInfo.frame)); } method: nextPrevState (int;) From 2581b67b8196fe68ba66e31754edfad0cb386885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Thu, 4 Dec 2025 10:33:40 -0500 Subject: [PATCH 5/9] Refactor clear paint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 150 ++++++++++++++---- 1 file changed, 120 insertions(+), 30 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index 3bf7fcd5b..faffd3f0d 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -1737,6 +1737,25 @@ class: AnnotateMinorMode : MinorMode setStringProperty(orderProperty, order, true); endCompoundStateChange(); } + + method: clearAllUsersUndoRedoStacks (void; string node, int frame, string excludeUser="") + { + regex undoRedoPattern = regex(".*\\.frame:[0-9]+\\.(undo|redo)_.*"); + + for_each (prop; properties(node)) + { + if (undoRedoPattern.match(prop) && propertyExists(prop)) + { + if (excludeUser != "") + { + regex excludePattern = regex(".*_(" + excludeUser + ")$"); + if (excludePattern.match(prop)) + { + continue; + } + } + setStringProperty(prop, string[] {}, true); + } } } @@ -1746,36 +1765,114 @@ class: AnnotateMinorMode : MinorMode let undoProperty = frameUserUndoStackName(node, frame); let redoProperty = frameUserRedoStackName(node, frame); - if (propertyExists(undoProperty)) + if (propertyExists(orderProperty) && propertyInfo(orderProperty).size > 0) { - if (!propertyExists(redoProperty)) + let order = getStringProperty(orderProperty); + + if (order.size() > 0) { - newProperty(redoProperty, StringType, 1); + string[] undo; + string[] redo; + + for_each(stroke; order) + { + undo.push_back(stroke); + } + undo.push_back(string(order.size())); + undo.push_back("clearAll"); + + order.clear(); + + beginCompoundStateChange(); + + if (!propertyExists(undoProperty)) + { + newProperty(undoProperty, StringType, 1); + } + if (!propertyExists(redoProperty)) + { + newProperty(redoProperty, StringType, 1); + } + + setStringProperty(undoProperty, undo, true); + setStringProperty(redoProperty, redo, true); + setStringProperty(orderProperty, order, true); + + let excludeUser = encodedName(_user) + "_" + _processId; + clearAllUsersUndoRedoStacks(node, frame, excludeUser); + + endCompoundStateChange(); } + } + } - let undo = getStringProperty(undoProperty); - let redo = getStringProperty(redoProperty); - let order = getStringProperty(orderProperty); + method: clearAllPaint (void;) + { + string[] clearAllActions; + clearAllActions.push_back("clearAllFrames"); - if (undo.size() > 0) + beginCompoundStateChange(); + + for_each(node; nodes()) + { + let annotatedFrames = findAnnotatedFrames(node); + for_each(frame; annotatedFrames) { - redo.push_back("start"); - for_each(stroke; undo) + let orderProperty = frameOrderName(node, frame); + if (propertyExists(orderProperty) && propertyInfo(orderProperty).size > 0) { - redo.push_back(stroke); + let order = getStringProperty(orderProperty); + for_each(stroke; order) + { + clearAllActions.push_back(node); + clearAllActions.push_back(stroke); + } + + setStringProperty(orderProperty, string[] {}, true); } - redo.push_back("end"); - undo.clear(); - order.clear(); + let sourceFrame = sourceFrame(frame); + if (sourceFrame != frame) + { + let sourceFrameOrderProperty = frameOrderName(node, sourceFrame); + if (propertyExists(sourceFrameOrderProperty) && propertyInfo(sourceFrameOrderProperty).size > 0) + { + let srcOrder = getStringProperty(sourceFrameOrderProperty); + for_each(stroke; srcOrder) + { + clearAllActions.push_back(node); + clearAllActions.push_back(stroke); + } + + setStringProperty(sourceFrameOrderProperty, string[] {}, true); + } + } + + clearAllUsersUndoRedoStacks(node, frame, ""); + } + } + + if (clearAllActions.size() > 1) + { + let clearAllUndoName = undoClearAllFramesActionName(); + let clearAllRedoName = redoClearAllFramesActionName(); + + if (!propertyExists(clearAllUndoName)) + { + newProperty(clearAllUndoName, StringType, 1); } - beginCompoundStateChange(); - setStringProperty(undoProperty, undo, true); - setStringProperty(redoProperty, redo, true); - setStringProperty(orderProperty, order, true); - endCompoundStateChange(); + setStringProperty(clearAllUndoName, clearAllActions, true); + + if (propertyExists(clearAllRedoName)) + { + deleteProperty(clearAllRedoName); + } } + + endCompoundStateChange(); + updateFrameDependentState(); + redraw(); } method: populateAnnotationList (void;) @@ -1918,20 +2015,13 @@ class: AnnotateMinorMode : MinorMode { let answer = alertPanel(true, InfoAlert, "Clear all annotations from the current timeline?", nil, "OK", "Cancel", nil); - if (answer != 0) - { - return; - } + if (answer != 0) + { + return; } - - for_each(node; nodes()) + else { - let annotatedFrames = findAnnotatedFrames(node); - for_each(frame; annotatedFrames) - { - clearPaint(node, frame); - clearPaint(node, sourceFrame(frame)); - } + clearAllPaint(); } updateFrameDependentState(); From 0b981f83058f943920963dc17d78fd387c6967b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Thu, 4 Dec 2025 10:34:55 -0500 Subject: [PATCH 6/9] Update undo/redo/clear UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 69 ++++++++++++++----- 1 file changed, 51 insertions(+), 18 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index faffd3f0d..a7c24f8d4 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -140,6 +140,8 @@ class: AnnotateMinorMode : MinorMode QAction _undoAct; QAction _redoAct; QAction _clearAct; + QAction _clearFrameAct; + QAction _clearAllFramesAct; QListWidget _annotationsWidget; QTextEdit _notesEdit; QDockWidget _manageDock; @@ -419,7 +421,7 @@ class: AnnotateMinorMode : MinorMode method: updateFrameDependentState (void;) { updateCurrentNode(); - undoRedoUpdate(); + undoRedoClearUpdate(); //populateAnnotationList(); } @@ -1143,7 +1145,7 @@ class: AnnotateMinorMode : MinorMode endCompoundStateChange(); } - undoRedoUpdate(); + undoRedoClearUpdate(); redraw(); } @@ -1398,6 +1400,7 @@ class: AnnotateMinorMode : MinorMode } updateDrawModeUI(); + undoRedoClearUpdate(); _toolSliderLabel.setText(if d.sliderName eq nil then "Opacity" else d.sliderName); } @@ -1451,13 +1454,15 @@ class: AnnotateMinorMode : MinorMode _colorDialog.show(); } - method: undoRedoUpdate (void;) + method: undoRedoClearUpdate (void;) { - if (_currentNode eq nil) + if (_currentDrawMode eq _selectDrawMode || _currentNode eq nil) { _undoAct.setEnabled(false); _redoAct.setEnabled(false); _clearAct.setEnabled(false); + _clearFrameAct.setEnabled(false); + _clearAllFramesAct.setEnabled(false); return; } @@ -1465,19 +1470,47 @@ class: AnnotateMinorMode : MinorMode let undoProperty = frameUserUndoStackName(_currentNode, frame); let redoProperty = frameUserRedoStackName(_currentNode, frame); let orderProperty = frameOrderName(_currentNode, frame); + let clearAllUndoProperty = undoClearAllFramesActionName(); + let clearAllRedoProperty = redoClearAllFramesActionName(); let playing = isPlaying(); - _undoAct.setEnabled(!playing && - propertyExists(undoProperty) && - propertyInfo(undoProperty).size > 0); + let hasUndoClearAll = propertyExists(clearAllUndoProperty) && + propertyInfo(clearAllUndoProperty).size > 0; + let hasFrameUndo = propertyExists(undoProperty) && + propertyInfo(undoProperty).size > 0; + _undoAct.setEnabled(!playing && (hasUndoClearAll || hasFrameUndo)); - _redoAct.setEnabled(!playing && - propertyExists(redoProperty) && - propertyInfo(redoProperty).size > 0); + let hasRedoClearAll = propertyExists(clearAllRedoProperty) && + propertyInfo(clearAllRedoProperty).size > 0; + let hasFrameRedo = propertyExists(redoProperty) && + propertyInfo(redoProperty).size > 0; + _redoAct.setEnabled(!playing && (hasRedoClearAll || hasFrameRedo)); - _clearAct.setEnabled(!playing && - propertyExists(orderProperty) && - propertyInfo(orderProperty).size > 0); + _clearAct.setEnabled(!playing); + + if (!playing) + { + bool hasCurrentFrameStrokes = propertyExists(orderProperty) && + propertyInfo(orderProperty).size > 0; + _clearFrameAct.setEnabled(hasCurrentFrameStrokes); + + bool hasAnyStrokes = false; + for_each(node; nodes()) + { + let annotatedFrames = findAnnotatedFrames(node); + if (!annotatedFrames.empty()) + { + hasAnyStrokes = true; + break; + } + } + _clearAllFramesAct.setEnabled(hasAnyStrokes); + } + else + { + _clearFrameAct.setEnabled(false); + _clearAllFramesAct.setEnabled(false); + } } method: undoPaint (void;) @@ -2859,14 +2892,14 @@ class: AnnotateMinorMode : MinorMode _clearButton.setDefaultAction(_clearAct); let clearMenu = QMenu("Clear Frame", _clearButton); - let clearFrame = clearMenu.addAction("Clear Frame"); - let clearAllFrames = clearMenu.addAction("Clear All Frames on Timeline"); + _clearFrameAct = clearMenu.addAction("Clear Frame"); + _clearAllFramesAct = clearMenu.addAction("Clear All Frames on Timeline"); _clearButton.setMenu(clearMenu); _clearButton.setPopupMode(QToolButton.InstantPopup); - connect(clearFrame, QAction.triggered, clearSlot); - connect(clearAllFrames, QAction.triggered, clearAllSlot); + connect(_clearFrameAct, QAction.triggered, clearSlot); + connect(_clearAllFramesAct, QAction.triggered, clearAllSlot); _clearButton.setStyleSheet("QToolButton::menu-indicator { subcontrol-position: bottom right; top: -2px; }"); _drawDock.setWidget(_drawPane); @@ -3093,7 +3126,7 @@ class: AnnotateMinorMode : MinorMode { updateCurrentNode(); updateToolAvailability(); - undoRedoUpdate(); + undoRedoClearUpdate(); if (commands.isEventCategoryEnabled("annotate_category")) { From 66fed65ef39db308fdea99266e0306301447e30f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Thu, 4 Dec 2025 11:55:19 -0500 Subject: [PATCH 7/9] Renamde clearAllFrames properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index a7c24f8d4..91c51628b 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -408,12 +408,12 @@ class: AnnotateMinorMode : MinorMode "%s.frame:%d.redo_%s_%d" % (node, frame, encodedName(_user), _processId); } - method: undoClearAllFramesActionName (string;) + method: undoClearAllFramesName (string;) { "%s.paint.undoClearAllFrames_%s_%d" % (viewNode(), encodedName(_user), _processId); } - method: redoClearAllFramesActionName (string;) + method: redoClearAllFramesName (string;) { "%s.paint.redoClearAllFrames_%s_%d" % (viewNode(), encodedName(_user), _processId); } @@ -1470,8 +1470,8 @@ class: AnnotateMinorMode : MinorMode let undoProperty = frameUserUndoStackName(_currentNode, frame); let redoProperty = frameUserRedoStackName(_currentNode, frame); let orderProperty = frameOrderName(_currentNode, frame); - let clearAllUndoProperty = undoClearAllFramesActionName(); - let clearAllRedoProperty = redoClearAllFramesActionName(); + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); let playing = isPlaying(); let hasUndoClearAll = propertyExists(clearAllUndoProperty) && @@ -1515,8 +1515,8 @@ class: AnnotateMinorMode : MinorMode method: undoPaint (void;) { - let clearAllUndoProperty = undoClearAllFramesActionName(); - let clearAllRedoProperty = redoClearAllFramesActionName(); + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); if (propertyExists(clearAllUndoProperty) && propertyInfo(clearAllUndoProperty).size > 0) { @@ -1551,7 +1551,7 @@ class: AnnotateMinorMode : MinorMode } setStringProperty(clearAllRedoProperty, clearAllUndo, true); - deleteProperty(clearAllUndoProperty); + setStringProperty(clearAllUndoProperty, string[] {}, true); endCompoundStateChange(); return; @@ -1641,12 +1641,12 @@ class: AnnotateMinorMode : MinorMode method: redoPaint (void;) { - let clearAllUndoName = undoClearAllFramesActionName(); - let clearAllRedoName = redoClearAllFramesActionName(); + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); - if (propertyExists(clearAllRedoName) && propertyInfo(clearAllRedoName).size > 0) + if (propertyExists(clearAllRedoProperty) && propertyInfo(clearAllRedoProperty).size > 0) { - let clearAllRedo = getStringProperty(clearAllRedoName); + let clearAllRedo = getStringProperty(clearAllRedoProperty); // clearAllRedo format: ["clearAllFrames", "node1", "stroke1", "node2", "stroke2"] if (clearAllRedo.size() > 1 && clearAllRedo[0] == "clearAllFrames") @@ -1677,13 +1677,13 @@ class: AnnotateMinorMode : MinorMode } } - if (!propertyExists(clearAllUndoName)) + if (!propertyExists(clearAllUndoProperty)) { - newProperty(clearAllUndoName, StringType, 1); + newProperty(clearAllUndoProperty, StringType, 1); } - setStringProperty(clearAllUndoName, clearAllRedo, true); + setStringProperty(clearAllUndoProperty, clearAllRedo, true); - deleteProperty(clearAllRedoName); + setStringProperty(clearAllRedoProperty, string[] {}, true); endCompoundStateChange(); return; @@ -1887,19 +1887,19 @@ class: AnnotateMinorMode : MinorMode if (clearAllActions.size() > 1) { - let clearAllUndoName = undoClearAllFramesActionName(); - let clearAllRedoName = redoClearAllFramesActionName(); + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); - if (!propertyExists(clearAllUndoName)) + if (!propertyExists(clearAllUndoProperty)) { - newProperty(clearAllUndoName, StringType, 1); + newProperty(clearAllUndoProperty, StringType, 1); } - setStringProperty(clearAllUndoName, clearAllActions, true); + setStringProperty(clearAllUndoProperty, clearAllActions, true); - if (propertyExists(clearAllRedoName)) + if (propertyExists(clearAllRedoProperty)) { - deleteProperty(clearAllRedoName); + setStringProperty(clearAllRedoProperty, string[] {}, true); } } @@ -2119,7 +2119,7 @@ class: AnnotateMinorMode : MinorMode return DisabledMenuState; } - let clearAllUndoProperty = undoClearAllFramesActionName(); + let clearAllUndoProperty = undoClearAllFramesName(); if (propertyExists(clearAllUndoProperty) && propertyInfo(clearAllUndoProperty).size > 0) { return UncheckedMenuState; @@ -2135,8 +2135,8 @@ class: AnnotateMinorMode : MinorMode return DisabledMenuState; } - let clearAllRedoProprety = redoClearAllFramesActionName(); - if (propertyExists(clearAllRedoProprety) && propertyInfo(clearAllRedoProprety).size > 0) + let clearAllRedoProperty = redoClearAllFramesName(); + if (propertyExists(clearAllRedoProperty) && propertyInfo(clearAllRedoProperty).size > 0) { return UncheckedMenuState; } From 12fcb2ae26d6d40502e818f0ae48c5aec8f23490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Mon, 8 Dec 2025 10:41:20 -0500 Subject: [PATCH 8/9] Update Annotate package to 1.21 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- src/plugins/rv-packages/annotate/PACKAGE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/rv-packages/annotate/PACKAGE b/src/plugins/rv-packages/annotate/PACKAGE index 0f19eccc4..49920d3f7 100644 --- a/src/plugins/rv-packages/annotate/PACKAGE +++ b/src/plugins/rv-packages/annotate/PACKAGE @@ -1,7 +1,7 @@ package: Annotation author: Autodesk, Inc. organization: Autodesk, Inc. -version: 1.20 +version: 1.21 rv: 2025 openrv: 3.0.0 requires: '' From 978f6608f3b9e1f55348ca4c07c454b0f219416d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lo=C3=AFse=20Brosseau?= Date: Tue, 9 Dec 2025 11:50:38 -0500 Subject: [PATCH 9/9] Reset global clearAll undo-redo properties on new annotation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Éloïse Brosseau --- .../rv-packages/annotate/annotate_mode.mu | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/plugins/rv-packages/annotate/annotate_mode.mu b/src/plugins/rv-packages/annotate/annotate_mode.mu index 91c51628b..c75c292a8 100644 --- a/src/plugins/rv-packages/annotate/annotate_mode.mu +++ b/src/plugins/rv-packages/annotate/annotate_mode.mu @@ -554,6 +554,19 @@ class: AnnotateMinorMode : MinorMode setStringProperty(redoName, string[] {}, true); } + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); + + if (propertyExists(clearAllUndoProperty)) + { + setStringProperty(clearAllUndoProperty, string[] {}, true); + } + + if (propertyExists(clearAllRedoProperty)) + { + setStringProperty(clearAllRedoProperty, string[] {}, true); + } + endCompoundStateChange(); return n; } @@ -673,6 +686,19 @@ class: AnnotateMinorMode : MinorMode setStringProperty(redoName, string[] {}, true); } + let clearAllUndoProperty = undoClearAllFramesName(); + let clearAllRedoProperty = redoClearAllFramesName(); + + if (propertyExists(clearAllUndoProperty)) + { + setStringProperty(clearAllUndoProperty, string[] {}, true); + } + + if (propertyExists(clearAllRedoProperty)) + { + setStringProperty(clearAllRedoProperty, string[] {}, true); + } + endCompoundStateChange(); return n; }