blob: aeb18811c08559612636b0422432c79c36c2aaed [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2005, 2012 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
* mgorning - Bug 379836 - StackOverflow when parent GA is the root GA of an inactive shape
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.graphiti.ui.internal.parts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.gef.CompoundSnapToHelper;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.SnapToGeometry;
import org.eclipse.gef.SnapToGrid;
import org.eclipse.gef.SnapToGuides;
import org.eclipse.gef.SnapToHelper;
import org.eclipse.gef.rulers.RulerProvider;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRenderer;
import org.eclipse.graphiti.tb.IToolBehaviorProvider;
import org.eclipse.graphiti.ui.internal.config.IConfigurationProviderInternal;
import org.eclipse.graphiti.ui.internal.util.ui.sfx.GFSnapFeedbackPolicy;
/**
* A GraphicalEditPart, which model is of the type ContainerShape.
*
* @noinstantiate This class is not intended to be instantiated by clients.
* @noextend This class is not intended to be subclassed by clients.
*/
public class ContainerShapeEditPart extends ShapeEditPart implements IContainerShapeEditPart {
private IFigure contentPaneFigureCache;
private Integer contentPaneChilds = 0;
/**
* Creates a new ContainerShapeEditPart.
*
* @param configurationProvider
* the configuration provider
* @param containerShape
* the container shape
*/
public ContainerShapeEditPart(IConfigurationProviderInternal configurationProvider, ContainerShape containerShape) {
super(configurationProvider, containerShape);
}
// ======================= overwriteable behaviour ========================
/**
* Creates the EditPolicies of this EditPart. Subclasses often overwrite
* this method to change the behaviour of the editpart. This implementation
* adds the layout-specific EditPolicy to the super-implementation.
*
* @see ShapeEditPart
*/
@Override
protected void createEditPolicies() {
super.createEditPolicies();
installEditPolicy(EditPolicy.LAYOUT_ROLE, getConfigurationProvider().getEditPolicyFactory()
.createShapeXYLayoutEditPolicy());
// installEditPolicy(EditPolicy.CONTAINER_ROLE,
// getConfigurationProvider().getEditPolicyFactory().createShapeXYLayoutEditPolicy());
installEditPolicy("Snap Feedback", new GFSnapFeedbackPolicy()); //$NON-NLS-1$
}
/**
* Creates the Figure of this editpart. This determines how the editpart
* will be displayed. The actual data for this figure should be provided in
* refreshVisuals().
*
* @return the i figure
*
* @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
*/
@Override
protected IFigure createFigure() {
if (getPictogramElement().getGraphicsAlgorithm() == null) {
throw new IllegalStateException(
"The ContainerShape must have a valid GraphicsAlgorithm: " + getPictogramElement().toString()); //$NON-NLS-1$
}
resetContentPaneFigureCache();
IFigure figure = super.createFigure();
if (figure != null) {
if (figure.getBackgroundColor() == null && !(figure instanceof IGraphicsAlgorithmRenderer))
figure.setBackgroundColor(ColorConstants.lightGray);
figure.setOpaque(true);
}
setFigure(figure);
contentPaneChilds = getContentPane().getChildren().size(); // initialize
// contentPaneChilds
return figure;
}
// ========================= standard behaviour ===========================
/**
* Returns the children of this EditPart.
*
* @return the model children
*
* @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
*/
@Override
public List<PictogramElement> getModelChildren() {
List<PictogramElement> result = new ArrayList<PictogramElement>();
if (getPictogramElementDelegate().isValid()) {
ContainerShape containerShape = (ContainerShape) getPictogramElement();
List<PictogramElement> activeChildren = collectActiveChildrenRecursively(containerShape);
result.addAll(activeChildren);
result.addAll(super.getModelChildren());
}
return result;
}
/**
* @param containerShape
* @return
*/
private List<PictogramElement> collectActiveChildrenRecursively(ContainerShape containerShape) {
Collection<? extends Shape> coll = containerShape.getChildren();
List<PictogramElement> activeChildren = new ArrayList<PictogramElement>();
for (Iterator<? extends Shape> iter = coll.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj != null && obj instanceof PictogramElement) {
PictogramElement pe = (PictogramElement) obj;
if (pe.isActive()) {
activeChildren.add(pe);
} else if (pe instanceof ContainerShape) {
activeChildren.addAll(collectActiveChildrenRecursively((ContainerShape) pe));
}
}
}
return activeChildren;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editparts.AbstractGraphicalEditPart#addChildVisual(org
* .eclipse.gef.EditPart, int)
*/
@Override
protected void addChildVisual(EditPart childEditPart, int index) {
resetContentPaneFigureCache();
int realIndex = index + getContentPaneChildCount();
super.addChildVisual(childEditPart, realIndex);
}
private void resetContentPaneFigureCache() {
contentPaneFigureCache = null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.ui.internal.parts.ShapeEditPart#getAdapter(java.
* lang.Class)
*/
@Override
public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) {
if (adapter == SnapToHelper.class) {
List<SnapToHelper> snapStrategies = new ArrayList<SnapToHelper>();
Boolean val = (Boolean) getViewer().getProperty(RulerProvider.PROPERTY_RULER_VISIBILITY);
if (val != null && val.booleanValue())
snapStrategies.add(new SnapToGuides(this));
val = (Boolean) getViewer().getProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED);
if (val != null && val.booleanValue())
snapStrategies.add(new SnapToGeometry(this));
val = (Boolean) getViewer().getProperty(SnapToGrid.PROPERTY_GRID_ENABLED);
if (val != null && val.booleanValue())
snapStrategies.add(new SnapToGrid(this));
if (snapStrategies.size() == 0)
return null;
if (snapStrategies.size() == 1)
return snapStrategies.get(0);
SnapToHelper ss[] = new SnapToHelper[snapStrategies.size()];
for (int i = 0; i < snapStrategies.size(); i++)
ss[i] = snapStrategies.get(i);
return new CompoundSnapToHelper(ss);
}
return super.getAdapter(adapter);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getContentPane()
*/
@Override
public IFigure getContentPane() {
if (getContentPaneFigureCache() != null) {
return getContentPaneFigureCache();
}
IToolBehaviorProvider tbp = getConfigurationProvider().getDiagramTypeProvider()
.getCurrentToolBehaviorProvider();
PictogramElement pe = getPictogramElement();
if (pe instanceof ContainerShape && !(this instanceof DiagramEditPart)) {
ContainerShape cs = (ContainerShape) pe;
GraphicsAlgorithm contentGa = tbp.getContentArea(cs);
if (contentGa != null) {
setConentPaneFigureCache(getPictogramElementDelegate().getFigureForGraphicsAlgorithm(contentGa));
if (getContentPaneFigureCache() != null) {
LayoutManager lm = getContentPaneFigureCache().getLayoutManager();
if (!(lm instanceof XYLayout)) {
getContentPaneFigureCache().setLayoutManager(new XYLayout());
}
return getContentPaneFigureCache();
}
}
}
IFigure ret = super.getContentPane();
return ret;
}
private void setConentPaneFigureCache(IFigure figure) {
contentPaneFigureCache = figure;
}
private IFigure getContentPaneFigureCache() {
return contentPaneFigureCache;
}
private Integer getContentPaneChildCount() {
return contentPaneChilds;
}
}