From 63467a17d06397b831373b0d736da9cb404436dd Mon Sep 17 00:00:00 2001 From: Simon Barner <barner@fortiss.org> Date: Tue, 30 Jan 2018 14:27:19 +0000 Subject: [PATCH] Ensure that hint how to create a connection is displayed until the user has successfully created one IConnection specialization. refs 2229 --- .../fortiss/tooling/base/ui/editor/.ratings | 3 +- .../ui/editor/CommonDiagramEditorBase.java | 82 ++++++++++--------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/.ratings b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/.ratings index ac0bea468..2b36aa4f2 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/.ratings +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/.ratings @@ -1,7 +1,6 @@ - AdvancedTreeViewerEditorBase.java 731483771c9d23f5b926da79b027b570001ea6cd GREEN AllocationDiagramEditorBase.java 3c03b9220f1c342ded673d6d1b2fd2c01b57fba6 GREEN -CommonDiagramEditorBase.java d1b10f0eae6fe13508d185c0cc983c46747928dc RED +CommonDiagramEditorBase.java 3d83b0b5eb1081b0a85e88d291062f215a7ca74e YELLOW ConstraintBasedProcessEditor.java ff7253ad26f25f681e09a36d0527b0214df08d30 RED DiagramEditorBase.java 3d2bb40e18548ebca0dfdd78f094598e5ee298d1 GREEN DiagramKeyHandler.java 9c59eca862c9f878da7cbf7c220f26b38737095c GREEN diff --git a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/CommonDiagramEditorBase.java b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/CommonDiagramEditorBase.java index 90047a448..47355bf09 100644 --- a/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/CommonDiagramEditorBase.java +++ b/org.fortiss.tooling.base.ui/trunk/src/org/fortiss/tooling/base/ui/editor/CommonDiagramEditorBase.java @@ -25,6 +25,7 @@ import static org.eclipse.gef.editparts.ZoomManager.FIT_WIDTH; import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_GRID_ORIGIN_X; import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_GRID_ORIGIN_Y; import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_GRID_SIZE; +import static org.fortiss.tooling.common.util.LambdaUtils.asStream; import static org.fortiss.tooling.kernel.ui.util.EObjectSelectionUtils.getEObjectElements; import static org.fortiss.tooling.kernel.ui.util.EObjectSelectionUtils.getFirstElement; @@ -34,6 +35,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.conqat.ide.commons.ui.selection.SelectionUtils; @@ -44,7 +46,6 @@ import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EContentAdapter; import org.eclipse.gef.EditDomain; @@ -141,15 +142,32 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< /** A container for editor actions. */ private final ActionRegistry actionRegistry = new ActionRegistry(); - /** - * Number of times the hint was displayed until we assume the user knows how to draw a - * connection. - */ - private static int numberOfHintDisplays = 1; + /** Maps projects to the number of {@link IConnection} contained in them. */ + private static Map<EObject, Long> connectionCountMap = new HashMap<EObject, Long>(); + + /** Predicate whether to show the hint how to create {@link IConnection}s. */ + private static boolean shouldDisplayCreateConnectionHint(EObject object) { + if(connectionCountMap == null) { + return false; + } + + // Determine number of connections in current rootObject ("project") + EObject rootObject = getRootObject(object); + Long n = asStream(rootObject.eAllContents()).filter(e -> e instanceof IConnection).count(); - /** Returns numberOfHintDisplays *and decrements it*. */ - private static boolean shouldDisplayHint() { - return numberOfHintDisplays-- >= 0; + Long oldN = connectionCountMap.get(rootObject); + boolean rval = oldN == null || n <= oldN; + if(rval == false) { + // Increase in IConnection count detected: Disable hint. + for(EObject obj : connectionCountMap.keySet()) { + obj.eAdapters().remove(addConnectionAdapter); + } + connectionCountMap = null; + } else { + connectionCountMap.put(rootObject, n); + } + + return rval; } /** Constructor. */ @@ -158,10 +176,7 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< this.editPartFactory = factory; } - /** - * Adapter to watch for added {@link IConnection}s (used to update {@link #numberOfHintDisplays} - * ). - */ + /** Adapter to watch for added {@link IConnection}s. */ private static final Adapter addConnectionAdapter = new EContentAdapter() { @Override public void notifyChanged(Notification notification) { @@ -177,18 +192,8 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< Object newValue = notification.getNewValue(); if(eventType == Notification.ADD && newValue instanceof IConnection && notification.getNotifier() == ((EObject)newValue).eContainer()) { - if(!shouldDisplayHint()) { - // Hints will no longer be displayed: remove adapter - EObject rootObj = (EObject)notification.getNotifier(); - while(rootObj.eContainer() != null) { - rootObj = rootObj.eContainer(); - } - rootObj.eAdapters().remove(addConnectionAdapter); - for(TreeIterator<EObject> iter = rootObj.eAllContents(); iter.hasNext();) { - EObject obj = iter.next(); - obj.eAdapters().remove(addConnectionAdapter); - } - } + + shouldDisplayCreateConnectionHint((EObject)notification.getNotifier()); } } }; @@ -205,7 +210,7 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< Object model = ep.getModel(); String hint = ""; - if(shouldDisplayHint()) { + if(model instanceof EObject && shouldDisplayCreateConnectionHint((EObject)model)) { String key = Platform.getOS().equals(Platform.OS_LINUX) ? "Ctrl" : "Alt"; String commonStr = " by pressing " + key + " and dragging"; if(model instanceof IConnector) { @@ -213,8 +218,6 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< } else if(model instanceof IHierarchicElement) { hint = "Create a connection" + commonStr; } - hint += - " (select anything on the diagram to prevent further display of this message)."; } control.setToolTipText(hint); } @@ -231,20 +234,25 @@ abstract class CommonDiagramEditorBase<T extends EObject> extends GEFEditorBase< .addSelectionListener(selectionListener); // Install adapter to top-most object to watch for addition of IConnections. - if(shouldDisplayHint()) { - EObject model = getEditedObject(); - EObject obj = model; - while(obj != null) { - obj = obj.eContainer(); - } - // TODO(VA) shouldn't obj be used here? Otherwise obj is used nowhere... - if(!model.eAdapters().contains(addConnectionAdapter)) { - model.eAdapters().add(addConnectionAdapter); + if(shouldDisplayCreateConnectionHint(getEditedObject())) { + EObject rootObj = getRootObject(getEditedObject()); + + if(!rootObj.eAdapters().contains(addConnectionAdapter)) { + rootObj.eAdapters().add(addConnectionAdapter); } } viewer.setKeyHandler(new DiagramKeyHandler(viewer)); } + /** Returns the root object of the given {@code object}. */ + private static EObject getRootObject(EObject object) { + EObject rootObj = object; + while(rootObj.eContainer() != null) { + rootObj = rootObj.eContainer(); + } + return rootObj; + } + /** {@inheritDoc} */ @Override public EObject getSelectedModelElement() { -- GitLab