From a3e117c4f06bd2fdd5ba8fd6ff3de91d5dd41573 Mon Sep 17 00:00:00 2001
From: Andreas Bayha <bayha@fortiss.org>
Date: Wed, 15 Jul 2020 11:44:23 +0200
Subject: [PATCH] Annotations: AnnotationView uses Generic Combo Column

Factored out the combo column to a generic implementation. Now, a
generic implementation for dynamic combo columns is reusable for all
DynamicTreetBaleViewers.

Issue-Ref: 4014
Issue-Url: https://af3-developer.fortiss.org/issues/4014
Signed-off-by: Andreas Bayha <bayha@fortiss.org>
---
 .../base/ui/annotation/view/fx/.ratings       |  1 +
 .../view/fx/AnnotationFxViewPart.java         | 10 +--
 .../view/fx/AnnotationViewFXController.java   | 89 ++++++++-----------
 3 files changed, 42 insertions(+), 58 deletions(-)
 create mode 100644 org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/.ratings

diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/.ratings
new file mode 100644
index 000000000..69936262e
--- /dev/null
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/.ratings
@@ -0,0 +1 @@
+AnnotationFxViewPart.java 34c845f7162a8a8bb680df6ee08160ce63a5a5a3 YELLOW
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java
index f7ea5e728..34c845f71 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationFxViewPart.java
@@ -20,19 +20,15 @@ import org.fortiss.tooling.common.ui.javafx.AF3FXViewPart;
 import javafx.scene.Scene;
 
 /**
+ * ViewPart for the FX implementation of the AnnotationView.
  * 
  * @author bayha
  */
 public class AnnotationFxViewPart extends AF3FXViewPart {
 
-	private static final AnnotationViewFXController VIEW_CONTROLLER =
-			new AnnotationViewFXController();
+	private static final AnnotationViewFXController VIEW_CONTROLLER = new AnnotationViewFXController();
 
-	/**
-	 * @param controller
-	 * @param cssLocation
-	 * @throws Exception
-	 */
+	/** Constructor. */
 	public AnnotationFxViewPart() throws Exception {
 		super(VIEW_CONTROLLER, null);
 	}
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java
index 642d916e5..b09c33d40 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/annotation/view/fx/AnnotationViewFXController.java
@@ -20,6 +20,7 @@ import static java.util.stream.Collectors.toList;
 import static javafx.scene.control.TreeSortMode.ALL_DESCENDANTS;
 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.LoggingUtils.showWarning;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -55,17 +56,12 @@ import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
 import org.fortiss.tooling.kernel.model.INamedCommentedElement;
 import org.fortiss.tooling.kernel.service.IPersistencyService;
 
-import javafx.collections.FXCollections;
-import javafx.collections.ObservableList;
 import javafx.fxml.FXML;
 import javafx.scene.Node;
 import javafx.scene.control.SplitPane;
 import javafx.scene.control.TreeItem;
-import javafx.scene.control.TreeTableCell;
 import javafx.scene.control.TreeTableColumn;
 import javafx.scene.control.TreeTableView;
-import javafx.scene.control.cell.ComboBoxTreeTableCell;
-import javafx.util.Callback;
 
 /**
  * 
@@ -75,26 +71,17 @@ import javafx.util.Callback;
 public class AnnotationViewFXController extends CompositeFXControllerBase<SplitPane, Node>
 		implements ISelectionListener {
 
-	/**  */
-	@FXML
-	private SplitPane annotationSplitPane;
 
 	/**  */
 	@FXML
 	private TreeTableView<AnnotationEntry> annotationTreeTableView;
 
 	/**  */
-	private DynamicTreeTableViewer<AnnotationEntry> annotationTreeViewer;
+	private DynamicTreeTableViewer<AnnotationEntry> annotationViewer;
 
 	/**  */
 	private IModelElement selectedElement;
 
-	/**  */
-	private DynamicTreeContentProviderBase<AnnotationEntry> contentProvider = new AnnotationTableContentProvider();
-
-	/**  */
-	private DynamicTreeTableUIProviderBase<AnnotationEntry> uiProvider = new AnnotationTreeTableUIProvider();
-
 	/**
 	 * Associates the handles of the annotations with their ordered column indexes.
 	 * Used for the UI providers of cell items.
@@ -135,13 +122,13 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
 		// Collect the annotation entries for all elements.
 		EList<IModelElement> childElements = getChildrenWithType(selectedElement, IModelElement.class);
 
-		ArtificialRoot root = new ArtificialRoot(selectedElement);
+		ArtificialRoot rootElement = new ArtificialRoot(selectedElement);
 
 		for (IModelElement elem : childElements) {
 			AnnotationEntry entry = IAnnotationValueService.getInstance().getAnnotationEntry(elem);
 
 			if (entry != null && !entry.getSpecificationsList().isEmpty()) {
-				root.elements.add(entry);
+				rootElement.elements.add(entry);
 			}
 		}
 
@@ -166,11 +153,13 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
 		// The DynamicTreeTableViewer needs to be created new, as the root is different.
 		boolean showRoot = false;
 		int revealLevel = 1;
-		annotationTreeViewer = new DynamicTreeTableViewer<AnnotationEntry>(annotationTreeTableView, root, showRoot,
+		DynamicTreeTableUIProviderBase<AnnotationEntry> uiProvider = new AnnotationTreeTableUIProvider();
+		DynamicTreeContentProviderBase<AnnotationEntry> contentProvider = new AnnotationTableContentProvider();
+		annotationViewer = new DynamicTreeTableViewer<AnnotationEntry>(annotationTreeTableView, rootElement, showRoot,
 				revealLevel, contentProvider, uiProvider);
 
-		annotationTreeViewer.addColumn("Model Element", 200);
-		annotationTreeViewer.addColumn("Comment", 250);
+		annotationViewer.addColumn("Model Element", 200);
+		annotationViewer.addColumn("Comment", 250);
 
 		int columnIdx = 2;
 		for (ColumnHandle<IAnnotatedSpecification> handle : sortedColumnHandles) {
@@ -194,44 +183,39 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
 
 		String columnName = valueProvider.getAnnotationName(specification);
 
-		TreeTableColumn<AnnotationEntry, String> column = annotationTreeViewer.addColumn(columnName, 150);
 		colIdxAnnotationMap.put(columnIdx, handle);
 
+		TreeTableColumn<AnnotationEntry, String> column = null;
+
+		// Case distinction for the cell factory depending on the type to be edited.
 		if (valueType == null) {
+			column = annotationViewer.addColumn(columnName, 150);
 			column.setEditable(false);
-			return;
-		}
-
-		column.setEditable(true);
 
-		// 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();
+			return;
+		} else if (valueType instanceof EEnum) {
+			// Add a combo column for enumerations.
+			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();
 
-					items.clear();
-					items.addAll(allLiterals.stream().map(l -> l.getLiteral()).collect(toList()));
+					return allLiterals.stream().map(l -> l.getLiteral()).collect(toList());
 				}
+				return emptyList();
 			});
 		} else if (valueType.getInstanceClass().equals(Boolean.class)) {
-			System.out.println(valueType);
+			// Use a checkbox column for booleans
+			annotationViewer.addCheckboxColumn(columnName, 100);
 		} else {
 			// For all other types, there is text editing.
+			column = annotationViewer.addColumn(columnName, 150);
 			column.setCellFactory(ttColumn -> new DynamicTextFieldTreeTableCell<AnnotationEntry>() {
 				protected boolean canEdit(AnnotationEntry element) {
 					// We start editing only, if this cell is supposed to be editable.
@@ -249,19 +233,23 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
 			});
 		}
 
-		column.setOnEditCommit(event -> {
-			TreeItem<AnnotationEntry> treeItem = event.getRowValue();
-			AnnotationEntry rowEntry = treeItem.getValue();
-			String newValue = event.getNewValue();
+		if (column != null) {
+			column.setEditable(true);
 
-			setAnnotationEntryValue(specification, rowEntry, newValue);
-		});
+			column.setOnEditCommit(event -> {
+				TreeItem<AnnotationEntry> treeItem = event.getRowValue();
+				AnnotationEntry rowEntry = treeItem.getValue();
+				String newValue = event.getNewValue();
 
-		column.setOnEditCancel(event -> {
-			System.out.println(event);
-		});
+				setAnnotationEntryValue(specification, rowEntry, newValue);
+			});
+		}
 	}
 
+	/**
+	 * Local helper to set the given newValue for the given annotationEntry and
+	 * specification.
+	 */
 	private void setAnnotationEntryValue(IAnnotatedSpecification specification, AnnotationEntry annotationEntry,
 			String newValue) {
 		ITopLevelElement tle = IPersistencyService.getInstance().getTopLevelElementFor(selectedElement);
@@ -270,8 +258,7 @@ public class AnnotationViewFXController extends CompositeFXControllerBase<SplitP
 			try {
 				annotationEntry.setSpecificationValue(newValue, specification.getClass());
 			} catch (Exception e1) {
-				// TODO Auto-generated catch block
-				e1.printStackTrace();
+				showWarning("Problem during setting an AnnotationValue: \n" + e1.getStackTrace());
 			}
 		});
 	}
-- 
GitLab