From b4e7527eb408c4cb477f2efca8cf2abccb0adc8e Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 16 Jul 2023 10:55:55 +0300 Subject: [PATCH 1/2] FBP-325. Improved cascade handling on element removal --- .../plugin/core/KeyboardEventHandler.kt | 2 +- .../actions/ElementRemoveActionHandler.kt | 26 +++++++++++-------- .../core/events/ProcessModelUpdateEvents.kt | 10 ++++++- .../core/render/DefaultBpmnProcessRenderer.kt | 2 +- .../elements/BaseDiagramRenderElement.kt | 13 +++++++++- .../elements/edges/EdgeRenderElement.kt | 14 +++++++--- .../elements/shapes/ShapeRenderElement.kt | 4 +-- 7 files changed, 50 insertions(+), 21 deletions(-) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/KeyboardEventHandler.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/KeyboardEventHandler.kt index 82326ab68..9a0b2508a 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/KeyboardEventHandler.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/KeyboardEventHandler.kt @@ -81,7 +81,7 @@ class KeyboardEventHandler(private val project: Project, private val canvas: Can KeyEvent.VK_DOWN -> canvas.dragCanvas(start, Point2D.Float(0.0f, -step)) KeyEvent.VK_LEFT -> canvas.dragCanvas(start, Point2D.Float(step, 0.0f)) KeyEvent.VK_RIGHT -> canvas.dragCanvas(start, Point2D.Float(-step, 0.0f)) - KeyEvent.VK_DELETE -> currentRemoveActionHandler(project).deleteElem() + KeyEvent.VK_DELETE -> currentRemoveActionHandler(project).deleteSelectedElements() } } } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt index bd48851d9..6879dbcd6 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt @@ -1,10 +1,9 @@ package com.valb3r.bpmn.intellij.plugin.core.actions import com.intellij.openapi.project.Project -import com.valb3r.bpmn.intellij.plugin.core.events.BpmnElementRemovedEvent -import com.valb3r.bpmn.intellij.plugin.core.events.DiagramElementRemovedEvent +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.PropertyUpdateWithId import com.valb3r.bpmn.intellij.plugin.core.events.updateEventsRegistry -import com.valb3r.bpmn.intellij.plugin.core.render.AreaType import com.valb3r.bpmn.intellij.plugin.core.render.currentCanvas import com.valb3r.bpmn.intellij.plugin.core.render.lastRenderedState import java.util.* @@ -19,17 +18,22 @@ fun currentRemoveActionHandler(project: Project): ElementRemoveActionHandler { class ElementRemoveActionHandler(private val project: Project) { - fun deleteElem() { + fun deleteSelectedElements() { val state = lastRenderedState(project)?.state ?: return - val targetIds = state.ctx.selectedIds.filter { - val area = state.elemMap[it]?.areaType - area == AreaType.SHAPE_THAT_NESTS || area == AreaType.SHAPE || area == AreaType.EDGE + + val toDelete = mutableListOf() + toDelete += state.ctx.selectedIds.mapNotNull { state.elemMap[it] }.flatMap { + val elemRemoval = it.getEventsToElementWithItsDiagram() + return@flatMap elemRemoval.diagram + elemRemoval.bpmn + elemRemoval.other + } + val inOrder = toDelete.sortedBy { + when (it) { + is PropertyUpdateWithId -> return@sortedBy 0 + else -> return@sortedBy 100 + } } - updateEventsRegistry(project).addElementRemovedEvent( - targetIds.map { DiagramElementRemovedEvent(it) }, - targetIds.mapNotNull { state.currentState.elementByDiagramId[it] }.map { BpmnElementRemovedEvent(it) } - ) + updateEventsRegistry(project).addEvents(inOrder) currentCanvas(project).repaint() } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/events/ProcessModelUpdateEvents.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/events/ProcessModelUpdateEvents.kt index 8070f7208..9756aac43 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/events/ProcessModelUpdateEvents.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/events/ProcessModelUpdateEvents.kt @@ -170,6 +170,7 @@ class ProcessModelUpdateEvents(private val committer: FileCommitter, private val is BpmnEdgeObjectAddedEvent -> addObjectEdgeEvent(toStore as Order) is BpmnElementRemovedEvent -> removeBpmnElement(event.bpmnElementId , toStore as Order ) is BpmnElementTypeChangeEvent -> changeBpmnElement(event.elementId , toStore as Order, toStore as Order) + is DiagramElementRemovedEvent -> removeDiagramElement(event, toStore as Order) else -> throw IllegalArgumentException("Can't bulk add: " + event::class.qualifiedName) } } @@ -196,7 +197,7 @@ class ProcessModelUpdateEvents(private val committer: FileCommitter, private val diagram.forEachIndexed {index, event -> val toStore = Order(current + index, event, EventBlock(blockSize)) updates.add(toStore) - deletionsByStaticId.computeIfAbsent(event.elementId) { CopyOnWriteArrayList() } += toStore + removeDiagramElement(event, toStore) } bpmn.forEachIndexed {index, event -> @@ -214,6 +215,13 @@ class ProcessModelUpdateEvents(private val committer: FileCommitter, private val commitToFile() } + private fun removeDiagramElement( + event: DiagramElementRemovedEvent, + toStore: Order + ) { + deletionsByStaticId.computeIfAbsent(event.elementId) { CopyOnWriteArrayList() } += toStore + } + private fun removeBpmnElement( bpmnElement: BpmnElementId, toStore: Order diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt index 9d997d3d7..3b33a0563 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/DefaultBpmnProcessRenderer.kt @@ -311,7 +311,7 @@ class DefaultBpmnProcessRenderer(private val project: Project, val icons: IconPr BoundsElement(maxX, minY, actionsIcoSize, actionsIcoSize), icons.recycleBin ) - state.ctx.interactionContext.clickCallbacks[delId] = { currentRemoveActionHandler(project).deleteElem() } + state.ctx.interactionContext.clickCallbacks[delId] = { currentRemoveActionHandler(project).deleteSelectedElements() } renderedArea[delId] = AreaWithZindex(deleteIconArea, AreaType.POINT, mutableSetOf(), mutableSetOf(), ANCHOR_Z_INDEX, null) } diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt index c59cd7bb0..8f007e2c4 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/BaseDiagramRenderElement.kt @@ -3,6 +3,7 @@ package com.valb3r.bpmn.intellij.plugin.core.render.elements import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.BpmnElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.DiagramElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.PropertyUpdateWithId import com.valb3r.bpmn.intellij.plugin.core.Colors import com.valb3r.bpmn.intellij.plugin.core.events.BpmnElementRemovedEvent import com.valb3r.bpmn.intellij.plugin.core.events.DiagramElementRemovedEvent @@ -115,6 +116,10 @@ abstract class BaseDiagramRenderElement( return listOf() } + open fun getEventsToElementWithItsDiagram(): ElementRemovalEvents { + return ElementRemovalEvents(getEventsToDeleteDiagram(), getEventsToDeleteElement(), emptyList()) + } + open fun zIndex(): Int { return if (isActiveOrDragged()) ANCHOR_Z_INDEX else (parents.firstOrNull()?.zIndex() ?: -1) + 1 } @@ -287,4 +292,10 @@ abstract class BaseDiagramRenderElement( currentOnScreenRect(state().ctx.canvas.camera) children.forEach {it.currentOnScreenRect(state().ctx.canvas.camera)} } -} \ No newline at end of file +} + +data class ElementRemovalEvents( + val diagram: List, + val bpmn: List, + val other: List +) \ No newline at end of file diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/EdgeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/EdgeRenderElement.kt index 207e0e13c..37a8b64c2 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/EdgeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/edges/EdgeRenderElement.kt @@ -4,6 +4,7 @@ import com.valb3r.bpmn.intellij.plugin.bpmn.api.bpmn.BpmnElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.DiagramElementId import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.BoundsElement import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.EdgeWithIdentifiableWaypoints +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event import com.valb3r.bpmn.intellij.plugin.bpmn.api.info.PropertyType import com.valb3r.bpmn.intellij.plugin.core.Colors import com.valb3r.bpmn.intellij.plugin.core.events.BpmnElementRemovedEvent @@ -27,14 +28,19 @@ class EdgeRenderElement( val delId = elementId.elemIdToRemove() val deleteIconArea = state().ctx.canvas.drawIcon(BoundsElement(x, y - ACTIONS_ICO_SIZE, ACTIONS_ICO_SIZE, ACTIONS_ICO_SIZE), state().icons.recycleBin) state().ctx.interactionContext.clickCallbacks[delId] = { dest -> - val currentProps = state().currentState.propertyWithElementByPropertyType - val cascadeEvents = computeCascadeChangeOfBpmnIncomingOutgoingIndex(bpmnElementId, currentProps, PropertyType.BPMN_INCOMING).toMutableList() + - computeCascadeChangeOfBpmnIncomingOutgoingIndex(bpmnElementId, currentProps, PropertyType.BPMN_OUTGOING) - dest.addElementRemovedEvent(getEventsToDeleteDiagram(), getEventsToDeleteElement(), cascadeEvents) + val removalEvents = getEventsToElementWithItsDiagram() + dest.addElementRemovedEvent(removalEvents.diagram, removalEvents.bpmn, removalEvents.other) } return mutableMapOf( delId to AreaWithZindex(deleteIconArea, AreaType.POINT, mutableSetOf(), mutableSetOf(), ICON_Z_INDEX, elementId) ) } + + override fun getEventsToElementWithItsDiagram(): ElementRemovalEvents { + val currentProps = state().currentState.propertyWithElementByPropertyType + val cascadeEvents = computeCascadeChangeOfBpmnIncomingOutgoingIndex(bpmnElementId, currentProps, PropertyType.BPMN_INCOMING).toMutableList() + + computeCascadeChangeOfBpmnIncomingOutgoingIndex(bpmnElementId, currentProps, PropertyType.BPMN_OUTGOING) + return ElementRemovalEvents(getEventsToDeleteDiagram(), getEventsToDeleteElement(), cascadeEvents) + } } \ No newline at end of file diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt index 26d69f8e1..9b0950e12 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/render/elements/shapes/ShapeRenderElement.kt @@ -89,7 +89,8 @@ abstract class ShapeRenderElement( val delId = elementId.elemIdToRemove() val deleteIconArea = state().ctx.canvas.drawIcon(BoundsElement(x, currY, ACTIONS_ICO_SIZE, ACTIONS_ICO_SIZE), state().icons.recycleBin) state().ctx.interactionContext.clickCallbacks[delId] = { dest -> - dest.addElementRemovedEvent(getEventsToDeleteDiagram(), getEventsToDeleteElement()) + val removalEvents = getEventsToElementWithItsDiagram() + dest.addElementRemovedEvent(removalEvents.diagram, removalEvents.bpmn, removalEvents.other) } if (ACTIONS_ICO_SIZE * actionCount >= (right.y - left.y)) { @@ -119,7 +120,6 @@ abstract class ShapeRenderElement( ) } - abstract fun doRender(ctx: RenderContext, shapeCtx: ShapeCtx): Map override fun doDragToWithoutChildren(dx: Float, dy: Float) { From 56f5f66564ece950c1e7c3d1fc1c8bede7dcb165 Mon Sep 17 00:00:00 2001 From: valb3r Date: Sun, 16 Jul 2023 11:39:15 +0300 Subject: [PATCH 2/2] FBP-325. Improved cascade handling on element removal --- .../plugin/core/actions/ActionUtil.kt | 20 ++++++++++++++++ .../actions/ElementRemoveActionHandler.kt | 13 ++--------- .../copypaste/CopyPasteActionHandler.kt | 23 ++++++++++--------- .../plugin/bpmn/parser/core/BaseBpmnParser.kt | 4 ++-- 4 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ActionUtil.kt diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ActionUtil.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ActionUtil.kt new file mode 100644 index 000000000..623f28e0b --- /dev/null +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ActionUtil.kt @@ -0,0 +1,20 @@ +package com.valb3r.bpmn.intellij.plugin.core.actions + +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event +import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.PropertyUpdateWithId +import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState + +fun removeElements(state: RenderState, diagramElementIds: List): List { + val toDelete = mutableListOf() + toDelete += diagramElementIds.mapNotNull { state.elemMap[it] }.flatMap { + val elemRemoval = it.getEventsToElementWithItsDiagram() + return@flatMap elemRemoval.diagram + elemRemoval.bpmn + elemRemoval.other + } + val inOrder = toDelete.sortedBy { + when (it) { + is PropertyUpdateWithId -> return@sortedBy 0 + else -> return@sortedBy 100 + } + } + return inOrder +} \ No newline at end of file diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt index 6879dbcd6..f9eff6142 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/ElementRemoveActionHandler.kt @@ -5,6 +5,7 @@ import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.Event import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.PropertyUpdateWithId import com.valb3r.bpmn.intellij.plugin.core.events.updateEventsRegistry import com.valb3r.bpmn.intellij.plugin.core.render.currentCanvas +import com.valb3r.bpmn.intellij.plugin.core.render.elements.RenderState import com.valb3r.bpmn.intellij.plugin.core.render.lastRenderedState import java.util.* @@ -21,17 +22,7 @@ class ElementRemoveActionHandler(private val project: Project) { fun deleteSelectedElements() { val state = lastRenderedState(project)?.state ?: return - val toDelete = mutableListOf() - toDelete += state.ctx.selectedIds.mapNotNull { state.elemMap[it] }.flatMap { - val elemRemoval = it.getEventsToElementWithItsDiagram() - return@flatMap elemRemoval.diagram + elemRemoval.bpmn + elemRemoval.other - } - val inOrder = toDelete.sortedBy { - when (it) { - is PropertyUpdateWithId -> return@sortedBy 0 - else -> return@sortedBy 100 - } - } + val inOrder = removeElements(state, state.ctx.selectedIds.toList()) updateEventsRegistry(project).addEvents(inOrder) diff --git a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/copypaste/CopyPasteActionHandler.kt b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/copypaste/CopyPasteActionHandler.kt index a2d9f7314..3c8a803a5 100644 --- a/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/copypaste/CopyPasteActionHandler.kt +++ b/bpmn-intellij-plugin-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/core/actions/copypaste/CopyPasteActionHandler.kt @@ -16,6 +16,7 @@ import com.valb3r.bpmn.intellij.plugin.bpmn.api.diagram.elements.ShapeElement import com.valb3r.bpmn.intellij.plugin.bpmn.api.events.EdgeWithIdentifiableWaypoints import com.valb3r.bpmn.intellij.plugin.bpmn.api.info.Property import com.valb3r.bpmn.intellij.plugin.bpmn.api.info.PropertyType +import com.valb3r.bpmn.intellij.plugin.core.actions.removeElements import com.valb3r.bpmn.intellij.plugin.core.events.* import com.valb3r.bpmn.intellij.plugin.core.render.EdgeElementState import com.valb3r.bpmn.intellij.plugin.core.render.elements.BaseDiagramRenderElement @@ -93,13 +94,9 @@ class CopyPasteActionHandler(private val clipboard: SystemClipboard) { .filter { if (alreadyRemovedBpmn.contains(it)) false else { alreadyRemovedBpmn += it; true } } .mapNotNull { elementsById[it] } - val bpmnToRemove = mutableListOf() - val diagramToRemove = mutableListOf() + val events = removeElements(ctx, elemsToDelete.map { it.elementId }) + updateEvents.addEvents(events) - elemsToDelete.forEach { bpmnToRemove += it.getEventsToDeleteElement() } - elemsToDelete.forEach { diagramToRemove += it.getEventsToDeleteDiagram() } - - updateEvents.addElementRemovedEvent(diagramToRemove, bpmnToRemove) clipboard.setContents(ClipboardFlavor(mapper.writeValueAsString(toCopy)), null) } @@ -123,8 +120,12 @@ class CopyPasteActionHandler(private val clipboard: SystemClipboard) { ?: 0.0f val delta = Point2D.Float(sceneLocation.x - minX, sceneLocation.y - minY) - val updatedShapes = updateShapes(delta, context.shapes, updatedIds, updatedDiagramIds) - val updatedEdges = updateEdges(delta, context.edges, updatedIds, updatedDiagramIds) + // TODO incoming/outgoing not handled properly + var updatedShapes = updateShapes(delta, context.shapes, updatedIds, updatedDiagramIds) + var updatedEdges = updateEdges(delta, context.edges, updatedIds, updatedDiagramIds) + // Update properties since they might depend on both shapes and edges + updatedShapes = updatedShapes.mapIndexed { index, shape -> shape.copy(props = copied(context.shapes[index].props, updatedIds)) }.toMutableList() + updatedEdges = updatedEdges.mapIndexed { index, edge -> edge.copy(props = copied(context.edges[index].props, updatedIds)) }.toMutableList() val updatedSelectedElems = computeElementsToSelect(context, updatedEdges, updatedDiagramIds) context.copy(shapes = updatedShapes, edges = updatedEdges, selectElements = updatedSelectedElems) @@ -218,7 +219,7 @@ class CopyPasteActionHandler(private val clipboard: SystemClipboard) { when { v.value == null -> result.add(k, v) PropertyType.ID == k -> result[k] = Property(copied(BpmnElementId(v.value as String), updatedIds).id) - PropertyType.ID == k.updatedBy -> result[k] = Property(copiedExistsOrEmpty(BpmnElementId(v.value as String), updatedIds)) + PropertyType.ID == k.updatedBy -> result.add(k, Property(copiedExistsOrEmpty(BpmnElementId(v.value as String), updatedIds))) else -> result.add(k, v) } } @@ -240,7 +241,7 @@ class CopyPasteActionHandler(private val clipboard: SystemClipboard) { ) } - return result.map { it.copy(props = copied(it.props, updatedIds), shape = copied(it.shape, delta, updatedIds, updatedDiagramIds)) }.toMutableList() + return result.map { it.copy(props = PropertyTable(mutableMapOf()), shape = copied(it.shape, delta, updatedIds, updatedDiagramIds)) }.toMutableList() } private fun updateEdges( @@ -257,7 +258,7 @@ class CopyPasteActionHandler(private val clipboard: SystemClipboard) { ) ) } - return result.map { it.copy(props = copied(it.props, updatedIds), edge = copied(it.edge, delta, updatedIds, updatedDiagramIds)) }.toMutableList() + return result.map { it.copy(props = PropertyTable(mutableMapOf()), edge = copied(it.edge, delta, updatedIds, updatedDiagramIds)) }.toMutableList() } private fun ensureRootElementsComeFirst(idsToCopy: MutableList, ctx: RenderState, elementsById: Map): MutableList { diff --git a/xml-parser-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/bpmn/parser/core/BaseBpmnParser.kt b/xml-parser-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/bpmn/parser/core/BaseBpmnParser.kt index 1b72d0af0..dbb869330 100644 --- a/xml-parser-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/bpmn/parser/core/BaseBpmnParser.kt +++ b/xml-parser-core/src/main/kotlin/com/valb3r/bpmn/intellij/plugin/bpmn/parser/core/BaseBpmnParser.kt @@ -534,10 +534,10 @@ abstract class BaseBpmnParser: BpmnParser { var (attrName, attrValue) = attributeSelector?.split("=") ?: listOf(null, null) if (true == attrValue?.contains('@')) { - if (null == value && null == valueIndexInArray) { // Skip null unindexable props + if (null == value || null == valueIndexInArray) { // Skip null unindexable props return } - attrValue = attrValue.replace("@", valueIndexInArray!!.removeAt(0)) + attrValue = attrValue.replace("@", valueIndexInArray.removeAt(0)) } val child = childOf(currentNode, name, attrName, attrValue)