blob: 4d052dbe9ff557a376e1d8d56d2cdaeab112db3e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 Obeo.
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram;
import static com.google.common.base.Predicates.instanceOf;
import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.figures.DecoratorFigure;
import org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.figures.EdgeFigure;
import org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.figures.NodeFigure;
import org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.figures.NodeListFigure;
import org.eclipse.emf.compare.diagram.internal.extensions.DiagramDiff;
import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.View;
/**
* Marker manager to create, hide or reveal marker figures related to deleted or added graphical objects.
*
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
public class MarkerManager extends AbstractDecoratorManager {
/**
* Marker represented by a <code>figure</code> on a <code>layer</code>, from the given <code>side</code>
* of the merge viewer. An edit part may be linked to the <code>figure</code> in some cases.<br>
* The marker is related to a <code>difference</code> and it is binded with the reference view and figure.
*
* @author <a href="mailto:cedric.notot@obeo.fr">Cedric Notot</a>
*/
private class Marker extends AbstractDecorator {
/**
* Constructor.
*
* @param layer
* {@link Marker#fLayer}.
* @param side
* {@link Marker#fSide}.
* @param originView
* {@link Marker#fOriginView}.
* @param originFigure
* {@link Marker#fOriginFigure}.
* @param diff
* {@link Marker#fDifference}.
*/
Marker(IFigure layer, MergeViewerSide side, View originView, IFigure originFigure, Diff diff) {
setLayer(layer);
setSide(side);
setOriginView(originView);
setOriginFigure(originFigure);
setDifference(diff);
}
}
/** Registry of created markers, indexed by difference. */
private Multimap<Diff, Marker> fMarkerRegistry = HashMultimap.create();
/**
* Constructor.
*
* @param compareConfiguration
* The compare configuration of the viewer.
* @param left
* The left area of the viewer.
* @param right
* The right area of the viewer.
* @param ancestor
* The ancestor area of the viewer.
* @param color
* The color of the difference.
*/
public MarkerManager(EMFCompareConfiguration compareConfiguration, DiagramMergeViewer left,
DiagramMergeViewer right, DiagramMergeViewer ancestor, ICompareColor color) {
super(compareConfiguration, left, right, ancestor, color);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#getReferenceViews(
* org.eclipse.emf.compare.diagram.internal.extensions.DiagramDiff)
*/
@Override
protected List<View> getReferenceViews(DiagramDiff difference) {
List<View> result = new ArrayList<View>();
Match matchValue = getCompareConfiguration().getComparison().getMatch(difference.getView());
if (matchValue != null) {
if (matchValue.getLeft() != null) {
result.add((View)matchValue.getLeft());
}
if (matchValue.getRight() != null) {
result.add((View)matchValue.getRight());
}
if (getCompareConfiguration().getComparison().isThreeWay()) {
switch (difference.getKind()) {
case DELETE:
case CHANGE:
case MOVE:
result.add((View)matchValue.getOrigin());
break;
default:
break;
}
}
}
return result;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#getTargetSide(org.eclipse.emf.compare.Match,
* org.eclipse.gmf.runtime.notation.View)
*/
@Override
public MergeViewerSide getTargetSide(Match match, View referenceView) {
return getSide(referenceView);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#createAndRegisterDecorator(org.eclipse.emf.compare.Diff,
* org.eclipse.gmf.runtime.notation.View, org.eclipse.draw2d.IFigure,
* org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide)
*/
@Override
protected Marker createAndRegisterDecorator(Diff diff, View referenceView, IFigure referenceFigure,
MergeViewerSide targetSide) {
Marker marker = createMarker(diff, referenceView, referenceFigure, targetSide);
if (marker != null) {
fMarkerRegistry.put(diff, marker);
}
return marker;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#removeDecorators(org.eclipse.emf.compare.Diff)
*/
@Override
public void removeDecorators(Diff difference) {
fMarkerRegistry.removeAll(difference);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#removeAll()
*/
@Override
public void removeAll() {
fMarkerRegistry.clear();
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#getDecorators(org.eclipse.emf.compare.Diff)
*/
@Override
protected Collection<Marker> getDecorators(Diff difference) {
return fMarkerRegistry.get(difference);
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#handleAddDecorator(org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager.AbstractDecorator,
* org.eclipse.draw2d.IFigure, org.eclipse.draw2d.IFigure, boolean)
*/
@Override
protected void handleAddDecorator(AbstractDecorator decorator, IFigure parent, IFigure toAdd,
boolean isMain) {
super.handleAddDecorator(decorator, parent, toAdd, isMain);
DiagramMergeViewer viewer = getViewer(decorator.getSide());
EditPart editPart = viewer.getEditPart(decorator.getOriginView());
if (editPart != null) {
viewer.getGraphicalViewer().reveal(editPart);
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.AbstractDecoratorManager#goodCandidate()
* <br>
* All graphical differences are concerned.
*/
@Override
protected Predicate<Diff> goodCandidate() {
return new Predicate<Diff>() {
public boolean apply(Diff difference) {
return instanceOf(DiagramDiff.class).apply(difference);
}
};
}
/**
* It creates a new marker from the given difference, view and figure.
*
* @param diff
* The related difference used as index for the main marker.
* @param referenceView
* The reference view as base for creation of the marker.
* @param referenceFigure
* The reference figure as base for creation of the marker.
* @param side
* The side where the marker has to be created.
* @return The phantom or null if the target layer is not found.
*/
private Marker createMarker(Diff diff, View referenceView, IFigure referenceFigure,
MergeViewerSide side) {
IFigure referenceLayer = getLayer(referenceView, side);
if (referenceLayer != null) {
Rectangle referenceBounds = referenceFigure.getBounds().getCopy();
translateCoordinates(referenceFigure, referenceLayer, referenceBounds);
DecoratorFigure markerFigure = null;
Marker marker = new Marker(referenceLayer, side, referenceView, referenceFigure, diff);
if (isNodeList(referenceView)) {
markerFigure = new NodeListFigure(diff, isThreeWay(), getCompareColor(), referenceFigure,
referenceBounds, false);
} else if (referenceView instanceof Edge && referenceFigure instanceof PolylineConnection) {
markerFigure = new EdgeFigure(diff, isThreeWay(), getCompareColor(), referenceFigure,
referenceBounds, false);
}
// Default case: Nodes
if (markerFigure == null) {
markerFigure = new NodeFigure(diff, isThreeWay(), getCompareColor(), referenceFigure,
referenceBounds, false);
}
marker.setDecoratorFigure(markerFigure);
return marker;
}
return null;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.IDecoratorManager#hideAll()
*/
public void hideAll() {
for (Marker marker : fMarkerRegistry.values()) {
handleDeleteDecorator(marker, marker.getLayer(), marker.getFigure());
}
}
/**
* {@inheritDoc}
*
* @see org.eclipse.emf.compare.diagram.ide.ui.internal.contentmergeviewer.diagram.IDecoratorManager#getAllDecorators()
*/
public Collection<AbstractDecorator> getAllDecorators() {
Collection<AbstractDecorator> markers = new ArrayList<AbstractDecorator>();
for (AbstractDecorator marker : fMarkerRegistry.values()) {
markers.add(marker);
}
return markers;
}
}