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 (202)
Showing
with 76 additions and 1644 deletions
......@@ -7,7 +7,7 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="build"/>
<classpathentry kind="src" path="res"/>
<classpathentry kind="lib" path="lib/opal-1.0.4.jar" sourcepath="lib/opal-1.0.4-src.zip"/>
<classpathentry exported="true" kind="lib" path="lib/com.google.guava-15.0.0.v201403281430.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/>
<classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.core-0.15.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/>
......@@ -16,4 +16,5 @@
<classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.force-0.4.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/>
<classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.layered-0.13.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/>
<classpathentry exported="true" kind="lib" path="lib/de.cau.cs.kieler.klay.tree-0.4.0.201602160301.jar" sourcepath="lib/klay-layouters-2016-02-src.zip"/>
<classpathentry kind="output" path="build"/>
</classpath>
......@@ -2,21 +2,18 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Tooling Base UI
Bundle-SymbolicName: org.fortiss.tooling.base.ui;singleton:=true
Bundle-Version: 2.17.0.qualifier
Bundle-Version: 2.18.0.qualifier
Bundle-Activator: org.fortiss.tooling.base.ui.ToolingBaseUIActivator
Require-Bundle: org.fortiss.tooling.base;bundle-version="2.17.0";visibility:=reexport,
org.fortiss.tooling.kernel.ui;bundle-version="2.17.0";visibility:=reexport,
org.eclipse.swt
Require-Bundle: org.fortiss.tooling.base;bundle-version="2.18.0";visibility:=reexport,
org.fortiss.tooling.kernel.ui;bundle-version="2.18.0";visibility:=reexport,
org.eclipse.swt,
org.fortiss.tooling.common.ui
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-11
Bundle-Vendor: fortiss GmbH
Export-Package: org.fortiss.tooling.base.ui,
org.fortiss.tooling.base.ui.annotation,
org.fortiss.tooling.base.ui.annotation.editingsupport,
org.fortiss.tooling.base.ui.annotation.labelprovider,
org.fortiss.tooling.base.ui.annotation.view,
org.fortiss.tooling.base.ui.annotation.view.generic,
org.fortiss.tooling.base.ui.annotation.view.generic.filter,
org.fortiss.tooling.base.ui.annotation.view.fx,
org.fortiss.tooling.base.ui.contentprovider,
org.fortiss.tooling.base.ui.dialog,
org.fortiss.tooling.base.ui.dnd.gef,
......
# (c) 2011 fortiss GmbH
source.. = src/
source.. = src/,\
res/
output.. = build/
bin.includes = META-INF/,\
.,\
......
......@@ -14,7 +14,7 @@
<!-- Keep ID constant in sync with org.fortiss.tooling.base.ui.annotation.view.IAnnotationViewPart.ANNOTATION_VIEW_ID -->
<extension point="org.eclipse.ui.views">
<view
class="org.fortiss.tooling.base.ui.annotation.view.generic.GenericAnnotationView"
class="org.fortiss.tooling.base.ui.annotation.view.fx.AnnotationFxViewPart"
icon="icons/annotation.gif"
id="org.fortiss.tooling.base.ui.annotationView"
name="Annotations"
......
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.RadioButton?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TreeTableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<SplitPane fx:id="annotationSplitPane" dividerPositions="0.8567839195979899" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" orientation="VERTICAL" prefHeight="400.0" prefWidth="1266.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<items>
<AnchorPane fx:id="annotationTablePane" minHeight="0.0" minWidth="0.0" prefHeight="1000.0" prefWidth="160.0">
<children>
<TreeTableView fx:id="annotationTreeTableView" layoutX="328.0" layoutY="20.0" prefHeight="1000.0" prefWidth="598.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children></AnchorPane>
<AnchorPane fx:id="filterPane" maxHeight="60.0" minHeight="52.0" minWidth="0.0" prefHeight="52.0" prefWidth="1189.0">
<children>
<HBox layoutX="158.0" layoutY="51.0" prefHeight="151.0" prefWidth="598.0" spacing="10.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<VBox prefHeight="1000.0" prefWidth="4000.0">
<children>
<HBox prefHeight="23.0" prefWidth="424.0" spacing="5.0">
<children>
<Label minHeight="20.0" text="Filter:" />
<RadioButton fx:id="radBtnFilterModelElements" minHeight="20.0" mnemonicParsing="false" text="model elements" />
<RadioButton fx:id="radBtnFilterAnnotationNames" minHeight="20.0" mnemonicParsing="false" text="annotation names:" />
<CheckBox fx:id="chkBoxMatchCase" mnemonicParsing="false" text="match case" />
</children>
</HBox>
<TextField fx:id="txtFilterText" minHeight="30.0" minWidth="390.0" prefHeight="30.0" prefWidth="3000.0" promptText="type filter text (regex)" />
</children>
</VBox>
<VBox minWidth="290.0" prefHeight="151.0" prefWidth="167.0">
<children>
<Label minHeight="20.0" text="Filter model element type:" />
<CheckBox fx:id="chkBoxselectedTypeOnly" minHeight="20.0" mnemonicParsing="false" text="Show only selected model element type" />
</children>
</VBox>
<VBox minWidth="250.0" prefHeight="151.0" prefWidth="162.0">
<children>
<Label text="Filter model element hierarchy level:" />
<ComboBox fx:id="comboHierarchy" prefWidth="240.0" />
</children>
</VBox>
<VBox minWidth="225.0" prefHeight="151.0" prefWidth="136.0">
<children>
<Label text="Filter annotation type:" />
<ComboBox fx:id="comboAnnotationType" prefWidth="220.0" />
</children>
</VBox>
</children>
</HBox>
</children></AnchorPane>
</items>
</SplitPane>
ToolingBaseUIActivator.java dbb6f64b87a553ffbcfeb92160d84b63073dfd89 GREEN
ToolingBaseUIActivator.java d961cd206d8f44e851b2211430b25fee3d9071c0 GREEN
......@@ -19,6 +19,8 @@ import static org.eclipse.jface.resource.ResourceLocator.imageDescriptorFromBund
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.fortiss.tooling.base.ui.cli.ShutdownPlatformCLIHandler;
import org.fortiss.tooling.kernel.service.ICommandLineInterfaceService;
import org.osgi.framework.BundleContext;
/**
......@@ -39,6 +41,9 @@ public class ToolingBaseUIActivator extends AbstractUIPlugin {
super.start(context);
plugin = this;
System.out.println("[Plugin] " + PLUGIN_ID + " started.");
ICommandLineInterfaceService cliService = ICommandLineInterfaceService.getInstance();
cliService.registerHandler("--shutdown", new ShutdownPlatformCLIHandler());
}
/** {@inheritDoc} */
......
AnnotationEditingSupportBase.java a5ecf54616b50f947d251f45cbb5789df5234170 GREEN
CheckBoxEditingSupport.java 1d8d9dd444f0e52767c65fd2711321438d3a9b29 GREEN
ComboBoxEditingSupport.java 6b6a23be327ebdea9bdaf007304bd3d7c14b2cef GREEN
EditingSupportFactory.java e42347692ef23a8cb71532edadcf176ae49e992d GREEN
ElementCommentEditingSupport.java 4be366924a040caf3f80e35b383e796e84aedcac GREEN
ElementEditingSupportBase.java a6360f99ee149276f0fbd299820ebd1c9731ea97 GREEN
ElementNameEditingSupport.java 0dcaecf4ba5f8ddefa3ccb7d6f4e4506f7f09b26 GREEN
IMultiValueAnnotationDialog.java b0e0c72c25c5655f8c791bb99b2ed4fd3d0b0c3e GREEN
IMultiValueAnnotationEditingSupport.java 12e93b20e71e31d30c54e6b9ead8895aaa38454c GREEN
LabelValueMapping.java 3b7a9c6112cc56595ec99f3b3ea0d469a61ebf1d GREEN
MultiValueAnnotationDialogBase.java 9d9e6e10e11d1d03a3c5a8c86c3d887aa39e37a6 GREEN
MultiValueAnnotationEditingSupportBase.java ac228c1a4dec5d7035729585c2dcb9799da6aba9 GREEN
MultiValueAnnotationSelectionDialog.java eb493c084158bfaf4267d6a1f3dd41bcf0867eef GREEN
MultiValueAnnotationSelectionEditingSupport.java a4c3c3f9c3cc4f43f27c95f9ba676b4bef01e157 GREEN
MultiValueAnnotationTextEditingDialog.java 50cf3bb99fe93be4b8f6453f563860193f6fcea4 GREEN
MultiValueAnnotationTextEditingSupport.java 38c780819396fc75d10fbb660832652d89d59378 GREEN
TextEditingSupport.java e761ea393816f23ca41157f2a9a9a8d8ef30b858 GREEN
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import static org.eclipse.jface.dialogs.MessageDialog.openError;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.widgets.Shell;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* Base class for {@link EditingSupport}s used to display an manipulate
* {@link IAnnotatedSpecification}s in {@link TableViewer}-based annotation views.
*
* @author barner
*/
public abstract class AnnotationEditingSupportBase extends EditingSupport {
/** Value used to allow user to unset annotation value. */
protected final static String UNSET_RESERVED_VALUE = "";
/** Specification class of this column. */
protected Class<? extends IAnnotatedSpecification> specClass;
/** Constructs a new {@link AnnotationEditingSupportBase}. */
public AnnotationEditingSupportBase(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> specClass) {
super(viewer);
this.specClass = specClass;
}
/** {@inheritDoc} */
@Override
protected boolean canEdit(Object element) {
if(element instanceof AnnotationEntry) {
AnnotationEntry annotationEntry = (AnnotationEntry)element;
return annotationEntry.canEdit(specClass);
}
return true;
}
/** Actually gets the value from the {@link IAnnotatedSpecification}. */
protected Object doGetValue(AnnotationEntry annotationEntry) {
return annotationEntry.getSpecificationValue(specClass);
}
/** {@inheritDoc} */
@Override
protected Object getValue(Object element) {
if(element instanceof AnnotationEntry) {
return doGetValue((AnnotationEntry)element);
}
return null;
}
/** Actually sets a {@link String} value into a {@link IAnnotatedSpecification}. */
protected void doSetValue(AnnotationEntry annotationEntry, String value) throws Exception {
annotationEntry.setSpecificationValue(value, specClass);
}
/** Actually sets a value into a {@link IAnnotatedSpecification}. */
protected void doSetValue(AnnotationEntry annotationEntry, Object value) throws Exception {
annotationEntry.setSpecificationValue(value, specClass);
}
/** {@inheritDoc} */
@Override
protected void setValue(Object element, final Object value) {
if(element instanceof AnnotationEntry) {
final AnnotationEntry annotationEntry = (AnnotationEntry)element;
ITopLevelElement modelContext = IPersistencyService.getInstance()
.getTopLevelElementFor(annotationEntry.getModelElement());
modelContext.runAsCommand(() -> {
try {
doSetValue(annotationEntry, value);
} catch(IllegalArgumentException e) {
String msg =
"The value you entered does not have the desired type.\nDetailed message:\n" +
e.getMessage();
openError(new Shell(), "ERROR", msg);
} catch(Exception e) {
openError(new Shell(), "ERROR", e.getMessage());
}
});
this.getViewer().refresh(true);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.widgets.Composite;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.annotation.valueprovider.ValueProviderBase;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IDerivedAnnotation;
/**
* {@link EditingSupport} providing a {@link ComboBoxViewerCellEditor} for suitable
* {@link IAnnotatedSpecification}s ({@link EEnum}s, fixed set of {@link String}s,
* {@link EReference}s).
*
* @author diewald
*/
public class ComboBoxEditingSupport extends AnnotationEditingSupportBase {
/** Combo box cell editor. */
private ComboBoxViewerCellEditor cellEditor = null;
/** Flag if this {@link ComboBoxEditingSupport} is editable. */
boolean isEditable;
/**
* Input-choice based on an {@link EStructuralFeature} (i.e., {@link EEnum} or
* {@link EReference}).
*/
EStructuralFeatureDescriptor eStructuralFeatureDescriptor;
/**
* Base constructor that sets up the {@link ComboBoxEditingSupport} (apart from the set of
* available choices which is prepared on demand in {@link #getCellEditor(Object)}.
*/
public ComboBoxEditingSupport(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, boolean isEditable) {
super(viewer, clazz);
this.isEditable = isEditable;
cellEditor = new ComboBoxViewerCellEditor((Composite)getViewer().getControl());
cellEditor.setLabelProvider(new LabelProvider());
cellEditor.setContentProvider(new ArrayContentProvider());
cellEditor.getViewer().getCCombo().setEditable(isEditable);
}
/**
* Creates a {@link ComboBoxEditingSupport} for a {@link EStructuralFeature}-based input-choice
* (i.e., {@link EEnum} or {@link EReference}.
*/
public ComboBoxEditingSupport(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, IAnnotatedSpecification specification,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor) {
// EENumns and EReferences are only of a set of possible choices, hence they are not
// 'editable'
// @CodeFormatterOff (cannot use local variables before explicit call of constructor)
this(viewer, clazz,
!(eStructuralFeatureDescriptor.getEType(specification) instanceof EEnum ||
eStructuralFeatureDescriptor.getEType(specification) instanceof EClass));
// @CodeFormatterOn
this.eStructuralFeatureDescriptor = eStructuralFeatureDescriptor;
}
/**
* <p>
* Creates a {@link LabelValueMapping} for the given {@link AnnotationEntry}.
* </p>
* <p>
* Note: Since {@link IDerivedAnnotation}s support that the {@link EStructuralFeature} of their
* return value is changed at runtime, the resulting {@link LabelValueMapping} should not be
* cached.
* </p>
*/
@SuppressWarnings("unchecked")
private <T extends IAnnotatedSpecification> LabelValueMapping
getLabelValueMapping(AnnotationEntry entry) {
ValueProviderBase<T> valueProvider =
(ValueProviderBase<T>)entry.getAnnotationValueProvider(specClass);
valueProvider.updateInputChoice(getViewer().getInput(), (Class<T>)specClass);
return new LabelValueMapping(eStructuralFeatureDescriptor,
entry.getSpecification(specClass), entry.getModelElement(),
valueProvider.getCurrentInputChoice());
}
/** {@inheritDoc} */
@Override
protected CellEditor getCellEditor(Object element) {
if(!(element instanceof AnnotationEntry)) {
return null;
}
AnnotationEntry entry = (AnnotationEntry)element;
List<String> labels = new ArrayList<String>(getLabelValueMapping(entry).getLabels());
// Allow to unset EReferences. This does not make sense for EENums which have a default
// value. Resetting of String-based annotations is handled in TextEditingSupport.
if(eStructuralFeatureDescriptor != null && eStructuralFeatureDescriptor
.getEType(entry.getSpecification(specClass)) instanceof EClass) {
labels.add(UNSET_RESERVED_VALUE);
}
cellEditor.setInput(labels);
return cellEditor;
}
/** {@inheritDoc} */
@Override
protected void setValue(Object element, Object label) {
if(!(element instanceof AnnotationEntry)) {
return;
}
if(isEditable && label == null) {
// New values, i.e values that have been entered into the text input field, and have not
// been selected from the combo box are indicated by a null value. Hence, fetch the text
// from the corresponding UI control.
label = ((CCombo)cellEditor.getControl()).getText();
}
if(label != null) {
super.setValue(element,
label.equals(UNSET_RESERVED_VALUE) ? null
: getLabelValueMapping((AnnotationEntry)element)
.getValueForLabel(label.toString()));
}
}
/** {@inheritDoc} */
@Override
protected Object getValue(Object element) {
return getLabel(element);
}
/**
* Returns a {@link String} label for the given annotation (identified by its
* {@link AnnotationEntry}).
*/
public String getLabel(Object element) {
if(!(element instanceof AnnotationEntry)) {
return null;
}
Object value = super.getValue(element);
if(value != null) {
return getLabelValueMapping((AnnotationEntry)element).getLabelForValue(value);
}
return null;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2015 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.ui.annotation.editingsupport;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.fortiss.tooling.base.annotation.valueprovider.DerivedAnnotationValueProviderBase;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor.EReferenceScope;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureValueProviderBase;
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.IDerivedAnnotation;
import org.fortiss.tooling.base.ui.annotation.view.generic.GenericAnnotationView;
/**
* Factory to build {@link AnnotationEditingSupportBase}-based {@link EditingSupport} for the
* {@link GenericAnnotationView}.
*
* @author barner
*/
public class EditingSupportFactory {
/**
* Creates the {@link EditingSupport} that is directly based on
* {@link DerivedAnnotationValueProviderBase}.
*/
private static <T extends IDerivedAnnotation<?>, V extends DerivedAnnotationValueProviderBase<T>>
EditingSupport createEditingSupport4DerivedAnnotationValueProviderBase(V valueProvider,
ColumnViewer viewer, Class<? extends IAnnotatedSpecification> clazz,
T specification) throws Exception {
if(!valueProvider.isEditableByUser()) {
return null;
}
return createEditingSupport4EStructuralFeatureValueProviderBase(
(EStructuralFeatureValueProviderBase<T>)valueProvider, viewer, clazz,
specification);
}
/**
* Creates the {@link EditingSupport} that is directly based on
* {@link EStructuralFeatureValueProviderBase}.
*
* @param valueProvider
* Annotation's {@link IAnnotationValueProvider}
* @param viewer
* {@link ColumnViewer} used to display annotation
* @param clazz
* Annotation type
* @param specification
* Annotation instance
* @return {@link EditingSupport} that is directly based on
* {@link EStructuralFeatureValueProviderBase}.
*/
private static <T extends IAnnotatedSpecification, V extends EStructuralFeatureValueProviderBase<T>>
EditingSupport createEditingSupport4EStructuralFeatureValueProviderBase(V valueProvider,
ColumnViewer viewer, Class<? extends IAnnotatedSpecification> clazz,
T specification) throws Exception {
EStructuralFeature structuralFeature = valueProvider.getEStructuralFeatureDescriptor()
.getEStructuralFeature(specification);
if(structuralFeature == null) {
throw new Exception("EStructuralValueProvider: feature has not been set.");
}
if(structuralFeature.getUpperBound() == 0) {
throw new Exception(
"EStructuralValueProvider: feature multiplicity == 0 is not supported.");
}
EClassifier eType = structuralFeature.getEType();
EStructuralFeatureDescriptor eStructuralFeatureDescriptor =
valueProvider.getEStructuralFeatureDescriptor();
if(structuralFeature.getUpperBound() == 1) {
EReferenceScope eReferenceScope = eStructuralFeatureDescriptor.getEReferenceScope();
boolean isSimpleType = (!(eType instanceof EEnum)) && (!(eType instanceof EClass));
if(isSimpleType || ((eType instanceof EClass) && (eReferenceScope == null))) {
return createEditingSupport4ValueProviderBase((ValueProviderBase<T>)valueProvider,
viewer, clazz, specification);
}
return new ComboBoxEditingSupport(viewer, clazz, specification,
eStructuralFeatureDescriptor);
}
if(eType instanceof EClass) {
return new MultiValueAnnotationSelectionEditingSupport<EObject>(viewer, clazz,
specification, eStructuralFeatureDescriptor);
} else if(eType instanceof EEnum) {
return new MultiValueAnnotationSelectionEditingSupport<EEnumLiteral>(viewer, clazz,
specification, eStructuralFeatureDescriptor);
}
return new MultiValueAnnotationTextEditingSupport<String>(viewer, clazz, specification,
eStructuralFeatureDescriptor);
}
/**
* Creates the {@link EditingSupport} for value providers that are directly based on
* {@link ValueProviderBase}.
*
* @param valueProvider
* Annotation's {@link IAnnotationValueProvider}
* @param viewer
* {@link ColumnViewer} used to display annotation
* @param clazz
* Annotation type
* @param specification
* Annotation instance
* @return {@link EditingSupport} for value providers that are directly based on
* {@link ValueProviderBase}.
*/
@SuppressWarnings("unchecked")
private static <T extends IAnnotatedSpecification, V extends ValueProviderBase<T>>
EditingSupport createEditingSupport4ValueProviderBase(V valueProvider,
ColumnViewer viewer, Class<? extends IAnnotatedSpecification> clazz,
T specification) throws Exception {
try {
valueProvider.updateInputChoice(viewer.getInput(), (Class<T>)clazz);
} catch(Exception e) {
// Use standard text editor as fall-back
valueProvider.setCurrentInputChoice(null);
}
// Input is not restricted -> free editing in text cell
Collection<String> currentInputChoice = valueProvider.getCurrentInputChoice();
if(currentInputChoice == null) {
if(valueProvider.getAnnotationValue(specification) instanceof Boolean) {
return new CheckBoxEditingSupport(viewer, clazz);
}
return new TextEditingSupport(viewer, clazz);
}
// Input is restricted to concrete set of values
// (use SingleEnumAttributeValueProviderBase for EEnum types!)
List<String> fixedInputChoice = valueProvider.getFixedInputChoice();
return new ComboBoxEditingSupport(viewer, clazz, fixedInputChoice.isEmpty());
}
/**
* Creates an {@link EditingSupport} for the given {@link IAnnotatedSpecification}.
*
* @param valueProvider
* Annotation's {@link IAnnotationValueProvider}
* @param viewer
* {@link ColumnViewer} used to display annotation
* @param clazz
* Annotation type
* @param specification
* Annotation instance
* @return {@link EditingSupport} for the given {@link IAnnotatedSpecification}.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static <T extends IAnnotatedSpecification> EditingSupport createEditingSupport(
IAnnotationValueProvider<T> valueProvider, ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, T specification) throws Exception {
if(valueProvider instanceof DerivedAnnotationValueProviderBase<?>) {
return createEditingSupport4DerivedAnnotationValueProviderBase(
(DerivedAnnotationValueProviderBase)valueProvider, viewer, clazz,
(IDerivedAnnotation)specification);
} else if(valueProvider instanceof EStructuralFeatureValueProviderBase<?>) {
return createEditingSupport4EStructuralFeatureValueProviderBase(
(EStructuralFeatureValueProviderBase<T>)valueProvider, viewer, clazz,
specification);
}
if(valueProvider instanceof ValueProviderBase<?>) {
return createEditingSupport4ValueProviderBase((ValueProviderBase<T>)valueProvider,
viewer, clazz, specification);
}
return null;
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.kernel.model.INamedCommentedElement;
/**
* {@link EditingSupport} that allows to edit the comment of {@link INamedCommentedElement}s.
*
* @author barner
*/
public class ElementCommentEditingSupport extends ElementEditingSupportBase {
/** Constructs a new {@link ElementCommentEditingSupport}. */
public ElementCommentEditingSupport(ColumnViewer viewer) {
super(viewer);
}
/** {@inheritDoc} */
@Override
protected Object doGetValue(AnnotationEntry annotationEntry) {
IModelElement modelElement = annotationEntry.getModelElement();
if(modelElement instanceof INamedCommentedElement) {
return ((INamedCommentedElement)modelElement).getComment();
}
return null;
}
/** {@inheritDoc} */
@Override
protected void doSetValue(AnnotationEntry annotationEntry, String value) throws Exception {
IModelElement modelElement = annotationEntry.getModelElement();
if(modelElement instanceof INamedCommentedElement) {
((INamedCommentedElement)modelElement).setComment(value);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
/**
* Base class for {@link EditingSupport}s that directly access models element fields (and not the
* model elements {@link IAnnotatedSpecification}s).
*
* @author barner
*/
public class ElementEditingSupportBase extends TextEditingSupport {
/** Constructs a new {@link ElementEditingSupportBase}. */
public ElementEditingSupportBase(ColumnViewer viewer) {
// Specification class is not needed, since the name is stored
// directly in the model (hence pass {@code null}).
super(viewer, null);
}
/** {@inheritDoc} */
@Override
protected boolean canEdit(Object element) {
return true;
}
/** {@inheritDoc} */
@Override
protected void doSetValue(AnnotationEntry annotationEntry, Object value) throws Exception {
String strVal = value.toString();
if(value.toString().equals(UNSET_RESERVED_VALUE)) {
strVal = null;
}
// Forward to String-based variant of doSetValue()
doSetValue(annotationEntry, strVal);
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.computeFullyQualifiedName;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.computeRelativeName;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor.EReferenceScope;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.kernel.model.IIdLabeled;
import org.fortiss.tooling.kernel.model.INamedElement;
import org.fortiss.tooling.kernel.model.IProjectRootElement;
import org.fortiss.tooling.kernel.utils.HierarchicalNameComparator;
/**
* Translates between the labels shown in a GUI and actual model elements (=values) (e.g.,
* required to integrate {@link EReference}s into {@link ComboBoxEditingSupport} or
* {@link MultiValueAnnotationSelectionEditingSupport}. This class ensures that its label set is
* unique.
*
* @author barner
*/
public class LabelValueMapping {
/** Map: label -> actual value */
private Map<String, Object> labelToValueMap;
/** {@link String}-based input choice */
Collection<String> stringLabels;
/**
* Constructs a {@link LabelValueMapping}. {@code eStructuralFeatureDescriptor} may be
* {@code null} in which case this translator acts as the identity-function.
*/
public LabelValueMapping(EStructuralFeatureDescriptor eStructuralFeatureDescriptor,
IAnnotatedSpecification specification, EObject modelElement,
Collection<String> stringLabels) {
if(eStructuralFeatureDescriptor == null) {
this.stringLabels = stringLabels;
return;
}
EClassifier eType = eStructuralFeatureDescriptor.getEType(specification);
if(eType instanceof EEnum) {
createEnumLabels((EEnum)eType, eStructuralFeatureDescriptor, modelElement);
} else if(eType instanceof EClass) {
EObject root = null;
switch(eStructuralFeatureDescriptor.getEReferenceScope()) {
case PROJECT:
root = getParentElement(modelElement, IProjectRootElement.class, true);
if(root != null) {
// Get FileProject (type is not available in this plugin)
root = root.eContainer();
}
break;
case MODEL:
root = getParentElement(modelElement, IProjectRootElement.class, true);
break;
case SUB_MODEL:
case STRICT_SUB_MODEL:
root = modelElement;
break;
}
if(root == null) {
return;
}
EList<EObject> values = new BasicEList<EObject>();
if(eStructuralFeatureDescriptor.getEReferenceScope() == EReferenceScope.SUB_MODEL) {
values.add(root);
}
@SuppressWarnings("unchecked") Class<? extends EObject> instanceClass =
(Class<? extends EObject>)eType.getInstanceClass();
for(EObject obj : getChildrenWithType(root, instanceClass)) {
if(eStructuralFeatureDescriptor.isAvailableObject(obj, specification,
modelElement)) {
values.add(obj);
}
}
Collections.sort(values, new HierarchicalNameComparator());
labelToValueMap = new LinkedHashMap<String, Object>();
for(Object v : values) {
if(v instanceof INamedElement) {
if(root instanceof INamedElement) {
String label = computeRelativeName((INamedElement)root, (INamedElement)v);
if(eStructuralFeatureDescriptor.getEReferenceScope()
.equals(EStructuralFeatureDescriptor.EReferenceScope.PROJECT)) {
// Strip explicit qualification of project name
int i = label.indexOf(".");
if(i != -1) {
label = label.substring(i + 1);
}
}
addLabelValuePair(label, v);
} else {
addLabelValuePair(computeFullyQualifiedName((INamedElement)v), v);
}
} else {
addLabelValuePair(v.toString(), v);
}
}
}
}
/**
* Creates the enum labels based on the literals that are given by the
* {@link EStructuralFeatureDescriptor}.
*/
private void createEnumLabels(EEnum eType,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor, EObject modelElement) {
labelToValueMap = new LinkedHashMap<String, Object>();
Set<String> enumValues = new TreeSet<String>();
Collection<EEnumLiteral> literalsToShow =
eStructuralFeatureDescriptor.getEnumLiterals(eType, modelElement);
for(EEnumLiteral e : literalsToShow) {
enumValues.add(e.getName());
addLabelValuePair(e.getName(), e.getInstance());
}
}
/** Returns the set of labels managed by this {@link LabelValueMapping}. */
public Collection<String> getLabels() {
if(labelToValueMap == null) {
return stringLabels;
}
return labelToValueMap.keySet();
}
/**
* Adds a label / value pair to this {@link LabelValueMapping}. This methods ensures that the
* label set managed by this {@link LabelValueMapping} unique.
*/
private void addLabelValuePair(String label, Object value) {
// Append IDs for IIdLabeled objects
if(value instanceof IIdLabeled) {
label += " [Id=" + ((IIdLabeled)value).getId() + "]";
}
// Be extra careful and add unique suffix if required.
String prefix = new String(label);
int i = 1;
while(labelToValueMap.keySet().contains(label)) {
label = prefix + " (" + i + ")";
i++;
}
label = prefix;
labelToValueMap.put(label, value);
}
/** Translates a value into the corresponding label. */
public String getLabelForValue(Object value) {
if(labelToValueMap == null) {
return value != null ? value.toString() : "";
}
for(String key : labelToValueMap.keySet()) {
Object currValue = labelToValueMap.get(key);
if(value == currValue) {
return key;
}
}
// In case the label could not be found, return a string representation of the value. This
// is useful to implement custom label providers for model elements are edited in combo
// boxes.
return value != null ? value.toString() : "";
}
/** Translates a label into the corresponding value. */
public Object getValueForLabel(String label) {
if(labelToValueMap == null) {
return label;
}
return labelToValueMap.get(label);
}
}
/*-------------------------------------------------------------------------+
| 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.ui.annotation.editingsupport;
import static org.eclipse.emf.ecore.ETypedElement.UNBOUNDED_MULTIPLICITY;
import static org.eclipse.emf.ecore.ETypedElement.UNSPECIFIED_MULTIPLICITY;
import java.util.Collection;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
/**
* Base class for dialogs to select/edit values of multi-valued annotations.
*
* @author barner
*/
public abstract class MultiValueAnnotationDialogBase<T> extends Dialog
implements IMultiValueAnnotationDialog<T> {
/** Lower multiplicity bound. */
private int lowerMultiplicityBound;
/** Upper multiplicity bound. */
private int upperMultiplicityBound;
/** Name of action performed in this dialog. */
private String actionName;
/** The collection of elements selected/edited using this dialog. */
private Collection<T> elements;
/** Constructs a new {@link MultiValueAnnotationDialogBase}. */
public MultiValueAnnotationDialogBase(String actionName, int lowerMultiplicityBound,
int upperMultiplicityBound) {
super((Shell)null);
this.actionName = actionName;
this.lowerMultiplicityBound = lowerMultiplicityBound;
this.upperMultiplicityBound = upperMultiplicityBound;
}
/** {@inheritDoc} */
@Override
protected final Control createButtonBar(Composite parent) {
Control ctrl = super.createButtonBar(parent);
updateOkButton();
return ctrl;
}
/** Helper to select the right number for "element". */
private String titleElementStringHelper(int n) {
return n != 1 ? "elements" : "element";
}
/** {@inheritDoc} */
@Override
protected final void configureShell(Shell newShell) {
super.configureShell(newShell);
String title;
if(lowerMultiplicityBound == UNSPECIFIED_MULTIPLICITY || lowerMultiplicityBound == 0) {
if(upperMultiplicityBound == UNSPECIFIED_MULTIPLICITY ||
upperMultiplicityBound == UNBOUNDED_MULTIPLICITY) {
title = actionName + " multiple elements";
} else {
title = actionName + " at most " + upperMultiplicityBound + " " +
titleElementStringHelper(upperMultiplicityBound);
}
} else {
if(upperMultiplicityBound == UNSPECIFIED_MULTIPLICITY ||
upperMultiplicityBound == UNBOUNDED_MULTIPLICITY) {
title = actionName + " at least " + lowerMultiplicityBound + " " +
titleElementStringHelper(lowerMultiplicityBound);
} else {
title = actionName + " " + lowerMultiplicityBound + " to " +
upperMultiplicityBound + " " +
titleElementStringHelper(upperMultiplicityBound);
}
}
newShell.setText(title);
}
/** Enables the Ok button iff the multiplicity constraints are met. */
protected final void updateOkButton() {
Button okButton = getButton(IDialogConstants.OK_ID);
int numElements = getElementsFromDialog().size();
boolean lowerBoundOk = lowerMultiplicityBound == UNSPECIFIED_MULTIPLICITY ||
numElements >= lowerMultiplicityBound;
boolean upperBoundOk = upperMultiplicityBound == UNSPECIFIED_MULTIPLICITY ||
upperMultiplicityBound == UNBOUNDED_MULTIPLICITY ||
numElements <= upperMultiplicityBound;
okButton.setEnabled(lowerBoundOk && upperBoundOk);
}
/** {@inheritDoc} */
@Override
protected final void okPressed() {
elements = getElementsFromDialog();
super.okPressed();
}
/** {@inheritDoc} */
@Override
public final Collection<T> getElements() {
return elements;
}
/** Returns the current {@link Collection} of elements from the corresponding widget of the editor. */
protected abstract Collection<T> getElementsFromDialog();
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import java.util.Collection;
import java.util.Iterator;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.DialogCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.fortiss.tooling.base.annotation.AnnotationEntry;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.model.INamedElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
/**
* Base class for {@link EditingSupport}s for annotations that can hold multiple values.
*
* @author barner
*/
public abstract class MultiValueAnnotationEditingSupportBase<T> extends AnnotationEditingSupportBase
implements IMultiValueAnnotationEditingSupport<T> {
/** The underlying annotation */
protected IAnnotatedSpecification specification;
/** Annotation's {@link EStructuralFeatureDescriptor}. */
protected EStructuralFeatureDescriptor eStructuralFeatureDescriptor;
/** Constructs a new {@link MultiValueAnnotationEditingSupportBase}. */
public MultiValueAnnotationEditingSupportBase(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, IAnnotatedSpecification specification,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor) {
super(viewer, clazz);
this.specification = specification;
this.eStructuralFeatureDescriptor = eStructuralFeatureDescriptor;
}
/** {@inheritDoc} */
@Override
protected CellEditor getCellEditor(Object element) {
if(!(element instanceof AnnotationEntry)) {
return null;
}
AnnotationEntry entry = (AnnotationEntry)element;
Object value = entry.getSpecificationValue(specClass);
if(!(value instanceof Collection<?>)) {
return null;
}
Composite parent = (Composite)getViewer().getControl();
@SuppressWarnings("unchecked") IMultiValueAnnotationDialog<T> dialog =
createMultiEditingDialog(parent, entry.getModelElement(), (Collection<T>)value);
return new MultiValueAnnotationCellEditor(parent, dialog);
}
/** {@inheritDoc} */
@Override
protected boolean canEdit(Object element) {
return true;
}
/** {@inheritDoc} */
@Override
protected Object getValue(Object element) {
return getLabel(element);
}
/** {@inheritDoc} */
@Override
public String getLabel(Object element) {
if(element instanceof AnnotationEntry) {
AnnotationEntry entry = (AnnotationEntry)element;
Object value = entry.getSpecificationValue(specClass);
if(value instanceof Collection<?>) {
StringBuffer valueCollectionString = new StringBuffer();
for(Iterator<?> iter = ((Collection<?>)value).iterator(); iter.hasNext();) {
Object v = iter.next();
if(v instanceof INamedElement) {
valueCollectionString.append(((INamedElement)v).getName());
} else {
valueCollectionString.append(v != null ? v.toString() : "<null>");
}
if(iter.hasNext()) {
valueCollectionString.append(", ");
}
}
return "[" + valueCollectionString + "]";
}
}
return "[]";
}
/** {@inheritDoc} */
@Override
protected void setValue(Object element, final Object value) {
// Writes back into the model the collection of selected elements
if(element instanceof AnnotationEntry && value instanceof Collection<?>) {
final AnnotationEntry entry = (AnnotationEntry)element;
ITopLevelElement modelContext = IPersistencyService.getInstance()
.getTopLevelElementFor(entry.getModelElement());
modelContext.runAsCommand(new Runnable() {
@Override
public void run() {
try {
entry.setSpecificationValue(value, specClass);
} catch(Exception e) {
return;
}
}
});
}
}
/** {@link CellEditor} that opens a dialog to edit a multi-valued annotation. */
private class MultiValueAnnotationCellEditor extends DialogCellEditor {
/** The dialog opened by this cell editor. */
private IMultiValueAnnotationDialog<T> dialog;
/** Constructor. */
public MultiValueAnnotationCellEditor(Composite parent,
IMultiValueAnnotationDialog<T> dialog) {
super(parent);
this.dialog = dialog;
}
/** {@inheritDoc} */
@Override
protected Object openDialogBox(Control cellEditorWindow) {
dialog.open();
return dialog.getElements();
}
}
}
/*-------------------------------------------------------------------------+
| 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.ui.annotation.editingsupport;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.mihalis.opal.itemSelector.DLItem;
import org.mihalis.opal.itemSelector.DualList;
import org.mihalis.opal.itemSelector.SelectionChangeEvent;
import org.mihalis.opal.itemSelector.SelectionChangeListener;
/**
* Dialog that allows to select multiple values
*
* @author barner
*/
public class MultiValueAnnotationSelectionDialog<T> extends MultiValueAnnotationDialogBase<T> {
/** Element selection dialog */
private DualList dl;
/** Mapping: label shown in GUI -> actual value. */
private LabelValueMapping labelValueMapping;
/** The {@link Collection} of initially selected elements. */
private Collection<T> initialElements;
/** Constructs a new {@link MultiValueAnnotationSelectionDialog}. */
public MultiValueAnnotationSelectionDialog(LabelValueMapping labelValueMapping,
EStructuralFeature eStructuralFeature, Collection<T> initialElements) {
super("Select", eStructuralFeature.getLowerBound(), eStructuralFeature.getUpperBound());
this.labelValueMapping = labelValueMapping;
this.initialElements = initialElements;
setShellStyle(getShellStyle() | SWT.RESIZE);
}
/** {@inheritDoc} */
@Override
protected Composite createDialogArea(Composite parent) {
/* Generate the dialog and its layout */
Composite area = (Composite)super.createDialogArea(parent);
area.setLayout(new FillLayout());
dl = new LabelValueMappingDualList(area, initialElements, labelValueMapping);
dl.addSelectionChangeListener(new SelectionChangeListener() {
@Override
public void widgetSelected(SelectionChangeEvent e) {
updateOkButton();
}
});
return area;
}
/** {@inheritDoc} */
@Override
protected Point getInitialSize() {
return new Point(800, 400);
}
/** {@inheritDoc} */
@Override
@SuppressWarnings("unchecked")
protected Collection<T> getElementsFromDialog() {
List<T> elements = new ArrayList<>();
for(DLItem item : dl.getSelection()) {
if(item != null) {
elements.add((T)labelValueMapping.getValueForLabel(item.getText()));
}
}
return elements;
}
/** Extension of {@link DualList} that is initialized from {@link LabelValueMapping}s. */
private class LabelValueMappingDualList extends DualList {
/**
* Constructs a new {@link LabelValueMappingDualList}.
*
* @param parent
* Parent {@link Composite} widget
* @param selectedElements
* Collection of elements that are selected initially
* @param labelValueMapping
* {@link LabelValueMapping} required to populate this
* {@link LabelValueMappingDualList}.
*/
public LabelValueMappingDualList(Composite parent, Collection<?> selectedElements,
LabelValueMapping labelValueMapping) {
super(parent, SWT.NONE);
List<String> labels = new ArrayList<String>();
labels.addAll(labelValueMapping.getLabels());
for(Object selectedItem : selectedElements) {
String label = labelValueMapping.getLabelForValue(selectedItem);
DLItem item = new DLItem(label);
add(item);
selectDoNotFireEvent(0);
remove(item);
labels.remove(label);
}
for(String label : labels) {
DLItem item = new DLItem(label);
add(item);
}
}
/** {@inheritDoc} */
@Override
public void deselectAll(final boolean shouldFireEvents) {
super.deselectAll(shouldFireEvents);
// Required to issue a selection changed event after all elements have actually been
// deselected. This is required for the invocation of
// MultiSelectionDialog.updateOkButton() to work correctly.
super.deselectAll(false);
}
}
}
/*-------------------------------------------------------------------------+
| Copyright 2014 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.ui.annotation.editingsupport;
import java.util.Collection;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.swt.widgets.Composite;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IModelElement;
/**
* {@link EditingSupport} that supports the selection of multiple values.
*
* @author barner
*/
public class MultiValueAnnotationSelectionEditingSupport<T>
extends MultiValueAnnotationEditingSupportBase<T> {
/** Constructs a new {@link MultiValueAnnotationSelectionEditingSupport}. */
public MultiValueAnnotationSelectionEditingSupport(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, IAnnotatedSpecification specification,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor) {
super(viewer, clazz, specification, eStructuralFeatureDescriptor);
}
/** {@inheritDoc} */
@Override
public IMultiValueAnnotationDialog<T> createMultiEditingDialog(Composite parent,
IModelElement modelElement, Collection<T> values) {
LabelValueMapping labelValueMapping = new LabelValueMapping(eStructuralFeatureDescriptor,
specification, modelElement, null);
EStructuralFeature eStructuralFeature =
eStructuralFeatureDescriptor.getEStructuralFeature(specification);
return new MultiValueAnnotationSelectionDialog<T>(labelValueMapping, eStructuralFeature,
values);
}
}
/*-------------------------------------------------------------------------+
| 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.ui.annotation.editingsupport;
import static java.lang.Integer.compare;
import static java.lang.Math.min;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import java.util.Collection;
import java.util.OptionalInt;
import java.util.stream.IntStream;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SegmentEvent;
import org.eclipse.swt.events.SegmentListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Text;
/**
* Dialog that allows to edit multiple values
*
* @author barner
*/
public class MultiValueAnnotationTextEditingDialog<T> extends MultiValueAnnotationDialogBase<T> {
/** The {@link Text} into which input is entered. */
private Text textInput;
/** {@link List} containing the current input. */
private List list;
/** {@link Button} to add the current value of {@link #textInput} to {@link #list}. */
private Button addButton;
/** {@link Button} to remove the currently selected item from {@link #list}. */
private Button removeButton;
/** {@link Button} to move up the currently selected item of {@link #list}. */
private Button upButton;
/** {@link Button} to move down the currently selected item of {@link #list}. */
private Button downButton;
/** Flag if dialog is currently set up in {@link #createDialogArea(Composite)}. */
private boolean isCreateDialogArea;
/** Underlying {@link EAttribute}. */
private EAttribute eAttribute;
/** The {@link Collection} of initial values. */
private Collection<T> initialValues;
/** Constructs a new {@link MultiValueAnnotationTextEditingDialog}. */
public MultiValueAnnotationTextEditingDialog(EAttribute eAttribute,
Collection<T> initialValues) {
super("Add", eAttribute.getLowerBound(), eAttribute.getUpperBound());
this.eAttribute = eAttribute;
this.initialValues = initialValues;
}
/** Returns the {@link EFactory} for the underlying {@link #eAttribute}. */
protected EFactory getEFactory() {
return eAttribute.getEType().getEPackage().getEFactoryInstance();
}
/** Refreshes the status of the dialog's UI elements. */
protected void refresh() {
if(isCreateDialogArea) {
return;
}
boolean isValidText = true;
try {
EFactory eFactory = getEFactory();
eFactory.createFromString(eAttribute.getEAttributeType(), textInput.getText());
} catch(Exception e) {
isValidText = false;
}
addButton.setEnabled(isValidText);
OptionalInt min = stream(list.getSelectionIndices()).reduce(Integer::min);
OptionalInt max = stream(list.getSelectionIndices()).reduce(Integer::max);
removeButton.setEnabled(min.isPresent());
upButton.setEnabled(min.isPresent() && min.getAsInt() > 0);
downButton.setEnabled(max.isPresent() && max.getAsInt() < list.getItemCount() - 1);
}
/** {@inheritDoc} */
@Override
protected Composite createDialogArea(Composite parent) {
isCreateDialogArea = true;
Composite area = (Composite)super.createDialogArea(parent);
area.setLayout(new GridLayout(2, false));
textInput = new Text(area, SWT.BORDER | SWT.LEFT);
GridData gd_Text = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1);
gd_Text.widthHint = 300;
gd_Text.minimumWidth = 300;
textInput.setLayoutData(gd_Text);
textInput.addSegmentListener(new SegmentListener() {
/** {@inheritDoc} */
@Override
public void getSegments(SegmentEvent event) {
refresh();
}
});
addButton = new Button(area, SWT.PUSH);
GridData gd_Buttons = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_Buttons.widthHint = 100;
gd_Buttons.minimumWidth = 100;
addButton.setLayoutData(gd_Buttons);
addButton.setText("Add");
addButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
list.add(textInput.getText());
textInput.setText("");
refresh();
}
});
list = new List(area, SWT.BORDER | SWT.LEFT | SWT.MULTI);
GridData gd_List = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 4);
gd_List.minimumWidth = 310;
gd_List.heightHint = 310;
list.setLayoutData(gd_List);
list.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
refresh();
}
});
for(Object value : initialValues) {
EFactory eFactory = getEFactory();
String valueLabel = eFactory.convertToString(eAttribute.getEAttributeType(), value);
list.add(valueLabel);
}
removeButton = new Button(area, SWT.PUSH);
removeButton.setLayoutData(gd_Buttons);
removeButton.setText("Remove");
removeButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
int[] selectionIndices = list.getSelectionIndices();
int index = -1;
if(selectionIndices.length == 1) {
index = selectionIndices[0];
}
for(int i : selectionIndices) {
list.remove(i);
}
list.setSelection(min(index, list.getItemCount()));
refresh();
}
});
upButton = new Button(area, SWT.PUSH);
upButton.setLayoutData(gd_Buttons);
upButton.setText("Up");
upButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
stream(list.getSelectionIndices()).sorted().forEach(i -> {
String swap = list.getItem(i - 1);
list.setItem(i - 1, list.getItem(i));
list.setItem(i, swap);
});
IntStream oldIndices = stream(list.getSelectionIndices());
list.deselectAll();
list.select(oldIndices.map(i -> i - 1).toArray());
refresh();
}
});
downButton = new Button(area, SWT.PUSH);
downButton.setLayoutData(gd_Buttons);
downButton.setText("Down");
downButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
stream(list.getSelectionIndices()).boxed().sorted((i1, i2) -> compare(i2, i1))
.forEach(i -> {
String swap = list.getItem(i + 1);
list.setItem(i + 1, list.getItem(i));
list.setItem(i, swap);
});
IntStream oldIndices = stream(list.getSelectionIndices());
list.deselectAll();
list.select(oldIndices.map(i -> i + 1).toArray());
refresh();
}
});
isCreateDialogArea = false;
refresh();
return area;
}
/** {@inheritDoc} */
@Override
public void create() {
super.create();
getShell().setDefaultButton(addButton);
}
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
protected Collection<T> getElementsFromDialog() {
return (Collection<T>)asList(list.getItems());
}
}
/*-------------------------------------------------------------------------+
| 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.ui.annotation.editingsupport;
import java.util.Collection;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.swt.widgets.Composite;
import org.fortiss.tooling.base.annotation.valueprovider.EStructuralFeatureDescriptor;
import org.fortiss.tooling.base.model.element.IAnnotatedSpecification;
import org.fortiss.tooling.base.model.element.IModelElement;
/**
* {@link EditingSupport} for textual editing of multi-value annotations.
*
* @author barner
*/
public class MultiValueAnnotationTextEditingSupport<T>
extends MultiValueAnnotationEditingSupportBase<T> {
/** Constructs a new {@link MultiValueAnnotationTextEditingSupport}. */
public MultiValueAnnotationTextEditingSupport(ColumnViewer viewer,
Class<? extends IAnnotatedSpecification> clazz, IAnnotatedSpecification specification,
EStructuralFeatureDescriptor eStructuralFeatureDescriptor) {
super(viewer, clazz, specification, eStructuralFeatureDescriptor);
}
/** {@inheritDoc} */
@Override
public IMultiValueAnnotationDialog<T> createMultiEditingDialog(Composite parent,
IModelElement modelElement, Collection<T> values) {
EStructuralFeature eStructuralFeature =
eStructuralFeatureDescriptor.getEStructuralFeature(specification);
return new MultiValueAnnotationTextEditingDialog<T>((EAttribute)eStructuralFeature, values);
}
}