blob: 35e710598e18b231162cdac63c4f96b108288d54 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011-2012 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eugen Neufeld - initial API and implementation
*
*******************************************************************************/
package org.eclipse.emf.ecp.internal.graphiti.feature;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.graphiti.internal.integration.ECPTutorialToolBehaviorProvider;
import org.eclipse.emf.ecp.spi.core.InternalProject;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.graphiti.features.context.IAddConnectionContext;
import org.eclipse.graphiti.features.context.IAddContext;
import org.eclipse.graphiti.features.context.ICreateConnectionContext;
import org.eclipse.graphiti.features.context.impl.AddConnectionContext;
import org.eclipse.graphiti.mm.GraphicsAlgorithmContainer;
import org.eclipse.graphiti.mm.algorithms.Polygon;
import org.eclipse.graphiti.mm.algorithms.Polyline;
import org.eclipse.graphiti.mm.algorithms.Text;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.pattern.AbstractConnectionPattern;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IGaService;
import org.eclipse.graphiti.services.IPeCreateService;
import org.eclipse.graphiti.util.ColorConstant;
import org.eclipse.graphiti.util.IColorConstant;
public class ContainmentPattern extends AbstractConnectionPattern {
private static final IColorConstant FOREGROUND = new ColorConstant(98, 131,
167);
@Override
public PictogramElement add(IAddContext context) {
final IAddConnectionContext addConContext = (IAddConnectionContext) context;
final IPeCreateService peCreateService = Graphiti.getPeCreateService();
// CONNECTION WITH POLYLINE
final Connection connection = peCreateService
.createFreeFormConnection(getDiagram());
connection.setStart(addConContext.getSourceAnchor());
connection.setEnd(addConContext.getTargetAnchor());
final IGaService gaService = Graphiti.getGaService();
final Polyline polyline = gaService.createPolyline(connection);
polyline.setLineWidth(2);
polyline.setForeground(manageColor(FOREGROUND));
// add dynamic text decorator for the association name
final ConnectionDecorator textDecorator = peCreateService
.createConnectionDecorator(connection, true, 0.5, true);
final Text text = gaService.createDefaultText(getDiagram(), textDecorator);
text.setForeground(manageColor(IColorConstant.BLACK));
gaService.setLocation(text, 10, 0);
// set reference name in the text decorator
final EReference eReference = (EReference) context.getNewObject();
// if(eReference==null)
// eReference = (EReference) context.getProperty("containment");
text.setValue(eReference.getName());
// create link and wire it
// link(connection, eReference);
final ConnectionDecorator cd = peCreateService.createConnectionDecorator(
connection, false, 0.0, true);
createArrow(cd);
return connection;
}
@Override
public void attachedToSource(ICreateConnectionContext context) {
super.attachedToSource(context);
final PictogramElement sourceElement = context.getSourcePictogramElement();
if (sourceElement == getDiagram()) {
return;
}
final EObject source = (EObject) getBusinessObjectForPictogramElement(sourceElement);
if (source == null) {
return;
}
for (final EReference eReference : source.eClass().getEAllContainments()) {
final EClass referenceClass = eReference.getEReferenceType();
final ECPProject project = ECPUtil.getECPProjectManager().getProject(
getBusinessObjectForPictogramElement(getDiagram()));
final InternalProject internalProject = (InternalProject) project;
final Iterator<EObject> referenceIterator = internalProject.getReferenceCandidates(source, eReference);
// Mark the allowed squares using decorators
final ECPTutorialToolBehaviorProvider toolBehaviorProvider = (ECPTutorialToolBehaviorProvider) getFeatureProvider()
.getDiagramTypeProvider().getCurrentToolBehaviorProvider();
while (referenceIterator.hasNext()) {
final EObject eObject = referenceIterator.next();
if (eReference.isMany()) {
final List<?> objects = (List<?>) source.eGet(eReference);
if (objects.contains(eObject)) {
continue;
}
}
else {
final Object object = source.eGet(eReference);
if (eObject.equals(object)) {
continue;
}
}
toolBehaviorProvider.allowEObject(eObject);
final PictogramElement pe = getFeatureProvider()
.getPictogramElementForBusinessObject(eObject);
getDiagramBehavior().refreshRenderingDecorators(pe);
}
toolBehaviorProvider.allowEObject(null);
}
}
@Override
public void canceledAttaching(ICreateConnectionContext context) {
// TODO Auto-generated method stub
super.canceledAttaching(context);
getDiagramBehavior().refresh();
}
@Override
public boolean canStartConnection(ICreateConnectionContext context) {
final PictogramElement sourceElement = context.getSourcePictogramElement();
if (sourceElement == getDiagram()) {
return false;
}
final EObject source = (EObject) getBusinessObjectForPictogramElement(sourceElement);
if (source == null) {
return false;
}
return !source.eClass().getEAllContainments().isEmpty();
}
@Override
public boolean canCreate(ICreateConnectionContext context) {
final PictogramElement targetPictogramElement = context
.getTargetPictogramElement();
if (targetPictogramElement == getDiagram()) {
return false;
}
final EObject source = (EObject) getBusinessObjectForPictogramElement(context
.getSourcePictogramElement());
final EObject target = (EObject) getBusinessObjectForPictogramElement(targetPictogramElement);
if (target == null) {
return false;
}
if (target.eContainer() == source) {
return false;
}
for (final EReference eReference : source.eClass().getEAllContainments()) {
if (eReference.getEReferenceType().isInstance(target)) {
if (eReference.isMany()
&& eReference.getUpperBound() != -1
&& eReference.getUpperBound() <= ((List) source
.eGet(eReference)).size()) {
return false;
}
context.putProperty("containment", eReference);
return true;
}
}
return false;
}
@Override
public Connection create(ICreateConnectionContext context) {
final EObject source = (EObject) getBusinessObjectForPictogramElement(context
.getSourcePictogramElement());
final EObject target = (EObject) getBusinessObjectForPictogramElement(context
.getTargetPictogramElement());
final EReference eReference = (EReference) context.getProperty("containment");
final Object o = getBusinessObjectForPictogramElement(getDiagram());
final ECPProject project = ECPUtil.getECPProjectManager().getProject(o);
final EditingDomain editingDomain = project.getEditingDomain();
Command command = null;
if (eReference.isMany()) {
command = AddCommand.create(editingDomain, source, eReference,
target);
} else {
command = SetCommand.create(editingDomain, source, eReference,
target);
}
editingDomain.getCommandStack().execute(command);
final AddConnectionContext addContext = new AddConnectionContext(
context.getSourceAnchor(), context.getTargetAnchor());
addContext.setNewObject(eReference);
final Connection newConnection = (Connection) getFeatureProvider()
.addIfPossible(addContext);
return newConnection;
}
@Override
public String getCreateName() {
return "Containment Edge";
}
@Override
public String getCreateImageId() {
return "containment";
}
private Polyline createArrow(GraphicsAlgorithmContainer gaContainer) {
final IGaService gaService = Graphiti.getGaService();
final Polygon polygon = gaService.createPolygon(gaContainer, new int[] { -10,
-10, -20, 0, -10, 10, 0, 0 });
polygon.setBackground(manageColor(FOREGROUND));
polygon.setFilled(true);
polygon.setLineVisible(false);
return polygon;
}
@Override
public boolean canAdd(IAddContext context) {
// return true if given business object is an EReference
// note, that the context must be an instance of IAddConnectionContext
if (!IAddConnectionContext.class.isInstance(context)) {
return false;
}
final IAddConnectionContext connectionContext = (IAddConnectionContext) context;
final EObject sourceObject = (EObject) getFeatureProvider()
.getBusinessObjectForPictogramElement(
(PictogramElement) connectionContext.getSourceAnchor()
.eContainer());
final EObject targetObject = (EObject) getFeatureProvider()
.getBusinessObjectForPictogramElement(
(PictogramElement) connectionContext.getTargetAnchor()
.eContainer());
return targetObject.eContainer() == sourceObject;
}
}