blob: ecce18d824dc7632b655345cca820c219487fc94 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012, 2013 Red Hat, Inc.
* All rights reserved.
* This program is 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:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.eclipse.bpmn2.modeler.core.features;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.BaseElement;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICopyContext;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.ui.features.AbstractCopyFeature;
/**
* Default Graphiti {@code CopyFeature} base class for all BPMN2 model elements which
* are associated with BPMN DI elements.
*/
public class DefaultCopyBPMNElementFeature extends AbstractCopyFeature {
/**
* Instantiates a new default {@code CopyFeature).
*
* @param fp the Feature Provider
*/
public DefaultCopyBPMNElementFeature(IFeatureProvider fp) {
super(fp);
}
/* (non-Javadoc)
* @see org.eclipse.graphiti.features.ICopyFeature#canCopy(org.eclipse.graphiti.features.context.ICopyContext)
*/
@Override
public boolean canCopy(ICopyContext context) {
final PictogramElement[] pes = context.getPictogramElements();
if (pes == null || pes.length == 0) { // nothing selected
return false;
}
// return true if all selected elements have linked BaseElements
for (PictogramElement pe : pes) {
final Object bo = BusinessObjectUtil.getFirstBaseElement(pe);
if (!(bo instanceof BaseElement)) {
return false;
}
}
return true;
}
/* (non-Javadoc)
* @see org.eclipse.graphiti.features.ICopyFeature#copy(org.eclipse.graphiti.features.context.ICopyContext)
*/
@Override
public void copy(ICopyContext context) {
PictogramElement[] pes = context.getPictogramElements();
List<PictogramElement> copied = new ArrayList<PictogramElement>();
for (int i = 0; i < pes.length; i++) {
PictogramElement pe = pes[i];
// only copy connections if both source and target Shapes
// are also selected (i.e. don't copy a "dangling" connection)
if (pe instanceof Connection) {
Connection connection = (Connection)pe;
PictogramElement source = connection.getStart().getParent();
PictogramElement target = connection.getEnd().getParent();
boolean containsSource = false;
boolean containsTarget = false;
for (PictogramElement p : pes) {
if (source==p)
containsSource = true;
else if (target==p)
containsTarget = true;
}
if (containsSource && containsTarget) {
copied.add(pe);
}
}
else {
copied.add(pe);
}
}
// include all connections between the selected shapes, even if they
// are not selected.
copied.addAll(findAllConnections(copied));
// remove PEs that are contained in FlowElementsContainers
List<PictogramElement> ignored = new ArrayList<PictogramElement>();
for (PictogramElement pe : copied) {
if (pe instanceof ContainerShape) {
for (PictogramElement childPe : ((ContainerShape) pe).getChildren()) {
if (copied.contains(childPe))
ignored.add(childPe);
}
}
}
copied.removeAll(ignored);
// copy all PictogramElements to the clipboard
putToClipboard(copied.toArray());
}
/**
* Find all outgoing and incoming connections attached to the given list of shapes.
*
* @param shapes the shapes
* @return a list of connections
*/
public static List<Connection> findAllConnections(List<PictogramElement> shapes) {
List<Connection> connections = new ArrayList<Connection>();
for (PictogramElement pe : shapes) {
if (pe instanceof ContainerShape) {
ContainerShape shape = (ContainerShape)pe;
for (Anchor a : shape.getAnchors()) {
for (Connection c : a.getIncomingConnections()) {
if ( (shapes.contains(c.getStart().getParent()) ||
shapes.contains(c.getEnd().getParent())) &&
!shapes.contains(c) && !connections.contains(c)) {
connections.add(c);
}
}
for (Connection c : a.getOutgoingConnections()) {
if ( (shapes.contains(c.getStart().getParent()) ||
shapes.contains(c.getEnd().getParent())) &&
!shapes.contains(c) && !connections.contains(c)) {
connections.add(c);
}
}
}
}
}
return connections;
}
}