From 39546a038a68dde35bafc32a6e047cd868bb7450 Mon Sep 17 00:00:00 2001
From: Tiziano Munaro <munaro@fortiss.org>
Date: Tue, 12 Nov 2019 17:28:08 +0100
Subject: [PATCH] [UI] Add support for editable columns within a
 'DynamicTreeTableViewer'

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

Signed-off-by: Tiziano Munaro <munaro@fortiss.org>
---
 .../ui/javafx/control/treetableview/.ratings  |  2 +-
 .../treetableview/DynamicTreeTableViewer.java | 60 +++++++++++++++----
 2 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
index 9c69b3c86..ead9f1fd6 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings
@@ -1,7 +1,7 @@
 DynamicTreeContentProviderBase.java dff437afeaf7486af05460fa54eca4fa61d7eae6 GREEN
 DynamicTreeItem.java afc105cf5acf3d2506d89e0892555100c234ce5b GREEN
 DynamicTreeTableUIProviderBase.java fd9fce19a65eb1006ceacb0d869bbe90a8c578b3 GREEN
-DynamicTreeTableViewer.java e474f3a890fd6525db7de8e299d7fbe67f932a15 GREEN
+DynamicTreeTableViewer.java 7c7b767fac8a3b4450a04f01176d1142911dc199 YELLOW
 DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN
 DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN
 DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN
diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
index e474f3a89..7c7b767fa 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java
@@ -15,13 +15,17 @@
  *******************************************************************************/
 package org.fortiss.tooling.common.ui.javafx.control.treetableview;
 
-import javafx.beans.property.ReadOnlyStringWrapper;
+import javafx.beans.property.SimpleObjectProperty;
+import javafx.event.EventHandler;
 import javafx.scene.Node;
 import javafx.scene.control.ContextMenu;
+import javafx.scene.control.SelectionMode;
 import javafx.scene.control.TreeItem;
 import javafx.scene.control.TreeTableCell;
 import javafx.scene.control.TreeTableColumn;
+import javafx.scene.control.TreeTableColumn.CellEditEvent;
 import javafx.scene.control.TreeTableView;
+import javafx.scene.control.cell.TextFieldTreeTableCell;
 
 /**
  * A JavaFX {@link TreeTableView} based on an {@link DynamicTreeContentProviderBase} and
@@ -51,6 +55,8 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
 		DynamicTreeItem<T> rootItem = new DynamicTreeItem<T>(root, this);
 		view.setRoot(rootItem);
 		view.setShowRoot(showRoot);
+		view.setEditable(true);
+		view.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
 		rootItem.update();
 		// expand to reveal (+1 if root node is not shown
 		expandItem(rootItem, showRoot ? revealLevel : revealLevel + 1);
@@ -82,26 +88,44 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
 		}
 	}
 
-	/** Adds a column to the table part of the view. */
-	public void addColumn(String headerLabel, int prefWidth) {
-		final int num = view.getColumns().size();
-		TreeTableColumn<T, String> col = new TreeTableColumn<>(headerLabel);
-		col.setPrefWidth(prefWidth);
-		col.setCellValueFactory(param -> {
+	/**
+	 * Creates non-editable column displaying the labels as defined by the
+	 * {@link DynamicTreeTableUIProviderBase} used as a basis for specific column types.
+	 */
+	private TreeTableColumn<T, String> createColumn(String headerLabel, int prefWidth) {
+		int num = view.getColumns().size();
+		TreeTableColumn<T, String> column = new TreeTableColumn<>(headerLabel);
+
+		column.setPrefWidth(prefWidth);
+		column.setCellValueFactory(param -> {
 			Object data = param.getValue().getValue();
-			return new ReadOnlyStringWrapper(uiProvider.getLabel(data, num));
+			return new SimpleObjectProperty<String>(uiProvider.getLabel(data, num));
 		});
-		col.setCellFactory(param -> {
+
+		view.getColumns().add(column);
+
+		return column;
+	}
+
+	/**
+	 * Adds a non-editable column to the table part of the view. The labels, context menus and icons
+	 * are shown as defined in the {@link DynamicTreeTableUIProviderBase}.
+	 */
+	public void addColumn(String headerLabel, int prefWidth) {
+		TreeTableColumn<T, String> column = createColumn(headerLabel, prefWidth);
+
+		column.setCellFactory(param -> {
 			TreeTableCell<T, String> cell = new TreeTableCell<T, String>() {
 				@Override
 				protected void updateItem(String item, boolean empty) {
 					super.updateItem(item, empty);
 					ContextMenu menu = null;
 					Node icon = null;
+					int index = view.getColumns().size() - 1;
 					if(!empty && item != null) {
 						T data = this.getTreeTableRow().getItem();
-						menu = uiProvider.createContextMenu(data, num);
-						icon = uiProvider.getIconNode(data, num);
+						menu = uiProvider.createContextMenu(data, index);
+						icon = uiProvider.getIconNode(data, index);
 					}
 					this.setContextMenu(menu);
 					this.setGraphic(icon);
@@ -110,7 +134,19 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
 			cell.textProperty().bind(cell.itemProperty());
 			return cell;
 		});
-		view.getColumns().add(col);
+	}
+
+	/**
+	 * Adds an editable column to the table part of the view. The labels defined in the
+	 * {@link DynamicTreeTableUIProviderBase} are used as predefined values. The
+	 * {@link EventHandler} is executed after a cell has been successfully edited.
+	 */
+	public void addColumn(String headerLabel, int prefWidth,
+			EventHandler<CellEditEvent<T, String>> eventHandler) {
+		TreeTableColumn<T, String> column = createColumn(headerLabel, prefWidth);
+
+		column.setCellFactory(TextFieldTreeTableCell.<T>forTreeTableColumn());
+		column.setOnEditCommit(eventHandler);
 	}
 
 	/** Returns the underlying {@link TreeTableView}. */
-- 
GitLab