From 06e5c328e26e7c3b0d539a541edd105d94660135 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Mon, 3 Feb 2020 15:08:27 +0100
Subject: [PATCH] TreeEditor FX: added default new menu based on compositor.

Issue-Ref: 3907
Issue-Url: https://af3-developer.fortiss.org/issues/3907
Signed-off-by: Florian Hoelzl <hoelzl@fortiss.org>
---
 .../base/ui/editor/fx/controller/.ratings     |   2 +-
 .../editor/fx/controller/ContextMenuUtil.java |   2 +-
 .../ui/javafx/control/treetableview/.ratings  |   4 +-
 .../treetableview/DynamicTreeItem.java        |   2 +-
 .../treetableview/DynamicTreeTableViewer.java |   1 +
 .../org/fortiss/tooling/kernel/utils/.ratings |   1 +
 .../KernelServiceBasedModelListenerBase.java  | 116 ++++++++++++++++++
 7 files changed, 123 insertions(+), 5 deletions(-)
 create mode 100644 org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java

diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings
index 4811e9c29..d08365c17 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings
@@ -1,4 +1,4 @@
-ContextMenuUtil.java 7be87ce47b775d90c533078e22d4d445d9864caf GREEN
+ContextMenuUtil.java a25d01f125fbd84fd199b6d3061eb0aa0a653715 YELLOW
 EObjectDiagramController.java 66b14c1c77953cad7caecae1e04f455958943f28 GREEN
 EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN
 EObjectRectangularResizableContentControllerBase.java 787a540213f29e8daaecd9afe98af8b3f4088db7 GREEN
diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
index 7be87ce47..a25d01f12 100644
--- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
+++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ContextMenuUtil.java
@@ -39,7 +39,7 @@ import javafx.scene.control.MenuItem;
  * 
  * @author hoelzl
  */
-final class ContextMenuUtil {
+public final class ContextMenuUtil {
 	/** Creates the menu populated with composable prototypes. */
 	public static List<MenuItem> createPrototypeMenu(EObject target,
 			IElementCompositionContext context) {
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 3102da926..68513a027 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 e801da995a1b6e5a1b757247c1638bafb6073e6d YELLOW
-DynamicTreeItem.java 15adce9e9a7fedf51f2369abf80e79ef659f066f YELLOW
+DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e YELLOW
 DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 GREEN
-DynamicTreeTableViewer.java 80df0fbe814da719b3fa6dc1644ea3333cffee93 YELLOW
+DynamicTreeTableViewer.java 43757359b3071192ae79710bcbc0e9577bb6f62d 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/DynamicTreeItem.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
index 15adce9e9..75dc5534b 100644
--- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
+++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeItem.java
@@ -22,7 +22,7 @@ import javafx.scene.control.TreeItem;
 
 /**
  * {@link TreeItem} with support for dynamic children using the
- * {@link DynamicTreeItem#update(String)} method.
+ * {@link DynamicTreeItem#update()} method.
  */
 public class DynamicTreeItem<T> extends TreeItem<T> {
 	/** The viewer. */
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 80df0fbe8..43757359b 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
@@ -76,6 +76,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> {
 		// wild cast works: see constructor
 		DynamicTreeItem<T> rootItem = (DynamicTreeItem<T>)view.getRoot();
 		rootItem.update();
+		view.refresh();
 	}
 
 	/** Expands items up to the given level. */
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
index 8fb040ffb..74035b2eb 100644
--- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/.ratings
@@ -7,6 +7,7 @@ HierarchicalNameComparator.java 6face1b673126701a0721af48ead2f9766c17d46 GREEN
 IdentifierUtils.java fff43dc4e84cdd89c3ece4f5d9d89aec4b0749c2 GREEN
 JavaUtils.java 65cdadfb9137a240ad59992eacf53a15b7f20804 GREEN
 KernelModelElementUtils.java fded09befe7e543fc04ea5184ffc1c8a309d7a66 GREEN
+KernelServiceBasedModelListenerBase.java 8d916509ae75f7118ce72564ee715c46556fb709 YELLOW
 LoggingUtils.java 0e0aa5d466d80ea29cfc7e91178b23a5cdd4ddf7 GREEN
 PrototypesUtils.java ec75bed75cfc5103f1f38e3a29df86f729428775 GREEN
 ResourceUtils.java 7f4941a83115dfbed75eb58b79c0a372fe1cbb94 GREEN
diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java
new file mode 100644
index 000000000..8d916509a
--- /dev/null
+++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/utils/KernelServiceBasedModelListenerBase.java
@@ -0,0 +1,116 @@
+/*-------------------------------------------------------------------------+
+| Copyright 2019 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.kernel.utils;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
+import org.fortiss.tooling.kernel.service.ICommandStackService;
+import org.fortiss.tooling.kernel.service.IPersistencyService;
+
+/**
+ * Base class for listeners using EMF {@link Adapter}s and {@link ICommandStackService}.
+ * <P>
+ * Sub-classes should override {@link #updateComplete(List)} in order to be notified when an
+ * update cycle has completed (one or more EMF notifications followed by a command stack
+ * change).
+ * <P>
+ * Sub-classes may also provide their custom EMF {@link Adapter}, but must call
+ * {@link #addNotification(Notification)} whenever a relevant EMF notification occurs.
+ * 
+ * @author hoelzl
+ */
+public abstract class KernelServiceBasedModelListenerBase<T extends EObject>
+		implements CommandStackListener {
+	/** The persistency service reference. */
+	private static final IPersistencyService persistencyService = IPersistencyService.getInstance();
+	/** The command stack service. */
+	private static final ICommandStackService commandStackService =
+			ICommandStackService.getInstance();
+	/** List of relevant {@link Notification}s recorded during a change transaction. */
+	private final List<Notification> notifications = new ArrayList<>();
+
+	/** The model element. */
+	private final T modelElement;
+	/** The EMF notification listener. */
+	private Adapter emfAdapter = new EContentAdapter() {
+		/** {@inheritDoc} */
+		@Override
+		public void notifyChanged(Notification notification) {
+			super.notifyChanged(notification);
+			addNotification(notification);
+		}
+	};
+
+	/** Constructor. */
+	public KernelServiceBasedModelListenerBase(T modelElement, Adapter emfAdapter) {
+		this.modelElement = modelElement;
+		this.emfAdapter = emfAdapter;
+	}
+
+	/** Constructor. */
+	public KernelServiceBasedModelListenerBase(T modelElement) {
+		this.modelElement = modelElement;
+	}
+
+	/**
+	 * Called when the update cycle is completed.
+	 * 
+	 * @param notifications
+	 *            the list of notifications of the completed cycle
+	 */
+	public void updateComplete(List<Notification> notifications) {
+		// default does nothing.
+	}
+
+	/** Adds the given {@link Notification} to list of notifications. */
+	protected final void addNotification(Notification event) {
+		notifications.add(event);
+	}
+
+	/** Registers the listener with the model and the command stack service. */
+	public final void register() {
+		notifications.clear();
+		ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
+		commandStackService.addCommandStackListener(root, this);
+		modelElement.eAdapters().add(emfAdapter);
+	}
+
+	/** Unregisters the listener from the model and the command stack service. */
+	public final void unregister() {
+		modelElement.eAdapters().remove(emfAdapter);
+		ITopLevelElement root = persistencyService.getTopLevelElementFor(modelElement);
+		commandStackService.removeCommandStackListener(root, this);
+		notifications.clear();
+	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void commandStackChanged(EventObject event) {
+		if(notifications.isEmpty()) {
+			return;
+		}
+		updateComplete(notifications);
+		notifications.clear();
+	}
+}
-- 
GitLab