From 8550b54e3b83d5f588c30563407e3c072483b76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Magu=C3=A9r=C3=A8s?= Date: Tue, 21 Apr 2026 14:43:54 +0200 Subject: [PATCH] =?UTF-8?q?fix=20issue=20:=20Undo=20of=20remove=20element?= =?UTF-8?q?=20doesn=E2=80=99t=20put=20it=20back=20in=20the=20same=20positi?= =?UTF-8?q?on=20#187?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PyramidAddChildCommand.class.st | 7 +- .../PyramidAddChildrenCommand.class.st | 4 +- ...amidRemoveSelectedElementsCommand.class.st | 29 ++++--- ...PyramidUndoRemoveChildCommandTest.class.st | 87 +++++++++++++++++++ src/Pyramid/PyramidCompositeMemento.class.st | 7 +- 5 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 src/Pyramid-Tests/PyramidUndoRemoveChildCommandTest.class.st diff --git a/src/Pyramid-Bloc/PyramidAddChildCommand.class.st b/src/Pyramid-Bloc/PyramidAddChildCommand.class.st index 5b13af98..05e2cb54 100644 --- a/src/Pyramid-Bloc/PyramidAddChildCommand.class.st +++ b/src/Pyramid-Bloc/PyramidAddChildCommand.class.st @@ -12,6 +12,9 @@ PyramidAddChildCommand >> commandInverse [ { #category : #'as yet unclassified' } PyramidAddChildCommand >> setValueFor: aBlElement with: aChildToAdd [ - - aBlElement addChild: aChildToAdd + | index | + index := aChildToAdd userData at: #removedAtIndex ifAbsent: [ 0 ]. + (index = 0 or: [ index > aBlElement children size ]) + ifTrue: [ aBlElement addChild: aChildToAdd ] + ifFalse: [ aBlElement addChild: aChildToAdd at: index ] ] diff --git a/src/Pyramid-Bloc/PyramidAddChildrenCommand.class.st b/src/Pyramid-Bloc/PyramidAddChildrenCommand.class.st index 1c146561..520fe7cd 100644 --- a/src/Pyramid-Bloc/PyramidAddChildrenCommand.class.st +++ b/src/Pyramid-Bloc/PyramidAddChildrenCommand.class.st @@ -12,6 +12,6 @@ PyramidAddChildrenCommand >> commandInverse [ { #category : #'as yet unclassified' } PyramidAddChildrenCommand >> setValueFor: aBlElement with: aChildrenToAdd [ - - aBlElement addChildren: aChildrenToAdd + aChildrenToAdd do: [ :child | + aBlElement addChild: child ] ] diff --git a/src/Pyramid-Bloc/PyramidRemoveSelectedElementsCommand.class.st b/src/Pyramid-Bloc/PyramidRemoveSelectedElementsCommand.class.st index 2beae596..9e281af1 100644 --- a/src/Pyramid-Bloc/PyramidRemoveSelectedElementsCommand.class.st +++ b/src/Pyramid-Bloc/PyramidRemoveSelectedElementsCommand.class.st @@ -15,18 +15,23 @@ PyramidRemoveSelectedElementsCommand >> getValueFor: anElementOfSelection [ { #category : #'as yet unclassified' } PyramidRemoveSelectedElementsCommand >> mementoFor: anElement withArguments: anArgument [ - - (anArgument includes: anElement) ifTrue: [ - ^ PyramidCommandMemento new - command: PyramidRemoveFromCollectionCommand new commandInverse; - target: anArgument; - arguments: anElement; - yourself ]. - ^ PyramidCommandMemento new - command: PyramidRemoveChildCommand new commandInverse; - target: anElement parent; - arguments: anElement; - yourself + | index | + "Save index before removing" + index := anElement parent + ifNotNil: [ :p | p children indexOf: anElement ] + ifNil: [ 0 ]. + anElement userData at: #removedAtIndex put: index. + (anArgument includes: anElement) ifTrue: [ + ^ PyramidCommandMemento new + command: PyramidRemoveFromCollectionCommand new commandInverse; + target: anArgument; + arguments: anElement; + yourself ]. + ^ PyramidCommandMemento new + command: PyramidRemoveChildCommand new commandInverse; + target: anElement parent; + arguments: anElement; + yourself ] { #category : #accessing } diff --git a/src/Pyramid-Tests/PyramidUndoRemoveChildCommandTest.class.st b/src/Pyramid-Tests/PyramidUndoRemoveChildCommandTest.class.st new file mode 100644 index 00000000..76ffedc0 --- /dev/null +++ b/src/Pyramid-Tests/PyramidUndoRemoveChildCommandTest.class.st @@ -0,0 +1,87 @@ +Class { + #name : #PyramidUndoRemoveChildCommandTest, + #superclass : #TestCase, + #category : #'Pyramid-Tests-cases-plugin-bloc' +} + +{ #category : #tests } +PyramidUndoRemoveChildCommandTest >> testUndoRemoveAllChildrenRestoresIndex [ + + | history commandExecutor parent child1 child2 child3 child4| + parent := BlElement new. + child1 := BlElement new. + child2 := BlElement new. + child3 := BlElement new. + child4 := BlElement new. + parent addChildren: {child1. child2 .child3. child4}. + + history := PyramidHistory new. + commandExecutor := PyramidHistoryCommandExecutor new + history: history; + wrappee: PyramidMainCommandExecutor new; + yourself. + commandExecutor + use: PyramidRemoveSelectedElementsCommand new + on: { + child4. + child2. + child1 } + with: { parent }. + + self deny: (parent children includes: child2). + self deny: (parent children includes: child1). + self deny: (parent children includes: child4). + + "Undo" + history undo. + + self assert: (parent children includes: child1). + self assert: (parent children includes: child2). + self assert: (parent children indexOf: child1) equals: 1. + self assert: (parent children indexOf: child2) equals: 2. + self assert: (parent children indexOf: child4) equals: 4 +] + +{ #category : #tests } +PyramidUndoRemoveChildCommandTest >> testUndoRemoveChildRestoresIndex [ + + | history commandExecutor parent child1 child2 child3 | + + parent := BlElement new. + child1 := BlElement new. + child2 := BlElement new. + child3 := BlElement new. + parent addChild: child1. + parent addChild: child2. + parent addChild: child3. + + history := PyramidHistory new. + commandExecutor := PyramidHistoryCommandExecutor new + history: history; + wrappee: PyramidMainCommandExecutor new; + yourself. + + commandExecutor + use: PyramidRemoveSelectedElementsCommand new + on: { child2 } + with: { parent }. + + self deny: (parent children includes: child2). + + "Undo" + history undo. + + self assert: (parent children includes: child2). + self assert: (parent children indexOf: child2) equals: 2. + + "Redo" + history redo. + + self deny: (parent children includes: child2). + + "Undo" + history undo. + + self assert: (parent children includes: child2). + self assert: (parent children indexOf: child2) equals: 2 +] diff --git a/src/Pyramid/PyramidCompositeMemento.class.st b/src/Pyramid/PyramidCompositeMemento.class.st index f3eb07f9..8ec74569 100644 --- a/src/Pyramid/PyramidCompositeMemento.class.st +++ b/src/Pyramid/PyramidCompositeMemento.class.st @@ -34,5 +34,10 @@ PyramidCompositeMemento >> mementos: anObject [ { #category : #'window management' } PyramidCompositeMemento >> restore [ - self mementos do: [ :each | each restore ] + (self mementos allSatisfy: [ :m | m arguments isKindOf: BlElement ]) + ifFalse: [ self mementos do: [ :each | each restore ]. ^ self ]. + (self mementos asSortedCollection: [ :a :b | + (a arguments userData at: #removedAtIndex ifAbsent: [ 0 ]) + < (b arguments userData at: #removedAtIndex ifAbsent: [ 0 ]) ]) + do: [ :each | each restore ] ]