diff --git a/src/Pyramid-Bloc/PyramidAddChildCommand.class.st b/src/Pyramid-Bloc/PyramidAddChildCommand.class.st index 5b13af9..05e2cb5 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 1c14656..520fe7c 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 2beae59..9e281af 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 0000000..76ffedc --- /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 f3eb07f..8ec7456 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 ] ]