Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • af3/kernel
  • diewald/kernel
2 results
Show changes
Commits on Source (30)
Showing
with 295 additions and 113 deletions
DefaultLayoutConstants.java 10ba39d25701f7aff7ef545ec69e42a6117ae7b1 GREEN
DiagramTapeMeasure.java 2aaf2d0765d0ba5292ec2468d0d04d52f36370a6 GREEN
DiagramTapeMeasure.java 4ac1310faa82746f0a66e684677588cbcdfcdde9 GREEN
HorizontalDiagramTapeMeasure.java 98bcb18ed5171c5ff191225cf21a305d5ef06440 GREEN
IAutoLayouter.java 8f22d3813491159151a8753dd683a5043554fb67 GREEN
IAutoLayouterTapeMeasure.java 5ef5c7d0a124714d582de283d3915d8b4bf7fda8 GREEN
KielerAutoLayouter.java 94de655f6abf6d7d6d747f96de07e0be50588abd GREEN
LayoutKeyConstants.java 1e35b73f26f2691ef80fa885e4c5fc6c6a60bd05 GREEN
KielerAutoLayouter.java 9cc7943ff90c55851b81bf7c4cde7b279992e925 GREEN
LayoutKeyConstants.java 00d19473f69e2e9bdd541d41e737d2c99a0fd281 GREEN
VerticalDiagramTapeMeasure.java 0b83af2189b4f55d0dfe121ae4e86cee064c5164 GREEN
......@@ -35,18 +35,16 @@ import javafx.geometry.Bounds;
import javafx.scene.text.Text;
/**
* {@link IAutoLayouterTapeMeasure} specialization to for automatic layout of models to be displayed
* in JavaFX-based editors.
* {@link IAutoLayouterTapeMeasure} base class of models to be displayed in JavaFX-based editors.
*
* @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
* {@code null}).
*/
private Bounds getTextExtent(IModelElement element) {
protected Bounds getTextExtent(IModelElement element) {
if(!(element instanceof INamedElement)) {
return null;
}
......@@ -55,6 +53,19 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure {
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} */
@Override
public int getElementWidth(IHierarchicElement element) {
......@@ -73,12 +84,7 @@ public class DiagramTapeMeasure implements IAutoLayouterTapeMeasure {
@Override
public int getElementHeight(IHierarchicElement element) {
Dimension dimension = getNodeSize((ILayoutedModelElement)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, dimension.getHeight());
return dimension.getHeight();
}
/** {@inheritDoc} */
......
/*--------------------------------------------------------------------------+
| |
| Copyright 2022 fortiss GmbH |
/*-------------------------------------------------------------------------+
| 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. |
......@@ -14,26 +13,23 @@
| See the License for the specific language governing permissions and |
| 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);
/**
* 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();
return getElementLength(height, element);
}
}
......@@ -35,6 +35,7 @@ import org.eclipse.elk.alg.layered.options.LayeredMetaDataProvider;
import org.eclipse.elk.alg.layered.options.LayeredOptions;
import org.eclipse.elk.core.AbstractLayoutProvider;
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.EdgeRouting;
import org.eclipse.elk.core.options.PortLabelPlacement;
......@@ -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.ILayoutData;
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.impl.PointsImpl;
import org.fortiss.tooling.base.utils.OffsetOrientationUtils;
import org.fortiss.tooling.kernel.model.INamedElement;
/**
......@@ -105,9 +108,18 @@ public class KielerAutoLayouter implements IAutoLayouter {
LayoutMetaDataService.getInstance()
.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.FEEDBACK_EDGES, true);
rootNode.setProperty(LayeredOptions.EDGE_ROUTING, EdgeRouting.ORTHOGONAL);
......@@ -126,6 +138,40 @@ public class KielerAutoLayouter implements IAutoLayouter {
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
* grid size.
......@@ -248,12 +294,18 @@ public class KielerAutoLayouter implements IAutoLayouter {
break;
}
// The parent component need not be aligned to the grid. The Y-coordinate
// of the parent is truncated. Since elkPort.getY() is relative to the
// Y-coordinate of the parent, we need to correct when snapping to the grid.
double parentGridOffset = elkPort.getParent().getY() % DEFAULT_GRID_SIZE;
setStickyConnectorLayoutData((ILayoutedModelElement)connector, orientation,
truncateSnap2Grid(elkPort.getY() + parentGridOffset));
if(side == PortSide.WEST || side == PortSide.EAST) {
// The parent component need not be aligned to the grid. The Y-coordinate
// of the parent is truncated. Since elkPort.getY() is relative to the
// Y-coordinate of the parent, we need to correct when snapping to the grid.
double parentGridOffset = elkPort.getParent().getY() % DEFAULT_GRID_SIZE;
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 {
* @param element
* The {@link IHierarchicElement} for which the {@link ElkNode} graph should be
* 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
* {@link IHierarchicElement}.
*/
private ElkNode createELKGraph(IHierarchicElement element) {
private ElkNode createELKGraph(IHierarchicElement element,
IAutoLayouterTapeMeasure tapeMeasure) {
ElkNode rootNode = createGraph();
......@@ -289,8 +345,6 @@ public class KielerAutoLayouter implements IAutoLayouter {
connectionsToElkEdges = new BasicEMap<IConnection, ElkEdge>();
undirectedConnectorsToElkPorts = new BasicEMap<IConnector, ElkPort>();
IAutoLayouterTapeMeasure tapeMeasure = new DiagramTapeMeasure();
// Create nodes
for(IHierarchicElement child : element.getContainedElements()) {
if(!(child instanceof ILayoutedModelElement)) {
......@@ -400,6 +454,7 @@ public class KielerAutoLayouter implements IAutoLayouter {
IConnector connector, ElkNode elkNode, EMap<IConnector, ElkPort> connectorsToelkPorts) {
ElkPort elkPort = createPort(elkNode);
elkPort.setParent(elkNode);
elkPort.setWidth(DEFAULT_CONNECTOR_SIZE);
elkPort.setHeight(DEFAULT_CONNECTOR_SIZE);
if(connector instanceof INamedElement) {
......
......@@ -36,18 +36,21 @@ public final class LayoutKeyConstants {
/** Points layout data key. */
public static final String CONNECTION_POINTS = "points";
/** Sticky position layout data key */
/** Sticky position layout data key. */
public static final String CONNECTOR_POSITION = "cpos";
/** Sticky dimension layout data key */
/** Sticky dimension layout data key. */
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";
/** Sticky offset layout data key */
/** Sticky offset layout data key. */
public static final String CONNECTOR_OFFSET = "coffset";
/** Sticky angle layout data key */
/** Sticky angle layout data key. */
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
DynamicListContentProvider.java 817cba44f246a361207a88ef9a4e1869215803f7 GREEN
DynamicStreamContentProvider.java f46e91400609cba54793dd240be0fe2aa0d5cced GREEN
DynamicTextFieldTreeTableCell.java de24117e6f785b328f1ff62383626a0b4b54e8ff GREEN
DynamicTextFieldTreeTableCell.java 62fa0c08b11d87e0eed41f84be85505c2740e75d GREEN
DynamicTreeContentProviderBase.java 91896b1fb5104d126544c44c1ff8c30f2a13a8d6 GREEN
DynamicTreeItem.java 7e81ea98038b5eca90df583e0268d4e8f37aaf25 GREEN
DynamicTreeItemBase.java d883066ecc181120302ca32f328538de7a45b093 GREEN
DynamicTreeTableUIProviderBase.java 25592d4d2fb4a6cf904e8bdd98fc5138cbea5f17 GREEN
DynamicTreeTableUIProviderBase.java 29aa753793ab90676d45e5b76b11f7b46ce02a97 GREEN
DynamicTreeTableViewer.java 77e9995a3bee37d57578dad9434a53c702128efa YELLOW
DynamicTreeUIProviderBase.java 82d3c051213f0147f4c67ad247a08696cee73110 GREEN
DynamicTreeViewer.java 33066062a82101cf28410e4d04f85bb9c24251db GREEN
......
......@@ -42,11 +42,21 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
/** The current entered text in the TextField. */
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.
*/
public DynamicTextFieldTreeTableCell() {
public DynamicTextFieldTreeTableCell(DynamicTreeTableUIProviderBase<T> uiProvider,
int columnIndex) {
this(new DefaultStringConverter());
this.uiProvider = uiProvider;
this.columnIndex = columnIndex;
}
/**
......@@ -103,19 +113,28 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
// Remember currently edited element.
currentlyEditedElement = currentEntry;
String initialEditorContent =
uiProvider.getInitialEditorContent(currentlyEditedElement, columnIndex);
// 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 {
// Reset buffer
currentlyEditedElement = 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();
});
currentInput = null;
}
}
......@@ -133,10 +152,16 @@ public class DynamicTextFieldTreeTableCell<T> extends TextFieldTreeTableCell<T,
// Set the current TextField value if intended.
if(currentlyEditedElement != null) {
setValueOnLeavingCell(currentlyEditedElement, currentInput);
String initialEditorContent =
uiProvider.getInitialEditorContent(currentlyEditedElement, columnIndex);
if(!currentInput.equals(initialEditorContent)) {
setValueOnLeavingCell(currentlyEditedElement, currentInput);
}
currentlyEditedElement = null;
}
}
getTreeTableView().refresh();
}
/** {@inheritDoc} */
......
......@@ -64,6 +64,19 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
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
* the element to be displayed in the current row
......@@ -534,27 +547,29 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
*/
public void applyToTextColumn(int columnIndex, TreeTableColumn<T, String> column) {
column.setCellFactory(ttColumn -> {
DynamicTextFieldTreeTableCell<T> cell = new DynamicTextFieldTreeTableCell<T>() {
DynamicTextFieldTreeTableCell<T> cell =
new DynamicTextFieldTreeTableCell<T>(this, columnIndex) {
/** {@inheritDoc} */
@Override
protected boolean canEdit(T element) {
return DynamicTreeTableUIProviderBase.this.isEditable(columnIndex, element);
}
/** {@inheritDoc} */
@Override
protected boolean canEdit(T element) {
return DynamicTreeTableUIProviderBase.this.isEditable(columnIndex,
element);
}
/** {@inheritDoc} */
@Override
protected void setValueOnLeavingCell(T element, String currentValue) {
updateValue(element, columnIndex, currentValue);
}
/** {@inheritDoc} */
@Override
protected void setValueOnLeavingCell(T element, String currentValue) {
updateValue(element, columnIndex, currentValue);
}
/** {@inheritDoc} */
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
styleCell(this, columnIndex);
}
};
/** {@inheritDoc} */
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
styleCell(this, columnIndex);
}
};
styleCell(cell, columnIndex);
......
......@@ -90,8 +90,8 @@ public abstract class CircularContentVisualBase extends ContentVisualBase {
double angleRad = toRadians(angleDeg);
double nx = cos(angleRad);
double ny = sin(angleRad);
double x = pb.getMinX() + w2 + radius * nx;
double y = pb.getMinY() + h2 + radius * ny;
double x = w2 + radius * nx;
double y = h2 + radius * ny;
return new DiagramCoordinate(x, y);
}
......
documentation.html c61291c1f8f77b6a418ba24cd29c2cfa7f661696 GREEN
documentation.html 99fa035c6b4de639d7ca4cd73380a02d3e364e80 GREEN
......@@ -15,11 +15,24 @@
<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.
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
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
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>
<p>The plugin contains the following packages (besides standard ones):
......
CrossFeatureConstraintPropertySectionBase.java 37e772fb3471f85320170d373cbe2f319c350655 GREEN
FeaturePropertySectionBase.java 2ac0a6a56ea4755852fd14a9b5df81dff4a5dc7e GREEN
HasPresenceConditionPropertySectionBase.java 1f3ed94e15529450b73c8c8772cef69b8e075260 GREEN
HasPresenceConditionPropertySectionBase.java ef300f0d9294d76f5d80e45b8cc0d94c24586a24 GREEN
......@@ -17,7 +17,6 @@
package org.fortiss.tooling.ext.variability.ui.properties;
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.setPresenceCondition;
import static org.fortiss.tooling.kernel.ui.util.WidgetsFactory.createTextWithUndo;
......@@ -60,15 +59,13 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
protected void setSectionInput(Object input) {
if(input instanceof IModelElement) {
this.inputElem = (IModelElement)input;
if(isVariabilityViewActive()) {
PresenceCondition pc = getPresenceCondition(inputElem);
if(pc != null) {
pcText.setText(pc.getStringRepresentation());
} else {
pcText.setText("");
}
createPcFieldAssist();
PresenceCondition pc = getPresenceCondition(inputElem);
if(pc != null) {
pcText.setText(pc.getStringRepresentation());
} else {
pcText.setText("");
}
createPcFieldAssist();
} else {
this.inputElem = null;
}
......@@ -76,7 +73,7 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
/** Creates and sets up the field assist. */
protected void createPcFieldAssist() {
if(pcText != null && inputElem != null && isVariabilityViewActive()) {
if(pcText != null && inputElem != null) {
if(pcFieldAssist != null) {
pcFieldAssist.setProposalProvider(new PresenceConditionProposalProvider(inputElem));
} else {
......@@ -104,11 +101,9 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
}
});
if(!isVariabilityViewActive()) {
pcLabel.setVisible(false);
pcText.setVisible(false);
pcText.setEnabled(false);
}
pcLabel.setVisible(false);
pcText.setVisible(false);
pcText.setEnabled(false);
}
/**
......@@ -127,10 +122,6 @@ public class HasPresenceConditionPropertySectionBase extends PropertySectionBase
public void refresh() {
super.refresh();
if(!isVariabilityViewActive()) {
return;
}
if(inputElem != null) {
pcLabel.setVisible(true);
pcText.setVisible(true);
......
PresenceConditionProposalProvider.java 0429296a1742618d241a0b5f2e399198b0733651 GREEN
PresenceConditionProposalProvider.java bd67b19e724cfa777611ec7783bd004407a7911c GREEN
PresenceConditionToStringConverter.java 1854a6474cf37deebe8b8b7c5f28c5e45a541bf8 GREEN
StringToPresenceConditionConverter.java 0d64415d229726a077a242c5c1f487f484df477c GREEN
VariabilityViewUtils.java 5846115ef3e0cc828ac6d868c00800146bcfac1c GREEN
......@@ -18,6 +18,7 @@ package org.fortiss.tooling.ext.variability.ui.util;
import static java.util.Arrays.asList;
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 java.util.List;
......@@ -61,7 +62,8 @@ public class PresenceConditionProposalProvider extends ProposalProviderBase {
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 =
stringLiterals.stream().filter(n -> n.startsWith(currentWord)).collect(toList());
......
VariabilityUtils.java e5883398e22b9c818d098403795f359455613c11 GREEN
VariabilityUtils.java ccbcc8a13557a107608130e25880f9523b84cfba GREEN
......@@ -16,6 +16,7 @@
package org.fortiss.tooling.ext.variability.util;
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 org.eclipse.emf.ecore.EObject;
......@@ -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.OptionalVariationPointSpecification;
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.presence.compiler.PresenceConditionCompiler;
......@@ -55,6 +57,31 @@ public class VariabilityUtils {
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
* condition. I.e. whether it is actually really optional.
......
FeatureModelTransformationUtils.java b38702296dcb48ff311b382bb9c05d2590e2dfac GREEN
Pair.java 2dfd7dc65f7b9ba09a120f1a6058d1e8e9556a37 GREEN
VariabilityUtils.java 1d84b70a1f26ee7b9df697fdc96b8e226762cb5d GREEN
VariabilityUtilsInternal.java 43d150214dd32e71f163bece306ad7661c2d5b4a GREEN
VariabilityUtils.java 66a727bdb58715dc7b1bd0ce320bd647f374f7d6 GREEN
VariabilityUtilsInternal.java 9c781a47513bb0c4ddcd13be1c27d62b70f25998 GREEN
......@@ -17,7 +17,6 @@ package org.fortiss.variability.util;
import static java.util.stream.Collectors.toList;
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.getParentsWithType;
......@@ -43,6 +42,17 @@ import org.fortiss.variability.model.presence.PresenceConditionTerm;
* @author bayha
*/
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
* the {@link PresenceCondition}s, that use it as a literal.
......@@ -156,8 +166,11 @@ public class VariabilityUtils {
* @return Whether the given name is compatible with the presence condition systax.
*/
public static boolean isNameLegalInPresenceCondition(String literalName) {
if(literalName.matches(PRESENCE_CONDITIONS_KEYWORDS)) {
return false;
}
return literalName.matches(FEATURE_LITERAL_LEGAL_CHAR_REGEX + "*");
// TODO (#3862): Check for keywords.
}
/**
......