Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Redor2016-03-10 10:52:56 +0000
committerLaurent Redor2016-03-15 09:11:50 +0000
commit20f68be177a1a298ba6c9d60bb9faa2ff1daa443 (patch)
tree5106be6c01abe7ee7ae3aee60c2553168cea3905
parent49cca04d72e542667fbabe872ad2ec2168dbafac (diff)
downloadorg.eclipse.sirius-20f68be177a1a298ba6c9d60bb9faa2ff1daa443.tar.gz
org.eclipse.sirius-20f68be177a1a298ba6c9d60bb9faa2ff1daa443.tar.xz
org.eclipse.sirius-20f68be177a1a298ba6c9d60bb9faa2ff1daa443.zip
[489199] Fix the detected regressions
* Move all code concerning EdgeLayoutUpdaterModelChangeTrigger in this class (instead of in the associated notification filter class RefreshEdgeLayoutNotificationFilter). * Consider the figure in case of one notification * Keep all notifications (not only REFRESH_FEATURES) for the EdgeLayoutUpdaterModelChangeTrigger to be able to detect if other notifications are consequences of the first one. Bug: 489199 Change-Id: I763254bf15a9b13b80c8b18cbf5666b1cf8a004e Signed-off-by: Laurent Redor <laurent.redor@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/EdgeLayoutUpdaterModelChangeTrigger.java163
-rw-r--r--plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/RefreshEdgeLayoutNotificationFilter.java60
2 files changed, 143 insertions, 80 deletions
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/EdgeLayoutUpdaterModelChangeTrigger.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/EdgeLayoutUpdaterModelChangeTrigger.java
index 80e7160f76..dfd873e48c 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/EdgeLayoutUpdaterModelChangeTrigger.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/EdgeLayoutUpdaterModelChangeTrigger.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 THALES GLOBAL SERVICES.
+ * Copyright (c) 2014, 2016 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,26 +13,35 @@ package org.eclipse.sirius.diagram.ui.internal.refresh.listeners;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Set;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.RelativeBendpoints;
import org.eclipse.gmf.runtime.notation.RoutingStyle;
import org.eclipse.sirius.business.api.session.ModelChangeTrigger;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionEventBroker;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.DEdge;
+import org.eclipse.sirius.diagram.DiagramPackage;
import org.eclipse.sirius.diagram.EdgeStyle;
import org.eclipse.sirius.diagram.ui.business.api.view.SiriusGMFHelper;
import org.eclipse.sirius.diagram.ui.business.internal.operation.AbstractModelChangeOperation;
import org.eclipse.sirius.diagram.ui.internal.operation.CenterEdgeEndModelChangeOperation;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
+import org.eclipse.sirius.viewpoint.ViewpointPackage;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
/**
* A Model Change Trigger that execute the
@@ -45,6 +54,36 @@ public class EdgeLayoutUpdaterModelChangeTrigger implements ModelChangeTrigger {
public static final int PRIORITY = FilterListener.COMPOSITE_FILTER_REFRESH_PRIORITY + 1;
+ /**
+ * List of features for which we consider that the edge layout must be
+ * recompute.
+ */
+ private static final Set<EStructuralFeature> REFRESH_FEATURES = new HashSet<EStructuralFeature>();
+
+ /**
+ * Sublist of <code>REFRESH_FEATURES</code> that also have other features as
+ * consequence.
+ */
+ private static final Set<EStructuralFeature> REFRESH_FEATURES_WITH_CONSEQUENCE = new HashSet<EStructuralFeature>();
+
+ /**
+ * List of features that are standard consequences of
+ * <code>REFRESH_FEATURES_WITH_CONSEQUENCE</code>.
+ */
+ private static final Set<EStructuralFeature> CONSEQUENCE_FEATURES = new HashSet<EStructuralFeature>();
+
+ static {
+ REFRESH_FEATURES_WITH_CONSEQUENCE.add(DiagramPackage.Literals.EDGE_STYLE__CENTERED);
+ REFRESH_FEATURES_WITH_CONSEQUENCE.add(NotationPackage.Literals.ROUTING_STYLE__ROUTING);
+
+ REFRESH_FEATURES.addAll(REFRESH_FEATURES_WITH_CONSEQUENCE);
+ REFRESH_FEATURES.add(DiagramPackage.Literals.DEDGE__OWNED_STYLE);
+ REFRESH_FEATURES.add(NotationPackage.Literals.DIAGRAM__PERSISTED_EDGES);
+
+ CONSEQUENCE_FEATURES.add(ViewpointPackage.Literals.CUSTOMIZABLE__CUSTOM_FEATURES);
+ CONSEQUENCE_FEATURES.add(DiagramPackage.Literals.EDGE_STYLE__ROUTING_STYLE);
+ }
+
private TransactionalEditingDomain domain;
private SessionEventBroker eventBroker;
@@ -80,30 +119,18 @@ public class EdgeLayoutUpdaterModelChangeTrigger implements ModelChangeTrigger {
Collection<Edge> edgesWithCreatedCommand = new HashSet<Edge>();
Collection<AbstractModelChangeOperation<Void>> operations = new ArrayList<AbstractModelChangeOperation<Void>>();
for (Notification notification : notifications) {
- Object notifier = notification.getNotifier();
- Edge gmfEdge = null;
- if (notifier instanceof DEdge) {
- gmfEdge = SiriusGMFHelper.getGmfEdge((DEdge) notifier);
- } else if (notifier instanceof EdgeStyle) {
- EObject container = ((EdgeStyle) notifier).eContainer();
- if (container instanceof DEdge) {
- gmfEdge = SiriusGMFHelper.getGmfEdge((DEdge) container);
- }
- } else if (notifier instanceof RoutingStyle) {
- EObject container = ((RoutingStyle) notifier).eContainer();
- if (container instanceof Edge) {
- gmfEdge = ((Edge) container);
+ // Only consider notification of
+ // RefreshEdgeLayoutNotificationFilter.REFRESH_FEATURES list
+ if (isRefreshEdgeLayoutNeededForNotification(notification)) {
+ Option<Edge> optionalGmfEdge = getCorrespondingEdge(notification);
+ if (optionalGmfEdge.some() && edgesWithCreatedCommand.add(optionalGmfEdge.get())) {
+ // if there are several notifications, we do not try to
+ // retrieve draw2D informations since they could be out of
+ // date.
+ boolean useFigure = otherNotificationsAreConsequences(notification, optionalGmfEdge.get(), notifications);
+ AbstractModelChangeOperation<Void> operation = new CenterEdgeEndModelChangeOperation(optionalGmfEdge.get(), useFigure);
+ operations.add(operation);
}
- } else if (notifier instanceof Diagram && notification.getNewValue() instanceof Edge) {
- gmfEdge = (Edge) notification.getNewValue();
- }
- if (gmfEdge != null && edgesWithCreatedCommand.add(gmfEdge)) {
- // if there are several notifications, we do not try to
- // retrieve draw2D informations since they could be out of
- // date.
- boolean useFigure = refreshEdgeLayoutNotificationFilter.otherNotificationsAreIndirectlyConcerned(notification, notifications);
- AbstractModelChangeOperation<Void> operation = new CenterEdgeEndModelChangeOperation(gmfEdge, useFigure);
- operations.add(operation);
}
}
if (!operations.isEmpty()) {
@@ -147,4 +174,92 @@ public class EdgeLayoutUpdaterModelChangeTrigger implements ModelChangeTrigger {
domain = null;
}
+
+ /**
+ * Test whether the other notifications are consequences of the given one.
+ * For instance, in case of a manual modification of the Sirius routing
+ * style (from Style tab of Properties view), we also update the GMF style
+ * and we add the routing style within the custom features. This method aims
+ * to check whether we are in the case of an individual modification or a
+ * global one.
+ *
+ * @param notification
+ * the notification for which we are notified.
+ * @param gmfEdge
+ * the GMF edge associated to the <code>notification</code>
+ * @param notifications
+ * the whole notification list.
+ * @return true if the notifications list contains only notifications
+ * induced by the first one.
+ */
+ public boolean otherNotificationsAreConsequences(final Notification notification, final Edge gmfEdge, Collection<Notification> notifications) {
+ boolean otherNotificationsAreIndirectlyConcerned = false;
+ if (notifications.size() == 1 && REFRESH_FEATURES.contains(notifications.iterator().next().getFeature())) {
+ otherNotificationsAreIndirectlyConcerned = true;
+ } else if (REFRESH_FEATURES_WITH_CONSEQUENCE.contains(notification.getFeature())) {
+ otherNotificationsAreIndirectlyConcerned = Iterables.all(notifications, new Predicate<Notification>() {
+ @Override
+ public boolean apply(Notification currentNotification) {
+ boolean considerAsConsequence = false;
+ if (currentNotification == notification) {
+ considerAsConsequence = true;
+ } else {
+ Option<Edge> optionalEdge = getCorrespondingEdge(currentNotification);
+ if (optionalEdge.some()) {
+ considerAsConsequence = optionalEdge.get().equals(gmfEdge) && CONSEQUENCE_FEATURES.contains(currentNotification.getFeature());
+ }
+ }
+ return considerAsConsequence;
+ }
+ });
+ }
+ return otherNotificationsAreIndirectlyConcerned;
+ }
+
+ /**
+ * Test whether the edge centering should be refreshed for this
+ * notification.
+ *
+ * @param notification
+ * The {@link Notification} to check.
+ * @return true if this notification concerns the edge ends centering, false
+ * otherwise.
+ */
+ private boolean isRefreshEdgeLayoutNeededForNotification(Notification notification) {
+ return REFRESH_FEATURES.contains(notification.getFeature());
+ }
+
+ /**
+ * Search the corresponding GMF edge associated to this notification.
+ *
+ * @param notification
+ * The {@link Notification} to analyze
+ * @return an optional {@link Edge}
+ */
+ private Option<Edge> getCorrespondingEdge(Notification notification) {
+ Edge gmfEdge = null;
+ Object notifier = notification.getNotifier();
+ if (notifier instanceof DEdge) {
+ gmfEdge = SiriusGMFHelper.getGmfEdge((DEdge) notifier);
+ } else if (notifier instanceof EdgeStyle) {
+ EObject container = ((EdgeStyle) notifier).eContainer();
+ if (container instanceof DEdge) {
+ gmfEdge = SiriusGMFHelper.getGmfEdge((DEdge) container);
+ }
+ } else if (notifier instanceof RoutingStyle) {
+ EObject container = ((RoutingStyle) notifier).eContainer();
+ if (container instanceof Edge) {
+ gmfEdge = ((Edge) container);
+ }
+ } else if (notifier instanceof Diagram && notification.getNewValue() instanceof Edge) {
+ gmfEdge = (Edge) notification.getNewValue();
+ } else if (notifier instanceof RelativeBendpoints) {
+ gmfEdge = (Edge) ((RelativeBendpoints) notifier).eContainer();
+ }
+ if (gmfEdge == null) {
+ return Options.newNone();
+ } else {
+ return Options.newSome(gmfEdge);
+ }
+ }
}
diff --git a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/RefreshEdgeLayoutNotificationFilter.java b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/RefreshEdgeLayoutNotificationFilter.java
index 27f65686c9..7164acb3d3 100644
--- a/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/RefreshEdgeLayoutNotificationFilter.java
+++ b/plugins/org.eclipse.sirius.diagram.ui/src-diag/org/eclipse/sirius/diagram/ui/internal/refresh/listeners/RefreshEdgeLayoutNotificationFilter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2014 THALES GLOBAL SERVICES.
+ * Copyright (c) 2014, 2016 THALES GLOBAL SERVICES.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,76 +10,24 @@
*******************************************************************************/
package org.eclipse.sirius.diagram.ui.internal.refresh.listeners;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
import org.eclipse.emf.common.notify.Notification;
-import org.eclipse.emf.ecore.EStructuralFeature;
-import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.sirius.business.api.dialect.DRepresentationNotificationFilter;
import org.eclipse.sirius.diagram.DDiagram;
-import org.eclipse.sirius.diagram.DiagramPackage;
-import org.eclipse.sirius.viewpoint.ViewpointPackage;
/**
- * A NotificationFilter to restrict the scope of RefreshEdgeLayoutChangeTrigger.
+ * A NotificationFilter to restrict the scope of RefreshEdgeLayoutChangeTrigger
+ * (all notifications of the current diagram that have a new value).
*
* @author Florian Barbin
*/
public class RefreshEdgeLayoutNotificationFilter extends DRepresentationNotificationFilter {
- private static final Set<EStructuralFeature> INTERESTING_FEATURES = new HashSet<EStructuralFeature>();
-
- static {
- INTERESTING_FEATURES.add(DiagramPackage.Literals.DEDGE__OWNED_STYLE);
- INTERESTING_FEATURES.add(DiagramPackage.Literals.EDGE_STYLE__CENTERED);
- INTERESTING_FEATURES.add(NotationPackage.Literals.ROUTING_STYLE__ROUTING);
- INTERESTING_FEATURES.add(NotationPackage.Literals.DIAGRAM__PERSISTED_EDGES);
- }
-
- private static final Set<EStructuralFeature> INDIRECT_INTERESTING_FEATURES = new HashSet<EStructuralFeature>();
-
- static {
- INDIRECT_INTERESTING_FEATURES.add(ViewpointPackage.Literals.CUSTOMIZABLE__CUSTOM_FEATURES);
- INDIRECT_INTERESTING_FEATURES.add(DiagramPackage.Literals.EDGE_STYLE__ROUTING_STYLE);
- }
-
public RefreshEdgeLayoutNotificationFilter(DDiagram dDiagram) {
super(dDiagram);
}
@Override
public boolean matches(Notification notification) {
- boolean matches = super.matches(notification) && notification.getNewValue() != null && INTERESTING_FEATURES.contains(notification.getFeature());
- return matches;
+ return super.matches(notification) && notification.getNewValue() != null;
}
-
- /**
- * Test whether the other notifications concern the given one. For instance,
- * in case of a manual modification of the GMF routing style, we also update
- * the Sirius style and we add the routing style within the custom features.
- * This method aims to check whether we are in the case of an individual
- * modification or a global one.
- *
- * @param notification
- * the notification for which we are notified.
- * @param notifications
- * the whole notification list.
- * @return true if the notifications list contains only notifications
- * induced by the first one.
- */
- public boolean otherNotificationsAreIndirectlyConcerned(Notification notification, Collection<Notification> notifications) {
- boolean otherNotificationsAreIndirectlyConcerned = false;
- if (NotationPackage.Literals.ROUTING_STYLE__ROUTING == notification.getFeature() || DiagramPackage.Literals.EDGE_STYLE__CENTERED == notification.getFeature()) {
- for (Notification currentNotification : notifications) {
- if (currentNotification != notification && !INDIRECT_INTERESTING_FEATURES.contains(currentNotification.getFeature())) {
- otherNotificationsAreIndirectlyConcerned = true;
- break;
- }
- }
- }
- return otherNotificationsAreIndirectlyConcerned;
- }
-
}

Back to the top