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 (55)
Showing
with 364 additions and 160 deletions
......@@ -2,10 +2,10 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tooling Base UI
Bundle-SymbolicName: org.fortiss.tooling.base.ui;singleton:=true
Bundle-Version: 2.19.0.qualifier
Bundle-Version: 2.20.0.qualifier
Bundle-Activator: org.fortiss.tooling.base.ui.ToolingBaseUIActivator
Require-Bundle: org.fortiss.tooling.base;bundle-version="2.19.0";visibility:=reexport,
org.fortiss.tooling.kernel.ui;bundle-version="2.19.0";visibility:=reexport,
Require-Bundle: org.fortiss.tooling.base;bundle-version="2.20.0";visibility:=reexport,
org.fortiss.tooling.kernel.ui;bundle-version="2.20.0";visibility:=reexport,
org.eclipse.swt,
org.fortiss.tooling.common.ui
Bundle-ActivationPolicy: lazy
......
AnnotationFxViewPart.java ca1548c49aa3842a9436262531464ba345b83688 GREEN
AnnotationTreeTableUIProvider.java 4d9ea9f5267e1a04985c5f67e748f34474c97e0f GREEN
AnnotationViewFXController.java 87d70534cde579cbd5f6470e729783306a139324 GREEN
AnnotationsFXUtils.java 754152735e037da59a4c40fa045602c3ed85a40f GREEN
ColumnHandle.java 761c2517b3f3e4725feb7ce7e8d5927ba191a4bb GREEN
FXAnnotationFilterContentProvider.java 2d3b32115f47bea44279e8bdf54691b93311d27b GREEN
AnnotationTreeTableUIProvider.java 9efdeb7261cafe9dfe763daf20af186c906c3ec3 GREEN
AnnotationViewFXController.java 7017eb40e9511b6bdc40fcc5a95fd9f79247dfee GREEN
AnnotationsFXUtils.java e180d593b69b1e4b90adf83ba47753b29f9d6ff8 GREEN
ColumnHandle.java 7b0fe536d4eb9faa63c4d812f0c078cf83d0fd42 GREEN
FXAnnotationFilterContentProvider.java ca4587ef5dce1288ee4d7bf3bea5bd544ce6b89e GREEN
......@@ -15,10 +15,17 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.annotation.view.fx;
import static java.util.stream.Collectors.joining;
import static org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationsFXUtils.SELECTED_ANNOTATION_BACKGROUND_COLOR;
import static org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationsFXUtils.getBackgroundColorForEntry;
import static org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationsFXUtils.getValueLabel;
import java.util.Collection;
import org.eclipse.emf.ecore.EObject;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.annotation.IAnnotationValueService;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.annotation.valueprovider.IAnnotationValueProvider;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IModelElement;
......@@ -57,16 +64,36 @@ import javafx.scene.paint.Color;
}
return "";
default:
IAnnotatedSpecification columnSpec = this.viewController.colIdxAnnotationMap
.get(column).getAnnotatedSpecification();
Object specificationValue = entry.getSpecificationValue(columnSpec.getClass());
if(specificationValue != null) {
return specificationValue.toString();
Class<? extends IAnnotatedSpecification> columnSpecType =
this.viewController.colIdxAnnotationMap.get(column)
.getAnnotatedSpecificationType();
IAnnotationValueProvider<IAnnotatedSpecification> valueProvider =
entry.getAnnotationValueProvider(columnSpecType);
EStructuralFeatureDescriptor eStructuralFeatureDescriptor = valueProvider != null
? valueProvider.getEStructuralFeatureDescriptor() : null;
Object specificationValue = entry.getSpecificationValue(columnSpecType);
if(specificationValue instanceof Collection) {
Collection<?> values = (Collection<?>)specificationValue;
return "[" + values.stream().map(o -> getLabel(o, eStructuralFeatureDescriptor))
.collect(joining(", ")) + "]";
} else if(specificationValue != null) {
return getLabel(specificationValue, eStructuralFeatureDescriptor);
}
return "";
}
}
/** Returns a label for the given value. */
private String getLabel(Object value,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor) {
EObject root = null;
if(value instanceof IModelElement) {
root = eStructuralFeatureDescriptor.getValueRootElement((IModelElement)value);
}
return getValueLabel(value, root);
}
/** {@inheritDoc} */
......@@ -88,25 +115,38 @@ import javafx.scene.paint.Color;
/** {@inheritDoc} */
@Override
public void updateValue(AnnotationEntry element, int column, Object value) {
IAnnotatedSpecification specification =
this.viewController.colIdxAnnotationMap.get(column).getAnnotatedSpecification();
this.viewController.setAnnotationEntryValue(specification, element, (String)value);
IAnnotatedSpecification spec = getAnnotation(column, element);
this.viewController.setAnnotationEntryValue(spec, element, value);
super.updateValue(element, column, value);
}
/** {@inheritDoc} */
@Override
public boolean isEditable(int column, AnnotationEntry element) {
public boolean isEditable(int column, AnnotationEntry ae) {
IAnnotatedSpecification spec = getAnnotation(column, ae);
// Check 'editable' predicate for specification/annotation contained by model element
// associated to given annotation entry (if it exists)
IAnnotationValueProvider<IAnnotatedSpecification> valueProvider =
spec != null ? ae.getAnnotationValueProvider(spec.getClass()) : null;
return valueProvider != null && valueProvider.canEdit(spec);
}
/** Get annotation specification associated to given annotation entry and column. */
private IAnnotatedSpecification getAnnotation(int column, AnnotationEntry ae) {
if(column > 1 && this.viewController.colIdxAnnotationMap.containsKey(column)) {
ColumnHandle<IAnnotatedSpecification> columnHandle =
this.viewController.colIdxAnnotationMap.get(column);
Class<IAnnotatedSpecification> specType = columnHandle.getAnnotatedSpecificationType();
IAnnotationValueService as = IAnnotationValueService.getInstance();
IAnnotatedSpecification spec =
this.viewController.colIdxAnnotationMap.get(column).getAnnotatedSpecification();
IAnnotationValueProvider<IAnnotatedSpecification> valueProvider =
element.getAnnotationValueProvider(spec.getClass());
return valueProvider != null && valueProvider.canEdit(spec);
as.getAnnotationEntry(ae.getModelElement()).getSpecification(specType);
return spec;
}
return false;
return null;
}
/** {@inheritDoc} */
......
......@@ -15,26 +15,33 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.ui.annotation.view.fx;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.sort;
import static java.util.stream.Collectors.toList;
import static org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationsFXUtils.getValueLabel;
import static org.fortiss.tooling.base.ui.annotation.view.fx.FXAnnotationFilterContentProvider.HIERARCHY_LEVELS_ALL;
import static org.fortiss.tooling.base.ui.annotation.view.fx.FXAnnotationFilterContentProvider.HIERARCHY_LEVELS_CURRENT;
import static org.fortiss.tooling.base.ui.annotation.view.fx.FXAnnotationFilterContentProvider.HIERARCHY_LEVELS_SELECTED_SUBMODEL;
import static org.fortiss.tooling.kernel.ui.util.SelectionUtils.checkAndPickFirst;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getFirstParentWithType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.showWarning;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
......@@ -46,8 +53,8 @@ import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.annotation.AnnotationValueService;
import org.fortiss.tooling.base.annotation.IAnnotationValueService;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor.EReferenceScope;
import org.fortiss.tooling.base.annotation.valueprovider.IAnnotationValueProvider;
import org.fortiss.tooling.base.annotation.valueprovider.ValueProviderBase;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeTableUIProviderBase;
......@@ -57,6 +64,7 @@ import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.INamedCommentedElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.utils.HierarchicalNameComparator;
import com.sun.webkit.ThemeClient;
......@@ -250,7 +258,8 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
for(AnnotationEntry entry : annotationEntries) {
for(IAnnotatedSpecification spec : entry.getSpecificationsList()) {
ColumnHandle<IAnnotatedSpecification> columnHandle =
new ColumnHandle<IAnnotatedSpecification>(entry, spec);
new ColumnHandle<IAnnotatedSpecification>(entry,
(Class<IAnnotatedSpecification>)spec.getClass());
columnHandles.add(columnHandle);
colNameToSpecification.put(columnHandle.getColumnName(), spec);
}
......@@ -390,14 +399,15 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
/** Creates the annotation column for the given handle. */
private TreeTableColumn<AnnotationEntry, ?> createColumnForHandle(int columnIdx,
ColumnHandle<IAnnotatedSpecification> handle) {
Class<IAnnotatedSpecification> annotationClass =
(Class<IAnnotatedSpecification>)handle.getAnnotatedSpecification().getClass();
Class<IAnnotatedSpecification> annotationType = handle.getAnnotatedSpecificationType();
AnnotationEntry entry = handle.getEntry();
IAnnotationValueProvider<IAnnotatedSpecification> valueProvider =
entry.getAnnotationValueProvider(annotationClass);
IAnnotatedSpecification specification = entry.getSpecification(annotationClass);
EClassifier valueType =
valueProvider.getEStructuralFeatureDescriptor().getEType(specification);
entry.getAnnotationValueProvider(annotationType);
IAnnotatedSpecification specification = entry.getSpecification(annotationType);
EStructuralFeatureDescriptor featureDescriptor =
valueProvider.getEStructuralFeatureDescriptor();
EClassifier valueType = featureDescriptor.getEType(specification);
String columnName = valueProvider.getAnnotationName(specification);
......@@ -413,25 +423,19 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
return column;
}
if(valueType instanceof EEnum) {
// Add a combo column for enumerations.
if(valueType instanceof EEnum || valueType instanceof EClass) {
// Add a combo column for enumerations and references
column = annotationViewer.addComboColumn(columnName, 150, rowEntry -> {
ValueProviderBase<IAnnotatedSpecification> annotationValueProvider =
(ValueProviderBase<IAnnotatedSpecification>)rowEntry
.getAnnotationValueProvider(annotationClass);
EStructuralFeatureDescriptor structuralFeature =
annotationValueProvider.getEStructuralFeatureDescriptor();
EClassifier type =
structuralFeature.getEType(rowEntry.getSpecification(annotationClass));
// Get the enum literals again, as it might be different for each row.
if(type instanceof EEnum) {
EList<EEnumLiteral> allLiterals = ((EEnum)type).getELiterals();
return allLiterals.stream().map(l -> l.getLiteral()).collect(toList());
}
return emptyList();
// We must retrieve the specification and model element for the edited row entry
IAnnotatedSpecification entrySpec =
pickFirstInstanceOf(annotationType, rowEntry.getSpecificationsList());
IModelElement entryElement = rowEntry.getModelElement();
Map<Object, String> comboValues =
getComboValues(featureDescriptor, entrySpec, entryElement);
return comboValues;
});
} else if(valueType.getInstanceClass().equals(Boolean.class)) {
// Use a checkbox column for booleans
column = annotationViewer.addCheckboxColumn(columnName, 100);
......@@ -447,12 +451,64 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
return column;
}
/**
* Returns mapping of annotation values and their labels to be displayed in a combo box (for
* enums and references).
*/
private Map<Object, String> getComboValues(EStructuralFeatureDescriptor featureDescriptor,
IAnnotatedSpecification specification, IModelElement modelElement) {
EClassifier eType = featureDescriptor.getEType(specification);
if(eType instanceof EEnum) {
Map<Object, String> rval = new TreeMap<>(new Comparator<Object>() {
@Override
public int compare(Object e1, Object e2) {
return Integer.compare(((Enumerator)e1).getValue(),
((Enumerator)e2).getValue());
}
});
for(EEnumLiteral lit : featureDescriptor.getEnumLiterals((EEnum)eType, modelElement)) {
rval.put(lit.getInstance(), lit.getLiteral());
}
return rval;
} else if(eType instanceof EClass) {
EObject root = featureDescriptor.getValueRootElement(modelElement);
if(root == null) {
return emptyMap();
}
EList<EObject> refValues = new BasicEList<EObject>();
if(featureDescriptor.getEReferenceScope() == EReferenceScope.SUB_MODEL) {
refValues.add(root);
}
Class<? extends EObject> clazz = (Class<? extends EObject>)eType.getInstanceClass();
for(EObject obj : getChildrenWithType(root, clazz)) {
if(featureDescriptor.isAvailableObject(obj, specification, modelElement)) {
refValues.add(obj);
}
}
Map<Object, String> rval = new TreeMap<>(new HierarchicalNameComparator());
for(EObject obj : refValues) {
rval.put(obj, getValueLabel(obj, root));
}
return rval;
}
return emptyMap();
}
/**
* Local helper to set the given newValue for the given annotationEntry and
* specification.
*/
void setAnnotationEntryValue(IAnnotatedSpecification specification,
AnnotationEntry annotationEntry, String newValue) {
AnnotationEntry annotationEntry, Object newValue) {
ITopLevelElement tle =
IPersistencyService.getInstance().getTopLevelElementFor(curentRootElement);
......
......@@ -20,11 +20,15 @@ import static javafx.scene.paint.Color.LIGHTGREY;
import static javafx.scene.paint.Color.LIGHTSEAGREEN;
import static javafx.scene.paint.Color.WHITE;
import static org.eclipse.swt.widgets.Display.getCurrent;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.computeFullyQualifiedName;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.computeRelativeName;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.swt.graphics.Device;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.annotation.valueprovider.IAnnotationValueProvider;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.kernel.model.INamedElement;
import javafx.scene.paint.Color;
......@@ -132,4 +136,18 @@ public class AnnotationsFXUtils {
int blue = (int)color.getBlue();
return new org.eclipse.swt.graphics.Color(device, red, green, blue);
}
/**
* Returns the label for a value shown in the annotation view. For values of EReferences, the
* hierarchical name of the value relative to the given {@code root} model element is returned.
*/
public static String getValueLabel(Object modelELement, EObject root) {
if(modelELement instanceof INamedElement) {
if(root instanceof INamedElement) {
return computeRelativeName((INamedElement)root, (INamedElement)modelELement);
}
return computeFullyQualifiedName((INamedElement)modelELement);
}
return modelELement.toString();
}
}
......@@ -30,8 +30,8 @@ public class ColumnHandle<T extends IAnnotatedSpecification> extends AnnotationI
implements Comparable<ColumnHandle<T>> {
/** Constructs a new {@link ColumnHandle}. */
public ColumnHandle(AnnotationEntry entry, T annotatedSpecification) {
super(entry, annotatedSpecification);
public ColumnHandle(AnnotationEntry entry, Class<T> specType) {
super(entry, specType);
}
/**
......
......@@ -175,8 +175,8 @@ public class FXAnnotationFilterContentProvider
* Returns true if the given specification passes the current annotation type
* filter.
*/
private boolean passesAnnotationTypeFilter(IAnnotatedSpecification spec) {
return annotationTypeFilter == null || spec.getClass().equals(annotationTypeFilter);
private boolean passesAnnotationTypeFilter(Class<? extends IAnnotatedSpecification> specType) {
return annotationTypeFilter == null || specType.equals(annotationTypeFilter);
}
/**
......@@ -186,8 +186,8 @@ public class FXAnnotationFilterContentProvider
public boolean passesColumnFilter(ColumnHandle<?> columnHandle) {
// Whether the annotation is visible (i.e., not principally hidden from any
// view)
boolean passesHiddenFilter = !columnHandle.getEntry()
.isHidden(columnHandle.getAnnotatedSpecification().getClass());
boolean passesHiddenFilter =
!columnHandle.getEntry().isHidden(columnHandle.getAnnotatedSpecificationType());
// Pass name filter, if: name is not filtered, or the condition is met
boolean passesNameFilter =
......@@ -196,7 +196,7 @@ public class FXAnnotationFilterContentProvider
// Check if column passes all tests
// @CodeFormatterOff
return passesHiddenFilter && passesNameFilter && passesSelectedElementTypeFilter(columnHandle.getEntry())
&& passesAnnotationTypeFilter(columnHandle.getAnnotatedSpecification());
&& passesAnnotationTypeFilter(columnHandle.getAnnotatedSpecificationType());
// @CodeFormatterOn
}
......
CurvedLinkLayoutedContentAnchorangeController.java e22faedbe98c3dab660b5d2df8ebd004e116c5ba GREEN
CurvedLinkLayoutedDiagramAnchorangeController.java f2e5e2a7cc9b6a070871e200e57371286bb15222 GREEN
EObjectDiagramController.java 7fe2cd69ee8449b0ecaeb42e4fe2b65fffd9b6c3 GREEN
EObjectDiagramController.java 45f5b1439f33685523b035d2603e8329b647b62a GREEN
EObjectEllipticResizableContentControllerBase.java f12e8f5a646a23fe428ed4768bf041c8b885ec81 GREEN
EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN
EObjectRectangularResizableContentControllerBase.java cde6c13659611d927691c03ecd2621cff2414b03 GREEN
......
......@@ -85,7 +85,7 @@ public class EObjectDiagramController<T extends EObject> extends DefaultDiagramC
IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, true,
getViewer().getFeatures().getCurrentZoomFactor());
List<MenuItem> result = createPrototypeMenu(modelParent, edc);
// Adds "Display" menu
// Adds "Display" and "Zoom" menus
result.addAll(super.contextMenuContributions(node, diagramLocation));
if(modelParent instanceof IHierarchicElement && enableAutoLayout()) {
result.add(createAutoLayoutMenu((IHierarchicElement)modelParent));
......
......@@ -2,14 +2,14 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.fortiss.tooling.base;singleton:=true
Bundle-Version: 2.19.0.qualifier
Bundle-Version: 2.20.0.qualifier
Bundle-ClassPath: .
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.emf.ecore;visibility:=reexport,
org.fortiss.tooling.kernel;visibility:=reexport;bundle-version="2.19.0"
org.fortiss.tooling.kernel;visibility:=reexport;bundle-version="2.20.0"
Bundle-ActivationPolicy: lazy
Export-Package: org.fortiss.tooling.base,
org.fortiss.tooling.base.annotation,
......
AnnotationInstSpec.java b4f2ed47a8984e751e04049de5bdb3cad2c0a933 GREEN
AnnotationInstSpec.java 7a6cb55bfa9cafa9ead1f72089e554ee8142e8bf GREEN
DerivedAnnotationValueProviderBase.java afedd21d3469127bbb20adb34c191b5c9c980f6c GREEN
EStructuralFeatureDescriptor.java 2e14df3830d854bc1693382727b2033b23d0051c GREEN
EStructuralFeatureValueProviderBase.java 287facbbce47c16d892bae82a214f64ceeef2263 GREEN
EStructuralFeatureDescriptor.java 0c4b8037481b4f20c5492b68be7096273645a912 GREEN
EStructuralFeatureValueProviderBase.java 8dcecac16f8f654732ee0af7098443fe13ce1c85 GREEN
IAnnotationValueProvider.java 08e0e5f66dc97865e9ac03e1ac646af332845e14 GREEN
ValueProviderBase.java e4e866840845346ec99a4304048f5327c4890996 GREEN
......@@ -35,12 +35,12 @@ public class AnnotationInstSpec<T extends IAnnotatedSpecification> {
* {@link IAnnotatedSpecification} from {@code entry} to be displayed in the column
* represented by this {@link AnnotationInstSpec}.
*/
private IAnnotatedSpecification annotatedSpecification;
private Class<T> specType;
/** Constructor. */
public AnnotationInstSpec(AnnotationEntry entry, T annotatedSpecification) {
public AnnotationInstSpec(AnnotationEntry entry, Class<T> specType) {
this.entry = entry;
this.annotatedSpecification = annotatedSpecification;
this.specType = specType;
}
/**
......@@ -52,20 +52,11 @@ public class AnnotationInstSpec<T extends IAnnotatedSpecification> {
}
/**
* Returns the {@link IAnnotatedSpecification} from {@code entry} to be displayed in the
* Returns the type of {@link IAnnotatedSpecification} from {@code entry} to be displayed in the
* column represented by this {@link AnnotationInstSpec}.
*/
@SuppressWarnings("unchecked")
public Class<T> getAnnotatedSpecificationType() {
return (Class<T>)annotatedSpecification.getClass();
}
/**
* Returns the {@link IAnnotatedSpecification} from {@code entry} to be displayed in the
* column represented by this {@link AnnotationInstSpec}.
*/
public IAnnotatedSpecification getAnnotatedSpecification() {
return annotatedSpecification;
return specType;
}
/**
......
......@@ -15,6 +15,8 @@
+--------------------------------------------------------------------------*/
package org.fortiss.tooling.base.annotation.valueprovider;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
import java.util.HashMap;
import java.util.Map;
......@@ -29,6 +31,7 @@ import org.eclipse.emf.ecore.EStructuralFeature;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IDerivedAnnotation;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
/**
* Description of a {@link EStructuralFeature} managed by a
......@@ -42,25 +45,25 @@ public class EStructuralFeatureDescriptor {
* resolved.
*/
public enum EReferenceScope {
/** Current project (all models). */
PROJECT,
/** Current model (e.g., ComponentArchitecture). */
MODEL,
/**
* Sub-model below the {@link IModelElement} to which the annotation is attached that
* contains the {@link EStructuralFeature} managed by this
* {@link EStructuralFeatureDescriptor} (including the element itself).
*/
SUB_MODEL,
/**
* Sub-model below the {@link IModelElement} to which the annotation is attached that
* contains the {@link EStructuralFeature} managed by this
* {@link EStructuralFeatureDescriptor} (NOT including the element itself).
*/
STRICT_SUB_MODEL
/** Current project (all models). */
PROJECT,
/** Current model (e.g., ComponentArchitecture). */
MODEL,
/**
* Sub-model below the {@link IModelElement} to which the annotation is attached that
* contains the {@link EStructuralFeature} managed by this
* {@link EStructuralFeatureDescriptor} (including the element itself).
*/
SUB_MODEL,
/**
* Sub-model below the {@link IModelElement} to which the annotation is attached that
* contains the {@link EStructuralFeature} managed by this
* {@link EStructuralFeatureDescriptor} (NOT including the element itself).
*/
STRICT_SUB_MODEL
}
/** {@link EStructuralFeature} managed by this {@link EStructuralFeatureDescriptor}. */
......@@ -150,19 +153,50 @@ public class EStructuralFeatureDescriptor {
*/
public boolean isAvailableObject(EObject obj, IAnnotatedSpecification specification,
EObject modelElement) {
// Prevent elements that are contained in nested IProjectRoot elements from being listed
// (e.g., elements in DSE ModelSnapshots).
boolean rootElementSeen = false;
while(obj != null) {
if(obj instanceof IProjectRootElement) {
if(rootElementSeen) {
return false;
}
rootElementSeen = true;
}
obj = obj.eContainer();
}
return true;
}
/**
* For the given {@link IModelElement}, return the model element used as the scope to provide
* reference values.
*/
public EObject getValueRootElement(IModelElement modelElement) {
switch(getEReferenceScope()) {
case PROJECT:
IProjectRootElement rootElement =
getParentElement(modelElement, IProjectRootElement.class, true);
return rootElement != null ? rootElement.eContainer() : null;
case MODEL:
return getParentElement(modelElement, IProjectRootElement.class, true);
case SUB_MODEL:
case STRICT_SUB_MODEL:
return modelElement;
default:
throw new RuntimeException("Unsupported reference scope: " + getEReferenceScope());
}
}
/**
* Returns the type of the structural feature managed by this
* {@link EStructuralFeatureDescriptor}.
*/
public EClassifier getEType(IAnnotatedSpecification specification) {
try {
return getEStructuralFeature(specification).getEType();
} catch(Exception e) {
return null;
}
EStructuralFeature esf = getEStructuralFeature(specification);
return esf != null ? esf.getEType() : null;
}
/**
......
......@@ -16,6 +16,7 @@
package org.fortiss.tooling.base.annotation.valueprovider;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
import java.util.ArrayList;
......@@ -230,25 +231,29 @@ public abstract class EStructuralFeatureValueProviderBase<T extends IAnnotatedSp
}
setAnnotationValueFromString((String)value, specification);
} else if(value instanceof Collection<?>) {
Collection<?> collection = (Collection<?>)value;
if(collection.isEmpty()) {
specification.eSet(eStructuralFeature, emptyList());
} else {
if(collection.iterator().next() instanceof String) {
setAnnotationValueFromString((Collection<String>)value, specification);
} else {
if(eStructuralFeature.isMany()) {
Collection<?> collection = (value instanceof Collection<?>) ? (Collection<?>)value
: singletonList(value);
if(collection.isEmpty()) {
specification.eSet(eStructuralFeature, emptyList());
} else {
specification.eSet(eStructuralFeature, value);
if(collection.iterator().next() instanceof String) {
setAnnotationValueFromString((Collection<String>)collection, specification);
} else {
specification.eSet(eStructuralFeature, collection);
}
}
}
} else {
if(value != null) {
specification.eSet(eStructuralFeature, value);
} else {
// Treat 'null' as special value used to unset EStructural features. This
// implementation choice prevents to distinguish between 'null' and unset for
// EReferences).
specification.eUnset(eStructuralFeature);
if(value != null) {
specification.eSet(eStructuralFeature, value);
} else {
// Treat 'null' as special value used to unset EStructural features. This
// implementation choice prevents to distinguish between 'null' and unset for
// EReferences).
specification.eUnset(eStructuralFeature);
}
}
}
}
......
......@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tooling Commons UI
Bundle-SymbolicName: org.fortiss.tooling.common.ui;singleton:=true
Bundle-Version: 2.19.0.qualifier
Bundle-Version: 2.20.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-11
Require-Bundle: org.fortiss.tooling.common;visibility:=reexport,
org.eclipse.core.resources;visibility:=reexport,
......
......@@ -5,8 +5,8 @@ DynamicTextFieldTreeTableCell.java de24117e6f785b328f1ff62383626a0b4b54e8ff GREE
DynamicTreeContentProviderBase.java 91896b1fb5104d126544c44c1ff8c30f2a13a8d6 GREEN
DynamicTreeItem.java 7486071d20e896d6ca9a9101bf105caccf3656d0 GREEN
DynamicTreeItemBase.java d883066ecc181120302ca32f328538de7a45b093 GREEN
DynamicTreeTableUIProviderBase.java a4cd60795d114984f7fd255f273fc39937889f22 GREEN
DynamicTreeTableViewer.java ead6f6671e9cb6b14632940bf440cba7e81fcd98 GREEN
DynamicTreeTableUIProviderBase.java d150a4c379cc41aab2a44a5f1643f4956332c8e3 GREEN
DynamicTreeTableViewer.java cb289413d15159abbcccfea87d731738905b4b28 GREEN
DynamicTreeUIProviderBase.java 82d3c051213f0147f4c67ad247a08696cee73110 GREEN
DynamicTreeViewer.java 545f1ca10b7b3cad171b294a4b447875da45c9ed GREEN
DynamicTreeViewerBase.java a2013538b62d86f6a09efdf2cd78babac2072484 GREEN
......
......@@ -13,10 +13,11 @@
*******************************************************************************/
package org.fortiss.tooling.common.ui.javafx.control.treetableview;
import static java.util.stream.Collectors.toMap;
import static javafx.collections.FXCollections.observableArrayList;
import static org.apache.commons.lang3.SystemUtils.IS_OS_LINUX;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import javafx.beans.property.SimpleBooleanProperty;
......@@ -48,6 +49,11 @@ import javafx.util.converter.DefaultStringConverter;
*/
public abstract class DynamicTreeTableUIProviderBase<T> {
/**
* Retrieves the label to be displayed in the given position.
*
* Note: An empty cell can only be editable, if an empty String is returned here instead of
* 'null'.
*
* @param element
* the element to be displayed in the current row
* @param column
......@@ -71,7 +77,6 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
/**
* Returns the style that shall be applied to the {@link TreeItem} of the given element. Return
*
* {@code null} for the default style.
*
* @param element
......@@ -81,6 +86,19 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
* @return style of the element in the CSS format.
*/
public String getCellStyle(T element, int column) {
if(element == null) {
return null;
}
Color bgColor = getBackgroundColor(column, element);
if(bgColor != null) {
// Some transparency is necessary here, for correctly displaying the selection
// bar when selecting a row. WIth out transparency, it would not be visible on
// this cell.
double alpha = 0.5;
String colorStr = colorToRgbaString(bgColor, alpha);
return "-fx-background-color: " + colorStr + ";";
}
return null;
}
......@@ -263,10 +281,11 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
* @param column
* The {@link TreeTableColumn} to be configured.
* @param comboValueFactory
* A {@link Function} that maps the cell elements to their respective combo values.
* A {@link Function} that maps cell elements to a combo value map (data model
* element -> label)
*/
/* package */ final void applyToComboColumn(int columnIndex, TreeTableColumn<T, String> column,
Function<T, Collection<String>> comboValueFactory) {
Function<T, Map<?, String>> comboValueFactory) {
column.setCellFactory(
createEditableComboCellFactory(columnIndex, column, comboValueFactory));
}
......@@ -287,22 +306,20 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
T data = cell.getTreeTableRow().getItem();
if(data != null) {
Color bgColor = getBackgroundColor(columnIndex, data);
if(bgColor != null) {
// Some transparency is necessary here, for correctly displaying the selection
// bar when selecting a row. WIth out transparency, it would not be visible on
// this cell.
double alpha = 0.5;
String colorStr = colorToRgbaString(bgColor, alpha);
cell.setStyle("-fx-background-color: " + colorStr);
}
final Node icon = getIconNode(data, columnIndex);
cell.setGraphic(icon);
cell.setStyle(getCellStyle(data, columnIndex));
} else {
// reset icon for cases, in which a row was styled before, but became empty by now.
cell.setGraphic(null);
cell.setStyle(null);
}
}
}
/** Converts a {@link Color} object into a rgba format as used in css. */
private final static String colorToRgbaString(Color color, double alpha) {
return String.format("rgba(%d,%d,%d,%.1f)", (int)(color.getRed() * 255),
return String.format("rgba(%d,%d,%d,%s)", (int)(color.getRed() * 255),
(int)(color.getGreen() * 255), (int)(color.getBlue() * 255), alpha);
}
......@@ -337,29 +354,59 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
/** Creates the cell factory for {@link ComboBox} editing. */
private Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>>
createEditableComboCellFactory(int columnIndex, TreeTableColumn<T, String> column,
Function<T, Collection<String>> comboValueFactory) {
Function<T, Map<?, String>> comboValueFactory) {
// The list with the choices to be offered in the combo.
ObservableList<String> items = observableArrayList();
Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> comboCellFactory =
param -> new ComboBoxTreeTableCell<T, String>(null, items) {
/** {@inheritDoc} */
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
styleCell(this, columnIndex);
}
/** {@inheritDoc} */
@Override
public void startEdit() {
// null items are in cells, which cannot contain a value. Otherwise they
// would contain an empty String.
if(getItem() == null) {
return;
}
super.startEdit();
}
};
// Changes the choices of the combo for every editing of every cell dynamically.
column.setOnEditStart(event -> {
TreeItem<T> treeItem = event.getRowValue();
T rowEntry = treeItem.getValue();
Collection<String> comboValues = comboValueFactory.apply(rowEntry);
T rowEntry = event.getRowValue().getValue();
Map<?, String> comboValueMap = comboValueFactory.apply(rowEntry);
items.clear();
items.addAll(comboValues);
items.addAll(comboValueMap.values());
});
column.setOnEditCommit(event -> {
// The column number needs to be retrieved from the viewer, as the the
// event.getTablePosition() does not take into account invisible columns for numbering.
TreeTableColumn<T, String> tableColumn = event.getTableColumn();
int colIndex = tableColumn.getTreeTableView().getColumns().indexOf(tableColumn);
// Convert displayed value label into underlying data model's value
String valueLabel = event.getNewValue();
T rowEntry = event.getRowValue().getValue();
Map<?, String> comboValueMap = comboValueFactory.apply(rowEntry);
Map<String, ?> valueMapInversed = comboValueMap.entrySet().stream()
.collect(toMap(Map.Entry::getValue, Map.Entry::getKey));
updateValue(rowEntry, colIndex, valueMapInversed.get(valueLabel));
column.getTreeTableView().refresh();
});
return comboCellFactory;
}
......@@ -377,7 +424,7 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
/** {@inheritDoc} */
@Override
public void startEdit() {
if(!isEditable() || !getTreeTableView().isEditable() ||
if(getItem() == null || !isEditable() || !getTreeTableView().isEditable() ||
!getTableColumn().isEditable()) {
return;
}
......@@ -409,6 +456,13 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
});
}
/** {@inheritDoc} */
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
styleCell(this, this.columnIndex);
}
/** {@inheritDoc} */
@Override
public void cancelEdit() {
......@@ -456,23 +510,16 @@ public abstract class DynamicTreeTableUIProviderBase<T> {
super.updateItem(item, empty);
ContextMenu menu = null;
Node icon = null;
if(!empty && item != null) {
T data = this.getTreeTableRow().getItem();
icon = getIconNode(data, colIndex);
menu = createContextMenu(data, colIndex);
if(IS_OS_LINUX && menu != null) {
// JFX-builtin handling is non-operation in Linux.
addContextMenuHandler(menu, data);
}
String style = getCellStyle(data, colIndex);
if(style != null) {
this.setStyle(style);
}
}
this.setGraphic(icon);
this.setContextMenu(menu);
styleCell(this, colIndex);
}
......
......@@ -19,6 +19,7 @@ import static java.lang.Integer.MAX_VALUE;
import static javafx.scene.control.cell.CheckBoxTreeTableCell.forTreeTableColumn;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
......@@ -194,8 +195,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
/**
* Adds an editable column to the table part of the view. The labels, context menus and icons
* are shown as
* defined in the {@link DynamicTreeTableUIProviderBase}.
* are shown as defined in the {@link DynamicTreeTableUIProviderBase}.
*/
public TreeTableColumn<T, String> addTextColumn(String headerLabel, int prefWidth) {
int num = view.getColumns().size();
......@@ -232,17 +232,29 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
* @param prefWidth
* The preferred width of the new column in px.
* @param comboValueFactory
* A Function, that maps cell elements to choices for the combo box.
* A {@link Function} that maps cell elements to a combo value map (data model
* element -> label)
*
* @return The newly created an configured column.
*/
public TreeTableColumn<T, String> addComboColumn(String headerLabel, int prefWidth,
Function<T, Collection<String>> comboValueFactory) {
Function<T, Map<?, String>> comboValueFactory) {
int num = view.getColumns().size();
TreeTableColumn<T, String> column = addColumn(headerLabel, prefWidth);
TreeTableColumn<T, String> column = new TreeTableColumn<>(headerLabel);
column.setPrefWidth(prefWidth);
column.setCellValueFactory(param -> {
T data = param.getValue().getValue();
SimpleObjectProperty<String> cell =
new SimpleObjectProperty<String>(uiProvider.getLabel(data, num));
return cell;
});
uiProvider.applyToComboColumn(num, column, comboValueFactory);
view.getColumns().add(column);
return column;
}
......@@ -266,7 +278,8 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
/** {@inheritDoc} */
@Override
protected T getSelectedObject() {
T value = view.getSelectionModel().getSelectedItem().getValue();
final TreeItem<T> selectedItem = view.getSelectionModel().getSelectedItem();
T value = selectedItem != null ? selectedItem.getValue() : null;
return value;
}
......
......@@ -2,7 +2,7 @@ DiagramCoordinate.java 6b00aec99054d4cd19003a72bd4e5e774ac6a641 GREEN
DiagramLayers.java 155cbb47a5f0aaa0025320ae607e6777f3a2d2e8 GREEN
DiagramViewer.java 920bb0f4ee6dd9ac6b607e44c01f04a413b2e2ed GREEN
DiagramViewerDefaultTags.java 6230763252409c60009ab8887b4ef582cf883229 GREEN
DiagramViewerFeatures.java 44f5315505d76ef8cb0b61b5a37d7d2501195788 GREEN
DiagramViewerFeatures.java 397c9600193df18e865f1ff7c829df577c56d383 GREEN
DiagramViewerSelection.java e833f592543bc97077907d980a39b123fc4044e6 GREEN
EDragGesture.java 5cfa098d3877db11981c2750e5e103156d62fc5e GREEN
FeedbackChange.java b088fa89af648f1674f2f9c1f7f99d585ce801ca GREEN
......
......@@ -26,9 +26,9 @@ public final class DiagramViewerFeatures {
/** The diagram viewer. */
private final DiagramViewer viewer;
/** The zoom factors. */
private double[] zoomFactors = new double[] {0.5, 0.75, 1, 1.5, 2};
private double[] zoomFactors = new double[] {0.125, 0.25, 0.5, 0.75, 1, 1.5, 2, 4, 8};
/** The current zoom factor array index. */
private int zoomFactorIndex = 2;
private int zoomFactorIndex = 4; // Index of 1
/** Flag indicating whether link highlighting is enabled. */
private boolean linkHighlightingEnabled = false;
/** Flag if interaction area shading is active. */
......