Skip to content
Snippets Groups Projects
Commit 0065869d authored by Sebastian Bergemann's avatar Sebastian Bergemann
Browse files

Merge branch 'master' of https://git.fortiss.org/af3/kernel.git into 4149

parents e26aba06 8fec72e0
No related branches found
No related tags found
1 merge request!181Added correct hash creation in reuse (+ update detection)
Pipeline #36087 failed
This commit is part of merge request !181. Comments created here will be created in the context of that merge request.
Showing
with 295 additions and 113 deletions
DefaultLayoutConstants.java 10ba39d25701f7aff7ef545ec69e42a6117ae7b1 GREEN DefaultLayoutConstants.java 10ba39d25701f7aff7ef545ec69e42a6117ae7b1 GREEN
DiagramTapeMeasure.java 2aaf2d0765d0ba5292ec2468d0d04d52f36370a6 GREEN DiagramTapeMeasure.java 4ac1310faa82746f0a66e684677588cbcdfcdde9 GREEN
HorizontalDiagramTapeMeasure.java 98bcb18ed5171c5ff191225cf21a305d5ef06440 GREEN
IAutoLayouter.java 8f22d3813491159151a8753dd683a5043554fb67 GREEN IAutoLayouter.java 8f22d3813491159151a8753dd683a5043554fb67 GREEN
IAutoLayouterTapeMeasure.java 5ef5c7d0a124714d582de283d3915d8b4bf7fda8 GREEN IAutoLayouterTapeMeasure.java 5ef5c7d0a124714d582de283d3915d8b4bf7fda8 GREEN
KielerAutoLayouter.java 94de655f6abf6d7d6d747f96de07e0be50588abd GREEN KielerAutoLayouter.java 9cc7943ff90c55851b81bf7c4cde7b279992e925 GREEN
LayoutKeyConstants.java 1e35b73f26f2691ef80fa885e4c5fc6c6a60bd05 GREEN LayoutKeyConstants.java 00d19473f69e2e9bdd541d41e737d2c99a0fd281 GREEN
VerticalDiagramTapeMeasure.java 0b83af2189b4f55d0dfe121ae4e86cee064c5164 GREEN
...@@ -35,18 +35,16 @@ import javafx.geometry.Bounds; ...@@ -35,18 +35,16 @@ import javafx.geometry.Bounds;
import javafx.scene.text.Text; import javafx.scene.text.Text;
/** /**
* {@link IAutoLayouterTapeMeasure} specialization to for automatic layout of models to be displayed * {@link IAutoLayouterTapeMeasure} base class of models to be displayed in JavaFX-based editors.
* in JavaFX-based editors.
* *
* @author barner * @author barner
*/ */
public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure { public abstract class DiagramTapeMeasure implements IAutoLayouterTapeMeasure {
/** /**
* Returns the an estimation of the text extent of the given {@code element}'s label (may be * Returns the an estimation of the text extent of the given {@code element}'s label (may be
* {@code null}). * {@code null}).
*/ */
private Bounds getTextExtent(IModelElement element) { protected Bounds getTextExtent(IModelElement element) {
if(!(element instanceof INamedElement)) { if(!(element instanceof INamedElement)) {
return null; return null;
} }
...@@ -55,6 +53,19 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure { ...@@ -55,6 +53,19 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure {
return text.getBoundsInLocal(); return text.getBoundsInLocal();
} }
/**
* Returns the maximum of the given length and a default length derived from the element's
* connector count.
*/
protected int getElementLength(int length, IHierarchicElement element) {
int numElemConnectors = element.getConnectors().size();
int numElemInputConnectors =
pickInstanceOf(EntryConnectorBase.class, element.getConnectors()).size();
int numConnectors = max(numElemInputConnectors, numElemConnectors - numElemInputConnectors);
return max((1 + 2 * numConnectors) * DEFAULT_CONNECTOR_SIZE, length);
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public int getElementWidth(IHierarchicElement element) { public int getElementWidth(IHierarchicElement element) {
...@@ -73,12 +84,7 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure { ...@@ -73,12 +84,7 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure {
@Override @Override
public int getElementHeight(IHierarchicElement element) { public int getElementHeight(IHierarchicElement element) {
Dimension dimension = getNodeSize((ILayoutedModelElement)element); Dimension dimension = getNodeSize((ILayoutedModelElement)element);
int numElemConnectors = element.getConnectors().size(); return dimension.getHeight();
int numElemInputConnectors =
pickInstanceOf(EntryConnectorBase.class, element.getConnectors()).size();
int numConnectors = max(numElemInputConnectors, numElemConnectors - numElemInputConnectors);
return max((1 + 2 * numConnectors) * DEFAULT_CONNECTOR_SIZE, dimension.getHeight());
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
/*--------------------------------------------------------------------------+ /*-------------------------------------------------------------------------+
| | | Copyright 2018 fortiss GmbH |
| Copyright 2022 fortiss GmbH |
| | | |
| Licensed under the Apache License, Version 2.0 (the "License"); | | Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. | | you may not use this file except in compliance with the License. |
...@@ -14,26 +13,23 @@ ...@@ -14,26 +13,23 @@
| See the License for the specific language governing permissions and | | See the License for the specific language governing permissions and |
| limitations under the License. | | limitations under the License. |
+--------------------------------------------------------------------------*/ +--------------------------------------------------------------------------*/
package org.fortiss.tooling.ext.variability.ui.util; package org.fortiss.tooling.base.layout;
import org.fortiss.tooling.kernel.ui.service.INavigatorService; import org.fortiss.tooling.base.model.element.IHierarchicElement;
/** /**
* Utility functions related to the variability visualization. * {@link IAutoLayouterTapeMeasure} specialization for automatic horizontal layout of models to be
* displayed in JavaFX-based editors.
* *
* @author bayha * @author barner
*/ */
public class VariabilityViewUtils { public class HorizontalDiagramTapeMeasure extends DiagramTapeMeasure {
/** {@inheritDoc} */
@Override
public int getElementHeight(IHierarchicElement element) {
int height = super.getElementHeight(element);
/** return getElementLength(height, element);
* Retrieves the information whether variability options shall be displayed in
* the UI.
*
* Currently this is coupled to the expert view.
*
* @return True if variability shall be available, otherwise false.
*/
public static boolean isVariabilityViewActive() {
return INavigatorService.getInstance().isExpertViewActive();
} }
} }
...@@ -35,6 +35,7 @@ import org.eclipse.elk.alg.layered.options.LayeredMetaDataProvider; ...@@ -35,6 +35,7 @@ import org.eclipse.elk.alg.layered.options.LayeredMetaDataProvider;
import org.eclipse.elk.alg.layered.options.LayeredOptions; import org.eclipse.elk.alg.layered.options.LayeredOptions;
import org.eclipse.elk.core.AbstractLayoutProvider; import org.eclipse.elk.core.AbstractLayoutProvider;
import org.eclipse.elk.core.data.LayoutMetaDataService; import org.eclipse.elk.core.data.LayoutMetaDataService;
import org.eclipse.elk.core.math.ElkPadding;
import org.eclipse.elk.core.options.Direction; import org.eclipse.elk.core.options.Direction;
import org.eclipse.elk.core.options.EdgeRouting; import org.eclipse.elk.core.options.EdgeRouting;
import org.eclipse.elk.core.options.PortLabelPlacement; import org.eclipse.elk.core.options.PortLabelPlacement;
...@@ -57,8 +58,10 @@ import org.fortiss.tooling.base.model.element.IHierarchicElement; ...@@ -57,8 +58,10 @@ import org.fortiss.tooling.base.model.element.IHierarchicElement;
import org.fortiss.tooling.base.model.layout.EOrientation; import org.fortiss.tooling.base.model.layout.EOrientation;
import org.fortiss.tooling.base.model.layout.ILayoutData; import org.fortiss.tooling.base.model.layout.ILayoutData;
import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; import org.fortiss.tooling.base.model.layout.ILayoutedModelElement;
import org.fortiss.tooling.base.model.layout.OffsetOrientation;
import org.fortiss.tooling.base.model.layout.Points; import org.fortiss.tooling.base.model.layout.Points;
import org.fortiss.tooling.base.model.layout.impl.PointsImpl; import org.fortiss.tooling.base.model.layout.impl.PointsImpl;
import org.fortiss.tooling.base.utils.OffsetOrientationUtils;
import org.fortiss.tooling.kernel.model.INamedElement; import org.fortiss.tooling.kernel.model.INamedElement;
/** /**
...@@ -105,9 +108,18 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -105,9 +108,18 @@ public class KielerAutoLayouter implements IAutoLayouter {
LayoutMetaDataService.getInstance() LayoutMetaDataService.getInstance()
.registerLayoutMetaDataProviders(new LayeredMetaDataProvider()); .registerLayoutMetaDataProviders(new LayeredMetaDataProvider());
ElkNode rootNode = createELKGraph(element); Direction direction = getDiagramDirection(element);
int offset = getDiagramOffset(element);
IAutoLayouterTapeMeasure tapeMeasure;
if(direction.isHorizontal()) {
tapeMeasure = new HorizontalDiagramTapeMeasure();
} else {
tapeMeasure = new VerticalDiagramTapeMeasure();
}
rootNode.setProperty(LayeredOptions.DIRECTION, Direction.RIGHT); ElkNode rootNode = createELKGraph(element, tapeMeasure);
rootNode.setProperty(LayeredOptions.DIRECTION, direction);
rootNode.setProperty(LayeredOptions.PADDING, new ElkPadding(offset));
rootNode.setProperty(LayeredOptions.INTERACTIVE_LAYOUT, true); rootNode.setProperty(LayeredOptions.INTERACTIVE_LAYOUT, true);
rootNode.setProperty(LayeredOptions.FEEDBACK_EDGES, true); rootNode.setProperty(LayeredOptions.FEEDBACK_EDGES, true);
rootNode.setProperty(LayeredOptions.EDGE_ROUTING, EdgeRouting.ORTHOGONAL); rootNode.setProperty(LayeredOptions.EDGE_ROUTING, EdgeRouting.ORTHOGONAL);
...@@ -126,6 +138,40 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -126,6 +138,40 @@ public class KielerAutoLayouter implements IAutoLayouter {
applyLayout(rootNode, element); applyLayout(rootNode, element);
} }
/** Reads the diagram direction from the model element or returns default */
private static Direction getDiagramDirection(IHierarchicElement diagram) {
if(diagram instanceof ILayoutedModelElement) {
OffsetOrientation offsetOrientation = OffsetOrientationUtils.getOffsetOrientation(
(ILayoutedModelElement)diagram, LayoutKeyConstants.DIAGRAM_OFFSET_ORIENTATION);
if(offsetOrientation != null) {
switch(offsetOrientation.getOrientation()) {
case NORTH:
return Direction.UP;
case EAST:
return Direction.RIGHT;
case SOUTH:
return Direction.DOWN;
case WEST:
return Direction.LEFT;
}
}
}
return Direction.RIGHT;
}
/** Reads the diagram offset from the model element or returns default */
private static int getDiagramOffset(IHierarchicElement diagram) {
if(diagram instanceof ILayoutedModelElement) {
OffsetOrientation offsetOrientation = OffsetOrientationUtils.getOffsetOrientation(
(ILayoutedModelElement)diagram, LayoutKeyConstants.DIAGRAM_OFFSET_ORIENTATION);
if(offsetOrientation != null) {
return offsetOrientation.getOffset();
}
}
return 0;
}
/** /**
* Truncates a given {@code float} value and decreases the value until it is a multiple of the * Truncates a given {@code float} value and decreases the value until it is a multiple of the
* grid size. * grid size.
...@@ -248,12 +294,18 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -248,12 +294,18 @@ public class KielerAutoLayouter implements IAutoLayouter {
break; break;
} }
// The parent component need not be aligned to the grid. The Y-coordinate if(side == PortSide.WEST || side == PortSide.EAST) {
// of the parent is truncated. Since elkPort.getY() is relative to the // The parent component need not be aligned to the grid. The Y-coordinate
// Y-coordinate of the parent, we need to correct when snapping to the grid. // of the parent is truncated. Since elkPort.getY() is relative to the
double parentGridOffset = elkPort.getParent().getY() % DEFAULT_GRID_SIZE; // Y-coordinate of the parent, we need to correct when snapping to the grid.
setStickyConnectorLayoutData((ILayoutedModelElement)connector, orientation, double parentGridOffset = elkPort.getParent().getY() % DEFAULT_GRID_SIZE;
truncateSnap2Grid(elkPort.getY() + parentGridOffset)); setStickyConnectorLayoutData((ILayoutedModelElement)connector, orientation,
truncateSnap2Grid(elkPort.getY() + parentGridOffset));
} else {
double parentGridOffset = elkPort.getParent().getX() % DEFAULT_GRID_SIZE;
setStickyConnectorLayoutData((ILayoutedModelElement)connector, orientation,
truncateSnap2Grid(elkPort.getX() + parentGridOffset));
}
} }
} }
...@@ -275,11 +327,15 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -275,11 +327,15 @@ public class KielerAutoLayouter implements IAutoLayouter {
* @param element * @param element
* The {@link IHierarchicElement} for which the {@link ElkNode} graph should be * The {@link IHierarchicElement} for which the {@link ElkNode} graph should be
* created * created
*
* @param tapeMeasure
* The {@link IAutoLayouterTapeMeasure} to estimate node sizes
* *
* @return A {@link ElkNode} graph with the same structure as the graph contained in the * @return A {@link ElkNode} graph with the same structure as the graph contained in the
* {@link IHierarchicElement}. * {@link IHierarchicElement}.
*/ */
private ElkNode createELKGraph(IHierarchicElement element) { private ElkNode createELKGraph(IHierarchicElement element,
IAutoLayouterTapeMeasure tapeMeasure) {
ElkNode rootNode = createGraph(); ElkNode rootNode = createGraph();
...@@ -289,8 +345,6 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -289,8 +345,6 @@ public class KielerAutoLayouter implements IAutoLayouter {
connectionsToElkEdges = new BasicEMap<IConnection, ElkEdge>(); connectionsToElkEdges = new BasicEMap<IConnection, ElkEdge>();
undirectedConnectorsToElkPorts = new BasicEMap<IConnector, ElkPort>(); undirectedConnectorsToElkPorts = new BasicEMap<IConnector, ElkPort>();
IAutoLayouterTapeMeasure tapeMeasure = new DiagramTapeMeasure();
// Create nodes // Create nodes
for(IHierarchicElement child : element.getContainedElements()) { for(IHierarchicElement child : element.getContainedElements()) {
if(!(child instanceof ILayoutedModelElement)) { if(!(child instanceof ILayoutedModelElement)) {
...@@ -400,6 +454,7 @@ public class KielerAutoLayouter implements IAutoLayouter { ...@@ -400,6 +454,7 @@ public class KielerAutoLayouter implements IAutoLayouter {
IConnector connector, ElkNode elkNode, EMap<IConnector, ElkPort> connectorsToelkPorts) { IConnector connector, ElkNode elkNode, EMap<IConnector, ElkPort> connectorsToelkPorts) {
ElkPort elkPort = createPort(elkNode); ElkPort elkPort = createPort(elkNode);
elkPort.setParent(elkNode); elkPort.setParent(elkNode);
elkPort.setWidth(DEFAULT_CONNECTOR_SIZE);
elkPort.setHeight(DEFAULT_CONNECTOR_SIZE); elkPort.setHeight(DEFAULT_CONNECTOR_SIZE);
if(connector instanceof INamedElement) { if(connector instanceof INamedElement) {
......
...@@ -36,18 +36,21 @@ public final class LayoutKeyConstants { ...@@ -36,18 +36,21 @@ public final class LayoutKeyConstants {
/** Points layout data key. */ /** Points layout data key. */
public static final String CONNECTION_POINTS = "points"; public static final String CONNECTION_POINTS = "points";
/** Sticky position layout data key */ /** Sticky position layout data key. */
public static final String CONNECTOR_POSITION = "cpos"; public static final String CONNECTOR_POSITION = "cpos";
/** Sticky dimension layout data key */ /** Sticky dimension layout data key. */
public static final String CONNECTOR_DIMENSION = "cdim"; public static final String CONNECTOR_DIMENSION = "cdim";
/** Sticky offset orientation layout data key */ /** Sticky offset orientation layout data key. */
public static final String CONNECTOR_OFFSET_ORIENTATION = "coffsetorient"; public static final String CONNECTOR_OFFSET_ORIENTATION = "coffsetorient";
/** Sticky offset layout data key */ /** Sticky offset layout data key. */
public static final String CONNECTOR_OFFSET = "coffset"; public static final String CONNECTOR_OFFSET = "coffset";
/** Sticky angle layout data key */ /** Sticky angle layout data key. */
public static final String CONNECTOR_ANGLE = "cangle"; public static final String CONNECTOR_ANGLE = "cangle";
/** Diagram offset orientation. */
public static final String DIAGRAM_OFFSET_ORIENTATION = "diagorient";
} }
/*-------------------------------------------------------------------------+
| Copyright 2018 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.layout;
import org.fortiss.tooling.base.model.element.IHierarchicElement;
/**
* {@link IAutoLayouterTapeMeasure} specialization for automatic vertical layout of models to be
* displayed in JavaFX-based editors.
*
* @author barner
*/
public class VerticalDiagramTapeMeasure extends DiagramTapeMeasure {
/** {@inheritDoc} */
@Override
public int getElementWidth(IHierarchicElement element) {
int width = super.getElementWidth(element);
return getElementLength(width, element);
}
}
DynamicList.java 786300e2e914826da239329d190abea1710478ea GREEN DynamicList.java 786300e2e914826da239329d190abea1710478ea GREEN
DynamicListContentProvider.java 817cba44f246a361207a88ef9a4e1869215803f7 GREEN DynamicListContentProvider.java 817cba44f246a361207a88ef9a4e1869215803f7 GREEN
DynamicStreamContentProvider.java f46e91400609cba54793dd240be0fe2aa0d5cced GREEN DynamicStreamContentProvider.java f46e91400609cba54793dd240be0fe2aa0d5cced GREEN
DynamicTextFieldTreeTableCell.java de24117e6f785b328f1ff62383626a0b4b54e8ff GREEN DynamicTextFieldTreeTableCell.java 62fa0c08b11d87e0eed41f84be85505c2740e75d GREEN
DynamicTreeContentProviderBase.java 91896b1fb5104d126544c44c1ff8c30f2a13a8d6 GREEN DynamicTreeContentProviderBase.java 91896b1fb5104d126544c44c1ff8c30f2a13a8d6 GREEN
DynamicTreeItem.java 7e81ea98038b5eca90df583e0268d4e8f37aaf25 GREEN DynamicTreeItem.java 7e81ea98038b5eca90df583e0268d4e8f37aaf25 GREEN
DynamicTreeItemBase.java d883066ecc181120302ca32f328538de7a45b093 GREEN DynamicTreeItemBase.java d883066ecc181120302ca32f328538de7a45b093 GREEN
DynamicTreeTableUIProviderBase.java 25592d4d2fb4a6cf904e8bdd98fc5138cbea5f17 GREEN DynamicTreeTableUIProviderBase.java 29aa753793ab90676d45e5b76b11f7b46ce02a97 GREEN
DynamicTreeTableViewer.java 77e9995a3bee37d57578dad9434a53c702128efa YELLOW DynamicTreeTableViewer.java 77e9995a3bee37d57578dad9434a53c702128efa YELLOW
DynamicTreeUIProviderBase.java 82d3c051213f0147f4c67ad247a08696cee73110 GREEN DynamicTreeUIProviderBase.java 82d3c051213f0147f4c67ad247a08696cee73110 GREEN
DynamicTreeViewer.java 33066062a82101cf28410e4d04f85bb9c24251db GREEN DynamicTreeViewer.java 33066062a82101cf28410e4d04f85bb9c24251db GREEN
......
...@@ -42,11 +42,21 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T, ...@@ -42,11 +42,21 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
/** The current entered text in the TextField. */ /** The current entered text in the TextField. */
private String currentInput = ""; private String currentInput = "";
/** The UIProvider of the editor in which this cell is embedded in. */
DynamicTreeTableUIProviderBase<T> uiProvider;
/** The column index, this cell is embedded in. */
int columnIndex;
/** /**
* Constructor. * Constructor.
*/ */
public DynamicTextFieldTreeTableCell() { public DynamicTextFieldTreeTableCell(DynamicTreeTableUIProviderBase<T> uiProvider,
int columnIndex) {
this(new DefaultStringConverter()); this(new DefaultStringConverter());
this.uiProvider = uiProvider;
this.columnIndex = columnIndex;
} }
/** /**
...@@ -103,19 +113,28 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T, ...@@ -103,19 +113,28 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
// Remember currently edited element. // Remember currently edited element.
currentlyEditedElement = currentEntry; currentlyEditedElement = currentEntry;
String initialEditorContent =
uiProvider.getInitialEditorContent(currentlyEditedElement, columnIndex);
// Reset currentInput buffer for the new element. // Reset currentInput buffer for the new element.
currentInput = ""; currentInput = initialEditorContent;
// We keep the current input in the buffer variable currentInput to be able to
// use it during unintended cancel options. See cancelEdit().
TextField textField = (TextField)getGraphic();
if(textField != null) {
textField.setOnKeyReleased(event -> {
currentInput = textField.getText();
});
textField.setText(initialEditorContent);
}
} else { } else {
// Reset buffer
currentlyEditedElement = null; currentlyEditedElement = null;
} currentInput = null;
// We keep the current input in the buffer variable currentInput to be able to
// use it during unintended cancel options. See cancelEdit().
TextField textField = (TextField)getGraphic();
if(textField != null) {
textField.setOnKeyReleased(event -> {
currentInput = textField.getText();
});
} }
} }
...@@ -133,10 +152,16 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T, ...@@ -133,10 +152,16 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
// Set the current TextField value if intended. // Set the current TextField value if intended.
if(currentlyEditedElement != null) { if(currentlyEditedElement != null) {
setValueOnLeavingCell(currentlyEditedElement, currentInput); String initialEditorContent =
uiProvider.getInitialEditorContent(currentlyEditedElement, columnIndex);
if(!currentInput.equals(initialEditorContent)) {
setValueOnLeavingCell(currentlyEditedElement, currentInput);
}
currentlyEditedElement = null; currentlyEditedElement = null;
} }
} }
getTreeTableView().refresh();
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
...@@ -64,6 +64,19 @@ public abstract class DynamicTreeTableUIProviderBase<T> { ...@@ -64,6 +64,19 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
return ""; return "";
} }
/**
* Determines, which {@link String} is in text editor cells when stating to edit.
*
* @param element
* The element for which eitr content shall be provided
* @param column
* The column index for which the content shall be provided
* @return The {@link String} which shal be displayed in the editor.
*/
public String getInitialEditorContent(T element, int column) {
return getLabel(element, column);
}
/** /**
* @param element * @param element
* the element to be displayed in the current row * the element to be displayed in the current row
...@@ -534,27 +547,29 @@ public abstract class DynamicTreeTableUIProviderBase<T> { ...@@ -534,27 +547,29 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
*/ */
public void applyToTextColumn(int columnIndex, TreeTableColumn<T, String> column) { public void applyToTextColumn(int columnIndex, TreeTableColumn<T, String> column) {
column.setCellFactory(ttColumn -> { column.setCellFactory(ttColumn -> {
DynamicTextFieldTreeTableCell<T> cell = new DynamicTextFieldTreeTableCell<T>() { DynamicTextFieldTreeTableCell<T> cell =
new DynamicTextFieldTreeTableCell<T>(this, columnIndex) {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
protected boolean canEdit(T element) { protected boolean canEdit(T element) {
return DynamicTreeTableUIProviderBase.this.isEditable(columnIndex, element); return DynamicTreeTableUIProviderBase.this.isEditable(columnIndex,
} element);
}
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
protected void setValueOnLeavingCell(T element, String currentValue) { protected void setValueOnLeavingCell(T element, String currentValue) {
updateValue(element, columnIndex, currentValue); updateValue(element, columnIndex, currentValue);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void updateItem(String item, boolean empty) { public void updateItem(String item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
styleCell(this, columnIndex); styleCell(this, columnIndex);
} }
}; };
styleCell(cell, columnIndex); styleCell(cell, columnIndex);
......
...@@ -90,8 +90,8 @@ public abstract class CircularContentVisualBase extends ContentVisualBase { ...@@ -90,8 +90,8 @@ public abstract class CircularContentVisualBase extends ContentVisualBase {
double angleRad = toRadians(angleDeg); double angleRad = toRadians(angleDeg);
double nx = cos(angleRad); double nx = cos(angleRad);
double ny = sin(angleRad); double ny = sin(angleRad);
double x = pb.getMinX() + w2 + radius * nx; double x = w2 + radius * nx;
double y = pb.getMinY() + h2 + radius * ny; double y = h2 + radius * ny;
return new DiagramCoordinate(x, y); return new DiagramCoordinate(x, y);
} }
......
documentation.html c61291c1f8f77b6a418ba24cd29c2cfa7f661696 GREEN documentation.html 99fa035c6b4de639d7ca4cd73380a02d3e364e80 GREEN
...@@ -15,11 +15,24 @@ ...@@ -15,11 +15,24 @@
<p>This plugin contains the basic functionality of reuse in AF3 projects. <p>This plugin contains the basic functionality of reuse in AF3 projects.
With it a user can create reuse libraries that are stored in a separate local project. With it a user can create reuse libraries that are stored in a separate local project.
These libraries can store supported reuse elements (which are standard AF3 elements to These libraries can store supported reuse elements (which are standard AF3 elements to
which a reuse specification is added). The stored reuse elements are displayed in the model which a reuse specification is added; see below). The stored reuse elements are displayed in the model
elements view and can be drag & dropped from there in AF3 projects. They are still linked elements view and can be drag & dropped from there in AF3 projects. They are still linked
with their libraries, which is why the elements can be updated at any time from the library with their libraries, which is why the elements can be updated at any time from the library
and vice versa (update the original element inside the library). Currently supported AF3 and vice versa (update the original element inside the library). Currently supported AF3
elements for reuse are: components, requirements and entries of data dictionaries.</p> elements for reuse are: components, tasks, requirements and entries of data dictionaries (functions, structures, enumerations).</p>
<p>If an AF3 element supports reuse libraries, it can get a reuse specification (not directly visible in AF3).
As soon as it has at least one reuse specification, the AF3 element is now a reuse element. It looks still
like the usual AF3 element and can also be used like before, but it has now at least one reference to a reuse
library via this reuse specification (or several reuse libraries if it has several reuse specifications).
If an AF3 element has a reuse specification, it means that an identical AF3 element ("deep copy") exists now
in this referenced reuse library. It is now possible to reuse this AF3 element from the reuse library and
insert it again in the same project but also in other projects of the same workspace or even of other workspaces
(and exchange updates). </p>
<p>Through the UUIDs and the reuse specifications it is ensured that you can only propagate modifications
between (reuse) elements that are connected due to their (reuse) origin. </p>
<h1><font size="5" style="font-size: 20pt">Package description</font></h1> <h1><font size="5" style="font-size: 20pt">Package description</font></h1>
<p>The plugin contains the following packages (besides standard ones): <p>The plugin contains the following packages (besides standard ones):
......
CrossFeatureConstraintPropertySectionBase.java 37e772fb3471f85320170d373cbe2f319c350655 GREEN CrossFeatureConstraintPropertySectionBase.java 37e772fb3471f85320170d373cbe2f319c350655 GREEN
FeaturePropertySectionBase.java 2ac0a6a56ea4755852fd14a9b5df81dff4a5dc7e GREEN FeaturePropertySectionBase.java 2ac0a6a56ea4755852fd14a9b5df81dff4a5dc7e GREEN
HasPresenceConditionPropertySectionBase.java 1f3ed94e15529450b73c8c8772cef69b8e075260 GREEN HasPresenceConditionPropertySectionBase.java ef300f0d9294d76f5d80e45b8cc0d94c24586a24 GREEN
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
package org.fortiss.tooling.ext.variability.ui.properties; package org.fortiss.tooling.ext.variability.ui.properties;
import static org.eclipse.swt.SWT.NONE; import static org.eclipse.swt.SWT.NONE;
import static org.fortiss.tooling.ext.variability.ui.util.VariabilityViewUtils.isVariabilityViewActive;
import static org.fortiss.tooling.ext.variability.util.VariabilityUtils.getPresenceCondition; import static org.fortiss.tooling.ext.variability.util.VariabilityUtils.getPresenceCondition;
import static org.fortiss.tooling.ext.variability.util.VariabilityUtils.setPresenceCondition; import static org.fortiss.tooling.ext.variability.util.VariabilityUtils.setPresenceCondition;
import static org.fortiss.tooling.kernel.ui.util.WidgetsFactory.createTextWithUndo; import static org.fortiss.tooling.kernel.ui.util.WidgetsFactory.createTextWithUndo;
...@@ -60,15 +59,13 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase ...@@ -60,15 +59,13 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
protected void setSectionInput(Object input) { protected void setSectionInput(Object input) {
if(input instanceof IModelElement) { if(input instanceof IModelElement) {
this.inputElem = (IModelElement)input; this.inputElem = (IModelElement)input;
if(isVariabilityViewActive()) { PresenceCondition pc = getPresenceCondition(inputElem);
PresenceCondition pc = getPresenceCondition(inputElem); if(pc != null) {
if(pc != null) { pcText.setText(pc.getStringRepresentation());
pcText.setText(pc.getStringRepresentation()); } else {
} else { pcText.setText("");
pcText.setText("");
}
createPcFieldAssist();
} }
createPcFieldAssist();
} else { } else {
this.inputElem = null; this.inputElem = null;
} }
...@@ -76,7 +73,7 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase ...@@ -76,7 +73,7 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
/** Creates and sets up the field assist. */ /** Creates and sets up the field assist. */
protected void createPcFieldAssist() { protected void createPcFieldAssist() {
if(pcText != null && inputElem != null && isVariabilityViewActive()) { if(pcText != null && inputElem != null) {
if(pcFieldAssist != null) { if(pcFieldAssist != null) {
pcFieldAssist.setProposalProvider(new PresenceConditionProposalProvider(inputElem)); pcFieldAssist.setProposalProvider(new PresenceConditionProposalProvider(inputElem));
} else { } else {
...@@ -104,11 +101,9 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase ...@@ -104,11 +101,9 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
} }
}); });
if(!isVariabilityViewActive()) { pcLabel.setVisible(false);
pcLabel.setVisible(false); pcText.setVisible(false);
pcText.setVisible(false); pcText.setEnabled(false);
pcText.setEnabled(false);
}
} }
/** /**
...@@ -127,10 +122,6 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase ...@@ -127,10 +122,6 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
public void refresh() { public void refresh() {
super.refresh(); super.refresh();
if(!isVariabilityViewActive()) {
return;
}
if(inputElem != null) { if(inputElem != null) {
pcLabel.setVisible(true); pcLabel.setVisible(true);
pcText.setVisible(true); pcText.setVisible(true);
......
PresenceConditionProposalProvider.java 0429296a1742618d241a0b5f2e399198b0733651 GREEN PresenceConditionProposalProvider.java bd67b19e724cfa777611ec7783bd004407a7911c GREEN
PresenceConditionToStringConverter.java 1854a6474cf37deebe8b8b7c5f28c5e45a541bf8 GREEN PresenceConditionToStringConverter.java 1854a6474cf37deebe8b8b7c5f28c5e45a541bf8 GREEN
StringToPresenceConditionConverter.java 0d64415d229726a077a242c5c1f487f484df477c GREEN StringToPresenceConditionConverter.java 0d64415d229726a077a242c5c1f487f484df477c GREEN
VariabilityViewUtils.java 5846115ef3e0cc828ac6d868c00800146bcfac1c GREEN
...@@ -18,6 +18,7 @@ package org.fortiss.tooling.ext.variability.ui.util; ...@@ -18,6 +18,7 @@ package org.fortiss.tooling.ext.variability.ui.util;
import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.fortiss.variability.util.VariabilityUtils.PRESENCE_CONDITIONS_KEYWORDS;
import static org.fortiss.variability.util.VariabilityUtilsInternal.getAllElementsFromSameContainmentTree; import static org.fortiss.variability.util.VariabilityUtilsInternal.getAllElementsFromSameContainmentTree;
import java.util.List; import java.util.List;
...@@ -61,7 +62,8 @@ public class PresenceConditionProposalProvider extends ProposalProviderBase { ...@@ -61,7 +62,8 @@ public class PresenceConditionProposalProvider extends ProposalProviderBase {
List<String> stringLiterals = literals.stream().map(l -> l.getName()).collect(toList()); List<String> stringLiterals = literals.stream().map(l -> l.getName()).collect(toList());
stringLiterals.addAll(asList("DEFAULT", "NOT", "AND", "OR")); final String[] keywords = PRESENCE_CONDITIONS_KEYWORDS.split("\\|");
stringLiterals.addAll(asList(keywords));
List<String> proposals = List<String> proposals =
stringLiterals.stream().filter(n -> n.startsWith(currentWord)).collect(toList()); stringLiterals.stream().filter(n -> n.startsWith(currentWord)).collect(toList());
......
VariabilityUtils.java e5883398e22b9c818d098403795f359455613c11 GREEN VariabilityUtils.java ccbcc8a13557a107608130e25880f9523b84cfba GREEN
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package org.fortiss.tooling.ext.variability.util; package org.fortiss.tooling.ext.variability.util;
import static org.fortiss.tooling.ext.variability.model.VariabilityModelElementFactory.createOptionalVariationPointSpecification; import static org.fortiss.tooling.ext.variability.model.VariabilityModelElementFactory.createOptionalVariationPointSpecification;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstChildWithType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf; import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EObject;
...@@ -23,6 +24,7 @@ import org.fortiss.tooling.base.model.element.IModelElement; ...@@ -23,6 +24,7 @@ import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.ext.variability.model.DeactivationSpecification; import org.fortiss.tooling.ext.variability.model.DeactivationSpecification;
import org.fortiss.tooling.ext.variability.model.OptionalVariationPointSpecification; import org.fortiss.tooling.ext.variability.model.OptionalVariationPointSpecification;
import org.fortiss.tooling.kernel.service.ICommandStackService; import org.fortiss.tooling.kernel.service.ICommandStackService;
import org.fortiss.variability.model.features.AbstractFeatureModel;
import org.fortiss.variability.model.presence.PresenceCondition; import org.fortiss.variability.model.presence.PresenceCondition;
import org.fortiss.variability.presence.compiler.PresenceConditionCompiler; import org.fortiss.variability.presence.compiler.PresenceConditionCompiler;
...@@ -55,6 +57,31 @@ public class VariabilityUtils { ...@@ -55,6 +57,31 @@ public class VariabilityUtils {
return dSpec != null; return dSpec != null;
} }
/**
* Checks for the given {@link EObject} whether it can contain any variability.
*
* Note, that currently this method checks for the existence of an {@link AbstractFeatureModel}
* in the project, only.
*
* @param element
* The {@link EObject} to check for possible variability.
* @return 'true' if the given element can contain any variability.
*/
public static boolean canContainVariability(EObject element) {
if(element instanceof AbstractFeatureModel) {
return true;
}
// Find the root container (usually a FileProject)
EObject topLevelElem = element;
while(topLevelElem.eContainer() != null) {
topLevelElem = topLevelElem.eContainer();
}
// Check whether this root container contains any AbstractFeatureModel.
return getFirstChildWithType(topLevelElem, AbstractFeatureModel.class) != null;
}
/** /**
* Checks whether the given {@link IModelElement} contains a non-empty presence * Checks whether the given {@link IModelElement} contains a non-empty presence
* condition. I.e. whether it is actually really optional. * condition. I.e. whether it is actually really optional.
......
FeatureModelTransformationUtils.java b38702296dcb48ff311b382bb9c05d2590e2dfac GREEN FeatureModelTransformationUtils.java b38702296dcb48ff311b382bb9c05d2590e2dfac GREEN
Pair.java 2dfd7dc65f7b9ba09a120f1a6058d1e8e9556a37 GREEN Pair.java 2dfd7dc65f7b9ba09a120f1a6058d1e8e9556a37 GREEN
VariabilityUtils.java 1d84b70a1f26ee7b9df697fdc96b8e226762cb5d GREEN VariabilityUtils.java 66a727bdb58715dc7b1bd0ce320bd647f374f7d6 GREEN
VariabilityUtilsInternal.java 43d150214dd32e71f163bece306ad7661c2d5b4a GREEN VariabilityUtilsInternal.java 9c781a47513bb0c4ddcd13be1c27d62b70f25998 GREEN
...@@ -17,7 +17,6 @@ package org.fortiss.variability.util; ...@@ -17,7 +17,6 @@ package org.fortiss.variability.util;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.fortiss.variability.model.VariabilityModelElementFactory.createFeatureConfigurationForFeature; import static org.fortiss.variability.model.VariabilityModelElementFactory.createFeatureConfigurationForFeature;
import static org.fortiss.variability.util.VariabilityUtilsInternal.FEATURE_LITERAL_LEGAL_CHAR_REGEX;
import static org.fortiss.variability.util.VariabilityUtilsInternal.getAllReferences; import static org.fortiss.variability.util.VariabilityUtilsInternal.getAllReferences;
import static org.fortiss.variability.util.VariabilityUtilsInternal.getParentsWithType; import static org.fortiss.variability.util.VariabilityUtilsInternal.getParentsWithType;
...@@ -43,6 +42,17 @@ import org.fortiss.variability.model.presence.PresenceConditionTerm; ...@@ -43,6 +42,17 @@ import org.fortiss.variability.model.presence.PresenceConditionTerm;
* @author bayha * @author bayha
*/ */
public class VariabilityUtils { public class VariabilityUtils {
/**
* Regex, describing all legal characters that might be in a feature literal
* name.
*/
public final static String FEATURE_LITERAL_LEGAL_CHAR_REGEX =
"[a-zA-Z\\d\\$&\\[\\]_\\-\\+@/\\\\,\\.=]";
/** Regex, describing all keywords. */
public final static String PRESENCE_CONDITIONS_KEYWORDS = "OR|AND|NOT|DEFAULT";
/** /**
* Renames the given literal reference and updates the StringReprtesentations of * Renames the given literal reference and updates the StringReprtesentations of
* the {@link PresenceCondition}s, that use it as a literal. * the {@link PresenceCondition}s, that use it as a literal.
...@@ -156,8 +166,11 @@ public class VariabilityUtils { ...@@ -156,8 +166,11 @@ public class VariabilityUtils {
* @return Whether the given name is compatible with the presence condition systax. * @return Whether the given name is compatible with the presence condition systax.
*/ */
public static boolean isNameLegalInPresenceCondition(String literalName) { public static boolean isNameLegalInPresenceCondition(String literalName) {
if(literalName.matches(PRESENCE_CONDITIONS_KEYWORDS)) {
return false;
}
return literalName.matches(FEATURE_LITERAL_LEGAL_CHAR_REGEX + "*"); return literalName.matches(FEATURE_LITERAL_LEGAL_CHAR_REGEX + "*");
// TODO (#3862): Check for keywords.
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment