From 396cd18ca8c7304d2f9563b8d1c579474a4dec4e Mon Sep 17 00:00:00 2001 From: Jette Petzold Date: Wed, 21 Oct 2020 12:28:36 +0200 Subject: [PATCH 01/45] interactive: regions must not be moveable --- .../sccharts/ui/synthesis/SCChartsSynthesis.xtend | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend index fc5870c7bd..e5fa7daa96 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend @@ -305,13 +305,23 @@ class SCChartsSynthesis extends AbstractDiagramSynthesis { override List getAdditionalLayoutConfigs(KNode viewModel) { val List additionalLayoutRuns = newArrayList // Add interactive Layout run. - if ((!viewModel.getChildren().isEmpty() && viewModel.getChildren().get(0) - .getProperty(CoreOptions.INTERACTIVE_LAYOUT))) { + if (!viewModel.getChildren().isEmpty() && (viewModel.getChildren().get(0) + .getProperty(CoreOptions.INTERACTIVE_LAYOUT) || isChildInteractive(viewModel))) { additionalLayoutRuns.add(new CompoundGraphElementVisitor( new InteractiveRectPackingGraphVisitor(), new InteractiveLayeredGraphVisitor())); } return additionalLayoutRuns; } + + private def isChildInteractive(KNode node) { + val children = node.getChildren.get(0).getChildren() + for (n : children) { + if (n.getProperty(CoreOptions.INTERACTIVE_LAYOUT)) { + return true + } + } + return false + } } From 5bf7e73aa3ed4f87e7245400858ecf4e802f8037 Mon Sep 17 00:00:00 2001 From: Jette Petzold Date: Fri, 30 Oct 2020 10:51:56 +0100 Subject: [PATCH 02/45] interactive: default value of interactive layout is true for regions --- .../sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 59b001a851..99a8ffbada 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -75,6 +75,11 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); + // default value of interactive layout for regions + if (!region.annotations.contains(CoreOptions.INTERACTIVE_LAYOUT)) { + node.setLayoutOption(CoreOptions::INTERACTIVE_LAYOUT, true) + } + node.configureNodeLOD(region) // Set KIdentifier for use with incremental update From 8898d6a83c72caab16679e93ded30fa5835db268 Mon Sep 17 00:00:00 2001 From: stu215592 Date: Mon, 23 May 2022 10:39:24 +0200 Subject: [PATCH 03/45] Initial commit, just testing for now --- ...uageServer with KLighD in Workspace.launch | 31 +++++++++---------- .../ControlflowRegionSynthesis.xtend | 12 +++++-- .../synthesis/DataflowRegionSynthesis.xtend | 10 +++++- .../ui/synthesis/StateSynthesis.xtend | 20 ++++++++++-- 4 files changed, 51 insertions(+), 22 deletions(-) diff --git a/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch b/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch index e5e5c5b2c5..b37502184c 100644 --- a/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch +++ b/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch @@ -65,40 +65,39 @@ - - - - - + + + + - - + + - - - - - - - - + + + + + + + + - + diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index f069dc824a..fe98afd047 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -206,9 +206,17 @@ class ControlflowRegionSynthesis extends SubSynthesis if (SHOW_COMMENTS.booleanValue) { region.getCommentAnnotations.forEach[ - node.children += it.transform + val comments = it.transform + node.children += comments + comments.forEach[ + setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + ] ] - } + } + + println("Controlflow") + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) return returnNodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 99c2797eaf..c1486a43f5 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -177,7 +177,11 @@ class DataflowRegionSynthesis extends SubSynthesis { if (SHOW_COMMENTS.booleanValue) { region.getCommentAnnotations.forEach[ - node.children += it.transform + val comments = it.transform + node.children += comments + comments.forEach[ + setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + ] ] } @@ -187,6 +191,10 @@ class DataflowRegionSynthesis extends SubSynthesis { if (!CIRCUIT.booleanValue) { node.setLayoutOption(CoreOptions::PADDING, new ElkPadding(18d, 7d, 7d, 7d)); } + + println("Dataflow") + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) return newArrayList(node) } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 5074615df3..a1fab54a41 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -140,10 +140,12 @@ class StateSynthesis extends SubSynthesis { override List performTranformation(State state) { val node = state.createNode().associateWith(state) + val proxyRendering = State.createNode(); // Set KIdentifier for use with incremental update if (!state.name.nullOrEmpty) { node.KID = state.name + proxyRendering.KID = state.name + "-proxy" } // configure region dependency layout config if an appropriate result is present. @@ -353,9 +355,21 @@ class StateSynthesis extends SubSynthesis { if (SHOW_COMMENTS.booleanValue) { state.getCommentAnnotations.forEach[ - returnNodes += it.transform - ] - } + val comments = it.transform + returnNodes += comments + comments.forEach[ + setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + ] + ] + } + + println("Node") + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_RENDERING, proxyRendering.data) + println("proxyRendering.data") + println(proxyRendering.data) + println("node.data") + println(node.data) return returnNodes } From b728d56073568ce3581fe4204401d5680a986822 Mon Sep 17 00:00:00 2001 From: stu215592 Date: Tue, 31 May 2022 13:02:30 +0200 Subject: [PATCH 04/45] SCCharts synthesis can now support the proxy-view API --- .../ControlflowRegionSynthesis.xtend | 21 ++++++- .../synthesis/DataflowRegionSynthesis.xtend | 15 ++++- .../ui/synthesis/StateSynthesis.xtend | 57 ++++++++++++++----- .../styles/ControlflowRegionStyles.xtend | 40 +++++++++++++ 4 files changed, 115 insertions(+), 18 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index fe98afd047..acc4a8bc8f 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -50,6 +50,7 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension de.cau.cs.kieler.klighd.util.ModelingUtil.* +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil /** * Transforms {@link ControlflowRegion} into {@link KNode} diagram elements. @@ -76,12 +77,14 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); + val proxy = createNode().associateWith(region) node.configureNodeLOD(region) // Set KIdentifier for use with incremental update if (!region.name.nullOrEmpty) { node.KID = region.name + proxy.KID = '''«region.name»-proxy''' } if (USE_KLAY.booleanValue) { @@ -201,6 +204,15 @@ class ControlflowRegionSynthesis extends SubSynthesis if (region.final) addFinalRegionStyle ] } + + // TODO: make this an actual good rendering + proxy.addRegionFigure => [ + if (region.override) addOverrideRegionStyle + if (region.abort) addAbortRegionStyle + if (region.final) addFinalRegionStyle + val label = region.serializeHighlighted(true) + addProxyRegion(label) + ] val returnNodes = newArrayList(node) @@ -208,15 +220,20 @@ class ControlflowRegionSynthesis extends SubSynthesis region.getCommentAnnotations.forEach[ val comments = it.transform node.children += comments + // Comments shouldn't be rendered as proxies comments.forEach[ setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) ] ] } - println("Controlflow") + // Set size to be square and at least 34 + val proxyBounds = PlacementUtil.estimateSize(proxy) + val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = size + proxy.height = size node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) + node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) return returnNodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index c1486a43f5..73e4dafa34 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -41,6 +41,7 @@ import org.eclipse.elk.core.options.EdgeRouting import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil /** * @author ssm @@ -80,6 +81,7 @@ class DataflowRegionSynthesis extends SubSynthesis { override performTranformation(DataflowRegion region) { val node = region.createNode().associateWith(region) + val proxy = createNode().associateWith(region) node.addLayoutParam(CoreOptions::ALGORITHM, LayeredOptions.ALGORITHM_ID) //node.setLayoutOption(LayeredOptions.CONSIDER_MODEL_ORDER, OrderingStrategy.PREFER_EDGES) @@ -173,12 +175,19 @@ class DataflowRegionSynthesis extends SubSynthesis { ] ] + proxy.addRegionFigure => [ + if (sLabel.length > 0) it.setUserScheduleStyle + if (region.override) addOverrideRegionStyle + ] + node.setSelectionStyle + proxy.setSelectionStyle if (SHOW_COMMENTS.booleanValue) { region.getCommentAnnotations.forEach[ val comments = it.transform node.children += comments + // Comments shouldn't be rendered as proxies comments.forEach[ setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) ] @@ -192,7 +201,11 @@ class DataflowRegionSynthesis extends SubSynthesis { node.setLayoutOption(CoreOptions::PADDING, new ElkPadding(18d, 7d, 7d, 7d)); } - println("Dataflow") + // Set size to be square and at least 34 + val proxyBounds = PlacementUtil.estimateSize(proxy) + val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = size + proxy.height = size node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index a1fab54a41..18752585e8 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -88,6 +88,10 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* +import org.eclipse.emf.common.util.EList +import de.cau.cs.kieler.klighd.kgraph.KGraphData +import de.cau.cs.kieler.klighd.kgraph.KGraphElement +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil /** * Transforms {@link State} into {@link KNode} diagram elements. @@ -139,13 +143,14 @@ class StateSynthesis extends SubSynthesis { } override List performTranformation(State state) { + // TODO: associateWith() val node = state.createNode().associateWith(state) - val proxyRendering = State.createNode(); + val proxy = createNode().associateWith(state) // Set KIdentifier for use with incremental update if (!state.name.nullOrEmpty) { node.KID = state.name - proxyRendering.KID = state.name + "-proxy" + proxy.KID = '''«state.name»-proxy''' } // configure region dependency layout config if an appropriate result is present. @@ -166,38 +171,51 @@ class StateSynthesis extends SubSynthesis { // Basic state style switch state { - case isConnector: + case isConnector: { node.addConnectorFigure - case state.isMacroState: + proxy.addConnectorFigure + } + case state.isMacroState: { node.addMacroFigure - default: + proxy.addMacroFigure + } + default: { node.addDefaultFigure + // Proxy should be more square-like + proxy.addMacroFigure + } } // Styles from modifiers if (state.isReferencing) { node.setReferencedStyle + proxy.setReferencedStyle } if (state.isInitial) { node.setInitialStyle + proxy.setInitialStyle if (USE_KLAY.booleanValue && state.parentRegion.states.head == state) { node.setLayoutOption(LayeredOptions::LAYERING_LAYER_CONSTRAINT, LayerConstraint::FIRST); } } if (state.isFinal) { node.setFinalStyle + proxy.setFinalStyle } if (state.isViolation) { val isHaltState = state.outgoingTransitions.size == 0 || !state.outgoingTransitions.exists[ targetState != state ] node.setViolationStyle(isHaltState) + proxy.setViolationStyle(isHaltState) } node.setSelectionStyle + proxy.setSelectionStyle // Shadow if (!isConnector) { node.setShadowStyle + proxy.setShadowStyle } // Add content @@ -243,10 +261,11 @@ class StateSynthesis extends SubSynthesis { } } node.addMacroStateLabel(label) + proxy.addMacroStateLabel(label) } else { node.addSimpleStateLabel(state.serializeHR.toString) + proxy.addSimpleStateLabel(state.serializeHR.toString) }) => [ - setProperty(TracingVisualizationProperties.TRACING_NODE, true) associateWith(state) if (it instanceof KText) configureTextLOD(state) eAllContents.filter(KRendering).toList.forEach[ @@ -256,6 +275,7 @@ class StateSynthesis extends SubSynthesis { ] } else { node.addEmptyStateLabel + proxy.addEmptyStateLabel } // Add declarations @@ -328,8 +348,12 @@ class StateSynthesis extends SubSynthesis { if (SHOW_INHERITANCE.booleanValue) regions.addAll(0, state.allVisibleInheritedRegions.toList) for (region : regions) { switch region { - ControlflowRegion: node.children += region.transform - DataflowRegion: node.children += region.transform + ControlflowRegion: { + node.children += region.transform + } + DataflowRegion: { + node.children += region.transform + } } } @@ -357,19 +381,22 @@ class StateSynthesis extends SubSynthesis { state.getCommentAnnotations.forEach[ val comments = it.transform returnNodes += comments + // Comments shouldn't be rendered as proxies comments.forEach[ setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) ] ] } - - println("Node") + + if (!isConnector) { + // Set size to be square and at least 34 (same as minimal node size) + val proxyBounds = PlacementUtil.estimateSize(proxy) + val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = size + proxy.height = size + } node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_RENDERING, proxyRendering.data) - println("proxyRendering.data") - println(proxyRendering.data) - println("node.data") - println(node.data) + node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) return returnNodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend index c9070bbf7c..9f3d94e2ff 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend @@ -191,6 +191,46 @@ class ControlflowRegionStyles { return button } + def KRendering addProxyRegion(KContainerRendering container, List> label) { + if (!label.nullOrEmpty) { + if (label.size == 1 && label.head.value == TextFormat.TEXT) { + container.addText(label.head.key.toString) => [ + suppressSelectability + foreground = REGION_LABEL.color; + fontSize = 10; + selectionTextUnderline = Underline.NONE // prevents default selection style + val size = estimateTextSize; + setPointPlacementData(LEFT, 1, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, size.width + 5, size.height) + setProperty(KlighdProperties.IS_NODE_TITLE, true) + ] + } else { + container.addKeywordLabel(label, 0) => [ + foreground = REGION_LABEL.color + fontSize = 10 + setPointPlacementData(LEFT, 1, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, 0, 0) + setProperty(KlighdProperties.IS_NODE_TITLE, true) + (children.last as KContainerRendering) => [ // Just for spacing at the end + val grid = it?.getChildPlacement() + if (grid instanceof KGridPlacement) { + grid.numColumns = grid.numColumns + 1 + addRectangle => [ + setGridPlacementData(5,5) + invisible = true + ] + } + ] + eAllContents.filter(KText).forEach[ + suppressSelectability + selectionTextUnderline = Underline.NONE // prevents default selection style + if (!styles.exists[it instanceof KForeground]) { + foreground = REGION_LABEL.color + } + ] + ] + } + } + } + /** * Adds an expand region button with label. */ From bf538f061a002f7e73cc65ddb9998ae8c23a37f5 Mon Sep 17 00:00:00 2001 From: stu215592 Date: Tue, 31 May 2022 13:37:44 +0200 Subject: [PATCH 05/45] Added a type check --- .../de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 18752585e8..2fb9ac4a42 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -388,6 +388,7 @@ class StateSynthesis extends SubSynthesis { ] } + // TODO: trim label to max size, put label in vertical middle if (!isConnector) { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) From c132cb7a3513989e0c19aaf491c00cbb8052a8b5 Mon Sep 17 00:00:00 2001 From: stu215592 Date: Mon, 6 Jun 2022 13:53:40 +0200 Subject: [PATCH 06/45] Made proxy-renderings non-square --- .../ui/synthesis/ControlflowRegionSynthesis.xtend | 8 +++++--- .../ui/synthesis/DataflowRegionSynthesis.xtend | 9 ++++++--- .../kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 10 ++++++---- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index acc4a8bc8f..3955989099 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -229,9 +229,11 @@ class ControlflowRegionSynthesis extends SubSynthesis // Set size to be square and at least 34 val proxyBounds = PlacementUtil.estimateSize(proxy) - val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = size - proxy.height = size + val minSize = 34 + // Use this size to make proxies square + // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = Math.max(minSize, proxyBounds.width) + proxy.height = Math.max(minSize, proxyBounds.height) node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 73e4dafa34..1eebe4db60 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -178,6 +178,7 @@ class DataflowRegionSynthesis extends SubSynthesis { proxy.addRegionFigure => [ if (sLabel.length > 0) it.setUserScheduleStyle if (region.override) addOverrideRegionStyle + if (!CIRCUIT.booleanValue) addProxyRegion(label) ] node.setSelectionStyle @@ -203,9 +204,11 @@ class DataflowRegionSynthesis extends SubSynthesis { // Set size to be square and at least 34 val proxyBounds = PlacementUtil.estimateSize(proxy) - val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = size - proxy.height = size + val minSize = 34 + // Use this size to make proxies square + // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = Math.max(minSize, proxyBounds.width) + proxy.height = Math.max(minSize, proxyBounds.height) node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 2fb9ac4a42..1007c51450 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -388,13 +388,15 @@ class StateSynthesis extends SubSynthesis { ] } - // TODO: trim label to max size, put label in vertical middle + // TODO: trim label to max size/length, put label in vertical middle if (!isConnector) { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) - val size = Math.max(34, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = size - proxy.height = size + val minSize = 34 + // Use this size to make proxies square + // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) + proxy.width = Math.max(minSize, proxyBounds.width) + proxy.height = Math.max(minSize, proxyBounds.height) } node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) From b5368a9e39ffe4166777cdd25198023bc7bf6f9d Mon Sep 17 00:00:00 2001 From: stu215592 Date: Mon, 6 Jun 2022 14:02:46 +0200 Subject: [PATCH 07/45] Made proxies even less intrusive & centered labels --- .../ui/synthesis/ControlflowRegionSynthesis.xtend | 10 +++++++--- .../ui/synthesis/DataflowRegionSynthesis.xtend | 10 +++++++--- .../kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 3955989099..ad0b8f5f3f 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -227,13 +227,17 @@ class ControlflowRegionSynthesis extends SubSynthesis ] } - // Set size to be square and at least 34 + // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 + val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 + proxy.width = nonZero ? proxyBounds.width : minSize + proxy.height = nonZero ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = Math.max(minSize, proxyBounds.width) - proxy.height = Math.max(minSize, proxyBounds.height) + // Use this to make proxies always be at least minSize x minSize + // proxy.width = Math.max(minSize, proxyBounds.width) + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 1eebe4db60..9ca956a5fd 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -202,13 +202,17 @@ class DataflowRegionSynthesis extends SubSynthesis { node.setLayoutOption(CoreOptions::PADDING, new ElkPadding(18d, 7d, 7d, 7d)); } - // Set size to be square and at least 34 + // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 + val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 + proxy.width = nonZero ? proxyBounds.width : minSize + proxy.height = nonZero ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = Math.max(minSize, proxyBounds.width) - proxy.height = Math.max(minSize, proxyBounds.height) + // Use this to make proxies always be at least minSize x minSize + // proxy.width = Math.max(minSize, proxyBounds.width) + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 1007c51450..73c908ae84 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -388,16 +388,20 @@ class StateSynthesis extends SubSynthesis { ] } - // TODO: trim label to max size/length, put label in vertical middle + // TODO: trim label to max size/length if (!isConnector) { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 + val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 + proxy.width = nonZero ? proxyBounds.width : minSize + proxy.height = nonZero ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - proxy.width = Math.max(minSize, proxyBounds.width) - proxy.height = Math.max(minSize, proxyBounds.height) + // Use this to make proxies always be at least minSize x minSize + // proxy.width = Math.max(minSize, proxyBounds.width) } + node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) From b2eb2d031573fb590a84dd38d74330817f6714c9 Mon Sep 17 00:00:00 2001 From: fight4day Date: Sun, 12 Jun 2022 17:05:09 +0200 Subject: [PATCH 08/45] Added a max label length --- .../synthesis/ControlflowRegionSynthesis.xtend | 7 +++++++ .../ui/synthesis/DataflowRegionSynthesis.xtend | 11 ++++++++++- .../sccharts/ui/synthesis/StateSynthesis.xtend | 17 ++++++++++++++--- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index ad0b8f5f3f..a19523973c 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -78,6 +78,7 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); val proxy = createNode().associateWith(region) + val maxProxyLabelLength = 5 node.configureNodeLOD(region) @@ -211,6 +212,12 @@ class ControlflowRegionSynthesis extends SubSynthesis if (region.abort) addAbortRegionStyle if (region.final) addFinalRegionStyle val label = region.serializeHighlighted(true) + if (label.length > 0) { + val name = label.get(0) + if (name.key.length > maxProxyLabelLength) { + label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + } + } addProxyRegion(label) ] diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 9ca956a5fd..97f03c4595 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -82,6 +82,7 @@ class DataflowRegionSynthesis extends SubSynthesis { override performTranformation(DataflowRegion region) { val node = region.createNode().associateWith(region) val proxy = createNode().associateWith(region) + val maxProxyLabelLength = 5 node.addLayoutParam(CoreOptions::ALGORITHM, LayeredOptions.ALGORITHM_ID) //node.setLayoutOption(LayeredOptions.CONSIDER_MODEL_ORDER, OrderingStrategy.PREFER_EDGES) @@ -178,7 +179,15 @@ class DataflowRegionSynthesis extends SubSynthesis { proxy.addRegionFigure => [ if (sLabel.length > 0) it.setUserScheduleStyle if (region.override) addOverrideRegionStyle - if (!CIRCUIT.booleanValue) addProxyRegion(label) + if (!CIRCUIT.booleanValue) { + if (label.length > 0) { + val name = label.get(0) + if (name.key.length > maxProxyLabelLength) { + label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + } + } + addProxyRegion(label) + } ] node.setSelectionStyle diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 73c908ae84..a55d9addfa 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -143,9 +143,9 @@ class StateSynthesis extends SubSynthesis { } override List performTranformation(State state) { - // TODO: associateWith() val node = state.createNode().associateWith(state) val proxy = createNode().associateWith(state) + val maxProxyLabelLength = 5 // Set KIdentifier for use with incremental update if (!state.name.nullOrEmpty) { @@ -261,10 +261,21 @@ class StateSynthesis extends SubSynthesis { } } node.addMacroStateLabel(label) + if (label.length > 0) { + val name = label.get(0) + if (name.key.length > maxProxyLabelLength) { + label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + } + } proxy.addMacroStateLabel(label) } else { - node.addSimpleStateLabel(state.serializeHR.toString) - proxy.addSimpleStateLabel(state.serializeHR.toString) + val label = state.serializeHR.toString + node.addSimpleStateLabel(label) + if (label.length > maxProxyLabelLength) { + proxy.addSimpleStateLabel(label.substring(0, maxProxyLabelLength) + "...") + } else { + proxy.addSimpleStateLabel(label) + } }) => [ associateWith(state) if (it instanceof KText) configureTextLOD(state) From 8ffddec89f9e037002ba34c1cd6406d95acc2b06 Mon Sep 17 00:00:00 2001 From: fight4day Date: Sun, 12 Jun 2022 17:14:50 +0200 Subject: [PATCH 09/45] Removed TODOs --- .../sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend | 1 - .../de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index a19523973c..db4be7fcc9 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -206,7 +206,6 @@ class ControlflowRegionSynthesis extends SubSynthesis ] } - // TODO: make this an actual good rendering proxy.addRegionFigure => [ if (region.override) addOverrideRegionStyle if (region.abort) addAbortRegionStyle diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index a55d9addfa..ded0ff37dd 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -399,7 +399,6 @@ class StateSynthesis extends SubSynthesis { ] } - // TODO: trim label to max size/length if (!isConnector) { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) From 10552f6a7fda67ffe29b14561f37e05ccd16c62a Mon Sep 17 00:00:00 2001 From: fight4day Date: Sat, 25 Jun 2022 10:43:56 +0200 Subject: [PATCH 10/45] Property name changes --- .../ui/synthesis/ControlflowRegionSynthesis.xtend | 7 ++++--- .../ui/synthesis/DataflowRegionSynthesis.xtend | 7 ++++--- .../kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 10 +++++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index db4be7fcc9..4837c62d38 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -228,7 +228,7 @@ class ControlflowRegionSynthesis extends SubSynthesis node.children += comments // Comments shouldn't be rendered as proxies comments.forEach[ - setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, false) ] ] } @@ -244,8 +244,9 @@ class ControlflowRegionSynthesis extends SubSynthesis // Use this to make proxies always be at least minSize x minSize // proxy.width = Math.max(minSize, proxyBounds.width) - node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) + node.setProperty(KlighdProperties.NODE_TYPE, "controlflowRegion") + node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) return returnNodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 97f03c4595..f787a54bd1 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -199,7 +199,7 @@ class DataflowRegionSynthesis extends SubSynthesis { node.children += comments // Comments shouldn't be rendered as proxies comments.forEach[ - setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, false) ] ] } @@ -222,8 +222,9 @@ class DataflowRegionSynthesis extends SubSynthesis { // Use this to make proxies always be at least minSize x minSize // proxy.width = Math.max(minSize, proxyBounds.width) - node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_RENDERING, node.data) + node.setProperty(KlighdProperties.NODE_TYPE, "dataflowRegion") + node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, node.data) return newArrayList(node) } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index ded0ff37dd..ebe4f98190 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -260,6 +260,7 @@ class StateSynthesis extends SubSynthesis { } } } + node.setProperty(KlighdProperties.NODE_TYPE, "hierarchicalState") node.addMacroStateLabel(label) if (label.length > 0) { val name = label.get(0) @@ -270,6 +271,7 @@ class StateSynthesis extends SubSynthesis { proxy.addMacroStateLabel(label) } else { val label = state.serializeHR.toString + node.setProperty(KlighdProperties.NODE_TYPE, "simpleState") node.addSimpleStateLabel(label) if (label.length > maxProxyLabelLength) { proxy.addSimpleStateLabel(label.substring(0, maxProxyLabelLength) + "...") @@ -332,6 +334,8 @@ class StateSynthesis extends SubSynthesis { node.addRegionsArea node.setLayoutOption(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE)) } + } else { + node.setProperty(KlighdProperties.NODE_TYPE, "connectorState") } // Transform all outgoing transitions @@ -394,7 +398,7 @@ class StateSynthesis extends SubSynthesis { returnNodes += comments // Comments shouldn't be rendered as proxies comments.forEach[ - setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, false) + setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, false) ] ] } @@ -412,8 +416,8 @@ class StateSynthesis extends SubSynthesis { // proxy.width = Math.max(minSize, proxyBounds.width) } - node.setProperty(KlighdProperties.RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_RENDERING, proxy.data) + node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) return returnNodes } From 215dc4c314c8128d65d500982b21925a18df1586 Mon Sep 17 00:00:00 2001 From: fight4day Date: Thu, 30 Jun 2022 17:32:09 +0200 Subject: [PATCH 11/45] Preparation for semantic filtering --- .../sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend | 1 - .../sccharts/ui/synthesis/DataflowRegionSynthesis.xtend | 1 - .../cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 4 ---- 3 files changed, 6 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 4837c62d38..04902c6d21 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -244,7 +244,6 @@ class ControlflowRegionSynthesis extends SubSynthesis // Use this to make proxies always be at least minSize x minSize // proxy.width = Math.max(minSize, proxyBounds.width) - node.setProperty(KlighdProperties.NODE_TYPE, "controlflowRegion") node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index f787a54bd1..879d451cd1 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -222,7 +222,6 @@ class DataflowRegionSynthesis extends SubSynthesis { // Use this to make proxies always be at least minSize x minSize // proxy.width = Math.max(minSize, proxyBounds.width) - node.setProperty(KlighdProperties.NODE_TYPE, "dataflowRegion") node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index ebe4f98190..a3d0e0e7e8 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -260,7 +260,6 @@ class StateSynthesis extends SubSynthesis { } } } - node.setProperty(KlighdProperties.NODE_TYPE, "hierarchicalState") node.addMacroStateLabel(label) if (label.length > 0) { val name = label.get(0) @@ -271,7 +270,6 @@ class StateSynthesis extends SubSynthesis { proxy.addMacroStateLabel(label) } else { val label = state.serializeHR.toString - node.setProperty(KlighdProperties.NODE_TYPE, "simpleState") node.addSimpleStateLabel(label) if (label.length > maxProxyLabelLength) { proxy.addSimpleStateLabel(label.substring(0, maxProxyLabelLength) + "...") @@ -334,8 +332,6 @@ class StateSynthesis extends SubSynthesis { node.addRegionsArea node.setLayoutOption(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.of(SizeConstraint.MINIMUM_SIZE)) } - } else { - node.setProperty(KlighdProperties.NODE_TYPE, "connectorState") } // Transform all outgoing transitions From f423fc74694ec7486b76695fbf0b7b18cf57bea4 Mon Sep 17 00:00:00 2001 From: fight4day Date: Thu, 30 Jun 2022 21:40:52 +0200 Subject: [PATCH 12/45] Added several semantic filters --- .../ControlflowRegionSynthesis.xtend | 13 +++- .../synthesis/DataflowRegionSynthesis.xtend | 13 +++- .../ui/synthesis/SCChartsSynthesis.xtend | 10 +++ .../ui/synthesis/StateSynthesis.xtend | 19 +++++- .../SCChartsSemanticFilterRules.java | 68 +++++++++++++++++++ .../filtering/SCChartsSemanticFilterTags.java | 45 ++++++++++++ 6 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java create mode 100644 plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 04902c6d21..db6b0297d5 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -51,6 +51,8 @@ import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisU import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension de.cau.cs.kieler.klighd.util.ModelingUtil.* import de.cau.cs.kieler.klighd.microlayout.PlacementUtil +import de.cau.cs.kieler.klighd.KlighdOptions +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * Transforms {@link ControlflowRegion} into {@link KNode} diagram elements. @@ -77,6 +79,11 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); + val semanticTags = newArrayList( + SCChartsSemanticFilterTags.REGION, + SCChartsSemanticFilterTags.CONTROLFLOW_REGION + ) + node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 @@ -236,9 +243,9 @@ class ControlflowRegionSynthesis extends SubSynthesis // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 - val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 - proxy.width = nonZero ? proxyBounds.width : minSize - proxy.height = nonZero ? proxyBounds.height : minSize + val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 + proxy.width = bigEnough ? proxyBounds.width : minSize + proxy.height = bigEnough ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) // Use this to make proxies always be at least minSize x minSize diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 879d451cd1..d9a7bb85e4 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -42,6 +42,8 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import de.cau.cs.kieler.klighd.microlayout.PlacementUtil +import de.cau.cs.kieler.klighd.KlighdOptions +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * @author ssm @@ -81,6 +83,11 @@ class DataflowRegionSynthesis extends SubSynthesis { override performTranformation(DataflowRegion region) { val node = region.createNode().associateWith(region) + val semanticTags = newArrayList( + SCChartsSemanticFilterTags.REGION, + SCChartsSemanticFilterTags.DATAFLOW_REGION + ) + node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 @@ -214,9 +221,9 @@ class DataflowRegionSynthesis extends SubSynthesis { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 - val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 - proxy.width = nonZero ? proxyBounds.width : minSize - proxy.height = nonZero ? proxyBounds.height : minSize + val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 + proxy.width = bigEnough ? proxyBounds.width : minSize + proxy.height = bigEnough ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) // Use this to make proxies always be at least minSize x minSize diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend index accdc3b81b..9a816d284d 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend @@ -55,6 +55,10 @@ import org.eclipse.elk.graph.properties.IProperty import org.eclipse.elk.graph.properties.Property import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* +import de.cau.cs.kieler.klighd.filtering.SemanticFilterRule +import de.cau.cs.kieler.klighd.filtering.SemanticFilterTag +import de.cau.cs.kieler.klighd.KlighdOptions +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterRules /** * Main diagram synthesis for SCCharts. @@ -167,6 +171,12 @@ class SCChartsSynthesis extends AbstractDiagramSynthesis { } else sccharts val rootNode = createNode + + // Set semantic filter rules + val rules = SCChartsSemanticFilterRules.fields.map[ + get(null) as SemanticFilterRule + ] + rootNode.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_RULES, rules) // If dot is used draw edges first to prevent overlapping with states when layout is bad usedContext.setProperty(KlighdProperties.EDGES_FIRST, !USE_KLAY.booleanValue) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index a3d0e0e7e8..0b158582f3 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -92,6 +92,8 @@ import org.eclipse.emf.common.util.EList import de.cau.cs.kieler.klighd.kgraph.KGraphData import de.cau.cs.kieler.klighd.kgraph.KGraphElement import de.cau.cs.kieler.klighd.microlayout.PlacementUtil +import de.cau.cs.kieler.klighd.KlighdOptions +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * Transforms {@link State} into {@link KNode} diagram elements. @@ -144,6 +146,8 @@ class StateSynthesis extends SubSynthesis { override List performTranformation(State state) { val node = state.createNode().associateWith(state) + val semanticTags = newArrayList(SCChartsSemanticFilterTags.STATE) + node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(state) val maxProxyLabelLength = 5 @@ -173,14 +177,17 @@ class StateSynthesis extends SubSynthesis { switch state { case isConnector: { node.addConnectorFigure + semanticTags.add(SCChartsSemanticFilterTags.CONNECTOR_STATE) proxy.addConnectorFigure } case state.isMacroState: { node.addMacroFigure + semanticTags.add(SCChartsSemanticFilterTags.HIERARCHICAL_STATE) proxy.addMacroFigure } default: { node.addDefaultFigure + semanticTags.add(SCChartsSemanticFilterTags.SIMPLE_STATE) // Proxy should be more square-like proxy.addMacroFigure } @@ -193,6 +200,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isInitial) { node.setInitialStyle + semanticTags.add(SCChartsSemanticFilterTags.INITIAL_STATE) proxy.setInitialStyle if (USE_KLAY.booleanValue && state.parentRegion.states.head == state) { node.setLayoutOption(LayeredOptions::LAYERING_LAYER_CONSTRAINT, LayerConstraint::FIRST); @@ -200,6 +208,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isFinal) { node.setFinalStyle + semanticTags.add(SCChartsSemanticFilterTags.FINAL_STATE) proxy.setFinalStyle } if (state.isViolation) { @@ -403,13 +412,17 @@ class StateSynthesis extends SubSynthesis { // Set size to be square and at least 34 (same as minimal node size) val proxyBounds = PlacementUtil.estimateSize(proxy) val minSize = 34 - val nonZero = proxyBounds.width > 0 && proxyBounds.height > 0 - proxy.width = nonZero ? proxyBounds.width : minSize - proxy.height = nonZero ? proxyBounds.height : minSize + val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 + proxy.width = bigEnough ? proxyBounds.width : minSize + proxy.height = bigEnough ? proxyBounds.height : minSize // Use this size to make proxies square // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) // Use this to make proxies always be at least minSize x minSize // proxy.width = Math.max(minSize, proxyBounds.width) + } else { + val connectorSize = 7 + proxy.width = connectorSize + proxy.height = connectorSize } node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java new file mode 100644 index 0000000000..6bc4a62c9c --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -0,0 +1,68 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright ${year} by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ui.synthesis.filtering; + +import de.cau.cs.kieler.klighd.filtering.*; + +/** + * Contains semantic filter rules for SCCharts. + * + * @author stu215592 + */ +public class SCChartsSemanticFilterRules { + /** Rule to exclude elements that are states. */ + public static final SemanticFilterRule NO_STATES = + new NegationConnective(SCChartsSemanticFilterTags.STATE, "Don't Show States"); + /** Rule to exclude elements that are regions. */ + public static final SemanticFilterRule NO_REGIONS = + new NegationConnective(SCChartsSemanticFilterTags.REGION, "Don't Show Regions"); + + /** Rule to exclude elements that are simple states. */ + public static final SemanticFilterRule NO_SIMPLE_STATE = new NegationConnective( + SCChartsSemanticFilterTags.SIMPLE_STATE, "Don't Show Simple States"); + /** Rule to exclude elements that are hierarchical states. */ + public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Don't Show Hierarchical States"); + /** Rule to exclude elements that are connector states. */ + public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( + SCChartsSemanticFilterTags.CONNECTOR_STATE, "Don't Show Connector States"); + /** Rule to exclude elements that are controlflow regions. */ + public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Don't Show Controlflow Regions"); + /** Rule to exclude elements that are dataflow regions. */ + public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( + SCChartsSemanticFilterTags.DATAFLOW_REGION, "Don't Show Dataflow Regions"); + + /** Rule to exclude elements that are initial states. */ + public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.INITIAL_STATE, "Don't Show Initial States"); + /** Rule to exclude elements that are final states. */ + public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.FINAL_STATE, "Don't Show Final States"); + + /** Rule to exclude elements that are either initial XOR final states. */ + public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = new NegationConnective( + new OrConnective( + new AndConnective(SCChartsSemanticFilterTags.INITIAL_STATE, NO_FINAL_STATE), + new AndConnective(NO_INITIAL_STATE, SCChartsSemanticFilterTags.FINAL_STATE)), + "Don't Show Initial XOR Final States"); // TODO + // new NegationConnective( + // new OrConnective( + // new AndConnective(SCChartsSemanticFilterTags.INITIAL_STATE, + // new NegationConnective(SCChartsSemanticFilterTags.FINAL_STATE)), + // new AndConnective( + // new NegationConnective( + // SCChartsSemanticFilterTags.INITIAL_STATE), + // SCChartsSemanticFilterTags.FINAL_STATE)), + // "Don't Show Initial XOR Final States"); +} diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java new file mode 100644 index 0000000000..17a1829b94 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -0,0 +1,45 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright ${year} by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ui.synthesis.filtering; + +import de.cau.cs.kieler.klighd.filtering.SemanticFilterTag; + +/** + * Contains semantic filter tags for SCCharts. + * + * @author stu215592 + */ +public class SCChartsSemanticFilterTags { + /** Tag giving semantic meaning that the element is a state. */ + public static final SemanticFilterTag STATE = new SemanticFilterTag("state"); + /** Tag giving semantic meaning that the element is a region. */ + public static final SemanticFilterTag REGION = new SemanticFilterTag("region"); + + /** Tag giving semantic meaning that the element is a simple state. */ + public static final SemanticFilterTag SIMPLE_STATE = new SemanticFilterTag("simpleState"); + /** Tag giving semantic meaning that the element is a hierarchical state. */ + public static final SemanticFilterTag HIERARCHICAL_STATE = + new SemanticFilterTag("hierarchicalState"); + /** Tag giving semantic meaning that the element is a connector state. */ + public static final SemanticFilterTag CONNECTOR_STATE = new SemanticFilterTag("connectorState"); + /** Tag giving semantic meaning that the element is a controlflow region. */ + public static final SemanticFilterTag CONTROLFLOW_REGION = + new SemanticFilterTag("controlflowRegion"); + /** Tag giving semantic meaning that the element is a dataflow region. */ + public static final SemanticFilterTag DATAFLOW_REGION = new SemanticFilterTag("dataflowRegion"); + + /** Tag giving semantic meaning that the element is an initial state. */ + public static final SemanticFilterTag INITIAL_STATE = new SemanticFilterTag("initialState"); + /** Tag giving semantic meaning that the element is a final state. */ + public static final SemanticFilterTag FINAL_STATE = new SemanticFilterTag("finalState"); +} From 0247b62f8578867da5eb7fd5ee871472a4f2cb1b Mon Sep 17 00:00:00 2001 From: fight4day Date: Fri, 1 Jul 2022 15:08:17 +0200 Subject: [PATCH 13/45] Removed some comments --- .../filtering/SCChartsSemanticFilterRules.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 6bc4a62c9c..6731daeffe 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -55,14 +55,5 @@ public class SCChartsSemanticFilterRules { new OrConnective( new AndConnective(SCChartsSemanticFilterTags.INITIAL_STATE, NO_FINAL_STATE), new AndConnective(NO_INITIAL_STATE, SCChartsSemanticFilterTags.FINAL_STATE)), - "Don't Show Initial XOR Final States"); // TODO - // new NegationConnective( - // new OrConnective( - // new AndConnective(SCChartsSemanticFilterTags.INITIAL_STATE, - // new NegationConnective(SCChartsSemanticFilterTags.FINAL_STATE)), - // new AndConnective( - // new NegationConnective( - // SCChartsSemanticFilterTags.INITIAL_STATE), - // SCChartsSemanticFilterTags.FINAL_STATE)), - // "Don't Show Initial XOR Final States"); + "Don't Show Initial XOR Final States"); } From 4e555034c8264e7e75f5724bda81a8b2aa215648 Mon Sep 17 00:00:00 2001 From: fight4day Date: Fri, 1 Jul 2022 21:46:17 +0200 Subject: [PATCH 14/45] Added a new tag, the corresponding rule is still TODO --- .../ui/synthesis/StateSynthesis.xtend | 10 ++-- .../SCChartsSemanticFilterRules.java | 50 ++++++++++++------- .../filtering/SCChartsSemanticFilterTags.java | 15 ++++-- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 0b158582f3..72ebdbb65b 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -200,7 +200,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isInitial) { node.setInitialStyle - semanticTags.add(SCChartsSemanticFilterTags.INITIAL_STATE) + semanticTags.add(SCChartsSemanticFilterTags.INITIAL) proxy.setInitialStyle if (USE_KLAY.booleanValue && state.parentRegion.states.head == state) { node.setLayoutOption(LayeredOptions::LAYERING_LAYER_CONSTRAINT, LayerConstraint::FIRST); @@ -208,7 +208,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isFinal) { node.setFinalStyle - semanticTags.add(SCChartsSemanticFilterTags.FINAL_STATE) + semanticTags.add(SCChartsSemanticFilterTags.FINAL) proxy.setFinalStyle } if (state.isViolation) { @@ -301,7 +301,8 @@ class StateSynthesis extends SubSynthesis { // Add declarations val declarations = new ArrayList(state.declarations) if (SHOW_INHERITANCE.booleanValue) declarations.addAll(0, state.allVisibleInheritedDeclarations.toList) - for (declaration : declarations.filter[!(it instanceof MethodImplementationDeclaration) || !SHOW_METHOD_BODY.booleanValue]) { + val filteredDeclarations = declarations.filter[!(it instanceof MethodImplementationDeclaration) || !SHOW_METHOD_BODY.booleanValue] + for (declaration : filteredDeclarations) { if (declaration instanceof ClassDeclaration) { node.addStructDeclarations(declaration, 0) } else { @@ -314,7 +315,8 @@ class StateSynthesis extends SubSynthesis { ] ] } - } + } + semanticTags.add(SCChartsSemanticFilterTags.DECLARATIONS(filteredDeclarations.size as double)) // Add actions val actions = new ArrayList(state.actions) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 6731daeffe..8ba2f537eb 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -17,43 +17,57 @@ /** * Contains semantic filter rules for SCCharts. * - * @author stu215592 + * @author tik */ public class SCChartsSemanticFilterRules { /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = - new NegationConnective(SCChartsSemanticFilterTags.STATE, "Don't Show States"); + new NegationConnective(SCChartsSemanticFilterTags.STATE, "Filter States"); /** Rule to exclude elements that are regions. */ public static final SemanticFilterRule NO_REGIONS = - new NegationConnective(SCChartsSemanticFilterTags.REGION, "Don't Show Regions"); + new NegationConnective(SCChartsSemanticFilterTags.REGION, "Filter Regions"); /** Rule to exclude elements that are simple states. */ - public static final SemanticFilterRule NO_SIMPLE_STATE = new NegationConnective( - SCChartsSemanticFilterTags.SIMPLE_STATE, "Don't Show Simple States"); + public static final SemanticFilterRule NO_SIMPLE_STATE = + new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Filter Simple States"); /** Rule to exclude elements that are hierarchical states. */ public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Don't Show Hierarchical States"); + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Filter Hierarchical States"); /** Rule to exclude elements that are connector states. */ public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( - SCChartsSemanticFilterTags.CONNECTOR_STATE, "Don't Show Connector States"); + SCChartsSemanticFilterTags.CONNECTOR_STATE, "Filter Connector States"); /** Rule to exclude elements that are controlflow regions. */ public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Don't Show Controlflow Regions"); + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Filter Controlflow Regions"); /** Rule to exclude elements that are dataflow regions. */ public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.DATAFLOW_REGION, "Don't Show Dataflow Regions"); + SCChartsSemanticFilterTags.DATAFLOW_REGION, "Filter Dataflow Regions"); /** Rule to exclude elements that are initial states. */ - public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.INITIAL_STATE, "Don't Show Initial States"); + public static final SemanticFilterRule NO_INITIAL_STATE = new AndConnective( + SCChartsSemanticFilterTags.STATE, + new NegationConnective(SCChartsSemanticFilterTags.INITIAL), "Filter Initial States"); /** Rule to exclude elements that are final states. */ - public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.FINAL_STATE, "Don't Show Final States"); + public static final SemanticFilterRule NO_FINAL_STATE = new AndConnective( + SCChartsSemanticFilterTags.STATE, + new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Filter Final States"); /** Rule to exclude elements that are either initial XOR final states. */ - public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = new NegationConnective( - new OrConnective( - new AndConnective(SCChartsSemanticFilterTags.INITIAL_STATE, NO_FINAL_STATE), - new AndConnective(NO_INITIAL_STATE, SCChartsSemanticFilterTags.FINAL_STATE)), - "Don't Show Initial XOR Final States"); + public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = + new AndConnective(SCChartsSemanticFilterTags.STATE, + new LogicEqualConnective(SCChartsSemanticFilterTags.INITIAL, + SCChartsSemanticFilterTags.FINAL), + "Filter Initial XOR Final States"); + + /** Rule to exclude elements that are neither initial states nor regions. */ + public static final SemanticFilterRule ONLY_INITIAL_STATES_AND_REGIONS = + new IfThenElseConnective(SCChartsSemanticFilterTags.STATE, + SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.REGION, + "Filter Everything but Initial States and Regions"); + + /** Rule to exclude elements that have less than 3 declarations. */ + public static final SemanticFilterRule AT_LEAST_3_DECLARATIONS = new OrConnective( // TODO: + new GreaterThanConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), + new NumericEqualConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), + "Filter Elements With Less Than 3 Declarations"); } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index 17a1829b94..1b1acc2103 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -17,7 +17,7 @@ /** * Contains semantic filter tags for SCCharts. * - * @author stu215592 + * @author tik */ public class SCChartsSemanticFilterTags { /** Tag giving semantic meaning that the element is a state. */ @@ -38,8 +38,13 @@ public class SCChartsSemanticFilterTags { /** Tag giving semantic meaning that the element is a dataflow region. */ public static final SemanticFilterTag DATAFLOW_REGION = new SemanticFilterTag("dataflowRegion"); - /** Tag giving semantic meaning that the element is an initial state. */ - public static final SemanticFilterTag INITIAL_STATE = new SemanticFilterTag("initialState"); - /** Tag giving semantic meaning that the element is a final state. */ - public static final SemanticFilterTag FINAL_STATE = new SemanticFilterTag("finalState"); + /** Tag giving semantic meaning that the element is initial. */ + public static final SemanticFilterTag INITIAL = new SemanticFilterTag("initial"); + /** Tag giving semantic meaning that the element is final. */ + public static final SemanticFilterTag FINAL = new SemanticFilterTag("final"); + + /** Returns a tag giving semantic meaning how many declarations an element has. */ + public static SemanticFilterTag DECLARATIONS(Double num) { + return new SemanticFilterTag("declarations", num); + } } From e4c4d0933eae81ecf34a55de54156b4d16811ea6 Mon Sep 17 00:00:00 2001 From: fight4day Date: Sat, 2 Jul 2022 17:22:15 +0200 Subject: [PATCH 15/45] Fixed AT_LEAST_3_DECLARATIONS rule --- .../ui/synthesis/filtering/SCChartsSemanticFilterRules.java | 6 ++++-- .../ui/synthesis/filtering/SCChartsSemanticFilterTags.java | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 8ba2f537eb..047ddb24c5 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -66,8 +66,10 @@ public class SCChartsSemanticFilterRules { "Filter Everything but Initial States and Regions"); /** Rule to exclude elements that have less than 3 declarations. */ - public static final SemanticFilterRule AT_LEAST_3_DECLARATIONS = new OrConnective( // TODO: - new GreaterThanConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), + public static final SemanticFilterRule AT_LEAST_3_DECLARATIONS = new OrConnective( + // 3 < num + new LessThanConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), + // 3 == num new NumericEqualConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), "Filter Elements With Less Than 3 Declarations"); } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index 1b1acc2103..4a207265d2 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -45,6 +45,6 @@ public class SCChartsSemanticFilterTags { /** Returns a tag giving semantic meaning how many declarations an element has. */ public static SemanticFilterTag DECLARATIONS(Double num) { - return new SemanticFilterTag("declarations", num); + return new SemanticFilterTag("numDeclarations", num); } } From eb4eec8b9608245888282f2d3cf7289dbc43e371 Mon Sep 17 00:00:00 2001 From: fight4day Date: Mon, 4 Jul 2022 12:54:43 +0200 Subject: [PATCH 16/45] Added some rules that test the util class --- .../SCChartsSemanticFilterRules.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 047ddb24c5..613794280b 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -20,6 +20,10 @@ * @author tik */ public class SCChartsSemanticFilterRules { + // Naming conventions: + // The names should start with NO_ or ONLY_, indicating + // which elements are kept out or left in + /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = new NegationConnective(SCChartsSemanticFilterTags.STATE, "Filter States"); @@ -59,17 +63,31 @@ public class SCChartsSemanticFilterRules { SCChartsSemanticFilterTags.FINAL), "Filter Initial XOR Final States"); - /** Rule to exclude elements that are neither initial states nor regions. */ - public static final SemanticFilterRule ONLY_INITIAL_STATES_AND_REGIONS = + /** Rule to only include elements that are either initial states or regions. */ + public static final SemanticFilterRule ONLY_INITIAL_STATES_OR_REGIONS = new IfThenElseConnective(SCChartsSemanticFilterTags.STATE, SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.REGION, - "Filter Everything but Initial States and Regions"); + "Filter Everything but Initial States or Regions"); - /** Rule to exclude elements that have less than 3 declarations. */ - public static final SemanticFilterRule AT_LEAST_3_DECLARATIONS = new OrConnective( + /** Rule to only include elements that have at least 3 declarations. */ + public static final SemanticFilterRule ONLY_AT_LEAST_3_DECLARATIONS = new OrConnective( // 3 < num new LessThanConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), // 3 == num new NumericEqualConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), "Filter Elements With Less Than 3 Declarations"); + + /** Rule to only include elements that are initial, final or a region. */ + public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = + ConnectiveUtil.getBigOrConnective("Filter Everything but Initial, Final or Regions", + SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, + SCChartsSemanticFilterTags.REGION); + + /** Rule to exclude every element. */ + public static final SemanticFilterRule NO_EVERYTHING = + ConnectiveUtil.addRuleName("Filter Everything", ConnectiveUtil.FALSE); + + /** Rule to only include every element. */ + public static final SemanticFilterRule ONLY_EVERYTHING = + ConnectiveUtil.addRuleName("Filter Nothing", ConnectiveUtil.TRUE); } From 220ee248d91a00f72dadd4d431405d802de59dda Mon Sep 17 00:00:00 2001 From: fight4day Date: Mon, 4 Jul 2022 12:55:40 +0200 Subject: [PATCH 17/45] Rename --- .../ui/synthesis/filtering/SCChartsSemanticFilterRules.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 613794280b..5e1cffe362 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -79,15 +79,15 @@ public class SCChartsSemanticFilterRules { /** Rule to only include elements that are initial, final or a region. */ public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = - ConnectiveUtil.getBigOrConnective("Filter Everything but Initial, Final or Regions", + SemanticFilterRuleUtil.getBigOrConnective("Filter Everything but Initial, Final or Regions", SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, SCChartsSemanticFilterTags.REGION); /** Rule to exclude every element. */ public static final SemanticFilterRule NO_EVERYTHING = - ConnectiveUtil.addRuleName("Filter Everything", ConnectiveUtil.FALSE); + SemanticFilterRuleUtil.addRuleName("Filter Everything", SemanticFilterRuleUtil.FALSE); /** Rule to only include every element. */ public static final SemanticFilterRule ONLY_EVERYTHING = - ConnectiveUtil.addRuleName("Filter Nothing", ConnectiveUtil.TRUE); + SemanticFilterRuleUtil.addRuleName("Filter Nothing", SemanticFilterRuleUtil.TRUE); } From 6e0100a020915df8c002b0d2357a738ddda928c1 Mon Sep 17 00:00:00 2001 From: fight4day Date: Wed, 6 Jul 2022 09:28:40 +0200 Subject: [PATCH 18/45] mka code review first change --- .../sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend | 2 +- .../kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend | 2 +- .../cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend | 2 +- .../de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 2 +- .../ui/synthesis/filtering/SCChartsSemanticFilterRules.java | 2 +- .../ui/synthesis/filtering/SCChartsSemanticFilterTags.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index db6b0297d5..b0edd4866a 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -83,7 +83,7 @@ class ControlflowRegionSynthesis extends SubSynthesis SCChartsSemanticFilterTags.REGION, SCChartsSemanticFilterTags.CONTROLFLOW_REGION ) - node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) + node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index d9a7bb85e4..9dfc6f24e5 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -87,7 +87,7 @@ class DataflowRegionSynthesis extends SubSynthesis { SCChartsSemanticFilterTags.REGION, SCChartsSemanticFilterTags.DATAFLOW_REGION ) - node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) + node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend index 9a816d284d..8c0c74c8a9 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend @@ -176,7 +176,7 @@ class SCChartsSynthesis extends AbstractDiagramSynthesis { val rules = SCChartsSemanticFilterRules.fields.map[ get(null) as SemanticFilterRule ] - rootNode.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_RULES, rules) + rootNode.setProperty(KlighdProperties.SEMANTIC_FILTER_RULES, rules) // If dot is used draw edges first to prevent overlapping with states when layout is bad usedContext.setProperty(KlighdProperties.EDGES_FIRST, !USE_KLAY.booleanValue) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 72ebdbb65b..0687646f69 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -147,7 +147,7 @@ class StateSynthesis extends SubSynthesis { override List performTranformation(State state) { val node = state.createNode().associateWith(state) val semanticTags = newArrayList(SCChartsSemanticFilterTags.STATE) - node.setLayoutOption(KlighdOptions.SEMANTIC_FILTER_TAGS, semanticTags) + node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(state) val maxProxyLabelLength = 5 diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 5e1cffe362..5768e7a292 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -19,7 +19,7 @@ * * @author tik */ -public class SCChartsSemanticFilterRules { +public abstract class SCChartsSemanticFilterRules { // Naming conventions: // The names should start with NO_ or ONLY_, indicating // which elements are kept out or left in diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index 4a207265d2..fe47d4ec2e 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -19,7 +19,7 @@ * * @author tik */ -public class SCChartsSemanticFilterTags { +public abstract class SCChartsSemanticFilterTags { /** Tag giving semantic meaning that the element is a state. */ public static final SemanticFilterTag STATE = new SemanticFilterTag("state"); /** Tag giving semantic meaning that the element is a region. */ From 6381522716a378f8ffe3a57a60e66217cd1c215a Mon Sep 17 00:00:00 2001 From: fight4day Date: Wed, 6 Jul 2022 17:08:00 +0200 Subject: [PATCH 19/45] Assume run-config as unchanged --- ...uageServer with KLighD in Workspace.launch | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch b/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch index d62e6b4817..8cf6661666 100644 --- a/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch +++ b/plugins/de.cau.cs.kieler.language.server/run-configurations/LanguageServer with KLighD in Workspace.launch @@ -65,39 +65,40 @@ + - - - - + + + + - - + + - - - - - - - - + + + + + + + + - + From 0950d48aeef7386570bc94281ca5807dc383ca92 Mon Sep 17 00:00:00 2001 From: fight4day Date: Wed, 6 Jul 2022 18:43:08 +0200 Subject: [PATCH 20/45] Most of the code review --- .../ControlflowRegionSynthesis.xtend | 33 ++++++++--------- .../synthesis/DataflowRegionSynthesis.xtend | 17 +++------ .../ui/synthesis/StateSynthesis.xtend | 33 ++++++----------- .../SCChartsSemanticFilterRules.java | 37 +++++++++++++++---- .../filtering/SCChartsSemanticFilterTags.java | 2 +- .../styles/ControlflowRegionStyles.xtend | 15 ++++++++ .../ui/synthesis/styles/StateStyles.xtend | 17 ++++++--- 7 files changed, 92 insertions(+), 62 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index b0edd4866a..aaa58f3614 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -25,6 +25,7 @@ import de.cau.cs.kieler.klighd.krendering.KText import de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.sccharts.ControlflowRegion import de.cau.cs.kieler.sccharts.Region @@ -32,9 +33,11 @@ import de.cau.cs.kieler.sccharts.State import de.cau.cs.kieler.sccharts.extensions.SCChartsScopeExtensions import de.cau.cs.kieler.sccharts.extensions.SCChartsSerializeHRExtensions import de.cau.cs.kieler.sccharts.ui.synthesis.actions.ReferenceExpandAction +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.MemorizingExpandCollapseAction import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ControlflowRegionStyles +import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import java.util.EnumSet import org.eclipse.elk.alg.layered.options.CenterEdgeLabelPlacementStrategy import org.eclipse.elk.alg.layered.options.FixedAlignment @@ -50,9 +53,6 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension de.cau.cs.kieler.klighd.util.ModelingUtil.* -import de.cau.cs.kieler.klighd.microlayout.PlacementUtil -import de.cau.cs.kieler.klighd.KlighdOptions -import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * Transforms {@link ControlflowRegion} into {@link KNode} diagram elements. @@ -79,11 +79,10 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); - val semanticTags = newArrayList( + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).addAll( SCChartsSemanticFilterTags.REGION, SCChartsSemanticFilterTags.CONTROLFLOW_REGION ) - node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 @@ -116,6 +115,14 @@ class ControlflowRegionSynthesis extends SubSynthesis // This node does not support comment boxes on the same layer, because regions are layouted by the box layouter. node.setProperty(MessageObjectReferencesManager.SUPPORTS_COMMENT_BOXES, false) + + val addCorrespondingRegionFigure = [ KNode x | + x.addRegionFigure => [ + if (region.override) addOverrideRegionStyle + if (region.abort) addAbortRegionStyle + if (region.final) addFinalRegionStyle + ] + ] if (!region.states.empty) { val label = region.serializeHighlighted(true) @@ -207,16 +214,12 @@ class ControlflowRegionSynthesis extends SubSynthesis ] } else { node.addRegionFigure => [ - if (region.override) addOverrideRegionStyle - if (region.abort) addAbortRegionStyle - if (region.final) addFinalRegionStyle + addCorrespondingRegionFigure(region) ] } proxy.addRegionFigure => [ - if (region.override) addOverrideRegionStyle - if (region.abort) addAbortRegionStyle - if (region.final) addFinalRegionStyle + addCorrespondingRegionFigure(region) val label = region.serializeHighlighted(true) if (label.length > 0) { val name = label.get(0) @@ -240,16 +243,12 @@ class ControlflowRegionSynthesis extends SubSynthesis ] } - // Set size to be square and at least 34 (same as minimal node size) + // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = 34 + val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 proxy.width = bigEnough ? proxyBounds.width : minSize proxy.height = bigEnough ? proxyBounds.height : minSize - // Use this size to make proxies square - // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - // Use this to make proxies always be at least minSize x minSize - // proxy.width = Math.max(minSize, proxyBounds.width) node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 9dfc6f24e5..bdb4b67f3a 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -22,13 +22,16 @@ import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.sccharts.DataflowRegion import de.cau.cs.kieler.sccharts.extensions.SCChartsSerializeHRExtensions import de.cau.cs.kieler.sccharts.extensions.TextFormat import de.cau.cs.kieler.sccharts.ui.synthesis.actions.ReferenceExpandAction +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.MemorizingExpandCollapseAction import de.cau.cs.kieler.sccharts.ui.synthesis.styles.DataflowRegionStyles +import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import org.eclipse.elk.alg.layered.options.GreedySwitchType import org.eclipse.elk.alg.layered.options.LayeredOptions import org.eclipse.elk.alg.layered.options.NodePlacementStrategy @@ -41,9 +44,6 @@ import org.eclipse.elk.core.options.EdgeRouting import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* -import de.cau.cs.kieler.klighd.microlayout.PlacementUtil -import de.cau.cs.kieler.klighd.KlighdOptions -import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * @author ssm @@ -83,11 +83,10 @@ class DataflowRegionSynthesis extends SubSynthesis { override performTranformation(DataflowRegion region) { val node = region.createNode().associateWith(region) - val semanticTags = newArrayList( + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).addAll( SCChartsSemanticFilterTags.REGION, SCChartsSemanticFilterTags.DATAFLOW_REGION ) - node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) val proxy = createNode().associateWith(region) val maxProxyLabelLength = 5 @@ -218,16 +217,12 @@ class DataflowRegionSynthesis extends SubSynthesis { node.setLayoutOption(CoreOptions::PADDING, new ElkPadding(18d, 7d, 7d, 7d)); } - // Set size to be square and at least 34 (same as minimal node size) + // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = 34 + val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 proxy.width = bigEnough ? proxyBounds.width : minSize proxy.height = bigEnough ? proxyBounds.height : minSize - // Use this size to make proxies square - // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - // Use this to make proxies always be at least minSize x minSize - // proxy.width = Math.max(minSize, proxyBounds.width) node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 0687646f69..2dcbe6536e 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -45,6 +45,7 @@ import de.cau.cs.kieler.klighd.krendering.extensions.KEdgeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KPolylineExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.sccharts.Action import de.cau.cs.kieler.sccharts.ControlflowRegion @@ -67,6 +68,7 @@ import de.cau.cs.kieler.sccharts.processors.dataflow.ControlDependencies import de.cau.cs.kieler.sccharts.processors.dataflow.RegionDependencies import de.cau.cs.kieler.sccharts.processors.dataflow.RegionLCAFMap import de.cau.cs.kieler.sccharts.processors.dataflow.StateDependencies +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.ToggleDependencyAction import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import de.cau.cs.kieler.scl.MethodImplementationDeclaration @@ -88,12 +90,6 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* -import org.eclipse.emf.common.util.EList -import de.cau.cs.kieler.klighd.kgraph.KGraphData -import de.cau.cs.kieler.klighd.kgraph.KGraphElement -import de.cau.cs.kieler.klighd.microlayout.PlacementUtil -import de.cau.cs.kieler.klighd.KlighdOptions -import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags /** * Transforms {@link State} into {@link KNode} diagram elements. @@ -146,8 +142,7 @@ class StateSynthesis extends SubSynthesis { override List performTranformation(State state) { val node = state.createNode().associateWith(state) - val semanticTags = newArrayList(SCChartsSemanticFilterTags.STATE) - node.setProperty(KlighdProperties.SEMANTIC_FILTER_TAGS, semanticTags) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.STATE) val proxy = createNode().associateWith(state) val maxProxyLabelLength = 5 @@ -177,17 +172,17 @@ class StateSynthesis extends SubSynthesis { switch state { case isConnector: { node.addConnectorFigure - semanticTags.add(SCChartsSemanticFilterTags.CONNECTOR_STATE) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.CONNECTOR_STATE) proxy.addConnectorFigure } case state.isMacroState: { node.addMacroFigure - semanticTags.add(SCChartsSemanticFilterTags.HIERARCHICAL_STATE) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.HIERARCHICAL_STATE) proxy.addMacroFigure } default: { node.addDefaultFigure - semanticTags.add(SCChartsSemanticFilterTags.SIMPLE_STATE) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.SIMPLE_STATE) // Proxy should be more square-like proxy.addMacroFigure } @@ -200,7 +195,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isInitial) { node.setInitialStyle - semanticTags.add(SCChartsSemanticFilterTags.INITIAL) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.INITIAL) proxy.setInitialStyle if (USE_KLAY.booleanValue && state.parentRegion.states.head == state) { node.setLayoutOption(LayeredOptions::LAYERING_LAYER_CONSTRAINT, LayerConstraint::FIRST); @@ -208,7 +203,7 @@ class StateSynthesis extends SubSynthesis { } if (state.isFinal) { node.setFinalStyle - semanticTags.add(SCChartsSemanticFilterTags.FINAL) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.FINAL) proxy.setFinalStyle } if (state.isViolation) { @@ -316,7 +311,7 @@ class StateSynthesis extends SubSynthesis { ] } } - semanticTags.add(SCChartsSemanticFilterTags.DECLARATIONS(filteredDeclarations.size as double)) + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.DECLARATIONS(filteredDeclarations.size as double)) // Add actions val actions = new ArrayList(state.actions) @@ -411,18 +406,14 @@ class StateSynthesis extends SubSynthesis { } if (!isConnector) { - // Set size to be square and at least 34 (same as minimal node size) + // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = 34 + val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 proxy.width = bigEnough ? proxyBounds.width : minSize proxy.height = bigEnough ? proxyBounds.height : minSize - // Use this size to make proxies square - // val size = Math.max(minSize, Math.max(proxyBounds.width, proxyBounds.height)) - // Use this to make proxies always be at least minSize x minSize - // proxy.width = Math.max(minSize, proxyBounds.width) } else { - val connectorSize = 7 + val connectorSize = StateStyles.CONNECTOR_FIGURE_SIZE proxy.width = connectorSize proxy.height = connectorSize } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 5768e7a292..97bb94b79d 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright ${year} by + * Copyright 2022 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group @@ -12,7 +12,15 @@ */ package de.cau.cs.kieler.sccharts.ui.synthesis.filtering; -import de.cau.cs.kieler.klighd.filtering.*; +import de.cau.cs.kieler.klighd.filtering.AndConnective; +import de.cau.cs.kieler.klighd.filtering.IfThenElseConnective; +import de.cau.cs.kieler.klighd.filtering.LessThanConnective; +import de.cau.cs.kieler.klighd.filtering.LogicEqualConnective; +import de.cau.cs.kieler.klighd.filtering.NegationConnective; +import de.cau.cs.kieler.klighd.filtering.NumericEqualConnective; +import de.cau.cs.kieler.klighd.filtering.OrConnective; +import de.cau.cs.kieler.klighd.filtering.SemanticFilterRule; +import de.cau.cs.kieler.klighd.filtering.SemanticFilterRuleUtil; /** * Contains semantic filter rules for SCCharts. @@ -56,14 +64,20 @@ public abstract class SCChartsSemanticFilterRules { SCChartsSemanticFilterTags.STATE, new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Filter Final States"); - /** Rule to exclude elements that are either initial XOR final states. */ + /** + * Rule to exclude elements that are either initial XOR final states. + * @example + */ public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = new AndConnective(SCChartsSemanticFilterTags.STATE, new LogicEqualConnective(SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL), "Filter Initial XOR Final States"); - /** Rule to only include elements that are either initial states or regions. */ + /** + * Rule to only include elements that are either initial states or regions. + * @example + */ public static final SemanticFilterRule ONLY_INITIAL_STATES_OR_REGIONS = new IfThenElseConnective(SCChartsSemanticFilterTags.STATE, SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.REGION, @@ -77,17 +91,26 @@ public abstract class SCChartsSemanticFilterRules { new NumericEqualConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), "Filter Elements With Less Than 3 Declarations"); - /** Rule to only include elements that are initial, final or a region. */ + /** + * Rule to only include elements that are initial, final or a region. + * @example + */ public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = SemanticFilterRuleUtil.getBigOrConnective("Filter Everything but Initial, Final or Regions", SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, SCChartsSemanticFilterTags.REGION); - /** Rule to exclude every element. */ + /** + * Rule to exclude every element. + * @example + */ public static final SemanticFilterRule NO_EVERYTHING = SemanticFilterRuleUtil.addRuleName("Filter Everything", SemanticFilterRuleUtil.FALSE); - /** Rule to only include every element. */ + /** + * Rule to only include every element. + * @example + */ public static final SemanticFilterRule ONLY_EVERYTHING = SemanticFilterRuleUtil.addRuleName("Filter Nothing", SemanticFilterRuleUtil.TRUE); } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index fe47d4ec2e..61c68e2e05 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -3,7 +3,7 @@ * * http://rtsys.informatik.uni-kiel.de/kieler * - * Copyright ${year} by + * Copyright 2022 by * + Kiel University * + Department of Computer Science * + Real-Time and Embedded Systems Group diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend index 9f3d94e2ff..6c41f8e8fb 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend @@ -191,6 +191,11 @@ class ControlflowRegionStyles { return button } + /** + * Adds a region figure similar to {@link addExpandButton()} and {@link addCollapseButton()} but without + * the button symbol and therefore without the text offset - since proxies for regions shouldn't be expandable + * or collapsable. + */ def KRendering addProxyRegion(KContainerRendering container, List> label) { if (!label.nullOrEmpty) { if (label.size == 1 && label.head.value == TextFormat.TEXT) { @@ -231,6 +236,16 @@ class ControlflowRegionStyles { } } + /** + * Adds the corresponding region figure to the node, + * taking its supposed style into account. + */ + def void addCorrespondingRegionFigure(KRectangle rect, ControlflowRegion region) { + if (region.override) rect.addOverrideRegionStyle + if (region.abort) rect.addAbortRegionStyle + if (region.final) rect.addFinalRegionStyle + } + /** * Adds an expand region button with label. */ diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend index 99573fbdec..c22e654a12 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend @@ -37,6 +37,7 @@ import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KPolylineExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KPortExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions +import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.sccharts.State import de.cau.cs.kieler.sccharts.extensions.TextFormat import java.util.EnumSet @@ -53,7 +54,6 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore.Color.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension org.eclipse.emf.ecore.util.EcoreUtil.* -import de.cau.cs.kieler.klighd.util.KlighdProperties /** * Styles for {@link State}. @@ -89,6 +89,13 @@ class StateStyles { /** This property is set on the content container rendering and points to the container holding the declaration labels */ public static final IProperty DECLARATIONS_CONTAINER = new Property( "de.cau.cs.kieler.sccharts.ui.synthesis.style.state.declarations", null); + + /** The default figure's corner radius. */ + public static final int DEFAULT_FIGURE_CORNER_RADIUS = 17; + /** The default figure's minimal node size. */ + public static final int DEFAULT_FIGURE_MIN_NODE_SIZE = 34; // 2 x corner radius + /** The connector figure's size. */ + public static final int CONNECTOR_FIGURE_SIZE = 7; protected var baseLineWidth = 1; protected var stateLabelTextSize = 11; @@ -97,7 +104,7 @@ class StateStyles { * Adds a connector figure. */ def KRoundedRectangle addConnectorFigure(KNode node) { - node.addRoundedRectangle(7, 7, baseLineWidth) => [ + node.addRoundedRectangle(CONNECTOR_FIGURE_SIZE, CONNECTOR_FIGURE_SIZE, baseLineWidth) => [ background = STATE_CONNECTOR.color; foreground = STATE_CONNECTOR.color; ] @@ -107,8 +114,8 @@ class StateStyles { * Adds a small state figure. */ def KRoundedRectangle addDefaultFigure(KNode node) { - node.setMinimalNodeSize(34, 34); // 2 x corner radius - node.addRoundedRectangle(17, 17, baseLineWidth) => [ + node.setMinimalNodeSize(DEFAULT_FIGURE_MIN_NODE_SIZE, DEFAULT_FIGURE_MIN_NODE_SIZE); + node.addRoundedRectangle(DEFAULT_FIGURE_CORNER_RADIUS, DEFAULT_FIGURE_CORNER_RADIUS, baseLineWidth) => [ // Mark this figure as container for further content setProperty(IS_CONTENT_CONTAINER, true); setBackgroundGradient(STATE_BACKGROUND_GRADIENT_1.color, STATE_BACKGROUND_GRADIENT_2.color, 90); @@ -120,7 +127,7 @@ class StateStyles { * Adds a macro state figure. */ def KRoundedRectangle addMacroFigure(KNode node) { - node.setMinimalNodeSize(34, 34); // same as default figure + node.setMinimalNodeSize(DEFAULT_FIGURE_MIN_NODE_SIZE, DEFAULT_FIGURE_MIN_NODE_SIZE); // same as default figure node.addRoundedRectangle(8, 8, baseLineWidth) => [ // Mark this figure as container for further content setProperty(IS_CONTENT_CONTAINER, true); From 889fee532e9da06ad6af2640b93d8679b3ae0893 Mon Sep 17 00:00:00 2001 From: fight4day Date: Wed, 20 Jul 2022 15:06:31 +0200 Subject: [PATCH 21/45] Code review --- .../ControlflowRegionSynthesis.xtend | 11 +++-- .../synthesis/DataflowRegionSynthesis.xtend | 11 +++-- .../ui/synthesis/SCChartsSynthesis.xtend | 5 +-- .../ui/synthesis/StateSynthesis.xtend | 11 +++-- .../SCChartsSemanticFilterRules.java | 44 +++++++++++++++++-- 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index aaa58f3614..890ea1c85d 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -245,10 +245,13 @@ class ControlflowRegionSynthesis extends SubSynthesis // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 - proxy.width = bigEnough ? proxyBounds.width : minSize - proxy.height = bigEnough ? proxyBounds.height : minSize + val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE + // Don't need to resize proxy if the node is already big enough by itself + val minSize = 10 + val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize + + proxy.width = bigEnough ? proxyBounds.width : minProxySize + proxy.height = bigEnough ? proxyBounds.height : minProxySize node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index bdb4b67f3a..8ad08ad848 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -219,10 +219,13 @@ class DataflowRegionSynthesis extends SubSynthesis { // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 - proxy.width = bigEnough ? proxyBounds.width : minSize - proxy.height = bigEnough ? proxyBounds.height : minSize + val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE + // Don't need to resize proxy if the node is already big enough by itself + val minSize = 10 + val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize + + proxy.width = bigEnough ? proxyBounds.width : minProxySize + proxy.height = bigEnough ? proxyBounds.height : minProxySize node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, node.data) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend index 8c0c74c8a9..ae9262a675 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/SCChartsSynthesis.xtend @@ -173,10 +173,7 @@ class SCChartsSynthesis extends AbstractDiagramSynthesis { val rootNode = createNode // Set semantic filter rules - val rules = SCChartsSemanticFilterRules.fields.map[ - get(null) as SemanticFilterRule - ] - rootNode.setProperty(KlighdProperties.SEMANTIC_FILTER_RULES, rules) + rootNode.setProperty(KlighdProperties.SEMANTIC_FILTER_RULES, SCChartsSemanticFilterRules.allFilters) // If dot is used draw edges first to prevent overlapping with states when layout is bad usedContext.setProperty(KlighdProperties.EDGES_FIRST, !USE_KLAY.booleanValue) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 2dcbe6536e..37c79e7e62 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -408,10 +408,13 @@ class StateSynthesis extends SubSynthesis { if (!isConnector) { // Set size to be at least minimal node size val proxyBounds = PlacementUtil.estimateSize(proxy) - val minSize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - val bigEnough = proxyBounds.width > 10 && proxyBounds.height > 10 - proxy.width = bigEnough ? proxyBounds.width : minSize - proxy.height = bigEnough ? proxyBounds.height : minSize + val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE + // Don't need to resize proxy if the node is already big enough by itself + val minSize = 10 + val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize + + proxy.width = bigEnough ? proxyBounds.width : minProxySize + proxy.height = bigEnough ? proxyBounds.height : minProxySize } else { val connectorSize = StateStyles.CONNECTOR_FIGURE_SIZE proxy.width = connectorSize diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 97bb94b79d..62d471d1e0 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -12,6 +12,10 @@ */ package de.cau.cs.kieler.sccharts.ui.synthesis.filtering; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + import de.cau.cs.kieler.klighd.filtering.AndConnective; import de.cau.cs.kieler.klighd.filtering.IfThenElseConnective; import de.cau.cs.kieler.klighd.filtering.LessThanConnective; @@ -28,9 +32,28 @@ * @author tik */ public abstract class SCChartsSemanticFilterRules { + + /** Returns all semantic filter rules defined in this class. */ + public static List getAllFilters() { + Field[] fields = SCChartsSemanticFilterRules.class.getFields(); + List filters = new ArrayList<>(fields.length); + // Map the fields to the actual rules + for (Field f : fields) { + try { + filters.add((SemanticFilterRule) f.get(null)); + } catch (IllegalArgumentException | IllegalAccessException e) { + // Neither of these should ever occur as + // 1. the fields are static, i.e. no instance is needed + // 2. the fields are accessible by this class + } + } + return filters; + } + // Naming conventions: - // The names should start with NO_ or ONLY_, indicating - // which elements are kept out or left in + // The class variables' names should start with NO_ or ONLY_, + // indicating which elements are kept out or left in + // The descriptions should utilize the checkbox as the verb /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = @@ -66,6 +89,7 @@ public abstract class SCChartsSemanticFilterRules { /** * Rule to exclude elements that are either initial XOR final states. + * * @example */ public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = @@ -76,6 +100,7 @@ public abstract class SCChartsSemanticFilterRules { /** * Rule to only include elements that are either initial states or regions. + * * @example */ public static final SemanticFilterRule ONLY_INITIAL_STATES_OR_REGIONS = @@ -93,15 +118,25 @@ public abstract class SCChartsSemanticFilterRules { /** * Rule to only include elements that are initial, final or a region. + * * @example */ - public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = - SemanticFilterRuleUtil.getBigOrConnective("Filter Everything but Initial, Final or Regions", + public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = SemanticFilterRuleUtil + .getBigOrConnective("Filter Everything but Initial, Final or Regions", SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, SCChartsSemanticFilterTags.REGION); + /** + * Rule to only include elements whose names start with "test", case-insensitive. TODO: + * + * @example + */ + public static final SemanticFilterRule ONLY_STARTING_WITH_TEST = + SemanticFilterRuleUtil.getBigOrConnective("TODO"); + /** * Rule to exclude every element. + * * @example */ public static final SemanticFilterRule NO_EVERYTHING = @@ -109,6 +144,7 @@ public abstract class SCChartsSemanticFilterRules { /** * Rule to only include every element. + * * @example */ public static final SemanticFilterRule ONLY_EVERYTHING = From 87f8c1640c27863877f644a6aff3409d89ce36d2 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Thu, 20 Oct 2022 18:03:33 +0200 Subject: [PATCH 22/45] Added SCTX constraint serializer. --- .../META-INF/MANIFEST.MF | 3 +- ...ighd.lsp.interactive.IConstraintSerializer | 1 + .../server/SCTXConstraintSerializer.xtend | 109 ++++++++++++++++++ 3 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer create mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/MANIFEST.MF b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/MANIFEST.MF index 7532b7ac9d..0e92675fb8 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/MANIFEST.MF +++ b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.antlr.runtime;bundle-version="[3.2.0,3.2.1)", de.cau.cs.kieler.scl.ide, de.cau.cs.kieler.klighd.lsp, com.google.gson, - de.cau.cs.kieler.kicool.ide + de.cau.cs.kieler.kicool.ide, + org.eclipse.lsp4j Export-Package: de.cau.cs.kieler.sccharts.ide.simulation, de.cau.cs.kieler.sccharts.ide.synthesis, de.cau.cs.kieler.sccharts.ide.text.contentassist.antlr, diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer new file mode 100644 index 0000000000..e534ff9f48 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer @@ -0,0 +1 @@ +de.cau.cs.kieler.sccharts.ide.language.server.SCTXConstraintSerializer \ No newline at end of file diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend new file mode 100644 index 0000000000..b08ac457eb --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend @@ -0,0 +1,109 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ide.language.server + +import de.cau.cs.kieler.annotations.Annotatable +import de.cau.cs.kieler.annotations.AnnotationsFactory +import de.cau.cs.kieler.annotations.TypedStringAnnotation +import de.cau.cs.kieler.klighd.internal.util.KlighdInternalProperties +import de.cau.cs.kieler.klighd.kgraph.KNode +import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient +import de.cau.cs.kieler.klighd.lsp.KGraphLanguageServerExtension +import de.cau.cs.kieler.klighd.lsp.interactive.ConstraintProperty +import de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer +import de.cau.cs.kieler.sccharts.impl.StateImpl +import java.io.ByteArrayOutputStream +import java.util.HashMap +import java.util.List +import java.util.Map +import org.eclipse.elk.graph.properties.IProperty +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.Range +import org.eclipse.lsp4j.TextEdit + +/** + * @author sdo + * + */ +class SCTXConstraintSerializer implements IConstraintSerializer { + + override canHandle(Object graph) { + return graph instanceof StateImpl + } + + override serializeConstraints(List> changedNodes, Object graph, String uri, + KGraphLanguageServerExtension ls, KGraphLanguageClient client) { + changedNodes.forEach[c| + val Annotatable anno = c.KNode.getProperty(KlighdInternalProperties.MODEL_ELEMEMT) as Annotatable + copyConstraintAnnotations(anno, c.KNode, c.property.id, c.property) + ] + // Serialize model into given uri. + val resource = ls.getResource(uri) + + // Get previous file content as String + var outputStream = new ByteArrayOutputStream + resource.save(outputStream, emptyMap) + val codeBefore = outputStream.toString + val Map> changes = newHashMap + // Get changed file as String + outputStream = new ByteArrayOutputStream + resource.save(outputStream, emptyMap) + val String codeAfter = outputStream.toString().trim + + // The range is the length of the previous file. + // Just make sure the range is big enough + val Range range = new Range(new Position(0, 0), new Position(codeBefore.split("\r\n|\r|\n").length * 2, 0)) + val TextEdit textEdit = new TextEdit(range, codeAfter) + changes.put(uri, #[textEdit]); + client.replaceContentInFile(uri, codeAfter, range) + } + + /** + * Copies an arbitrary IProperty of a KNode to a State if the value on the KNode + * is different to the value on the State. + * If the new value on the KNode was the default value of the property + * then the property is set to null on the State. + * @param state The target sate + * @param kNode The source KNode of the property + * @param annotation The annotation that should be set + * @param prop Determines which IProperty should be copied + */ + static def copyConstraintAnnotations(Annotatable state, KNode kNode, String annotation, IProperty prop) { + val String value = "" + kNode.getProperty(prop) + + val anns = state.getAnnotations().filter(TypedStringAnnotation) + + // remove old annotation if it exists + var TypedStringAnnotation removeA = null + for (ann : anns) { + if (ann.type.equals(annotation)) { + removeA = ann + } + } + if (removeA !== null) { + state.annotations.remove(removeA) + } + + // add annotation with new value if the value is not the default one + if (kNode.getProperty(prop) !== null && !kNode.getProperty(prop).equals(prop.^default)) { + var newA = AnnotationsFactory::eINSTANCE.createTypedStringAnnotation => [ + it.name = "layout" + it.type = annotation + it.values += value + ] + state.annotations.add(newA) + } + + } + +} From 6737be3bfa498afff57bcbb3c230b884cb96cf9c Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Fri, 21 Oct 2022 13:12:54 +0200 Subject: [PATCH 23/45] scharts.ide: Added interactive node id provider for SCTX. --- ...ler.klighd.lsp.interactive.INodeIdProvider | 1 + .../server/SCTXConstraintSerializer.xtend | 1 - .../language/server/SCTXNodeIdProvider.xtend | 36 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider create mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider new file mode 100644 index 0000000000..8f56e1e350 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider @@ -0,0 +1 @@ +de.cau.cs.kieler.sccharts.ide.language.server.SCTXNodeIdProvider \ No newline at end of file diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend index b08ac457eb..31ffcfb831 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend @@ -23,7 +23,6 @@ import de.cau.cs.kieler.klighd.lsp.interactive.ConstraintProperty import de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer import de.cau.cs.kieler.sccharts.impl.StateImpl import java.io.ByteArrayOutputStream -import java.util.HashMap import java.util.List import java.util.Map import org.eclipse.elk.graph.properties.IProperty diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend new file mode 100644 index 0000000000..e6ec9d1c06 --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend @@ -0,0 +1,36 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2022 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ide.language.server + +import de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider +import de.cau.cs.kieler.sccharts.impl.ScopeImpl + +/** + * Service class that returns the id of regions or states. + * + * @author sdo + * + */ +class SCTXNodeIdProvider implements INodeIdProvider { + + override canHandle(Object graph) { + return graph instanceof ScopeImpl + } + + override getNodeId(Object element) { + if (element instanceof ScopeImpl) { + return element.name + } + } + +} From 697e3b9c0088fc1181d76df83f9c2fc6656333b0 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Mon, 24 Oct 2022 15:16:45 +0200 Subject: [PATCH 24/45] scharts.ide.interactive: Remove NodeIdProvider service interface. --- ...ler.klighd.lsp.interactive.INodeIdProvider | 1 - .../language/server/SCTXNodeIdProvider.xtend | 36 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider delete mode 100644 plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider b/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider deleted file mode 100644 index 8f56e1e350..0000000000 --- a/plugins/de.cau.cs.kieler.sccharts.ide/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider +++ /dev/null @@ -1 +0,0 @@ -de.cau.cs.kieler.sccharts.ide.language.server.SCTXNodeIdProvider \ No newline at end of file diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend deleted file mode 100644 index e6ec9d1c06..0000000000 --- a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXNodeIdProvider.xtend +++ /dev/null @@ -1,36 +0,0 @@ -/* - * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient - * - * http://rtsys.informatik.uni-kiel.de/kieler - * - * Copyright 2022 by - * + Kiel University - * + Department of Computer Science - * + Real-Time and Embedded Systems Group - * - * This code is provided under the terms of the Eclipse Public License (EPL). - */ -package de.cau.cs.kieler.sccharts.ide.language.server - -import de.cau.cs.kieler.klighd.lsp.interactive.INodeIdProvider -import de.cau.cs.kieler.sccharts.impl.ScopeImpl - -/** - * Service class that returns the id of regions or states. - * - * @author sdo - * - */ -class SCTXNodeIdProvider implements INodeIdProvider { - - override canHandle(Object graph) { - return graph instanceof ScopeImpl - } - - override getNodeId(Object element) { - if (element instanceof ScopeImpl) { - return element.name - } - } - -} From f7bf8dce8bf7ad4dc1c73b2480ecc7d07a06962c Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Mon, 7 Nov 2022 17:16:42 +0100 Subject: [PATCH 25/45] scharts.ide/ui: Documentation, setting interactive layout in synthesis removed. --- .../server/SCTXConstraintSerializer.xtend | 35 ++++++++++--------- .../ControlflowRegionSynthesis.xtend | 5 --- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend index 31ffcfb831..16bd665877 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ide/src/de/cau/cs/kieler/sccharts/ide/language/server/SCTXConstraintSerializer.xtend @@ -31,6 +31,8 @@ import org.eclipse.lsp4j.Range import org.eclipse.lsp4j.TextEdit /** + * Serialize a constraint for an SCChart node (region or state) as a layout annotation. + * * @author sdo * */ @@ -72,29 +74,30 @@ class SCTXConstraintSerializer implements IConstraintSerializer { * is different to the value on the State. * If the new value on the KNode was the default value of the property * then the property is set to null on the State. - * @param state The target sate - * @param kNode The source KNode of the property - * @param annotation The annotation that should be set - * @param prop Determines which IProperty should be copied + * + * @param state The target state. + * @param kNode The source KNode of the property. + * @param annotation The annotation that should be set. + * @param property Determines which IProperty should be copied. */ - static def copyConstraintAnnotations(Annotatable state, KNode kNode, String annotation, IProperty prop) { - val String value = "" + kNode.getProperty(prop) + static def copyConstraintAnnotations(Annotatable state, KNode kNode, String annotation, IProperty property) { + val String value = "" + kNode.getProperty(property) - val anns = state.getAnnotations().filter(TypedStringAnnotation) + val annotations = state.getAnnotations().filter(TypedStringAnnotation) - // remove old annotation if it exists - var TypedStringAnnotation removeA = null - for (ann : anns) { - if (ann.type.equals(annotation)) { - removeA = ann + // Remove old annotation if it exists. + var TypedStringAnnotation annotationToRemove = null + for (a : annotations) { + if (a.type.equals(annotation)) { + annotationToRemove = a } } - if (removeA !== null) { - state.annotations.remove(removeA) + if (annotationToRemove !== null) { + state.annotations.remove(annotationToRemove) } - // add annotation with new value if the value is not the default one - if (kNode.getProperty(prop) !== null && !kNode.getProperty(prop).equals(prop.^default)) { + // Add annotation with new value if the value is not the default one. + if (kNode.getProperty(property) !== null && !kNode.getProperty(property).equals(property.^default)) { var newA = AnnotationsFactory::eINSTANCE.createTypedStringAnnotation => [ it.name = "layout" it.type = annotation diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 8784fb3767..e1f0e4047c 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -77,11 +77,6 @@ class ControlflowRegionSynthesis extends SubSynthesis override performTranformation(ControlflowRegion region) { val node = region.createNode().associateWith(region); - // default value of interactive layout for regions - if (!region.annotations.contains(CoreOptions.INTERACTIVE_LAYOUT)) { - node.setLayoutOption(CoreOptions::INTERACTIVE_LAYOUT, true) - } - node.configureNodeLOD(region) // Set KIdentifier for use with incremental update From c746ab72a5f423a9dd503e43f08abd40e6676358 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Tue, 8 Nov 2022 17:13:12 +0100 Subject: [PATCH 26/45] Add MrTree lS extension and configuration. --- .../de/cau/cs/kieler/language/server/LSCreator.xtend | 5 +++++ .../de.cau.cs.kieler.scg.klighd/META-INF/MANIFEST.MF | 3 ++- .../klighd/ssa/domtree/DominatorTreeSynthesis.xtend | 12 +++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend b/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend index 497aac4575..2f30a7a42f 100644 --- a/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend +++ b/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend @@ -17,6 +17,7 @@ import de.cau.cs.kieler.core.services.KielerServiceLoader import de.cau.cs.kieler.kgraph.text.services.KGraphGrammarAccess import de.cau.cs.kieler.klighd.lsp.KGraphLanguageClient import de.cau.cs.kieler.klighd.lsp.interactive.layered.LayeredInteractiveLanguageServerExtension +import de.cau.cs.kieler.klighd.lsp.interactive.mrtree.MrTreeInteractiveLanguageServerExtension import de.cau.cs.kieler.klighd.lsp.interactive.rectpacking.RectpackingInteractiveLanguageServerExtension import de.cau.cs.kieler.klighd.lsp.launch.AbstractLsCreator import java.util.List @@ -37,6 +38,8 @@ class LSCreator extends AbstractLsCreator { RectpackingInteractiveLanguageServerExtension rectPack + MrTreeInteractiveLanguageServerExtension mrTree + List diagramHighlighters List iLanguageServerExtensions @@ -54,6 +57,7 @@ class LSCreator extends AbstractLsCreator { override getLanguageServerExtensions() { constraints = injector.getInstance(LayeredInteractiveLanguageServerExtension) rectPack = injector.getInstance(RectpackingInteractiveLanguageServerExtension) + mrTree = injector.getInstance(MrTreeInteractiveLanguageServerExtension) iLanguageServerExtensions = newArrayList(constraints, rectPack) for (lse : KielerServiceLoader.load(ILanguageServerContribution)) { iLanguageServerExtensions.add(lse.getLanguageServerExtension(injector)) @@ -75,6 +79,7 @@ class LSCreator extends AbstractLsCreator { } constraints.client = languageClient as KGraphLanguageClient rectPack.client = languageClient as KGraphLanguageClient + mrTree.client = languageClient as KGraphLanguageClient diagramHighlighters = newArrayList for (iLSdhc : KielerServiceLoader.load(ILSDiagramHighlighterContribution)) { var highlighter = iLSdhc.getHighlighter(injector) diff --git a/plugins/de.cau.cs.kieler.scg.klighd/META-INF/MANIFEST.MF b/plugins/de.cau.cs.kieler.scg.klighd/META-INF/MANIFEST.MF index 08d4ad264f..7d264e3dd1 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/META-INF/MANIFEST.MF +++ b/plugins/de.cau.cs.kieler.scg.klighd/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.elk.core;bundle-version="0.7.1", de.cau.cs.kieler.kicool.ui, de.cau.cs.kieler.simulation.ide, de.cau.cs.kieler.simulation.ui, - de.cau.cs.kieler.annotations.ide + de.cau.cs.kieler.annotations.ide, + org.eclipse.elk.alg.mrtree Bundle-RequiredExecutionEnvironment: JavaSE-11 Export-Package: de.cau.cs.kieler.scg.klighd Bundle-ActivationPolicy: lazy diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend index 527644312c..c4cb5785ec 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend @@ -16,6 +16,7 @@ package de.cau.cs.kieler.scg.klighd.ssa.domtree import com.google.inject.Inject import de.cau.cs.kieler.annotations.extensions.AnnotationsExtensions import de.cau.cs.kieler.klighd.LightDiagramServices +import de.cau.cs.kieler.klighd.SynthesisOption import de.cau.cs.kieler.klighd.internal.util.SourceModelTrackingAdapter import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.krendering.SimpleUpdateStrategy @@ -33,13 +34,15 @@ import de.cau.cs.kieler.scg.SchedulingBlock import de.cau.cs.kieler.scg.extensions.SCGControlFlowExtensions import de.cau.cs.kieler.scg.extensions.SCGCoreExtensions import de.cau.cs.kieler.scg.processors.ssa.DominatorTree +import java.util.List import java.util.Map +import org.eclipse.elk.alg.mrtree.options.EdgeRoutingMode +import org.eclipse.elk.alg.mrtree.options.MrTreeOptions +import org.eclipse.elk.alg.mrtree.options.OrderWeighting import org.eclipse.elk.core.options.CoreOptions import org.eclipse.elk.core.options.Direction import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* -import de.cau.cs.kieler.klighd.SynthesisOption -import java.util.List class DominatorTreeSynthesis extends AbstractDiagramSynthesis { @@ -133,8 +136,11 @@ class DominatorTreeSynthesis extends AbstractDiagramSynthesis { nodes.entrySet.forEach[nodes.createDTEdge(value, key, dt)] val dtDiagram = createNode - dtDiagram.addLayoutParam(CoreOptions::ALGORITHM, "org.eclipse.elk.mrtree") + dtDiagram.addLayoutParam(CoreOptions::ALGORITHM, MrTreeOptions.ALGORITHM_ID) dtDiagram.addLayoutParam(CoreOptions::DIRECTION, Direction.DOWN) + dtDiagram.addLayoutParam(MrTreeOptions::EDGE_ROUTING_MODE, EdgeRoutingMode.AvoidOverlap) + dtDiagram.addLayoutParam(MrTreeOptions::WEIGHTING, OrderWeighting.NONE) + dtDiagram.addLayoutParam(MrTreeOptions::COMPACTION, false) dtDiagram.children += nodes.values return dtDiagram From 9eb7cc2ce8ab8afa92d5c42812d3c8d3b0d97771 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Fri, 11 Nov 2022 16:00:30 +0100 Subject: [PATCH 27/45] Added Mrtree so supported ls extensions. --- .../src/de/cau/cs/kieler/language/server/LSCreator.xtend | 2 +- .../scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend b/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend index 2f30a7a42f..f2456ded4a 100644 --- a/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend +++ b/plugins/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/LSCreator.xtend @@ -58,7 +58,7 @@ class LSCreator extends AbstractLsCreator { constraints = injector.getInstance(LayeredInteractiveLanguageServerExtension) rectPack = injector.getInstance(RectpackingInteractiveLanguageServerExtension) mrTree = injector.getInstance(MrTreeInteractiveLanguageServerExtension) - iLanguageServerExtensions = newArrayList(constraints, rectPack) + iLanguageServerExtensions = newArrayList(constraints, rectPack, mrTree) for (lse : KielerServiceLoader.load(ILanguageServerContribution)) { iLanguageServerExtensions.add(lse.getLanguageServerExtension(injector)) } diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend index c4cb5785ec..8abbec5285 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/ssa/domtree/DominatorTreeSynthesis.xtend @@ -138,8 +138,8 @@ class DominatorTreeSynthesis extends AbstractDiagramSynthesis { val dtDiagram = createNode dtDiagram.addLayoutParam(CoreOptions::ALGORITHM, MrTreeOptions.ALGORITHM_ID) dtDiagram.addLayoutParam(CoreOptions::DIRECTION, Direction.DOWN) - dtDiagram.addLayoutParam(MrTreeOptions::EDGE_ROUTING_MODE, EdgeRoutingMode.AvoidOverlap) - dtDiagram.addLayoutParam(MrTreeOptions::WEIGHTING, OrderWeighting.NONE) + dtDiagram.addLayoutParam(MrTreeOptions::EDGE_ROUTING_MODE, EdgeRoutingMode.AVOID_OVERLAP) + dtDiagram.addLayoutParam(MrTreeOptions::WEIGHTING, OrderWeighting.MODEL_ORDER) dtDiagram.addLayoutParam(MrTreeOptions::COMPACTION, false) dtDiagram.children += nodes.values From 53287ae98078ba0bafce338a5fce7e8b115c5c64 Mon Sep 17 00:00:00 2001 From: fight4day Date: Tue, 2 Aug 2022 13:11:31 +0200 Subject: [PATCH 28/45] Trivial rules fixed --- .../synthesis/filtering/SCChartsSemanticFilterRules.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 62d471d1e0..0222575db6 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -17,6 +17,7 @@ import java.util.List; import de.cau.cs.kieler.klighd.filtering.AndConnective; +import de.cau.cs.kieler.klighd.filtering.FalseConnective; import de.cau.cs.kieler.klighd.filtering.IfThenElseConnective; import de.cau.cs.kieler.klighd.filtering.LessThanConnective; import de.cau.cs.kieler.klighd.filtering.LogicEqualConnective; @@ -25,6 +26,7 @@ import de.cau.cs.kieler.klighd.filtering.OrConnective; import de.cau.cs.kieler.klighd.filtering.SemanticFilterRule; import de.cau.cs.kieler.klighd.filtering.SemanticFilterRuleUtil; +import de.cau.cs.kieler.klighd.filtering.TrueConnective; /** * Contains semantic filter rules for SCCharts. @@ -139,14 +141,12 @@ public static List getAllFilters() { * * @example */ - public static final SemanticFilterRule NO_EVERYTHING = - SemanticFilterRuleUtil.addRuleName("Filter Everything", SemanticFilterRuleUtil.FALSE); + public static final SemanticFilterRule NO_EVERYTHING = new FalseConnective("Filter Everything"); /** * Rule to only include every element. * * @example */ - public static final SemanticFilterRule ONLY_EVERYTHING = - SemanticFilterRuleUtil.addRuleName("Filter Nothing", SemanticFilterRuleUtil.TRUE); + public static final SemanticFilterRule ONLY_EVERYTHING = new TrueConnective("Filter Nothing"); } From fda6cea53b7426359ff1c05862933461a615c9a1 Mon Sep 17 00:00:00 2001 From: fight4day Date: Tue, 2 Aug 2022 16:49:58 +0200 Subject: [PATCH 29/45] Tested semantic filtering v2 --- .../ui/synthesis/StateSynthesis.xtend | 43 ++++++++++++++++++- .../SCChartsSemanticFilterRules.java | 30 +++++++++---- .../filtering/SCChartsSemanticFilterTags.java | 32 ++++++++++++++ 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 37c79e7e62..19e1b3f93c 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -90,6 +90,7 @@ import static de.cau.cs.kieler.sccharts.ui.synthesis.GeneralSynthesisOptions.* import static extension de.cau.cs.kieler.annotations.ide.klighd.CommonSynthesisUtil.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* +import de.cau.cs.kieler.kexpressions.VariableDeclaration /** * Transforms {@link State} into {@link KNode} diagram elements. @@ -310,8 +311,46 @@ class StateSynthesis extends SubSynthesis { ] ] } - } - node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.DECLARATIONS(filteredDeclarations.size as double)) + } + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add( + SCChartsSemanticFilterTags.DECLARATIONS( + filteredDeclarations + .size as double + ) + ) + + // Set declaration tags + var numInput = 0 + var numOutput = 0 + var numStatic = 0 + var numSignal = 0 + var numConst = 0 + var numExtern = 0 + var numVolatile = 0 + var numGlobal = 0 + for (declaration : filteredDeclarations) { + if (declaration instanceof VariableDeclaration) { + // Note that a declaration may have an arbitrary combination of these + if (declaration.input) numInput++ + if (declaration.output) numOutput++ + if (declaration.static) numStatic++ + if (declaration.signal) numSignal++ + if (declaration.const) numConst++ + if (declaration.extern) numExtern++ + if (declaration.volatile) numVolatile++ + if (declaration.global) numGlobal++ + } + } + node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).addAll( + SCChartsSemanticFilterTags.INPUT_DECLARATIONS(numInput as double), + SCChartsSemanticFilterTags.OUTPUT_DECLARATIONS(numOutput as double), + SCChartsSemanticFilterTags.STATIC_DECLARATIONS(numStatic as double), + SCChartsSemanticFilterTags.SIGNAL_DECLARATIONS(numSignal as double), + SCChartsSemanticFilterTags.CONST_DECLARATIONS(numConst as double), + SCChartsSemanticFilterTags.EXTERN_DECLARATIONS(numExtern as double), + SCChartsSemanticFilterTags.VOLATILE_DECLARATIONS(numVolatile as double), + SCChartsSemanticFilterTags.GLOBAL_DECLARATIONS(numGlobal as double) + ) // Add actions val actions = new ArrayList(state.actions) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 0222575db6..f202e465f9 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -18,11 +18,16 @@ import de.cau.cs.kieler.klighd.filtering.AndConnective; import de.cau.cs.kieler.klighd.filtering.FalseConnective; +import de.cau.cs.kieler.klighd.filtering.GreaterEqualsConnective; +import de.cau.cs.kieler.klighd.filtering.GreaterThanConnective; import de.cau.cs.kieler.klighd.filtering.IfThenElseConnective; import de.cau.cs.kieler.klighd.filtering.LessThanConnective; import de.cau.cs.kieler.klighd.filtering.LogicEqualConnective; import de.cau.cs.kieler.klighd.filtering.NegationConnective; +import de.cau.cs.kieler.klighd.filtering.NumericAdditionConnective; +import de.cau.cs.kieler.klighd.filtering.NumericConstantConnective; import de.cau.cs.kieler.klighd.filtering.NumericEqualConnective; +import de.cau.cs.kieler.klighd.filtering.NumericSubtractionConnective; import de.cau.cs.kieler.klighd.filtering.OrConnective; import de.cau.cs.kieler.klighd.filtering.SemanticFilterRule; import de.cau.cs.kieler.klighd.filtering.SemanticFilterRuleUtil; @@ -111,12 +116,10 @@ public static List getAllFilters() { "Filter Everything but Initial States or Regions"); /** Rule to only include elements that have at least 3 declarations. */ - public static final SemanticFilterRule ONLY_AT_LEAST_3_DECLARATIONS = new OrConnective( - // 3 < num - new LessThanConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), - // 3 == num - new NumericEqualConnective(SCChartsSemanticFilterTags.DECLARATIONS(3.0)), - "Filter Elements With Less Than 3 Declarations"); + public static final SemanticFilterRule ONLY_AT_LEAST_3_DECLARATIONS = + new GreaterEqualsConnective(SCChartsSemanticFilterTags.DECLARATIONS(null), + new NumericConstantConnective(3.0), + "Filter Elements with less than 3 Declarations"); /** * Rule to only include elements that are initial, final or a region. @@ -133,8 +136,8 @@ public static List getAllFilters() { * * @example */ - public static final SemanticFilterRule ONLY_STARTING_WITH_TEST = - SemanticFilterRuleUtil.getBigOrConnective("TODO"); + // public static final SemanticFilterRule ONLY_STARTING_WITH_TEST = + // SemanticFilterRuleUtil.getBigOrConnective("TODO"); /** * Rule to exclude every element. @@ -149,4 +152,15 @@ public static List getAllFilters() { * @example */ public static final SemanticFilterRule ONLY_EVERYTHING = new TrueConnective("Filter Nothing"); + + /** + * Rule to only include elements with more input/output declarations than the total number of declarations. + * + * @example + */ + public static final SemanticFilterRule ONLY_MORE_IO_THAN_DECLARATIONS = new GreaterThanConnective( + new NumericAdditionConnective(SCChartsSemanticFilterTags.INPUT_DECLARATIONS(null), + SCChartsSemanticFilterTags.OUTPUT_DECLARATIONS(null)), + SCChartsSemanticFilterTags.DECLARATIONS(null), + "Only Show Elements with more Input/Output Declarations than the total Number of Declarations"); } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index 61c68e2e05..c62c77bb06 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -47,4 +47,36 @@ public abstract class SCChartsSemanticFilterTags { public static SemanticFilterTag DECLARATIONS(Double num) { return new SemanticFilterTag("numDeclarations", num); } + /** Returns a tag giving semantic meaning how many input declarations an element has. */ + public static SemanticFilterTag INPUT_DECLARATIONS(Double num) { + return new SemanticFilterTag("numInputDeclarations", num); + } + /** Returns a tag giving semantic meaning how many output declarations an element has. */ + public static SemanticFilterTag OUTPUT_DECLARATIONS(Double num) { + return new SemanticFilterTag("numOutputDeclarations", num); + } + /** Returns a tag giving semantic meaning how many static declarations an element has. */ + public static SemanticFilterTag STATIC_DECLARATIONS(Double num) { + return new SemanticFilterTag("numStaticDeclarations", num); + } + /** Returns a tag giving semantic meaning how many signal declarations an element has. */ + public static SemanticFilterTag SIGNAL_DECLARATIONS(Double num) { + return new SemanticFilterTag("numSignalDeclarations", num); + } + /** Returns a tag giving semantic meaning how many const declarations an element has. */ + public static SemanticFilterTag CONST_DECLARATIONS(Double num) { + return new SemanticFilterTag("numConstDeclarations", num); + } + /** Returns a tag giving semantic meaning how many extern declarations an element has. */ + public static SemanticFilterTag EXTERN_DECLARATIONS(Double num) { + return new SemanticFilterTag("numExternDeclarations", num); + } + /** Returns a tag giving semantic meaning how many volatile declarations an element has. */ + public static SemanticFilterTag VOLATILE_DECLARATIONS(Double num) { + return new SemanticFilterTag("numVolatileDeclarations", num); + } + /** Returns a tag giving semantic meaning how many global declarations an element has. */ + public static SemanticFilterTag GLOBAL_DECLARATIONS(Double num) { + return new SemanticFilterTag("numGlobalDeclarations", num); + } } From 429ac7355732523671bfe4e876481ab773ff0dcc Mon Sep 17 00:00:00 2001 From: fight4day Date: Mon, 29 Aug 2022 15:51:35 +0200 Subject: [PATCH 30/45] Beautification --- .../filtering/SCChartsSemanticFilterRules.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index f202e465f9..7fb85d3b93 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -131,14 +131,6 @@ public static List getAllFilters() { SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, SCChartsSemanticFilterTags.REGION); - /** - * Rule to only include elements whose names start with "test", case-insensitive. TODO: - * - * @example - */ - // public static final SemanticFilterRule ONLY_STARTING_WITH_TEST = - // SemanticFilterRuleUtil.getBigOrConnective("TODO"); - /** * Rule to exclude every element. * @@ -162,5 +154,5 @@ public static List getAllFilters() { new NumericAdditionConnective(SCChartsSemanticFilterTags.INPUT_DECLARATIONS(null), SCChartsSemanticFilterTags.OUTPUT_DECLARATIONS(null)), SCChartsSemanticFilterTags.DECLARATIONS(null), - "Only Show Elements with more Input/Output Declarations than the total Number of Declarations"); + "Filter Elements with #IO Declarations <= #Declarations"); } From d11065670abbc2367149a334753a42f0a3428865 Mon Sep 17 00:00:00 2001 From: fight4day Date: Mon, 12 Sep 2022 11:34:35 +0200 Subject: [PATCH 31/45] Implemented an SCGraph specific proxy-rendering --- .../klighd/SCGraphComponentSynthesis.xtend | 34 +++++++++++++++++++ .../scg/klighd/SCGraphDiagramSynthesis.xtend | 2 ++ .../klighd/SCGraphHierarchySynthesis.xtend | 7 +++- .../scg/klighd/SCGraphSynthesisHelper.xtend | 24 +++++++++++++ .../scg/klighd/SCGraphsDiagramSynthesis.xtend | 4 +++ 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphComponentSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphComponentSynthesis.xtend index 0a654040be..80b6a0c605 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphComponentSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphComponentSynthesis.xtend @@ -30,6 +30,7 @@ import de.cau.cs.kieler.klighd.krendering.extensions.KLabelExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KPortExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.klighd.util.KlighdSynthesisProperties import de.cau.cs.kieler.scg.Assignment @@ -85,10 +86,15 @@ class SCGraphComponentSynthesis { */ def dispatch createComponentNode(Assignment assignment) { val node = assignment.createNode().associateWith(assignment) + val proxy = createNode().associateWith(assignment) + // Straightforward rectangle drawing val figure = node.addRoundedRectangle(SCGraphSynthesisHelper.CORNERRADIUS, SCGraphSynthesisHelper.CORNERRADIUS, SCGraphSynthesisHelper.LINEWIDTH) figure.addText("").setSurroundingSpace(6, 0, 2, 0) + val proxyFigure = proxy.addRoundedRectangle(SCGraphSynthesisHelper.CORNERRADIUS, SCGraphSynthesisHelper.CORNERRADIUS, + SCGraphSynthesisHelper.LINEWIDTH) + proxyFigure.addText("").setSurroundingSpace(6, 0, 2, 0) var isSCGRef = false if (assignment.expression instanceof ReferenceCall) { val call = assignment.expression as ReferenceCall @@ -99,10 +105,13 @@ class SCGraphComponentSynthesis { } if (isSCGRef) { figure.setBackgroundGradient("#fcf7fc".color, "#e6cbf2".color, 90.0f) + proxyFigure.setBackgroundGradient("#fcf7fc".color, "#e6cbf2".color, 90.0f) } else { figure.background = "white".color; + proxyFigure.background = "white".color; } node.initialiseFigure(assignment) + proxy.initialiseAssignmentProxyFigure() // Add ports for control-flow and dependency routing. if (isGuardSCG) { @@ -164,6 +173,14 @@ class SCGraphComponentSynthesis { if (assignment.hasAnnotation(PriorityAuxiliaryData.OPTIMIZED_NODE_PRIORITIES_ANNOTATION)) { node.createOptimizedPriorityLabel(assignment).setAreaPlacementData.from(LEFT, 0, 0.9f, TOP, 0, 0.3f).to(RIGHT, 0, 0.9f, BOTTOM, 0, 0) } + + // Estimate proxy size + val proxyBounds = PlacementUtil.estimateSize(proxy) + proxy.width = proxyBounds.width + proxy.height = proxyBounds.height + + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) + return node } @@ -176,9 +193,14 @@ class SCGraphComponentSynthesis { */ def dispatch createComponentNode(Conditional conditional) { val node = conditional.createNode().associateWith(conditional) + val proxy = createNode().associateWith(conditional) + // Draw a diamond figure for conditionals. node.addPolygon.createDiamondShape node.initialiseFigure(conditional) + proxy.addPolygon.createDiamondShape + proxy.initialiseConditionalProxyFigure + // Add ports for control-flow and dependency routing. var switchBranch = false val branchAnnotation = conditional.getAnnotation(ANNOTATION_BRANCH) @@ -244,6 +266,16 @@ class SCGraphComponentSynthesis { if (conditional.hasAnnotation(PriorityAuxiliaryData.OPTIMIZED_NODE_PRIORITIES_ANNOTATION)) { node.createOptimizedPriorityLabel(conditional).setAreaPlacementData.from(LEFT, 0, 0, TOP, 0, 0.6f).to(RIGHT, 0, 0, BOTTOM, 0, 0) } + + // Estimate proxy size + val proxyBounds = PlacementUtil.estimateSize(proxy) + // Use additionalWidth since the estimation doesn't consider the diamond shape + val additionalWidth = 5 + proxy.width = proxyBounds.width + additionalWidth + proxy.height = proxyBounds.height + + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) + return node } @@ -338,6 +370,7 @@ class SCGraphComponentSynthesis { */ def dispatch createComponentNode(Entry entry) { val node = entry.createNode().associateWith(entry) + val scg = entry.eContainer as SCGraph // If the corresponding option is set to true, exit nodes are placed in the first layer; if (ALIGN_ENTRYEXIT_NODES.booleanValue) @@ -396,6 +429,7 @@ class SCGraphComponentSynthesis { if (entry.hasAnnotation(PriorityAuxiliaryData.OPTIMIZED_NODE_PRIORITIES_ANNOTATION)) { node.createOptimizedPriorityLabel(entry).setAreaPlacementData.from(LEFT, 0, 0.8f, TOP, 0, 0.1f) } + return node } diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend index 158be4c6c9..b86fb70994 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend @@ -289,6 +289,7 @@ class SCGraphDiagramSynthesis extends AbstractDiagramSynthesis { */ private def KNode synthesize(SCGraph scg) { val node = scg.createNode().associateWith(scg) + // Set root node and layout options. rootNode = node isSCPDG = scg.hasAnnotation(ANNOTATION_SCPDGTRANSFORMATION) @@ -475,6 +476,7 @@ class SCGraphDiagramSynthesis extends AbstractDiagramSynthesis { scg.synthesizeScheduleGroups scg.applyDependencyHierarchy + return node } diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphHierarchySynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphHierarchySynthesis.xtend index a94da92ea6..5b1c2aea45 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphHierarchySynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphHierarchySynthesis.xtend @@ -46,6 +46,7 @@ import de.cau.cs.kieler.scg.extensions.SCGDependencyExtensions import de.cau.cs.kieler.scg.extensions.SCGSerializeHRExtensions import de.cau.cs.kieler.scg.extensions.SCGThreadExtensions import de.cau.cs.kieler.scg.extensions.ThreadPathType +import de.cau.cs.kieler.scg.processors.SCGAnnotations import de.cau.cs.kieler.scg.processors.analyzer.LoopAnalyzerV2 import de.cau.cs.kieler.scg.processors.analyzer.LoopData import de.cau.cs.kieler.scg.processors.priority.PriorityAuxiliaryData @@ -67,7 +68,6 @@ import static de.cau.cs.kieler.scg.processors.SCGAnnotations.* import static extension de.cau.cs.kieler.klighd.syntheses.DiagramSyntheses.* import static extension org.eclipse.emf.ecore.util.EcoreUtil.* -import de.cau.cs.kieler.scg.processors.SCGAnnotations /** * @author kolja @@ -374,6 +374,7 @@ class SCGraphHierarchySynthesis { kNodeList += annotationNode } ] + val proxy = createNode("hierarchy" + nodeGrouping.toString) // Set options for the container. if (topdown()) @@ -496,6 +497,10 @@ class SCGraphHierarchySynthesis { } } + + // Don't render container + kContainer.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, false) + kContainer } } diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphSynthesisHelper.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphSynthesisHelper.xtend index 75cdc6f054..fe58981514 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphSynthesisHelper.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphSynthesisHelper.xtend @@ -171,6 +171,30 @@ class SCGraphSynthesisHelper { figure.children.filter(KText).head.text = label } + /** + * Assignment proxy figures consist of a "=". + */ + def initialiseAssignmentProxyFigure(KNode node) { + node.initialiseProxyFigure("=") + } + + /** + * Conditional proxy figures consist of a "?". + */ + def initialiseConditionalProxyFigure(KNode node) { + node.initialiseProxyFigure("?") + } + + /** + * Initialises a proxy figure with the given label. + */ + def initialiseProxyFigure(KNode node, String label) { + node.setMinimalNodeSize(MINIMALWIDTH, MINIMALHEIGHT) + val figure = node.data.filter(KContainerRendering).last + if(SHOW_SHADOW.booleanValue) figure.shadow = "black".color + figure.children.filter(KText).head.text = label + } + /** * Draw a dotted line from the corresponding surface node to the given depth node. * diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphsDiagramSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphsDiagramSynthesis.xtend index f3d5912a09..d4bcbb769c 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphsDiagramSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphsDiagramSynthesis.xtend @@ -18,6 +18,7 @@ import de.cau.cs.kieler.klighd.ViewContext import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions import de.cau.cs.kieler.klighd.syntheses.AbstractDiagramSynthesis +import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.scg.SCGraphs import javax.inject.Inject @@ -57,6 +58,9 @@ class SCGraphsDiagramSynthesis extends AbstractDiagramSynthesis { addRectangle => [invisible = true] ] } + + // All nodes should be shown as proxies + node.setProperty(KlighdProperties.PROXY_VIEW_HIERARCHICAL_OFF_SCREEN_DEPTH, -1) // Report duration usedContext?.setProperty(KiCoDiagramViewProperties.SYNTHESIS_TIME, System.currentTimeMillis - timestamp) From 7204d363c21d46385853029ca05c004543a33878 Mon Sep 17 00:00:00 2001 From: Niklas Rentz Date: Fri, 3 Mar 2023 11:19:08 +0100 Subject: [PATCH 32/45] sccharts.ui: removed example code for semantic filtering. --- .../SCChartsSemanticFilterRules.java | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 7fb85d3b93..8ca54e9f4f 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -93,66 +93,4 @@ public static List getAllFilters() { public static final SemanticFilterRule NO_FINAL_STATE = new AndConnective( SCChartsSemanticFilterTags.STATE, new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Filter Final States"); - - /** - * Rule to exclude elements that are either initial XOR final states. - * - * @example - */ - public static final SemanticFilterRule NO_INITIAL_XOR_FINAL_STATE = - new AndConnective(SCChartsSemanticFilterTags.STATE, - new LogicEqualConnective(SCChartsSemanticFilterTags.INITIAL, - SCChartsSemanticFilterTags.FINAL), - "Filter Initial XOR Final States"); - - /** - * Rule to only include elements that are either initial states or regions. - * - * @example - */ - public static final SemanticFilterRule ONLY_INITIAL_STATES_OR_REGIONS = - new IfThenElseConnective(SCChartsSemanticFilterTags.STATE, - SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.REGION, - "Filter Everything but Initial States or Regions"); - - /** Rule to only include elements that have at least 3 declarations. */ - public static final SemanticFilterRule ONLY_AT_LEAST_3_DECLARATIONS = - new GreaterEqualsConnective(SCChartsSemanticFilterTags.DECLARATIONS(null), - new NumericConstantConnective(3.0), - "Filter Elements with less than 3 Declarations"); - - /** - * Rule to only include elements that are initial, final or a region. - * - * @example - */ - public static final SemanticFilterRule ONLY_INITIAL_OR_FINAL_OR_REGION = SemanticFilterRuleUtil - .getBigOrConnective("Filter Everything but Initial, Final or Regions", - SCChartsSemanticFilterTags.INITIAL, SCChartsSemanticFilterTags.FINAL, - SCChartsSemanticFilterTags.REGION); - - /** - * Rule to exclude every element. - * - * @example - */ - public static final SemanticFilterRule NO_EVERYTHING = new FalseConnective("Filter Everything"); - - /** - * Rule to only include every element. - * - * @example - */ - public static final SemanticFilterRule ONLY_EVERYTHING = new TrueConnective("Filter Nothing"); - - /** - * Rule to only include elements with more input/output declarations than the total number of declarations. - * - * @example - */ - public static final SemanticFilterRule ONLY_MORE_IO_THAN_DECLARATIONS = new GreaterThanConnective( - new NumericAdditionConnective(SCChartsSemanticFilterTags.INPUT_DECLARATIONS(null), - SCChartsSemanticFilterTags.OUTPUT_DECLARATIONS(null)), - SCChartsSemanticFilterTags.DECLARATIONS(null), - "Filter Elements with #IO Declarations <= #Declarations"); } From 5fc246c098bb53396c0f8e6200e15ec63557f3f4 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Mon, 6 Mar 2023 11:09:02 +0100 Subject: [PATCH 33/45] extract common values and methods to ProxyStyles class --- .../ControlflowRegionSynthesis.xtend | 19 ++------ .../synthesis/DataflowRegionSynthesis.xtend | 19 ++------ .../ui/synthesis/styles/ProxyStyles.xtend | 47 +++++++++++++++++++ 3 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ProxyStyles.xtend diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 30cffa906a..21bf5728b9 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -37,6 +37,7 @@ import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTa import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.MemorizingExpandCollapseAction import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ControlflowRegionStyles +import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ProxyStyles import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import java.util.EnumSet import org.eclipse.elk.alg.layered.options.CenterEdgeLabelPlacementStrategy @@ -84,7 +85,6 @@ class ControlflowRegionSynthesis extends SubSynthesis SCChartsSemanticFilterTags.CONTROLFLOW_REGION ) val proxy = createNode().associateWith(region) - val maxProxyLabelLength = 5 node.configureNodeLOD(region) @@ -222,8 +222,8 @@ class ControlflowRegionSynthesis extends SubSynthesis val label = region.serializeHighlighted(true) if (label.length > 0) { val name = label.get(0) - if (name.key.length > maxProxyLabelLength) { - label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + if (name.key.length > ProxyStyles.MAX_PROXY_LABEL_LENGTH) { + label.set(0, new Pair(name.key.subSequence(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...", name.value)) } } addProxyRegion(label) @@ -242,18 +242,7 @@ class ControlflowRegionSynthesis extends SubSynthesis ] } - // Set size to be at least minimal node size - val proxyBounds = PlacementUtil.estimateSize(proxy) - val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - // Don't need to resize proxy if the node is already big enough by itself - val minSize = 10 - val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize - - proxy.width = bigEnough ? proxyBounds.width : minProxySize - proxy.height = bigEnough ? proxyBounds.height : minProxySize - - node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) + ProxyStyles.setProxySize(node, proxy) return returnNodes } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 8ad08ad848..27e324d789 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -31,6 +31,7 @@ import de.cau.cs.kieler.sccharts.ui.synthesis.actions.ReferenceExpandAction import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.MemorizingExpandCollapseAction import de.cau.cs.kieler.sccharts.ui.synthesis.styles.DataflowRegionStyles +import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ProxyStyles import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import org.eclipse.elk.alg.layered.options.GreedySwitchType import org.eclipse.elk.alg.layered.options.LayeredOptions @@ -88,7 +89,6 @@ class DataflowRegionSynthesis extends SubSynthesis { SCChartsSemanticFilterTags.DATAFLOW_REGION ) val proxy = createNode().associateWith(region) - val maxProxyLabelLength = 5 node.addLayoutParam(CoreOptions::ALGORITHM, LayeredOptions.ALGORITHM_ID) //node.setLayoutOption(LayeredOptions.CONSIDER_MODEL_ORDER, OrderingStrategy.PREFER_EDGES) @@ -188,8 +188,8 @@ class DataflowRegionSynthesis extends SubSynthesis { if (!CIRCUIT.booleanValue) { if (label.length > 0) { val name = label.get(0) - if (name.key.length > maxProxyLabelLength) { - label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + if (name.key.length > ProxyStyles.MAX_PROXY_LABEL_LENGTH) { + label.set(0, new Pair(name.key.subSequence(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...", name.value)) } } addProxyRegion(label) @@ -217,18 +217,7 @@ class DataflowRegionSynthesis extends SubSynthesis { node.setLayoutOption(CoreOptions::PADDING, new ElkPadding(18d, 7d, 7d, 7d)); } - // Set size to be at least minimal node size - val proxyBounds = PlacementUtil.estimateSize(proxy) - val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - // Don't need to resize proxy if the node is already big enough by itself - val minSize = 10 - val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize - - proxy.width = bigEnough ? proxyBounds.width : minProxySize - proxy.height = bigEnough ? proxyBounds.height : minProxySize - - node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) - node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, node.data) + ProxyStyles.setProxySize(node, proxy) return newArrayList(node) } diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ProxyStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ProxyStyles.xtend new file mode 100644 index 0000000000..006d57fd0d --- /dev/null +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ProxyStyles.xtend @@ -0,0 +1,47 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2023 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.sccharts.ui.synthesis.styles + +import de.cau.cs.kieler.klighd.kgraph.KNode +import de.cau.cs.kieler.klighd.microlayout.PlacementUtil +import de.cau.cs.kieler.klighd.util.KlighdProperties + +/** + * @author mka + * + */ +class ProxyStyles { + + /** The maximum number of characters to be shown in a proxy label. */ + public static final int MAX_PROXY_LABEL_LENGTH = 5 + + /** Minimum size of proxies. */ + public static final int MIN_PROXY_SIZE = 10 + + static def setProxySize(KNode node, KNode proxy) { + // Set size to be at least minimal node size + val proxyBounds = PlacementUtil.estimateSize(proxy) + val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE + // Don't need to resize proxy if the node is already big enough by itself + val isBigEnough = proxyBounds.width > ProxyStyles.MIN_PROXY_SIZE + && proxyBounds.height > ProxyStyles.MIN_PROXY_SIZE + + proxy.width = isBigEnough ? proxyBounds.width : minProxySize + proxy.height = isBigEnough ? proxyBounds.height : minProxySize + + node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) + node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) + + } + +} \ No newline at end of file From cf2419c2e1565c3bd7b3ed588ae696269274a217 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Mon, 6 Mar 2023 11:15:20 +0100 Subject: [PATCH 34/45] use proxystyles defined values --- .../kieler/sccharts/ui/synthesis/StateSynthesis.xtend | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 677f15a1a0..87007da805 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -70,6 +70,7 @@ import de.cau.cs.kieler.sccharts.processors.dataflow.RegionLCAFMap import de.cau.cs.kieler.sccharts.processors.dataflow.StateDependencies import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.ToggleDependencyAction +import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ProxyStyles import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import de.cau.cs.kieler.scl.MethodImplementationDeclaration import java.util.ArrayList @@ -145,7 +146,6 @@ class StateSynthesis extends SubSynthesis { val node = state.createNode().associateWith(state) node.getProperty(KlighdProperties.SEMANTIC_FILTER_TAGS).add(SCChartsSemanticFilterTags.STATE) val proxy = createNode().associateWith(state) - val maxProxyLabelLength = 5 // Set KIdentifier for use with incremental update if (!state.name.nullOrEmpty) { @@ -268,16 +268,16 @@ class StateSynthesis extends SubSynthesis { node.addMacroStateLabel(label) if (label.length > 0) { val name = label.get(0) - if (name.key.length > maxProxyLabelLength) { - label.set(0, new Pair(name.key.subSequence(0, maxProxyLabelLength) + "...", name.value)) + if (name.key.length > ProxyStyles.MAX_PROXY_LABEL_LENGTH) { + label.set(0, new Pair(name.key.subSequence(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...", name.value)) } } proxy.addMacroStateLabel(label) } else { val label = state.serializeHR.toString node.addSimpleStateLabel(label) - if (label.length > maxProxyLabelLength) { - proxy.addSimpleStateLabel(label.substring(0, maxProxyLabelLength) + "...") + if (label.length > ProxyStyles.MAX_PROXY_LABEL_LENGTH) { + proxy.addSimpleStateLabel(label.substring(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...") } else { proxy.addSimpleStateLabel(label) } From 7f74b0e162ea7e0b16c2f0bb2a28e5d3e984b4f7 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Mon, 6 Mar 2023 12:33:51 +0100 Subject: [PATCH 35/45] refactoring --- .../sccharts/ui/synthesis/StateSynthesis.xtend | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index 87007da805..a880ee8b65 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -404,12 +404,8 @@ class StateSynthesis extends SubSynthesis { if (SHOW_INHERITANCE.booleanValue) regions.addAll(0, state.allVisibleInheritedRegions.toList) for (region : regions) { switch region { - ControlflowRegion: { - node.children += region.transform - } - DataflowRegion: { - node.children += region.transform - } + ControlflowRegion: node.children += region.transform + DataflowRegion: node.children += region.transform } } @@ -449,8 +445,8 @@ class StateSynthesis extends SubSynthesis { val proxyBounds = PlacementUtil.estimateSize(proxy) val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE // Don't need to resize proxy if the node is already big enough by itself - val minSize = 10 - val bigEnough = proxyBounds.width > minSize && proxyBounds.height > minSize + val bigEnough = proxyBounds.width > ProxyStyles.MIN_PROXY_SIZE + && proxyBounds.height > ProxyStyles.MIN_PROXY_SIZE proxy.width = bigEnough ? proxyBounds.width : minProxySize proxy.height = bigEnough ? proxyBounds.height : minProxySize From 24b0934ab70b01b6cd62fbb30d7bfa0878097509 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Mon, 6 Mar 2023 12:38:58 +0100 Subject: [PATCH 36/45] refactoring --- .../cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend | 2 +- .../de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend index c22e654a12..2977d438f8 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/StateStyles.xtend @@ -93,7 +93,7 @@ class StateStyles { /** The default figure's corner radius. */ public static final int DEFAULT_FIGURE_CORNER_RADIUS = 17; /** The default figure's minimal node size. */ - public static final int DEFAULT_FIGURE_MIN_NODE_SIZE = 34; // 2 x corner radius + public static final int DEFAULT_FIGURE_MIN_NODE_SIZE = 2 * DEFAULT_FIGURE_CORNER_RADIUS; /** The connector figure's size. */ public static final int CONNECTOR_FIGURE_SIZE = 7; diff --git a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend index b86fb70994..610c96097f 100644 --- a/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.scg.klighd/src/de/cau/cs/kieler/scg/klighd/SCGraphDiagramSynthesis.xtend @@ -289,7 +289,7 @@ class SCGraphDiagramSynthesis extends AbstractDiagramSynthesis { */ private def KNode synthesize(SCGraph scg) { val node = scg.createNode().associateWith(scg) - + // Set root node and layout options. rootNode = node isSCPDG = scg.hasAnnotation(ANNOTATION_SCPDGTRANSFORMATION) @@ -476,7 +476,6 @@ class SCGraphDiagramSynthesis extends AbstractDiagramSynthesis { scg.synthesizeScheduleGroups scg.applyDependencyHierarchy - return node } From 941c4a43812f7fd68ced3b70167cbbdd3653fe22 Mon Sep 17 00:00:00 2001 From: Niklas Rentz Date: Tue, 7 Mar 2023 13:28:18 +0100 Subject: [PATCH 37/45] sccharts.ui: removed some code duplication/unneeded code. --- .../ControlflowRegionSynthesis.xtend | 12 +-- .../synthesis/DataflowRegionSynthesis.xtend | 2 +- .../SCChartsSemanticFilterRules.java | 13 --- .../styles/ControlflowRegionStyles.xtend | 99 +++++++------------ 4 files changed, 39 insertions(+), 87 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend index 21bf5728b9..3cb7a0ae80 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/ControlflowRegionSynthesis.xtend @@ -25,7 +25,6 @@ import de.cau.cs.kieler.klighd.krendering.KText import de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared import de.cau.cs.kieler.klighd.krendering.extensions.KNodeExtensions import de.cau.cs.kieler.klighd.krendering.extensions.KRenderingExtensions -import de.cau.cs.kieler.klighd.microlayout.PlacementUtil import de.cau.cs.kieler.klighd.util.KlighdProperties import de.cau.cs.kieler.sccharts.ControlflowRegion import de.cau.cs.kieler.sccharts.Region @@ -38,7 +37,6 @@ import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.actions.MemorizingExpandColl import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ColorStore import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ControlflowRegionStyles import de.cau.cs.kieler.sccharts.ui.synthesis.styles.ProxyStyles -import de.cau.cs.kieler.sccharts.ui.synthesis.styles.StateStyles import java.util.EnumSet import org.eclipse.elk.alg.layered.options.CenterEdgeLabelPlacementStrategy import org.eclipse.elk.alg.layered.options.FixedAlignment @@ -114,14 +112,6 @@ class ControlflowRegionSynthesis extends SubSynthesis // This node does not support comment boxes on the same layer, because regions are layouted by the box layouter. node.setProperty(MessageObjectReferencesManager.SUPPORTS_COMMENT_BOXES, false) - - val addCorrespondingRegionFigure = [ KNode x | - x.addRegionFigure => [ - if (region.override) addOverrideRegionStyle - if (region.abort) addAbortRegionStyle - if (region.final) addFinalRegionStyle - ] - ] if (!region.states.empty) { val label = region.serializeHighlighted(true) @@ -226,7 +216,7 @@ class ControlflowRegionSynthesis extends SubSynthesis label.set(0, new Pair(name.key.subSequence(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...", name.value)) } } - addProxyRegion(label) + addRegionLabel(label) ] val returnNodes = newArrayList(node) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend index 27e324d789..bd4528692c 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/DataflowRegionSynthesis.xtend @@ -192,7 +192,7 @@ class DataflowRegionSynthesis extends SubSynthesis { label.set(0, new Pair(name.key.subSequence(0, ProxyStyles.MAX_PROXY_LABEL_LENGTH) + "...", name.value)) } } - addProxyRegion(label) + addRegionLabel(label) } ] diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 8ca54e9f4f..a24dc53451 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -17,21 +17,8 @@ import java.util.List; import de.cau.cs.kieler.klighd.filtering.AndConnective; -import de.cau.cs.kieler.klighd.filtering.FalseConnective; -import de.cau.cs.kieler.klighd.filtering.GreaterEqualsConnective; -import de.cau.cs.kieler.klighd.filtering.GreaterThanConnective; -import de.cau.cs.kieler.klighd.filtering.IfThenElseConnective; -import de.cau.cs.kieler.klighd.filtering.LessThanConnective; -import de.cau.cs.kieler.klighd.filtering.LogicEqualConnective; import de.cau.cs.kieler.klighd.filtering.NegationConnective; -import de.cau.cs.kieler.klighd.filtering.NumericAdditionConnective; -import de.cau.cs.kieler.klighd.filtering.NumericConstantConnective; -import de.cau.cs.kieler.klighd.filtering.NumericEqualConnective; -import de.cau.cs.kieler.klighd.filtering.NumericSubtractionConnective; -import de.cau.cs.kieler.klighd.filtering.OrConnective; import de.cau.cs.kieler.klighd.filtering.SemanticFilterRule; -import de.cau.cs.kieler.klighd.filtering.SemanticFilterRuleUtil; -import de.cau.cs.kieler.klighd.filtering.TrueConnective; /** * Contains semantic filter rules for SCCharts. diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend index 9ccf5d9089..5e68ab9050 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/styles/ControlflowRegionStyles.xtend @@ -18,6 +18,7 @@ import de.cau.cs.kieler.klighd.kgraph.KNode import de.cau.cs.kieler.klighd.krendering.KContainerRendering import de.cau.cs.kieler.klighd.krendering.KForeground import de.cau.cs.kieler.klighd.krendering.KGridPlacement +import de.cau.cs.kieler.klighd.krendering.KPolygon import de.cau.cs.kieler.klighd.krendering.KRectangle import de.cau.cs.kieler.klighd.krendering.KRendering import de.cau.cs.kieler.klighd.krendering.KText @@ -131,73 +132,39 @@ class ControlflowRegionStyles { } /** - * Adds a button with text. + * Adds a button with text and a label. */ private def KRendering addRegionButton(KContainerRendering container, String text, List> label) { - val button = container.addPolygon => [ - lineWidth = 0 - background = container.foreground.color.copy - selectionBackground = SELECTION.color - addKPosition(LEFT, 0.5f, 0, TOP, 0.5f, 0) - addKPosition(LEFT, 0.5f, 0, TOP, 19, 0) - addKPosition(LEFT, 18, 0, TOP, 0.5f, 0) - ] - button.addText(text) => [ - suppressSelectability - foreground = REGION_BUTTON_FOREGROUND.color - selectionForeground = REGION_BUTTON_FOREGROUND.color - fontSize = 8; - fontBold = true - val size = estimateTextSize; - setPointPlacementData(LEFT, if (text.equals("-")) 3f else 2f, 0, TOP, 0, 0, H_LEFT, V_TOP, 0, 0, size.width, size.height); - ] - if (!label.nullOrEmpty) { - if (label.size == 1 && label.head.value == TextFormat.TEXT) { - container.addText(label.head.key.toString) => [ - suppressSelectability - foreground = REGION_LABEL.color; - fontSize = 10; - selectionTextUnderline = Underline.NONE // prevents default selection style - val size = estimateTextSize; - setPointPlacementData(LEFT, 14, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, size.width + 5, size.height) - setProperty(KlighdProperties.IS_NODE_TITLE, true) - ] - } else { - container.addKeywordLabel(label, 0) => [ - foreground = REGION_LABEL.color - fontSize = 10 - setPointPlacementData(LEFT, 14, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, 0, 0) - setProperty(KlighdProperties.IS_NODE_TITLE, true) - (children.last as KContainerRendering) => [ // Just for spacing at the end - val grid = it?.getChildPlacement() - if (grid instanceof KGridPlacement) { - grid.numColumns = grid.numColumns + 1 - addRectangle => [ - setGridPlacementData(5,5) - invisible = true - ] - } - ] - eAllContents.filter(KText).forEach[ - suppressSelectability - selectionTextUnderline = Underline.NONE // prevents default selection style - if (!styles.exists[it instanceof KForeground]) { - foreground = REGION_LABEL.color - } - ] - ] - } - } - return button + return addRegionButton(container, text, label, false) } /** - * Adds a region figure similar to {@link addExpandButton()} and {@link addCollapseButton()} but without - * the button symbol and therefore without the text offset - since proxies for regions shouldn't be expandable - * or collapsable. + * Adds a button with text and a label. + * For a proxy, only adds the label and no button. */ - def KRendering addProxyRegion(KContainerRendering container, List> label) { + private def KRendering addRegionButton(KContainerRendering container, String text, List> label, boolean proxy) { + var KPolygon button = null + if (!proxy) { + button = container.addPolygon => [ + lineWidth = 0 + background = container.foreground.color.copy + selectionBackground = SELECTION.color + addKPosition(LEFT, 0.5f, 0, TOP, 0.5f, 0) + addKPosition(LEFT, 0.5f, 0, TOP, 19, 0) + addKPosition(LEFT, 18, 0, TOP, 0.5f, 0) + ] + button.addText(text) => [ + suppressSelectability + foreground = REGION_BUTTON_FOREGROUND.color + selectionForeground = REGION_BUTTON_FOREGROUND.color + fontSize = 8; + fontBold = true + val size = estimateTextSize; + setPointPlacementData(LEFT, if (text.equals("-")) 3f else 2f, 0, TOP, 0, 0, H_LEFT, V_TOP, 0, 0, size.width, size.height); + ] + } if (!label.nullOrEmpty) { + val absLeftOffset = if(proxy) 1 else 14; if (label.size == 1 && label.head.value == TextFormat.TEXT) { container.addText(label.head.key.toString) => [ suppressSelectability @@ -205,14 +172,14 @@ class ControlflowRegionStyles { fontSize = 10; selectionTextUnderline = Underline.NONE // prevents default selection style val size = estimateTextSize; - setPointPlacementData(LEFT, 1, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, size.width + 5, size.height) + setPointPlacementData(LEFT, absLeftOffset, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, size.width + 5, size.height) setProperty(KlighdProperties.IS_NODE_TITLE, true) ] } else { container.addKeywordLabel(label, 0) => [ foreground = REGION_LABEL.color fontSize = 10 - setPointPlacementData(LEFT, 1, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, 0, 0) + setPointPlacementData(LEFT, absLeftOffset, 0, TOP, 1, 0, H_LEFT, V_TOP, 0, 0, 0, 0) setProperty(KlighdProperties.IS_NODE_TITLE, true) (children.last as KContainerRendering) => [ // Just for spacing at the end val grid = it?.getChildPlacement() @@ -234,6 +201,7 @@ class ControlflowRegionStyles { ] } } + return button } /** @@ -271,6 +239,13 @@ class ControlflowRegionStyles { def KRendering addCollapseButton(KContainerRendering container, String label) { return container.addRegionButton("-", newArrayList(new Pair(label, TextFormat.TEXT))) } + + /** + * Adds a region with a label and no button. + */ + def KRendering addRegionLabel(KContainerRendering container, List> label) { + return container.addRegionButton(null, label, true) + } /** * Adds an area for inner states.
From 7b89469621d4f7016d474c1e797fab95f9115de8 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Wed, 15 Mar 2023 16:03:42 +0100 Subject: [PATCH 38/45] rename filters --- .../filtering/SCChartsSemanticFilterRules.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index a24dc53451..185713e2fd 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -51,33 +51,33 @@ public static List getAllFilters() { /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = - new NegationConnective(SCChartsSemanticFilterTags.STATE, "Filter States"); + new NegationConnective(SCChartsSemanticFilterTags.STATE, "States"); /** Rule to exclude elements that are regions. */ public static final SemanticFilterRule NO_REGIONS = - new NegationConnective(SCChartsSemanticFilterTags.REGION, "Filter Regions"); + new NegationConnective(SCChartsSemanticFilterTags.REGION, "Regions"); /** Rule to exclude elements that are simple states. */ public static final SemanticFilterRule NO_SIMPLE_STATE = - new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Filter Simple States"); + new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Simple States"); /** Rule to exclude elements that are hierarchical states. */ public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Filter Hierarchical States"); + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Hierarchical States"); /** Rule to exclude elements that are connector states. */ public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( - SCChartsSemanticFilterTags.CONNECTOR_STATE, "Filter Connector States"); + SCChartsSemanticFilterTags.CONNECTOR_STATE, "Connector States"); /** Rule to exclude elements that are controlflow regions. */ public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Filter Controlflow Regions"); + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Controlflow Regions"); /** Rule to exclude elements that are dataflow regions. */ public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.DATAFLOW_REGION, "Filter Dataflow Regions"); + SCChartsSemanticFilterTags.DATAFLOW_REGION, "Dataflow Regions"); /** Rule to exclude elements that are initial states. */ public static final SemanticFilterRule NO_INITIAL_STATE = new AndConnective( SCChartsSemanticFilterTags.STATE, - new NegationConnective(SCChartsSemanticFilterTags.INITIAL), "Filter Initial States"); + new NegationConnective(SCChartsSemanticFilterTags.INITIAL), "Initial States"); /** Rule to exclude elements that are final states. */ public static final SemanticFilterRule NO_FINAL_STATE = new AndConnective( SCChartsSemanticFilterTags.STATE, - new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Filter Final States"); + new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Final States"); } From 378e35fcecf33ee02300784c61b6e17ffb80f164 Mon Sep 17 00:00:00 2001 From: Niklas Rentz Date: Tue, 25 Apr 2023 17:32:03 +0200 Subject: [PATCH 39/45] sccharts.ui: removed layout calculation of proxies in the synthesis. This is now done by KLighD directly. --- .../sccharts/ui/synthesis/StateSynthesis.xtend | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend index a880ee8b65..c8af981f92 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/StateSynthesis.xtend @@ -440,22 +440,6 @@ class StateSynthesis extends SubSynthesis { ] } - if (!isConnector) { - // Set size to be at least minimal node size - val proxyBounds = PlacementUtil.estimateSize(proxy) - val minProxySize = StateStyles.DEFAULT_FIGURE_MIN_NODE_SIZE - // Don't need to resize proxy if the node is already big enough by itself - val bigEnough = proxyBounds.width > ProxyStyles.MIN_PROXY_SIZE - && proxyBounds.height > ProxyStyles.MIN_PROXY_SIZE - - proxy.width = bigEnough ? proxyBounds.width : minProxySize - proxy.height = bigEnough ? proxyBounds.height : minProxySize - } else { - val connectorSize = StateStyles.CONNECTOR_FIGURE_SIZE - proxy.width = connectorSize - proxy.height = connectorSize - } - node.setProperty(KlighdProperties.PROXY_VIEW_RENDER_NODE_AS_PROXY, true) node.setProperty(KlighdProperties.PROXY_VIEW_PROXY_RENDERING, proxy.data) From b350366ff5d3c123808035d212f9ff0540d7f6a2 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Tue, 12 Sep 2023 13:28:41 +0200 Subject: [PATCH 40/45] changed the semantic filter rules to be consistent with their description --- .../filtering/SCChartsSemanticFilterRules.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 185713e2fd..1b5733c339 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -73,11 +73,9 @@ public static List getAllFilters() { SCChartsSemanticFilterTags.DATAFLOW_REGION, "Dataflow Regions"); /** Rule to exclude elements that are initial states. */ - public static final SemanticFilterRule NO_INITIAL_STATE = new AndConnective( - SCChartsSemanticFilterTags.STATE, - new NegationConnective(SCChartsSemanticFilterTags.INITIAL), "Initial States"); + public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.INITIAL, "Initial States"); /** Rule to exclude elements that are final states. */ - public static final SemanticFilterRule NO_FINAL_STATE = new AndConnective( - SCChartsSemanticFilterTags.STATE, - new NegationConnective(SCChartsSemanticFilterTags.FINAL), "Final States"); + public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.FINAL, "Final States"); } From 635ca6ad184584638dec40588fdf0851f5018321 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Tue, 12 Sep 2023 13:49:15 +0200 Subject: [PATCH 41/45] clearer labels for semantic filter rules --- .../SCChartsSemanticFilterRules.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 1b5733c339..5c815e02d7 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -48,34 +48,36 @@ public static List getAllFilters() { // The class variables' names should start with NO_ or ONLY_, // indicating which elements are kept out or left in // The descriptions should utilize the checkbox as the verb + // If turning on the checkbox results in hiding something use the explicit word "Hide" otherwise the function + // of the checkbox is confusing /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = - new NegationConnective(SCChartsSemanticFilterTags.STATE, "States"); + new NegationConnective(SCChartsSemanticFilterTags.STATE, "Hide States"); /** Rule to exclude elements that are regions. */ public static final SemanticFilterRule NO_REGIONS = - new NegationConnective(SCChartsSemanticFilterTags.REGION, "Regions"); + new NegationConnective(SCChartsSemanticFilterTags.REGION, "Hide Regions"); /** Rule to exclude elements that are simple states. */ public static final SemanticFilterRule NO_SIMPLE_STATE = - new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Simple States"); + new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Hide Simple States"); /** Rule to exclude elements that are hierarchical states. */ public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Hierarchical States"); + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Hide Hierarchical States"); /** Rule to exclude elements that are connector states. */ public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( - SCChartsSemanticFilterTags.CONNECTOR_STATE, "Connector States"); + SCChartsSemanticFilterTags.CONNECTOR_STATE, "Hide Connector States"); /** Rule to exclude elements that are controlflow regions. */ public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Controlflow Regions"); + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Hide Controlflow Regions"); /** Rule to exclude elements that are dataflow regions. */ public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.DATAFLOW_REGION, "Dataflow Regions"); + SCChartsSemanticFilterTags.DATAFLOW_REGION, "Hide Dataflow Regions"); /** Rule to exclude elements that are initial states. */ public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.INITIAL, "Initial States"); + SCChartsSemanticFilterTags.INITIAL, "Hide Initial States"); /** Rule to exclude elements that are final states. */ public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.FINAL, "Final States"); + SCChartsSemanticFilterTags.FINAL, "Hide Final States"); } From 76dc47b0e6028da61e3934ed87e29c712ed98671 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Tue, 12 Sep 2023 14:19:26 +0200 Subject: [PATCH 42/45] set sensible default values for semantic filters --- .../filtering/SCChartsSemanticFilterRules.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 5c815e02d7..4083f31b61 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -53,31 +53,31 @@ public static List getAllFilters() { /** Rule to exclude elements that are states. */ public static final SemanticFilterRule NO_STATES = - new NegationConnective(SCChartsSemanticFilterTags.STATE, "Hide States"); + new NegationConnective(SCChartsSemanticFilterTags.STATE, false, "Hide States"); /** Rule to exclude elements that are regions. */ public static final SemanticFilterRule NO_REGIONS = - new NegationConnective(SCChartsSemanticFilterTags.REGION, "Hide Regions"); + new NegationConnective(SCChartsSemanticFilterTags.REGION, false, "Hide Regions"); /** Rule to exclude elements that are simple states. */ public static final SemanticFilterRule NO_SIMPLE_STATE = - new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, "Hide Simple States"); + new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, false, "Hide Simple States"); /** Rule to exclude elements that are hierarchical states. */ public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.HIERARCHICAL_STATE, "Hide Hierarchical States"); + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, false, "Hide Hierarchical States"); /** Rule to exclude elements that are connector states. */ public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( - SCChartsSemanticFilterTags.CONNECTOR_STATE, "Hide Connector States"); + SCChartsSemanticFilterTags.CONNECTOR_STATE, true, "Hide Connector States"); /** Rule to exclude elements that are controlflow regions. */ public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.CONTROLFLOW_REGION, "Hide Controlflow Regions"); + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, false, "Hide Controlflow Regions"); /** Rule to exclude elements that are dataflow regions. */ public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.DATAFLOW_REGION, "Hide Dataflow Regions"); + SCChartsSemanticFilterTags.DATAFLOW_REGION, false, "Hide Dataflow Regions"); /** Rule to exclude elements that are initial states. */ public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.INITIAL, "Hide Initial States"); + SCChartsSemanticFilterTags.INITIAL, false, "Hide Initial States"); /** Rule to exclude elements that are final states. */ public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.FINAL, "Hide Final States"); + SCChartsSemanticFilterTags.FINAL, false, "Hide Final States"); } From fd5104bbe19b2c20011aa87677639e3e2e088101 Mon Sep 17 00:00:00 2001 From: Max Kasperowski Date: Wed, 13 Sep 2023 14:00:50 +0200 Subject: [PATCH 43/45] Change semantic filter rules to align with client-side interpretation --- .../SCChartsSemanticFilterRules.java | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java index 4083f31b61..5aaae96587 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterRules.java @@ -44,40 +44,37 @@ public static List getAllFilters() { return filters; } - // Naming conventions: - // The class variables' names should start with NO_ or ONLY_, - // indicating which elements are kept out or left in // The descriptions should utilize the checkbox as the verb - // If turning on the checkbox results in hiding something use the explicit word "Hide" otherwise the function - // of the checkbox is confusing + // The filters exclude element types, but on the UI of the client the checkbox will be inverted i.e. indicating + // that the user excludes these elements by unchecking the box /** Rule to exclude elements that are states. */ - public static final SemanticFilterRule NO_STATES = - new NegationConnective(SCChartsSemanticFilterTags.STATE, false, "Hide States"); + public static final SemanticFilterRule SHOW_STATES = + new NegationConnective(SCChartsSemanticFilterTags.STATE, true, "All States"); /** Rule to exclude elements that are regions. */ - public static final SemanticFilterRule NO_REGIONS = - new NegationConnective(SCChartsSemanticFilterTags.REGION, false, "Hide Regions"); + public static final SemanticFilterRule SHOW_REGIONS = + new NegationConnective(SCChartsSemanticFilterTags.REGION, true, "All Regions"); /** Rule to exclude elements that are simple states. */ - public static final SemanticFilterRule NO_SIMPLE_STATE = - new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, false, "Hide Simple States"); + public static final SemanticFilterRule SHOW_SIMPLE_STATE = + new NegationConnective(SCChartsSemanticFilterTags.SIMPLE_STATE, true, "Simple States"); /** Rule to exclude elements that are hierarchical states. */ - public static final SemanticFilterRule NO_HIERARCHICAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.HIERARCHICAL_STATE, false, "Hide Hierarchical States"); + public static final SemanticFilterRule SHOW_HIERARCHICAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.HIERARCHICAL_STATE, true, "Hierarchical States"); /** Rule to exclude elements that are connector states. */ - public static final SemanticFilterRule NO_CONNECTOR_STATE = new NegationConnective( - SCChartsSemanticFilterTags.CONNECTOR_STATE, true, "Hide Connector States"); + public static final SemanticFilterRule SHOW_CONNECTOR_STATE = new NegationConnective( + SCChartsSemanticFilterTags.CONNECTOR_STATE, false, "Connector States"); /** Rule to exclude elements that are controlflow regions. */ - public static final SemanticFilterRule NO_CONTROLFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.CONTROLFLOW_REGION, false, "Hide Controlflow Regions"); + public static final SemanticFilterRule SHOW_CONTROLFLOW_REGION = new NegationConnective( + SCChartsSemanticFilterTags.CONTROLFLOW_REGION, true, "Controlflow Regions"); /** Rule to exclude elements that are dataflow regions. */ - public static final SemanticFilterRule NO_DATAFLOW_REGION = new NegationConnective( - SCChartsSemanticFilterTags.DATAFLOW_REGION, false, "Hide Dataflow Regions"); + public static final SemanticFilterRule SHOW_DATAFLOW_REGION = new NegationConnective( + SCChartsSemanticFilterTags.DATAFLOW_REGION, true, "Dataflow Regions"); /** Rule to exclude elements that are initial states. */ - public static final SemanticFilterRule NO_INITIAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.INITIAL, false, "Hide Initial States"); + public static final SemanticFilterRule SHOW_INITIAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.INITIAL, true, "Initial States"); /** Rule to exclude elements that are final states. */ - public static final SemanticFilterRule NO_FINAL_STATE = new NegationConnective( - SCChartsSemanticFilterTags.FINAL, false, "Hide Final States"); + public static final SemanticFilterRule SHOW_FINAL_STATE = new NegationConnective( + SCChartsSemanticFilterTags.FINAL, true, "Final States"); } From 110e5e3bf45d7f0b87d4d18515b5f3b234f7fa78 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Thu, 7 Mar 2024 18:24:41 +0100 Subject: [PATCH 44/45] Fixed SCTX Serializer. --- ...cs.kieler.klighd.lsp.interactive.IConstraintSerializer | 2 +- .../server/sccharts/SCTXConstraintSerializer.xtend | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer index e534ff9f48..c20236902b 100644 --- a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer +++ b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.interactive.IConstraintSerializer @@ -1 +1 @@ -de.cau.cs.kieler.sccharts.ide.language.server.SCTXConstraintSerializer \ No newline at end of file +de.cau.cs.kieler.language.server.sccharts.SCTXConstraintSerializer \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/SCTXConstraintSerializer.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/SCTXConstraintSerializer.xtend index 85f594897e..d7f3c717e9 100644 --- a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/SCTXConstraintSerializer.xtend +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/SCTXConstraintSerializer.xtend @@ -44,10 +44,6 @@ class SCTXConstraintSerializer implements IConstraintSerializer { override serializeConstraints(List> changedNodes, Object graph, String uri, KGraphLanguageServerExtension ls, KGraphLanguageClient client) { - changedNodes.forEach[c| - val Annotatable anno = c.KNode.getProperty(KlighdInternalProperties.MODEL_ELEMEMT) as Annotatable - copyConstraintAnnotations(anno, c.KNode, c.property.id, c.property) - ] // Serialize model into given uri. val resource = ls.getResource(uri) @@ -56,6 +52,10 @@ class SCTXConstraintSerializer implements IConstraintSerializer { resource.save(outputStream, emptyMap) val codeBefore = outputStream.toString val Map> changes = newHashMap + changedNodes.forEach[c| + val Annotatable anno = c.KNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Annotatable + copyConstraintAnnotations(anno, c.KNode, c.property.id, c.property) + ] // Get changed file as String outputStream = new ByteArrayOutputStream resource.save(outputStream, emptyMap) From b34cebb441a697082e8822efd038a0524dba1436 Mon Sep 17 00:00:00 2001 From: Soeren Domroes Date: Tue, 12 Mar 2024 16:03:55 +0100 Subject: [PATCH 45/45] Added structure based editing for SCCharts (not tested). --- ...de.cau.cs.kieler.klighd.lsp.IActionHandler | 1 + ...anguage.server.ILanguageServerContribution | 3 +- ....sccharts.ui.synthesis.hooks.SynthesisHook | 1 + .../structurebasedediting/EdgeActions.xtend | 292 ++++++ .../GeneralActions.xtend | 59 ++ .../structurebasedediting/RegionActions.xtend | 101 ++ ...sedEditingLanguageServerContribution.xtend | 27 + ...tsStructureBasedEditingActionHandler.xtend | 122 +++ ...eBasedEditingLanguageServerExtension.xtend | 892 ++++++++++++++++++ .../structurebasedediting/StateActions.xtend | 299 ++++++ .../StructureBasedEditingHook.xtend | 82 ++ .../filtering/SCChartsSemanticFilterTags.java | 11 + 12 files changed, 1889 insertions(+), 1 deletion(-) create mode 100644 language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.IActionHandler create mode 100644 language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/EdgeActions.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/GeneralActions.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/RegionActions.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructeBasedEditingLanguageServerContribution.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingActionHandler.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingLanguageServerExtension.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StateActions.xtend create mode 100644 language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StructureBasedEditingHook.xtend diff --git a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.IActionHandler b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.IActionHandler new file mode 100644 index 0000000000..ed4b1b8b26 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.klighd.lsp.IActionHandler @@ -0,0 +1 @@ +de.cau.cs.kieler.language.server.sccharts.structurebasedediting.SCChartsStructureBasedEditingActionHandler \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.language.server.ILanguageServerContribution b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.language.server.ILanguageServerContribution index 4dcb5ba1fb..a142937f1d 100644 --- a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.language.server.ILanguageServerContribution +++ b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.language.server.ILanguageServerContribution @@ -1,4 +1,5 @@ de.cau.cs.kieler.language.server.registration.RegistrationLanguageServerContribution de.cau.cs.kieler.language.server.kicool.KiCoolLanguageServerContribution de.cau.cs.kieler.language.server.simulation.SimulationLanguageServerContribution -de.cau.cs.kieler.language.server.verification.VerificationLanguageServerContribution \ No newline at end of file +de.cau.cs.kieler.language.server.verification.VerificationLanguageServerContribution +de.cau.cs.kieler.language.server.sccharts.structurebasedediting.SCChartsStructeBasedEditingLanguageServerContribution \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook new file mode 100644 index 0000000000..4dd1df1999 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/META-INF/services/de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook @@ -0,0 +1 @@ +de.cau.cs.kieler.sccharts.ui.synthesis.hooks.StructuralEditingHook \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/EdgeActions.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/EdgeActions.xtend new file mode 100644 index 0000000000..8ba4f6eae9 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/EdgeActions.xtend @@ -0,0 +1,292 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import de.cau.cs.kieler.klighd.structurebasedediting.InputType +import de.cau.cs.kieler.klighd.structurebasedediting.StructureBasedEditingMessage +import java.util.function.Consumer +import org.eclipse.sprotty.Action +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.EqualsHashCode +import org.eclipse.xtend.lib.annotations.ToString + +/** + * Action received from client when a change of target is requested. + * The transmitted information is the new target state id and the id of the edge. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeTargetStateAction implements Action { + public static val LABEL = "Change target state" + public static val KIND = 'SCChart_graph_changeTargetState' + String kind = KIND + + public String id + public String new_target + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("new_target", "SelectTarget", "New target state"); + return #[input1]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeTargetStateAction.LABEL, + ChangeTargetStateAction.KIND, + false, + ChangeTargetStateAction.getInputs() + ) + } +} + +/** + * Action received from client when a change of source is requested. + * The transmitted information is the new source state id and the id of the edge. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeSourceStateAction implements Action { + public static val LABEL = "Change source state" + public static val KIND = 'SCChart_graph_changeSourceState' + String kind = KIND + + public String id + public String new_source + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("new_source", "SelectSource", "New source state"); + return #[input1]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeSourceStateAction.LABEL, + ChangeSourceStateAction.KIND, + false, + ChangeSourceStateAction.getInputs() + ) + } +} + +/** + * Action received from client if a change of trigger or effect is requested. + * The given information is the id of the edge and the new trigger and effects as string representations. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeTriggerEffectAction implements Action { + public static val LABEL = "Change trigger and effect" + public static val KIND = 'SCChart_graph_changeTriggerAndEffect' + String kind = KIND + + public String id + public String trigger + public String effect + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("trigger", "String", "New trigger"); + val input2 = new InputType("effect", "String", "New effect"); + return #[input1, input2]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeTriggerEffectAction.LABEL, + ChangeTriggerEffectAction.KIND, + false, + ChangeTriggerEffectAction.getInputs() + ) + } +} + +/** + * Action received from the client if a edge priority should change. + * The given information is the new priority and the edge id. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangePriorityAction implements Action { + public static val LABEL = "Change priority" + public static val KIND = 'SCChart_graph_changePriorityOfEdge' + String kind = KIND + + public String id + public String priority + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("priority", "String", "Change Priority"); + return #[input1]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangePriorityAction.LABEL, + ChangePriorityAction.KIND, + false, + ChangePriorityAction.getInputs() + ) + } +} + +/** + * Action received from the client if a transition should be weak + * The given information is the id of the edge + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeToWeakTransitionAction implements Action { + public static val LABEL = "Change to weak transition" + public static val KIND = 'SCChart_graph_changeToWeakTransition' + String kind = KIND + + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeToWeakTransitionAction.LABEL, + ChangeToWeakTransitionAction.KIND, + false, + ChangeToWeakTransitionAction.getInputs() + ) + } +} + +/** + * Action received from the client if a transition should be aborting + * The given information is the id of the edge + * + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeToAbortingTransitionAction implements Action { + public static val LABEL = "Change to aborting transition" + public static val KIND = 'SCChart_graph_changeToAbortTransition' + String kind = KIND + + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeToAbortingTransitionAction.LABEL, + ChangeToAbortingTransitionAction.KIND, + false, + ChangeToAbortingTransitionAction.getInputs() + ) + } +} + +/** + * Action received from the client if a transition should be terminating + * The given information is the id of the edge + * + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ChangeToTerminatingTransitionAction implements Action { + public static val LABEL = "Change to terminating transition" + public static val KIND = 'SCChart_graph_changeToTerminatingTransition' + String kind = KIND + + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ChangeToTerminatingTransitionAction.LABEL, + ChangeToTerminatingTransitionAction.KIND, + false, + ChangeToTerminatingTransitionAction.getInputs() + ) + } +} diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/GeneralActions.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/GeneralActions.xtend new file mode 100644 index 0000000000..478e436dd4 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/GeneralActions.xtend @@ -0,0 +1,59 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import de.cau.cs.kieler.klighd.structurebasedediting.InputType +import de.cau.cs.kieler.klighd.structurebasedediting.StructureBasedEditingMessage +import java.util.function.Consumer +import org.eclipse.sprotty.Action +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.EqualsHashCode +import org.eclipse.xtend.lib.annotations.ToString + +/** + * The delete action is supported by all selectable elements. + * The given information are one or many nodes ids seperated by : + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class DeleteAction implements Action { + public static val LABEL = "Delete" + public static val KIND = 'SCChart_graph_Delete' + String kind = KIND + + public String id + public Boolean mergable = true + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + DeleteAction.LABEL, + DeleteAction.KIND, + true, + DeleteAction.getInputs() + ) + } +} diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/RegionActions.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/RegionActions.xtend new file mode 100644 index 0000000000..4920775db9 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/RegionActions.xtend @@ -0,0 +1,101 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import de.cau.cs.kieler.klighd.structurebasedediting.InputType +import de.cau.cs.kieler.klighd.structurebasedediting.StructureBasedEditingMessage +import java.util.function.Consumer +import org.eclipse.sprotty.Action +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.EqualsHashCode +import org.eclipse.xtend.lib.annotations.ToString + +/** + * Action received from client to rename a region. + * Given information is the regions id and the new name of the region. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class RenameRegionAction implements Action { + public static val LABEL = "Rename region" + public static val KIND = 'SCChart_graph_RenameRegion' + String kind = KIND + + public String id + public String region_name + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("region_name", "String", "New Name"); + return #[input1]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + RenameRegionAction.LABEL, + RenameRegionAction.KIND, + false, + RenameRegionAction.getInputs() + ) + } +} + +/** + * Action received from client to add concurrent behavior. + * Given information is the new concurrent regions name and the name of the initial state in it. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class AddConcurrentRegionAction implements Action { + public static val LABEL = "Add concurrent region" + public static val KIND = 'SCChart_graph_AddConcurrentRegion' + String kind = KIND + + public String id + public String region_name + public String state_name + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("state_name", "String", "New initial state name"); + val input2 = new InputType("region_name", "String", "New Region Name"); + return #[input1, input2]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + AddConcurrentRegionAction.LABEL, + AddConcurrentRegionAction.KIND, + false, + AddConcurrentRegionAction.getInputs() + ) + } +} diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructeBasedEditingLanguageServerContribution.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructeBasedEditingLanguageServerContribution.xtend new file mode 100644 index 0000000000..2cbe6ca176 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructeBasedEditingLanguageServerContribution.xtend @@ -0,0 +1,27 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import com.google.inject.Injector +import de.cau.cs.kieler.language.server.ILanguageServerContribution + +/** + * Used during creation of a language server and to set the client accordingly. + * + */ +class SCChartsStructeBasedEditingLanguageServerContribution implements ILanguageServerContribution { + + override getLanguageServerExtension(Injector injector) { + return injector.getInstance(SCChartsStructureBasedEditingLanguageServerExtension) + } +} diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingActionHandler.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingActionHandler.xtend new file mode 100644 index 0000000000..8ef8dd7557 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingActionHandler.xtend @@ -0,0 +1,122 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import com.google.inject.Inject +import de.cau.cs.kieler.klighd.lsp.AbstractActionHandler +import de.cau.cs.kieler.klighd.lsp.KGraphDiagramServer +import org.eclipse.sprotty.Action + +class SCChartsStructureBasedEditingActionHandler extends AbstractActionHandler { + + @Inject + SCChartsStructureBasedEditingLanguageServerExtension lsExtension + + new() { + this.supportedMessages = newHashMap( + DeleteAction.KIND -> DeleteAction, + RenameStateAction.KIND -> RenameStateAction, + AddSuccessorStateAction.KIND -> AddSuccessorStateAction, + AddHierarchicalStateAction.KIND -> AddHierarchicalStateAction, + ChangeTargetStateAction.KIND -> ChangeTargetStateAction, + ChangeSourceStateAction.KIND -> ChangeSourceStateAction, + ChangeTriggerEffectAction.KIND -> ChangeTriggerEffectAction, + RenameRegionAction.KIND -> RenameRegionAction, + AddConcurrentRegionAction.KIND -> AddConcurrentRegionAction, + ChangeToAbortingTransitionAction.KIND -> ChangeToAbortingTransitionAction, + ChangeToTerminatingTransitionAction.KIND -> ChangeToTerminatingTransitionAction, + ChangeToWeakTransitionAction.KIND -> ChangeToWeakTransitionAction, + AddTransitionAction.KIND -> AddTransitionAction, + ToggleFinalStateAction.KIND -> ToggleFinalStateAction, + MakeInitialStateAction.KIND -> MakeInitialStateAction, + EditSemanticDeclarationAction.KIND -> EditSemanticDeclarationAction, + ChangePriorityAction.KIND -> ChangePriorityAction + ) + } + + override handle(Action action, String clientId, KGraphDiagramServer server) { + + if (action.kind == DeleteAction.KIND) { + synchronized (server.modelLock) { + lsExtension.delete(action as DeleteAction, clientId) + } + } else if (action.kind == RenameStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.rename(action, clientId) + } + } else if (action.kind == AddSuccessorStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.addSuccessorState(action as AddSuccessorStateAction, clientId) + } + } else if (action.kind == AddHierarchicalStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.addHirachicalNode(action as AddHierarchicalStateAction, clientId) + } + } else if (action.kind == ChangeTargetStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeDestination(action as ChangeTargetStateAction, clientId) + } + } else if (action.kind == ChangeSourceStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeSource(action as ChangeSourceStateAction, clientId) + } + } else if (action.kind == ChangeTriggerEffectAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeIO(action as ChangeTriggerEffectAction, clientId) + } + } else if (action.kind == RenameRegionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.rename(action, clientId) + } + } else if (action.kind == AddConcurrentRegionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.addConcurrentRegion(action as AddConcurrentRegionAction, clientId) + } + } else if (action.kind == ChangeToAbortingTransitionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeToAbort(action as ChangeToAbortingTransitionAction, clientId) + } + } else if (action.kind == ChangeToTerminatingTransitionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeToTerminating(action as ChangeToTerminatingTransitionAction, clientId) + } + } else if (action.kind == ChangeToWeakTransitionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeToWeak(action as ChangeToWeakTransitionAction, clientId) + } + } else if (action.kind == AddTransitionAction.KIND) { + synchronized (server.modelLock) { + lsExtension.addNewTransition(action as AddTransitionAction, clientId) + } + } else if (action.kind == ToggleFinalStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.toggleFinalState(action as ToggleFinalStateAction, clientId) + } + } else if (action.kind == MakeInitialStateAction.KIND) { + synchronized (server.modelLock) { + lsExtension.makeInitialState(action as MakeInitialStateAction, clientId) + } + } else if (action.kind == EditSemanticDeclarationAction.KIND) { + synchronized (server.modelLock) { + lsExtension.editSemanticDeclaration(action as EditSemanticDeclarationAction, clientId) + } + } else if (action.kind == ChangePriorityAction.KIND) { + synchronized (server.modelLock) { + lsExtension.changeEdgePriority(action as ChangePriorityAction, clientId) + } + } else { + throw new IllegalArgumentException("Action " + action.kind + " not supported by handler " + + this.class.simpleName) + } + } +} \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingLanguageServerExtension.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingLanguageServerExtension.xtend new file mode 100644 index 0000000000..8cd8f22c7c --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/SCChartsStructureBasedEditingLanguageServerExtension.xtend @@ -0,0 +1,892 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import com.google.inject.Inject +import de.cau.cs.kieler.kexpressions.impl.OperatorExpressionImpl +import de.cau.cs.kieler.kexpressions.impl.ValuedObjectImpl +import de.cau.cs.kieler.kexpressions.impl.ValuedObjectReferenceImpl +import de.cau.cs.kieler.kexpressions.keffects.impl.AssignmentImpl +import de.cau.cs.kieler.kexpressions.kext.KExtStandaloneParser +import de.cau.cs.kieler.klighd.internal.util.KlighdInternalProperties +import de.cau.cs.kieler.klighd.kgraph.KEdge +import de.cau.cs.kieler.klighd.kgraph.KNode +import de.cau.cs.kieler.klighd.lsp.KGraphDiagramState +import de.cau.cs.kieler.klighd.lsp.KGraphLanguageServerExtension +import de.cau.cs.kieler.klighd.lsp.LSPUtil +import de.cau.cs.kieler.language.server.ILanguageClientProvider +import de.cau.cs.kieler.language.server.KeithLanguageClient +import de.cau.cs.kieler.sccharts.ControlflowRegion +import de.cau.cs.kieler.sccharts.PreemptionType +import de.cau.cs.kieler.sccharts.Region +import de.cau.cs.kieler.sccharts.State +import de.cau.cs.kieler.sccharts.Transition +import de.cau.cs.kieler.sccharts.extensions.SCChartsTransitionExtensions +import de.cau.cs.kieler.sccharts.impl.SCChartsFactoryImpl +import java.io.ByteArrayOutputStream +import java.util.List +import java.util.Map +import javax.inject.Singleton +import org.eclipse.lsp4j.Position +import org.eclipse.lsp4j.Range +import org.eclipse.lsp4j.TextEdit +import org.eclipse.lsp4j.services.LanguageClient +import org.eclipse.sprotty.Action +import org.eclipse.xtext.ide.server.ILanguageServerAccess +import org.eclipse.xtext.ide.server.ILanguageServerExtension + +/** + * Structure based editing language server extension for SCCharts. This handles all actions that may be send by the client. + */ +@Singleton +class SCChartsStructureBasedEditingLanguageServerExtension implements ILanguageServerExtension, ILanguageClientProvider { + + @Inject extension SCChartsTransitionExtensions + + @Inject + extension KGraphLanguageServerExtension + + @Inject KGraphDiagramState diagramState + + /** + * The language client allows to send notifications or requests from the server to the client. + * Notifications are preferred, since they allow more asynchronity. + */ + KeithLanguageClient client + + SCChartsFactoryImpl factory = new SCChartsFactoryImpl + + Position previsionRange + + override initialize(ILanguageServerAccess access) { + factory = new SCChartsFactoryImpl() + } + + override setLanguageClient(LanguageClient client) { + this.client = client as KeithLanguageClient + } + + override getLanguageClient() { + return this.client + } + + /** + * Finds the range, i.e. the number of lines, in the file currently active in the diagram state of the client. + * + * @param clientId The clientId + */ + def initCurrentResource(String clientId) { + val uri = diagramState.getURIString(clientId) + val resource = getResource(uri); + val outputStream = new ByteArrayOutputStream + resource.save(outputStream, emptyMap) + val codeBefore = outputStream.toString().trim() + val lines = codeBefore.split("\r\n|\r|\n") + // The range is the length of the previous file. + val lastLine = lines.get(lines.length - 1) + previsionRange = new Position(lines.length, lastLine.length) + } + + /** + * Called to add a new transition to a state. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def addNewTransition(AddTransitionAction action, String clientId) { + initCurrentResource(clientId) + + // get the node corresponding to the selected state on the client. Since the contextmenu was opened for a specific + // state we know the id exists and is a state so we can omit a try catch block + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + + if (node.parentRegion === null) { + this.client.sendMessage("The root may not have a successor.", "error") + return + } + val new_transition = factory.createTransition() + + // Since trigger and effect are given as strings there may be variables that are not inputs / outputs + // also we only allow assignments in effects. + try { + changeTrigger(new_transition, action.trigger, uri) + changeEffect(new_transition, action.effect, uri) + } catch (ValuedObjectNotFoundException ex) { + client.sendMessage("During the parsing of the expression " + action.trigger + " the object: " + ex.message + + " could not be found.", "error") + return + } catch (ExpressionParseException ex) { + client.sendMessage( + "During the parsing of the expression " + action.effect + " the expression: " + ex.message + + " could not be converted to an assignment expression.", "error") + return + } catch (NullPointerException ex) { + client.sendMessage("The expression could not be parsed.", "error") + return + } + + // Since the destination was selected it may be a region or a state outside the parent region of the selected node + try { + val kDest = LSPUtil.getKNode(diagramState, uri, action.destination) + val dest = kDest.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + // need to check if the destination is in the same region as the source + if (dest.parentRegion !== node.parentRegion) { + client.sendMessage("The selected state is not part of the same region.", "error") + return + } + new_transition.sourceState = node + new_transition.targetState = dest + } catch (ClassCastException|NullPointerException ex) { + // Catching the moment when not a state is selected as destination + client.sendMessage("The selected element is not a targetable state.", "error") + return + } + + updateDocument(uri) + } + + /** + * Changes a given transition to a weak transition. + * + * @param action The action to perform. + * @param clientId The id of the frontend client + * @param server The diagram server + */ + def changeToWeak(ChangeToWeakTransitionAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + edge.preemption = PreemptionType.WEAK + + updateDocument(uri) + } + + /** + * Changes a given transition to a terminating transition. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeToTerminating(ChangeToTerminatingTransitionAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + edge.preemption = PreemptionType.TERMINATION + + updateDocument(uri) + } + + /** + * Changes a given transition to a aborting transition. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeToAbort(ChangeToAbortingTransitionAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + edge.preemption = PreemptionType.STRONG + + updateDocument(uri) + } + + /** + * Changes the trigger and effect of a transition. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeIO(ChangeTriggerEffectAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + var edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + // currently as workaround we delete the edge and add it again since adjusting trigger and effect directly + // introduces some weird spacing in the updateDocument step + val prio = edge.priority + val target = edge.targetState + val source = edge.sourceState + + val newedge = createTransitionTo(source, target) + + // Since trigger and effect are given as strings there may be variables that are not inputs / outputs + // also we only allow assignments in effects. + try { + changeTrigger(newedge, action.trigger, uri) + changeEffect(newedge, action.effect, uri) + setSpecificPriority(newedge, prio) + } catch (ValuedObjectNotFoundException ex) { + client.sendMessage("During the parsing of the expression " + action.trigger + " the object: " + ex.message + + " could not be found.", "error") + return + } catch (ExpressionParseException ex) { + client.sendMessage( + "During the parsing of the expression " + action.effect + " the expression: " + ex.message + + " could not be converted to an assignment expression.", "error") + return + } catch (NullPointerException ex) { + client.sendMessage("The expression could not be parsed.", "error") + return + } + deleteEdge(kEdge) + + updateDocument(uri) + } + + /** + * Method to change the destination of a given transition. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeDestination(ChangeTargetStateAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + // since the destination is selected by the user it may be inside another region or be no state atall + try { + val kNode = LSPUtil.getKNode(diagramState, uri, action.new_target) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + // checking if the selected state is inside the same region as the source + if (node.parentRegion !== edge.targetState.parentRegion) { + client.sendMessage("The selected state is not part of the same region.", "error") + return + } + + edge.targetState.incomingTransitions.remove(edge) + edge.targetState = node + + node.incomingTransitions.add(edge) + } catch (ClassCastException|NullPointerException ex) { + // catching the cases where the selected element is not a state + client.sendMessage("The selected element is not a targetable state.", "error") + return + } + + updateDocument(uri) + } + + /** + * Method to change the source of a given transition. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeSource(ChangeSourceStateAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as Transition + + // we need to check if the selected element is a state and if the selected element is inside the same region + try { + val kNode = LSPUtil.getKNode(diagramState, uri, action.new_source) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + // checking the the target and source are in the same region + if (node.parentRegion !== edge.targetState.parentRegion) { + client.sendMessage("The selected state is not part of the same region.", "error") + return + } + + edge.sourceState.outgoingTransitions.remove(edge) + edge.sourceState = node + + node.outgoingTransitions.add(edge) + } catch (ClassCastException|NullPointerException ex) { + // catching all cases where not a state was selected. + client.sendMessage("The selected element is not a targetable state.", "error") + return + } + + updateDocument(uri) + } + + /** + * Method to add an hierarchical state. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def addHirachicalNode(AddHierarchicalStateAction action, String clientId) { + initCurrentResource(clientId) + // we need to make sure that the new states name is given + if (action.state_name.equals("")) { + this.client.sendMessage("You must provide a state id.", "error") + return + } + val newState = factory.createState() + val state_id = getId(action.state_name) + // we need to make sure the new name obeys the rules for state names. + if (state_id.equals("_") || state_id.equals("")) { + this.client.sendMessage("The state id needs to have atleast one number or letter in it.", "error") + return + } + // we want to display the desired name as label in the graph + if (!state_id.equals(action.state_name)) { + newState.label = action.state_name + } + newState.name = state_id + newState.initial = true + + // Regions follow a laxer definition for id's there may be regions that have no name etc. + val newRegion = factory.createControlflowRegion() + if (!action.region_name.equals("")) { + val region_id = getId(action.region_name) + + if (!region_id.equals(action.region_name)) + newRegion.label = action.region_name + + newRegion.name = region_id + } + + newRegion.states.add(newState) + + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + + node.regions.add(newRegion) + + updateDocument(uri) + } + + /** + * Method to add a concurrent behavior. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def addConcurrentRegion(AddConcurrentRegionAction action, String clientId) { + initCurrentResource(clientId) + + // To make sure there is a name given for the state. + if (action.state_name.equals("")) { + this.client.sendMessage("You must provide a state id.", "error") + return + } + val newState = factory.createState() + val state_id = getId(action.state_name) + // we need to make sure the new name obeys the rules for state names. + if (state_id.equals("_") || state_id.equals("")) { + this.client.sendMessage("The state id needs to have atleast one number or letter in it.", "error") + return + } + // we want to display the desired name as label in the graph + if (!state_id.equals(action.state_name)) { + newState.label = action.state_name + } + newState.name = state_id + newState.initial = true + + // Regions follow a laxer definition for id's there may be regions that have no name etc. + val newRegion = factory.createControlflowRegion() + if (!action.region_name.equals("")) { + val region_id = getId(action.region_name) + + if (!region_id.equals(action.region_name)) + newRegion.label = action.region_name + + if (!(region_id.equals("") || region_id.equals("_"))) + newRegion.name = region_id + } + + newRegion.states.add(newState) + + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + + if (node instanceof ControlflowRegion) { + (node as ControlflowRegion).parentState.regions.add(newRegion) + } + + updateDocument(uri) + } + + /** + * Method to rename states and regions. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def rename(Action action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + // We need to differentiate between states and regions + if (action.kind === RenameStateAction.KIND) { + val kNode = LSPUtil.getKNode(diagramState, uri, (action as RenameStateAction).id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + // we need to make sure the new name obeys the rules for state ids + if ((action as RenameStateAction).state_name.equals("")) { + this.client.sendMessage("You must provide a state id.", "error") + return + } + val state_id = getId((action as RenameStateAction).state_name) + if (state_id.equals("_") || state_id.equals("")) { + this.client.sendMessage("The state id needs to have atleast one number or letter in it.", "error") + return + } + if (!state_id.equals((action as RenameStateAction).state_name)) { + (node as State).label = (action as RenameStateAction).state_name + } + (node as State).name = state_id + + } else if (action.kind === RenameRegionAction.KIND) { + val kNode = LSPUtil.getKNode(diagramState, uri, (action as RenameRegionAction).id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + // we need to make sure the new name obeys the rules for region names. + if((action as RenameRegionAction).region_name.equals("")) return + + val region_id = getId((action as RenameRegionAction).region_name) + + if (!region_id.equals((action as RenameRegionAction).region_name)) { + (node as Region).label = (action as RenameRegionAction).region_name + } + + (node as Region).name = region_id + + } + + updateDocument(uri) + } + + /** + * Method to delete elements ie. Regions, States and Transitions. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def delete(DeleteAction action, String clientId) { + initCurrentResource(clientId) + + try { + // for multiple slected elements + val nodes = action.id.split(":"); + for (x : nodes) { + this.deleteSingleElem(x, clientId) + } + } catch (NullPointerException ex) { + // single element was send and should be deleted + this.deleteSingleElem(action.id, clientId) + } + + val uri = diagramState.getURIString(clientId) + + updateDocument(uri) + } + + /** + * Method to add a successor state to a given state. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def addSuccessorState(AddSuccessorStateAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + if (node.parentRegion === null) { + this.client.sendMessage("The root may not have a successor.", "error") + return + } + + // we need to make sure a name for the new state is given + if (action.state_name.equals("")) { + this.client.sendMessage("You must provide a state id.", "error") + return + } + val newState = factory.createState() + val state_id = getId(action.state_name) + // we need to make sure the new name obeys the rules for state id's + if (state_id.equals("_") || state_id.equals("")) { + this.client.sendMessage("The state id needs to have atleast one number or letter in it.", "error") + return + } + // we want to display the given name in the graph and have the id only as id + if (!state_id.equals(action.state_name)) { + newState.label = action.state_name + } + newState.name = state_id + + val new_transition = factory.createTransition() + + // the trigger and effect are given as strings and can therefore can be false. + // The Variables may not be initialised or the effect may not be an expression that assigns somthing. + try { + changeTrigger(new_transition, action.trigger, uri) + changeEffect(new_transition, action.effect, uri) + } catch (ValuedObjectNotFoundException ex) { + client.sendMessage("During the parsing of the expression " + action.trigger + " the object: " + ex.message + + " could not be found.", "error") + return + } catch (ExpressionParseException ex) { + client.sendMessage( + "During the parsing of the expression " + action.effect + " the expression: " + ex.message + + " could not be converted to an assignment expression.", "error") + return + } catch (NullPointerException ex) { + client.sendMessage("The expression could not be parsed.", "error") + return + } + + new_transition.sourceState = node + new_transition.targetState = newState + + node.parentRegion.states.add(newState) + + updateDocument(uri) + } + + /** + * Method to toggle a state to be final or not. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def toggleFinalState(ToggleFinalStateAction action, String clientId) { + initCurrentResource(clientId) + + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + if (node.parentRegion === null) { + this.client.sendMessage("The root may not be final.", "error") + return + } + node.final = !node.final + + updateDocument(uri) + } + + /** + * Send from client to server to indicate that the focused tab should be different. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def editSemanticDeclaration(EditSemanticDeclarationAction action, String clientId) { + val uri = diagramState.getURIString(clientId) + this.client.sendMessage(uri, "switchEditor") + } + + /** + * Makes the desired state initial and changes the old initial state to be normal. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def makeInitialState(MakeInitialStateAction action, String clientId) { + initCurrentResource(clientId) + + // since the action is triggered with the contextmenu for states the action id is the id of a state and thus we can omit the try catch's + val uri = diagramState.getURIString(clientId) + val kNode = LSPUtil.getKNode(diagramState, uri, action.id) + val newInitial = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + if (newInitial.parentRegion === null) { + this.client.sendMessage("The root may not be an initial node.", "error") + return + } + // changes the old initial state to be normal + for (node : newInitial.parentRegion.states) { + if(node.initial) node.initial = false + } + + newInitial.initial = true + + updateDocument(uri) + } + + /** + * Method to change a transitions priority. + * The edge moves up/down the hierarchy and the others are moved up or down by one. + * + * @param action The action to perform. + * @param clientId The id of the client. + */ + def changeEdgePriority(ChangePriorityAction action, String clientId) { + initCurrentResource(clientId) + val uri = diagramState.getURIString(clientId) + val kEdge = LSPUtil.getKEdge(diagramState, uri, action.id) + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + val priority = Integer.parseInt(action.priority) + setSpecificPriority(edge as Transition, priority) + updateDocument(uri) + } + + /** + * Helper method to delete a single element. + * + * @param id The element id. + * @param clientId The id of the client. + */ + def deleteSingleElem(String id, String clientId) { + val uri = diagramState.getURIString(clientId) + // kNode may be states or regions. + val kNode = LSPUtil.getKNode(diagramState, uri, id) + + if (kNode !== null && kNode.parent !== null) { + deleteNode(kNode); + } + // edges are transitions + val kEdge = LSPUtil.getKEdge(diagramState, uri, id) + if (kEdge !== null) { + deleteEdge(kEdge); + } + } + + /** + * Helper method to delete edges by removing the edge from source and target. + * + * @param kEdge The KEdge to delete. + */ + def deleteEdge(KEdge kEdge) { + val edge = kEdge.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + val source = kEdge.source.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + val target = kEdge.target.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + + source.outgoingTransitions.remove(edge) + target.incomingTransitions.remove(edge) + } + + /** + * Helper method to delete nodes or regions. + * + * @param kNode The KNode to delete. + */ + def void deleteNode(KNode kNode) { + val node = kNode.getProperty(KlighdInternalProperties.MODEL_ELEMENT) + + if (node instanceof State) { + // if we delete the last state in a region we instead want to delete the region itself + if (node.parentRegion.states.length === 1) { + node.parentRegion.parentState.regions.remove(node.parentRegion) + return + } + // for all incomming edges we need to delete edge and remove it from the source + for (incommingEdge : kNode.incomingEdges) { + + val source = incommingEdge.source.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + + val transitions = source.getOutgoingTransitions() + val toDelete = newArrayList + + for (transition : transitions) { + if (transition.getTargetState() === node) { + toDelete.add(transition) + } + } + for (transition : toDelete) { + source.outgoingTransitions.remove(transition) + } + + } + // for all outgoing edges we need to delete the edge and remove it from the target + for (outgoingEdge : kNode.outgoingEdges) { + val target = outgoingEdge.target.getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + + val transitions = target.getIncomingTransitions() + val toDelete = newArrayList + + for (transition : transitions) { + if (transition.getSourceState() === node) { + toDelete.add(transition) + } + } + for (transition : toDelete) { + target.incomingTransitions.remove(transition) + } + } + // if the node is initial we want to make any other node initial + if (node.initial) { + if (node.parentRegion.states.get(0) !== node) { + node.parentRegion.states.get(0).initial = true + } else { + node.parentRegion.states.get(1).initial = true + } + + } + // finally we want to remove the node from the region. + node.parentRegion.states.remove(node) + } else { + // in case of regions we want to delete them from the parent state + (node as ControlflowRegion).parentState.regions.remove(node) + } + + } + + /** + * Helper method to change the trigger of an transition. + * + * @param transition The transition + * @param trigger The trigger + * @param uri The uri String + */ + def changeTrigger(Transition transition, String trigger, String uri) { + if (trigger != "") { + // may yield nothing and thus throw a nullpointer exception (Handeled when the mehtod is used) + val newTrigger = KExtStandaloneParser.parseExpression(trigger) + + // The expression may consist of multiple operators + if ((newTrigger instanceof OperatorExpressionImpl)) { + changeTriggerSubExpressions(transition, newTrigger, uri) + + } else if (newTrigger instanceof ValuedObjectReferenceImpl) { + // If there is a valued objectreverence we need to change the reference to the one in the model + (newTrigger as ValuedObjectReferenceImpl).valuedObject = getValuedObjectReference(diagramState, uri, + (newTrigger as ValuedObjectReferenceImpl).valuedObject.name) + } + + transition.trigger = newTrigger + } + } + + /** + * Helper method to change the valued object references recursively for all valued objects. + * + * @param transition The transition + * @param trigger The trigger + * @param uri The uri string + */ + def void changeTriggerSubExpressions(Transition transition, OperatorExpressionImpl trigger, String uri) { + for (exp : trigger.subExpressions) { + // If we have an operator we want to change the subexpressions + if (exp instanceof OperatorExpressionImpl) { + changeTriggerSubExpressions(transition, exp, uri) + + } else if (exp instanceof ValuedObjectReferenceImpl) { + // if we have a object reference we want to change it to the one in the model + exp.valuedObject = getValuedObjectReference(diagramState, uri, exp.valuedObject.name) + } + } + } + + /** + * Helper function to change the effect of a transition. + * + * @param transition The transition + * @param rawEffectString The raw effect string + * @param uri The uri string + */ + def changeEffect(Transition transition, String rawEffectString, String uri) { + // we want to delete any old effects + transition.effects.removeAll(transition.effects) + + if (rawEffectString != "") { + // since there may be multiple assignments in a effect we need to split those up before parsing. + val effectStrings = rawEffectString.split(";") + for (effectString : effectStrings) { + try { + // may be null if no expression could be generated + val effect = KExtStandaloneParser.parseEffect(effectString); + // need to update the valued object since the parser generates dummys + // cast can throw a class cast exception since the user input may be no assingment + (effect as AssignmentImpl).reference.valuedObject = getValuedObjectReference(diagramState, uri, + (effect as AssignmentImpl).reference.valuedObject.name) + transition.effects.add(effect) + } catch (ClassCastException ex) { + // simply rethrown for readability in the catch cases outside of method + throw new ExpressionParseException(effectString) + } + } + } + } + + /** + * Updates the textual representation on the client. + * For now everything is replaced. + * + * @param uri String uri of resource + */ + def updateDocument(String uri) { + val Map> changes = newHashMap + + val resource = getResource(uri); + + val outputStream = new ByteArrayOutputStream + resource.save(outputStream, emptyMap) + val codeAfter = outputStream.toString().trim() + + // The range is the length of the previous file. + val Range range = new Range(new Position(0, 0), previsionRange) + + val TextEdit textEdit = new TextEdit(range, codeAfter) + changes.put(uri, #[textEdit]); + + this.client.replaceContentInFile(uri, codeAfter, range) + } + + /** + * Removes all characters that can not be in an id from a string and returns the resulting string. + * + * @param name String name to replace characters in + * @reurn The same string instance with deletes characters. + */ + def getId(String name) { + return name.replaceAll("[^a-zA-Z0-9_]", "") + } + + static def ValuedObjectImpl getValuedObjectReference(KGraphDiagramState diagramState, String uri, String name) { + + val root = LSPUtil.getRoot(diagramState, uri) + val node = root.children.get(0).getProperty(KlighdInternalProperties.MODEL_ELEMENT) as State + for (declaration : node.declarations) { + for (obj : declaration.valuedObjects) { + if(obj.name == name) return obj as ValuedObjectImpl + } + } + throw new ValuedObjectNotFoundException(name) + } + +} + +/** + * Simple exception to throw if a valued object could not be found. + */ +class ValuedObjectNotFoundException extends Exception { + + new(String notFound) { + super(notFound) + } +} + +/** + * Simple exception for readability when error arises during the parsing of a expression + */ +class ExpressionParseException extends Exception { + + new(String expression) { + super(expression) + } + +} diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StateActions.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StateActions.xtend new file mode 100644 index 0000000000..a31a776816 --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StateActions.xtend @@ -0,0 +1,299 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import de.cau.cs.kieler.klighd.structurebasedediting.InputType +import de.cau.cs.kieler.klighd.structurebasedediting.StructureBasedEditingMessage +import java.util.function.Consumer +import org.eclipse.sprotty.Action +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.EqualsHashCode +import org.eclipse.xtend.lib.annotations.ToString + +/** + * Action received from the client if the window should switch to the code base. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class EditSemanticDeclarationAction implements Action { + public static val LABEL = "Edit sematic declarations" + public static val KIND = 'SCChart_EditSemanticDeclarations' + String kind = KIND + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + EditSemanticDeclarationAction.LABEL, + EditSemanticDeclarationAction.KIND, + false, + EditSemanticDeclarationAction.getInputs() + ) + } +} + +/** + * Action received from the client if a state should be renamed. + * The given information is the state id and the new name. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class RenameStateAction implements Action { + public static val LABEL = "Rename state" + public static val KIND = 'SCChart_graph_RenameState' + String kind = KIND + + public String id + public String state_name + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("state_name", "String", "New Name"); + return #[input1]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + RenameStateAction.LABEL, + RenameStateAction.KIND, + false, + RenameStateAction.getInputs() + ) + } +} + +/** + * Action received from client if a new transition should be added. + * Given from client are the id of the source node the new destination + * as well as trigger and effect as strings. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class AddTransitionAction implements Action { + public static val LABEL = "Add new transition" + public static val KIND = 'SCChart_graph_AddTransition' + String kind = KIND + + public String id + public String destination + public String trigger + public String effect + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("destination", "SelectTarget", "Destination"); + val input2 = new InputType("trigger", "String", "Trigger"); + val input3 = new InputType("effect", "String", "Effect") + return #[input1, input2, input3]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + AddTransitionAction.LABEL, + AddTransitionAction.KIND, + false, + AddTransitionAction.getInputs() + ) + } +} + +/** + * Action received from client for adding a new successor state. + * the given information is the predecessor node the new nodes name as well as + * trigger and effect + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class AddSuccessorStateAction implements Action { + public static val LABEL = "Add successor state" + public static val KIND = 'SCChart_graph_AddSuccessorState' + String kind = KIND + + public String id + public String state_name + public String trigger + public String effect + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("state_name", "String", "Name of state"); + val input2 = new InputType("trigger", "String", "Trigger"); + val input3 = new InputType("effect", "String", "Effect") + return #[input1, input2, input3]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + AddSuccessorStateAction.LABEL, + AddSuccessorStateAction.KIND, + false, + AddSuccessorStateAction.getInputs() + ) + } +} + +/** + * Action received from the client to add a hirachical behavior to a state. + * Given information is the states id the new regions name and the new states name. + * + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class AddHierarchicalStateAction implements Action { + public static val LABEL = "Add region" + public static val KIND = 'SCChart_graph_AddHierarchicalState' + String kind = KIND + + public String id + public String state_name + public String region_name + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + val input1 = new InputType("state_name", "String", "State Name"); + val input2 = new InputType("region_name", "String", "Region Name"); + return #[input1, input2]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + AddHierarchicalStateAction.LABEL, + AddHierarchicalStateAction.KIND, + false, + AddHierarchicalStateAction.getInputs() + ) + } +} + +/** + * Action received from the client if a state should be made initial. + * Given information is the state id of the state that should be initial. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class MakeInitialStateAction implements Action { + public static val LABEL = "Make initial state" + public static val KIND = 'SCChart_graph_MakeInitialState' + String kind = KIND + + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + MakeInitialStateAction.LABEL, + MakeInitialStateAction.KIND, + false, + MakeInitialStateAction.getInputs() + ) + } +} + +/** + * Action received to toggle a state to a final state or back. + * Given information is the state id which should be toggled. + */ +@Accessors +@EqualsHashCode +@ToString(skipNulls=true) +class ToggleFinalStateAction implements Action { + public static val LABEL = "Toggle final state" + public static val KIND = 'SCChart_graph_MakeFinalState' + String kind = KIND + + public String id + + new() { + } + + new(Consumer initializer) { + initializer.accept(this) + } + + /* Returns the array of inputs requested from the user to perform the action. */ + def static InputType[] getInputs() { + return #[]; + } + + /* Used in the synthesis to append the supported actions to the root node for the use on the client. */ + def static StructureBasedEditingMessage getMsg() { + return new StructureBasedEditingMessage( + ToggleFinalStateAction.LABEL, + ToggleFinalStateAction.KIND, + false, + ToggleFinalStateAction.getInputs() + ) + } +} \ No newline at end of file diff --git a/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StructureBasedEditingHook.xtend b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StructureBasedEditingHook.xtend new file mode 100644 index 0000000000..277810acbb --- /dev/null +++ b/language-server/de.cau.cs.kieler.language.server/src/de/cau/cs/kieler/language/server/sccharts/structurebasedediting/StructureBasedEditingHook.xtend @@ -0,0 +1,82 @@ +/* + * KIELER - Kiel Integrated Environment for Layout Eclipse RichClient + * + * http://rtsys.informatik.uni-kiel.de/kieler + * + * Copyright 2024 by + * + Kiel University + * + Department of Computer Science + * + Real-Time and Embedded Systems Group + * + * This code is provided under the terms of the Eclipse Public License (EPL). + */ +package de.cau.cs.kieler.language.server.sccharts.structurebasedediting + +import de.cau.cs.kieler.klighd.kgraph.KNode +import de.cau.cs.kieler.klighd.krendering.ViewSynthesisShared +import de.cau.cs.kieler.klighd.structurebasedediting.StructureBasedEditingOptions +import de.cau.cs.kieler.klighd.util.KlighdProperties +import de.cau.cs.kieler.sccharts.Scope +import de.cau.cs.kieler.sccharts.ui.synthesis.filtering.SCChartsSemanticFilterTags +import de.cau.cs.kieler.sccharts.ui.synthesis.hooks.SynthesisHook +import java.util.HashMap + +/** + * Class for adding a property to the root state of a scchart diagram + */ +@ViewSynthesisShared +class StructureBasedEditingHook extends SynthesisHook { + + override finish(Scope scope, KNode node) { + val map = new HashMap() + + // all states support the following actions + map.put(SCChartsSemanticFilterTags.STATE, #[ + EditSemanticDeclarationAction.getMsg(), + RenameStateAction.getMsg(), + AddSuccessorStateAction.getMsg(), + AddHierarchicalStateAction.getMsg(), + AddTransitionAction.getMsg(), + ToggleFinalStateAction.getMsg(), + DeleteAction.getMsg() + ]) + + // Non initial states support one more action + map.put(SCChartsSemanticFilterTags.NOT_INITIAL_STATE, #[ + MakeInitialStateAction.getMsg() + ]) + + // Transitions supported actions + map.put(SCChartsSemanticFilterTags.TRANSITION, #[ + ChangeTargetStateAction.getMsg(), + ChangeSourceStateAction.getMsg(), + ChangeTriggerEffectAction.getMsg(), + DeleteAction.getMsg(), + ChangePriorityAction.getMsg() + ]) + // Depending on the type of transition we can change it to the other two options + map.put(SCChartsSemanticFilterTags.WEAK_TRANSITION, #[ + ChangeToTerminatingTransitionAction.getMsg(), + ChangeToAbortingTransitionAction.getMsg() + ]) + map.put(SCChartsSemanticFilterTags.ABORTING_TRANSITION, #[ + ChangeToWeakTransitionAction.getMsg(), + ChangeToTerminatingTransitionAction.getMsg() + ]) + map.put(SCChartsSemanticFilterTags.TERMINATING_TRANSITION, #[ + ChangeToWeakTransitionAction.getMsg(), + ChangeToAbortingTransitionAction.getMsg() + ]) + + // Actions supported by regions + map.put(SCChartsSemanticFilterTags.REGION, #[ + RenameRegionAction.getMsg(), + AddConcurrentRegionAction.getMsg(), + DeleteAction.getMsg() + ]) + + val options = new StructureBasedEditingOptions(map) + // sets the property for the root node + node.setProperty(KlighdProperties.STRUCTURED_EDITING, options) + } +} \ No newline at end of file diff --git a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java index c62c77bb06..ef2249b198 100644 --- a/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java +++ b/plugins/de.cau.cs.kieler.sccharts.ui/src/de/cau/cs/kieler/sccharts/ui/synthesis/filtering/SCChartsSemanticFilterTags.java @@ -38,8 +38,19 @@ public abstract class SCChartsSemanticFilterTags { /** Tag giving semantic meaning that the element is a dataflow region. */ public static final SemanticFilterTag DATAFLOW_REGION = new SemanticFilterTag("dataflowRegion"); + /** Tag giving semantic meaning that the element is a transition. */ + public static final SemanticFilterTag TRANSITION = new SemanticFilterTag("transition"); + /** Tag giving semantic meaning that the element is a transition. */ + public static final SemanticFilterTag WEAK_TRANSITION = new SemanticFilterTag("weakTransition"); + /** Tag giving semantic meaning that the element is a transition. */ + public static final SemanticFilterTag TERMINATING_TRANSITION = new SemanticFilterTag("terminatingTransition"); + /** Tag giving semantic meaning that the element is a transition. */ + public static final SemanticFilterTag ABORTING_TRANSITION = new SemanticFilterTag("abortingTransition"); + /** Tag giving semantic meaning that the element is initial. */ public static final SemanticFilterTag INITIAL = new SemanticFilterTag("initial"); + /** Tag giving semantic meaning that the element is a dataflow region. */ + public static final SemanticFilterTag NOT_INITIAL_STATE = new SemanticFilterTag("notInitialState"); /** Tag giving semantic meaning that the element is final. */ public static final SemanticFilterTag FINAL = new SemanticFilterTag("final");