/******************************************************************************* * <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; } }