Skip to content
Snippets Groups Projects
Commit 19ffabc3 authored by Andreas Bayha's avatar Andreas Bayha
Browse files

Annotations: Text Editing for Annotation View works

Editing textual-based annotation entries in the table works now.
Also unintended cancel operations (e.g. when clicking onto another cell)
are catched and handled correctly.

It remains to make the implementation more genierc to be reusable for
other views.

Issue-Ref: 4014
Issue-Url: https://af3-developer.fortiss.org/issues/4014


Signed-off-by: default avatarAndreas Bayha <bayha@fortiss.org>
parent ad1bf893
No related branches found
No related tags found
1 merge request!1254014
......@@ -59,12 +59,18 @@ import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.ComboBoxTreeTableCell;
import javafx.scene.control.cell.TextFieldTreeTableCell;
import javafx.scene.input.KeyCode;
import javafx.util.Callback;
import javafx.util.StringConverter;
import javafx.util.converter.DefaultStringConverter;
/**
*
......@@ -189,49 +195,152 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
IAnnotationValueProvider<IAnnotatedSpecification> valueProvider = entry
.getAnnotationValueProvider(annotationClass);
IAnnotatedSpecification specification = entry.getSpecification(annotationClass);
EClassifier valueType = valueProvider.getEStructuralFeatureDescriptor().getEType(specification);
String columnName = valueProvider.getAnnotationName(specification);
TreeTableColumn<AnnotationEntry, String> column = annotationTreeViewer.addColumn(columnName, 150);
colIdxAnnotationMap.put(columnIdx, handle);
ObservableList<String> items = FXCollections.observableArrayList();
Callback<TreeTableColumn<AnnotationEntry, String>, TreeTableCell<AnnotationEntry, String>> comboCellFactory = ComboBoxTreeTableCell
.forTreeTableColumn(items);
column.setCellFactory(comboCellFactory);
if (valueType == null) {
column.setEditable(false);
return;
}
column.setEditable(true);
column.setOnEditStart(event -> {
// Case distinction for the cell factory depending on the type to be edited.
if (valueType instanceof EEnum) {
ObservableList<String> items = FXCollections.observableArrayList();
Callback<TreeTableColumn<AnnotationEntry, String>, TreeTableCell<AnnotationEntry, String>> comboCellFactory = ComboBoxTreeTableCell
.forTreeTableColumn(items);
column.setCellFactory(comboCellFactory);
column.setOnEditStart(event -> {
// We need to get the type for every row individually, as it might be different
// Enums for every row.
TreeItem<AnnotationEntry> treeItem = event.getRowValue();
AnnotationEntry rowEntry = treeItem.getValue();
ValueProviderBase<IAnnotatedSpecification> annotationValueProvider = (ValueProviderBase<IAnnotatedSpecification>) rowEntry
.getAnnotationValueProvider(annotationClass);
EStructuralFeatureDescriptor structuralFeature = annotationValueProvider
.getEStructuralFeatureDescriptor();
EClassifier type = structuralFeature.getEType(rowEntry.getSpecification(annotationClass));
if (type instanceof EEnum) {
EList<EEnumLiteral> allLiterals = ((EEnum) type).getELiterals();
items.clear();
items.addAll(allLiterals.stream().map(l -> l.getLiteral()).collect(toList()));
}
});
} else if (valueType.getInstanceClass().equals(Boolean.class)) {
System.out.println(valueType);
} else {
// For all other types, there is text editing.
column.setCellFactory(
ttColumn -> new AnnotationTextFieldTreeTableCell(new DefaultStringConverter(), annotationClass));
}
column.setOnEditCommit(event -> {
TreeItem<AnnotationEntry> treeItem = event.getRowValue();
AnnotationEntry rowEntry = treeItem.getValue();
ValueProviderBase<IAnnotatedSpecification> annotationValueProvider = (ValueProviderBase<IAnnotatedSpecification>) rowEntry
.getAnnotationValueProvider(annotationClass);
String newValue = event.getNewValue();
setAnnotationEntryValue(specification, rowEntry, newValue);
});
EStructuralFeatureDescriptor structuralFeature = annotationValueProvider.getEStructuralFeatureDescriptor();
column.setOnEditCancel(event -> {
System.out.println(event);
});
}
EClassifier type = structuralFeature.getEType(rowEntry.getSpecification(annotationClass));
if (type instanceof EEnum) {
EList<EEnumLiteral> allLiterals = ((EEnum) type).getELiterals();
private void setAnnotationEntryValue(IAnnotatedSpecification specification, AnnotationEntry annotationEntry,
String newValue) {
ITopLevelElement tle = IPersistencyService.getInstance().getTopLevelElementFor(selectedElement);
items.clear();
items.addAll(allLiterals.stream().map(l -> l.getLiteral()).collect(toList()));
tle.runAsCommand(() -> {
try {
annotationEntry.setSpecificationValue(newValue, specification.getClass());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
});
column.setOnEditCommit(event -> {
TreeItem<AnnotationEntry> treeItem = event.getRowValue();
AnnotationEntry rowEntry = treeItem.getValue();
}
private class AnnotationTextFieldTreeTableCell extends TextFieldTreeTableCell<AnnotationEntry, String> {
private final Class<IAnnotatedSpecification> annotationClass;
private boolean escapePressed = false;
private AnnotationEntry currentlyEditedEntry;
private String currentInput = "";
private AnnotationTextFieldTreeTableCell(StringConverter<String> converter,
Class<IAnnotatedSpecification> annotationClass) {
super(converter);
ITopLevelElement tle = IPersistencyService.getInstance().getTopLevelElementFor(selectedElement);
this.annotationClass = annotationClass;
tle.runAsCommand(() -> {
try {
rowEntry.setSpecificationValue(event.getNewValue(), specification.getClass());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
this.setOnKeyPressed(event -> {
if (event.getCode().equals(KeyCode.ESCAPE)) {
escapePressed = true;
}
});
});
}
@Override
public void startEdit() {
TreeTableRow<AnnotationEntry> row = getTreeTableRow();
AnnotationEntry currentEntry = row.getItem();
// We start editing only, if this cell is supposed to be editable.
IAnnotationValueProvider<IAnnotatedSpecification> annotationValueProvider = currentEntry
.getAnnotationValueProvider(annotationClass);
IAnnotatedSpecification currentSpecification = currentEntry.getSpecification(annotationClass);
if (annotationValueProvider != null && annotationValueProvider.canEdit(currentSpecification)) {
super.startEdit();
currentlyEditedEntry = currentEntry;
// Reset currentInput buffer for the new element.
currentInput = "";
} else {
currentlyEditedEntry = null;
}
// We keep the current input in the buffer variable currentInput to be able to
// use it during unintended cancel options. See cancelEdit().
TextField textField = (TextField) getGraphic();
if (textField != null) {
textField.setOnKeyReleased(event -> {
currentInput = textField.getText();
});
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText(currentInput);
if (escapePressed) {
escapePressed = false;
currentlyEditedEntry = null;
} else {
if (currentlyEditedEntry != null) {
IAnnotatedSpecification specification = currentlyEditedEntry.getSpecification(annotationClass);
setAnnotationEntryValue(specification, currentlyEditedEntry, currentInput);
currentlyEditedEntry = null;
}
}
}
@Override
public void commitEdit(String newValue) {
currentlyEditedEntry = null;
super.commitEdit(newValue);
}
}
/**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment