Commit 1018e652 authored by Ashmi Banerjee's avatar Ashmi Banerjee

FTA Editor WIP

Bug in GUI

Issue Ref: 3462
Signed-off-by: default avatarAshmi Banerjee <ashmi.banerjee@tum.de>
parents 55c25626 f1a8d629
......@@ -38,27 +38,35 @@ import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.af3.mira.model.functional.FunctionalFactory;
import org.fortiss.af3.mira.model.functional.Signal;
import org.fortiss.af3.mira.model.safety.FTASolutionRequirementSpecification;
import org.fortiss.af3.mira.model.safety.MinCutSets;
import org.fortiss.af3.mira.model.safety.SafetyFactory;
import org.fortiss.tooling.base.model.element.IModelElementSpecification;
import org.fortiss.tooling.base.ui.ToolingBaseUIActivator;
import org.fortiss.tooling.base.ui.editor.StyledTextCellEditor;
import org.fortiss.tooling.base.ui.utils.TreeViewerUtils;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.ui.presentation.ModelElementLabelProvider;
import org.fortiss.tooling.kernel.ui.service.IActionService;
import org.fortiss.tooling.kernel.ui.util.SelectionUtils;
......@@ -67,68 +75,64 @@ import org.fortiss.tooling.kernel.ui.util.SelectionUtils;
* @author ashmi
*/
public class FTASolutionRequirementEditor<T extends Requirement> extends AspectEditorBase<T> {
private TreeViewer viewer;
/** The edited solution specification. */
private FTASolutionRequirementSpecification spec;
/** Label width. */
public static final int PROPERTIES_LABEL_WIDTH = 150;
/** List of the registered source viewers. We store this in a field because.... */
protected List<SourceViewer> localRegisteredSourceViewers;
/** Default text displayed in the input signals table. */
private static final String CLICK_TO_ADD_A_NEW_SIGNAL = "Click to add a new signal";
/**
* The tree viewer displaying the signals table. Only used as a table, but we use trees
* because it does
* not cost anything.
*/
private TreeViewer viewer;
private static final String CLICK_TO_ADD_A_NEW_MINCUTSET = "Click to add a new min cut set";
/** Top level element for the edited object. */
private ITopLevelElement top;
/** List of the registered source viewers. We store this in a field because.... */
protected List<SourceViewer> localRegisteredSourceViewers;
/** The default shell - for component dialog. */
private Shell shell;
/** {@inheritDoc} */
@Override
protected void createAspectSection() {
localRegisteredSourceViewers = new ArrayList<SourceViewer>();
EList<IModelElementSpecification> specs = editedObject.getSpecifications();
spec = pickFirstInstanceOf(FTASolutionRequirementSpecification.class, specs);
addFTAHeaderSection(spec);
addSignalSection(spec);
addFTADefinitionSection(spec);
addTableFTASection(spec);
}
/**
* Definition of the Hazard section
* Definition of the FTA section
*/
private void addFTAHeaderSection(FTASolutionRequirementSpecification spec) {
Composite headerSection =
createNewSection("FTA Solution Requirement",
"This requirement defines FTA parameters:");
headerSection.setLayout(new GridLayout(2, false));
Label nameLabel = toolkit.createLabel(headerSection, "Name: ", SWT.READ_ONLY);
private void addFTADefinitionSection(FTASolutionRequirementSpecification spec) {
Composite FTASection =
createNewSection("FTA Solution", "This requirement defines FTA parameters:");
FTASection.setLayout(new GridLayout(2, false));
Label nameLabel = toolkit.createLabel(FTASection, "FTA Name ", SWT.READ_ONLY);
singleLineLabelFactory.applyTo(nameLabel);
SourceViewer inputName = createSourceViewer(form, headerSection, SWT.BORDER, analysis);
SourceViewer inputName = createSourceViewer(form, FTASection, SWT.BORDER, analysis);
registeredSourceViewers.add(inputName);
singleLineInputFactory.applyTo(inputName.getControl());
bind(dbc, inputName.getTextWidget(), spec, INAMED_ELEMENT__NAME);
}
/** {@inheritDoc} */
@Override
protected List<IModelElementSpecification> getElementsToDelete() {
ArrayList<IModelElementSpecification> res = new ArrayList<>();
res.addAll(pickInstanceOf(FTASolutionRequirementSpecification.class,
editedObject.getSpecifications()));
return res;
Label eventLabel = toolkit.createLabel(FTASection, "FTA Main Event Name ", SWT.READ_ONLY);
singleLineLabelFactory.applyTo(eventLabel);
SourceViewer inputEventName = createSourceViewer(form, FTASection, SWT.BORDER, analysis);
registeredSourceViewers.add(inputEventName);
singleLineInputFactory.applyTo(inputEventName.getControl());
bind(dbc, inputEventName.getTextWidget(), spec, INAMED_ELEMENT__NAME);
}
/** Section for signal component. */
private Composite addSignalSection(FTASolutionRequirementSpecification ms) {
private Composite addTableFTASection(FTASolutionRequirementSpecification spec) {
Composite ftaSection =
createNewSection("Table of minimum cut sets",
"This requirement defines the table of minimum cut sets ");
createNewSection("Input Signals",
"This requirement defines the MinCut Set Solution:");
ftaSection.setLayout(new GridLayout(1, false));
viewer = new TreeViewer(ftaSection, SWT.BORDER | SWT.FULL_SELECTION);
Tree tree = viewer.getTree();
......@@ -147,62 +151,105 @@ public class FTASolutionRequirementEditor<T extends Requirement> extends AspectE
/** {@inheritDoc} */
@Override
public String getText(Object element) {
if(element instanceof FakeChild) {
return "Click to add a cut set component";
}
return spec.getMinCutSet().get((Integer)element).getName();
return "ID";
// return spec.getMinCutSet().get((Integer)element).getName();
}
});
nameColumn.setEditingSupport(createNameEditingSupport(viewer, nameColumn));
Button addMinCutSetRowButton =
toolkit.createButton(ftaSection, "Add min cut set row ", SWT.FLAT);
Button addMinCutSetElementButton =
toolkit.createButton(ftaSection, "Add min cut set element", SWT.FLAT);
Button delMinCutSetElementButton =
toolkit.createButton(ftaSection, "Delete min cut set element", SWT.FLAT);
Button delMinCutSetRowButton =
toolkit.createButton(ftaSection, "Delete min cut set row", SWT.FLAT);
addMinCutSetElementButton(spec, addMinCutSetElementButton);
addMinCutSetRowButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
modelContext.runAsCommand(new Runnable() {
MinCutSets mcs = SafetyFactory.eINSTANCE.createMinCutSets();
@Override
public void run() {
spec.getMinCutSet().add(mcs);
}
});
}
});
viewer.setContentProvider(new TreeContentProviderBase() {
@Override
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof List<?>) {
List<Object> range = new ArrayList<Object>();
range.add(new FakeChild());
range.addAll(IntStream.rangeClosed(0, ms.getMinCutSet().size() - 1).boxed()
MinCutSets mcs = SafetyFactory.eINSTANCE.createMinCutSets();
// spec.getMinCutSet().add(mcs);
// range.add(new FakeChild());
range.add(mcs);
range.addAll(IntStream.rangeClosed(0, spec.getMinCutSet().size() - 1).boxed()
.collect(Collectors.toList()));
return range.toArray();
}
return new Object[0];
}
});
viewer.getControl().addKeyListener(new ViewerKeyAdapter());
viewer.setInput(spec.getMinCutSet());
return ftaSection;
}
/** Fake child used to add new elements. */
private static class FakeChild {
// Nothing to implement: just a marker class
}
/**
* Checks if the name is empty or already exists among current signals, if so displays an error
* message and return true, otherwise returns false.
* @param spec
* @param addMinCutSetElementButton
*/
private boolean emptyOrAlreadyExists(String name) {
if(name.equals("") || name.equals(CLICK_TO_ADD_A_NEW_SIGNAL)) {
Status status =
new Status(ERROR, ToolingBaseUIActivator.PLUGIN_ID, 0,
"Signal name is not valid.", null);
openError(Display.getCurrent().getActiveShell(), "Error", null, status);
return true;
}
List<String> signalNames =
spec.getMinCutSet().stream().map(c -> c.getName().toLowerCase())
.collect(Collectors.toList());
if(signalNames.contains(name.toLowerCase()) ||
name.toLowerCase().equals(CLICK_TO_ADD_A_NEW_SIGNAL)) {
Status status =
new Status(ERROR, ToolingBaseUIActivator.PLUGIN_ID, 0,
"A Signal with this name already exists.", null);
openError(Display.getCurrent().getActiveShell(), "Error", null, status);
return true;
}
return false;
private void addMinCutSetElementButton(FTASolutionRequirementSpecification spec,
Button addMinCutSetElementButton) {
addMinCutSetElementButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
ITreeContentProvider tcp = new FormalSpecificationTreeContentProvider();
ElementTreeSelectionDialog dlg =
new ElementTreeSelectionDialog(shell, new ModelElementLabelProvider(), tcp);
dlg.setAllowMultiple(false);
dlg.setTitle("Select the Min Cut Set Rows)");
EList<MinCutSets> cutSetList =
pickInstanceOf(MinCutSets.class, editedObject.getContainer()
.getContainedElements());
ArrayList<MinCutSets> csList = new ArrayList<MinCutSets>();
for(MinCutSets cs : cutSetList) {
if(pickInstanceOf(MinCutSets.class, cs.getCutSet()).size() > 0) {
csList.add(cs);
}
}
dlg.setInput(csList);
if(dlg.open() == 1 || dlg.getResult().length == 0) {
return;
}
modelContext.runAsCommand(new Runnable() {
@Override
public void run() {
spec.getRelatedTo().add((Requirement)dlg.getFirstResult());
viewer.refresh();
}
});
}
});
}
/** {@link EditingSupport} for the name column. */
......@@ -214,15 +261,13 @@ public class FTASolutionRequirementEditor<T extends Requirement> extends AspectE
@Override
protected void setValue(Object element, Object value) {
if(element instanceof FakeChild) {
if(!emptyOrAlreadyExists((String)value)) {
top.runAsCommand(() -> {
Signal newSig = FunctionalFactory.eINSTANCE.createSignal();
newSig.setName((String)value);
spec.getMinCutSet().add(newSig);
viewer.refresh();
});
}
if(!emptyOrAlreadyExists((String)value)) {
top.runAsCommand(() -> {
MinCutSets newMcs = SafetyFactory.eINSTANCE.createMinCutSets();
newMcs.setName((String)value);
spec.getMinCutSet().add(newMcs);
viewer.refresh();
});
}
}
......@@ -244,6 +289,41 @@ public class FTASolutionRequirementEditor<T extends Requirement> extends AspectE
};
}
/**
* Checks if the name is empty or already exists among current signals, if so displays an error
* message and return true, otherwise returns false.
*/
private boolean emptyOrAlreadyExists(String name) {
if(name.equals("") || name.equals(CLICK_TO_ADD_A_NEW_MINCUTSET)) {
Status status =
new Status(ERROR, ToolingBaseUIActivator.PLUGIN_ID, 0,
"Signal name is not valid.", null);
openError(Display.getCurrent().getActiveShell(), "Error", null, status);
return true;
}
List<String> signalNames =
spec.getMinCutSet().stream().map(c -> c.getName().toLowerCase())
.collect(Collectors.toList());
if(signalNames.contains(name.toLowerCase()) ||
name.toLowerCase().equals(CLICK_TO_ADD_A_NEW_MINCUTSET)) {
Status status =
new Status(ERROR, ToolingBaseUIActivator.PLUGIN_ID, 0,
"A Signal with this name already exists.", null);
openError(Display.getCurrent().getActiveShell(), "Error", null, status);
return true;
}
return false;
}
/** {@inheritDoc} */
@Override
protected List<IModelElementSpecification> getElementsToDelete() {
ArrayList<IModelElementSpecification> res = new ArrayList<IModelElementSpecification>();
res.addAll(pickInstanceOf(FTASolutionRequirementSpecification.class,
editedObject.getSpecifications()));
return res;
}
/** Key adapter to deal with copy/paste/delete/... done through the keyboard. */
public class ViewerKeyAdapter extends KeyAdapter {
/** Constructor. */
......@@ -269,5 +349,4 @@ public class FTASolutionRequirementEditor<T extends Requirement> extends AspectE
}
}
}
}
......@@ -203,7 +203,7 @@ public class AspectBindings {
/** {@inheritDoc} */
@Override
public String getLabel() {
return "FTA Solution definition";
return "FTA Solution";
}
/** {@inheritDoc} */
......
......@@ -32,12 +32,17 @@ Export-Package: org.fortiss.af3.mira,
org.fortiss.af3.mira.model.requirementSource.impl,
org.fortiss.af3.mira.model.requirementSource.util,
org.fortiss.af3.mira.model.safety,
org.fortiss.af3.mira.model.safety.impl,
org.fortiss.af3.mira.model.safety.util,
org.fortiss.af3.mira.model.security,
org.fortiss.af3.mira.model.security.impl,
org.fortiss.af3.mira.model.security.util,
org.fortiss.af3.mira.model.timing,
org.fortiss.af3.mira.model.timing.impl,
org.fortiss.af3.mira.model.timing.util,
org.fortiss.af3.mira.model.usecase,
org.fortiss.af3.mira.model.usecase.impl,
org.fortiss.af3.mira.model.usecase.util,
org.fortiss.af3.mira.model.util,
org.fortiss.af3.mira.model.verification,
org.fortiss.af3.mira.model.verification.impl,
......
......@@ -841,7 +841,12 @@
<eClassifiers xsi:type="ecore:EClass" name="FTASolutionRequirementSpecification"
eSuperTypes="platform:/resource/org.fortiss.tooling.base/model/base.ecore#//element/IModelElementSpecification #//INonFunctionalRequirement platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedElement">
<eStructuralFeatures xsi:type="ecore:EReference" name="minCutSet" upperBound="-1"
eType="#//functional/Signal" containment="true"/>
eType="#//safety/MinCutSets" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="mainEvent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="MinCutSets" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedElement">
<eStructuralFeatures xsi:type="ecore:EReference" name="cutSet" upperBound="-1"
eType="ecore:EClass platform:/resource/org.fortiss.tooling.base/model/base.ecore#//element/IModelElement"/>
</eClassifiers>
</eSubpackages>
</ecore:EPackage>
......@@ -431,6 +431,11 @@
</genClasses>
<genClasses ecoreClass="mira.ecore#//safety/FTASolutionRequirementSpecification">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference mira.ecore#//safety/FTASolutionRequirementSpecification/minCutSet"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute mira.ecore#//safety/FTASolutionRequirementSpecification/mainEvent"/>
</genClasses>
<genClasses ecoreClass="mira.ecore#//safety/MinCutSets">
<genFeatures notify="false" createChild="false" propertySortChoices="true"
ecoreFeature="ecore:EReference mira.ecore#//safety/MinCutSets/cutSet"/>
</genClasses>
</nestedGenPackages>
</genPackages>
......
......@@ -11,46 +11,86 @@
uri="http://www.fortiss.org/af3/mira"
class="org.fortiss.af3.mira.model.MiraPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/usecase"
class="org.fortiss.af3.mira.model.usecase.UsecasePackage"/>
class="org.fortiss.af3.mira.model.usecase.UsecasePackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/relations"
class="org.fortiss.af3.mira.model.relations.RelationsPackage"/>
class="org.fortiss.af3.mira.model.relations.RelationsPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/verification"
class="org.fortiss.af3.mira.model.verification.VerificationPackage"/>
class="org.fortiss.af3.mira.model.verification.VerificationPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/functional"
class="org.fortiss.af3.mira.model.functional.FunctionalPackage"/>
class="org.fortiss.af3.mira.model.functional.FunctionalPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/glossary"
class="org.fortiss.af3.mira.model.glossary.GlossaryPackage"/>
class="org.fortiss.af3.mira.model.glossary.GlossaryPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/requirementSource"
class="org.fortiss.af3.mira.model.requirementSource.RequirementSourcePackage"/>
class="org.fortiss.af3.mira.model.requirementSource.RequirementSourcePackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/constraints"
class="org.fortiss.af3.mira.model.constraints.ConstraintsPackage"/>
class="org.fortiss.af3.mira.model.constraints.ConstraintsPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/timing"
class="org.fortiss.af3.mira.model.timing.TimingPackage"/>
class="org.fortiss.af3.mira.model.timing.TimingPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/security"
class="org.fortiss.af3.mira.model.security.SecurityPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.eclipse.emf.ecore.generated_package">
<!-- @generated mira -->
<package
uri="http://www.fortiss.org/af3/mira/safety"
class="org.fortiss.af3.mira.model.safety.SafetyPackage"
genModel="model/mira.genmodel"/>
</extension>
<extension point="org.fortiss.tooling.kernel.modelPrototypeProvider">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment