| /******************************************************************************* |
| * <copyright> |
| * |
| * Copyright (c) 2005, 2017 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 |
| * mwenz - Bug 348662 - Setting tooptip to null in tool behavior provider doesn't clear up |
| * tooltip if the associated figure has a previous tooltip |
| * mgorning - Bug 363229 - Nested GA inside Anchors are not correctly refreshed |
| * Felix Velasco (mwenz) - Bug 349416 - Support drag&drop operations on FixPointAnchors |
| * the same way as for BoxRelativeAnchors |
| * mgorning - Bug 347144 - Angle of MultiText objects can't be modified |
| * Felix Velasco (mgorning) - Bug 328279 - Support rendering decorator positioning for connection text decorator |
| * Bug 336488 - DiagramEditor API |
| * mwenz - Bug 341898 - Support for AdvancedPropertySheet |
| * mwenz - Bug 358255 - Add Border/Background decorators |
| * mgorning - Bug 368124 - ConnectionDecorator with Text causes problems |
| * fvelasco - Bug 396247 - ImageDescriptor changes |
| * Andreas Graf/mwenz - Bug 396793 - Text decorators |
| * pjpaulin - Bug 352120 - Now uses IDiagramContainerUI interface |
| * mwenz - Bug 412858 - canUpdate is not consulted before calling updateNeeded during startup |
| * mwenz - Bug 434458 - Connections don't support Color decorators |
| * mwenz - Bug 459386 - Refresh Connection when getDiagramBehavior().refreshRenderingDecorators(PEInstance) is called |
| * mwenz - Bug 464857 - Images created by GFImageFigure are not destroyed |
| * mwenz - Bug 481619 - Graphiti is not using custom PlatformGraphicsAlgorithm's layout manager; enforces XYLayout |
| * palldredge - Bug 465675 - Improve SWT Font management |
| * mwenz - Bug 522699 - NullPointerException in GefService.getConnectionPointAt |
| * </copyright> |
| * |
| *******************************************************************************/ |
| package org.eclipse.graphiti.ui.internal.parts; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.draw2d.ColorConstants; |
| import org.eclipse.draw2d.Figure; |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.ImageFigure; |
| import org.eclipse.draw2d.Label; |
| import org.eclipse.draw2d.LineBorder; |
| import org.eclipse.draw2d.MarginBorder; |
| import org.eclipse.draw2d.PolylineConnection; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.RotatableDecoration; |
| import org.eclipse.draw2d.Shape; |
| import org.eclipse.draw2d.TextUtilities; |
| import org.eclipse.draw2d.XYLayout; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PointList; |
| import org.eclipse.draw2d.geometry.PrecisionPoint; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.gef.EditPartViewer; |
| import org.eclipse.gef.GraphicalEditPart; |
| import org.eclipse.graphiti.datatypes.IDimension; |
| import org.eclipse.graphiti.datatypes.ILocation; |
| import org.eclipse.graphiti.datatypes.IRectangle; |
| import org.eclipse.graphiti.dt.IDiagramTypeProvider; |
| import org.eclipse.graphiti.features.IFeatureProvider; |
| import org.eclipse.graphiti.features.IReason; |
| import org.eclipse.graphiti.features.IUpdateFeature; |
| import org.eclipse.graphiti.features.context.IUpdateContext; |
| import org.eclipse.graphiti.features.context.impl.UpdateContext; |
| import org.eclipse.graphiti.features.impl.Reason; |
| import org.eclipse.graphiti.internal.datatypes.impl.LocationImpl; |
| import org.eclipse.graphiti.internal.pref.GFPreferences; |
| import org.eclipse.graphiti.internal.services.GraphitiInternal; |
| import org.eclipse.graphiti.internal.util.T; |
| import org.eclipse.graphiti.mm.algorithms.AbstractText; |
| import org.eclipse.graphiti.mm.algorithms.Ellipse; |
| import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm; |
| import org.eclipse.graphiti.mm.algorithms.Image; |
| import org.eclipse.graphiti.mm.algorithms.MultiText; |
| import org.eclipse.graphiti.mm.algorithms.PlatformGraphicsAlgorithm; |
| import org.eclipse.graphiti.mm.algorithms.Polygon; |
| import org.eclipse.graphiti.mm.algorithms.Polyline; |
| import org.eclipse.graphiti.mm.algorithms.Rectangle; |
| import org.eclipse.graphiti.mm.algorithms.RoundedRectangle; |
| import org.eclipse.graphiti.mm.algorithms.Text; |
| import org.eclipse.graphiti.mm.algorithms.styles.LineStyle; |
| import org.eclipse.graphiti.mm.algorithms.styles.Orientation; |
| import org.eclipse.graphiti.mm.pictograms.AdvancedAnchor; |
| import org.eclipse.graphiti.mm.pictograms.Anchor; |
| import org.eclipse.graphiti.mm.pictograms.BoxRelativeAnchor; |
| import org.eclipse.graphiti.mm.pictograms.Connection; |
| import org.eclipse.graphiti.mm.pictograms.ConnectionDecorator; |
| import org.eclipse.graphiti.mm.pictograms.ContainerShape; |
| import org.eclipse.graphiti.mm.pictograms.FixPointAnchor; |
| import org.eclipse.graphiti.mm.pictograms.FreeFormConnection; |
| import org.eclipse.graphiti.mm.pictograms.PictogramElement; |
| import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRenderer; |
| import org.eclipse.graphiti.platform.ga.IGraphicsAlgorithmRendererFactory; |
| import org.eclipse.graphiti.platform.ga.IRendererContext; |
| import org.eclipse.graphiti.platform.ga.IVisualState; |
| import org.eclipse.graphiti.platform.ga.RendererContext; |
| import org.eclipse.graphiti.platform.ga.VisualState; |
| import org.eclipse.graphiti.services.Graphiti; |
| import org.eclipse.graphiti.tb.DefaultToolBehaviorProvider; |
| import org.eclipse.graphiti.tb.IBorderDecorator; |
| import org.eclipse.graphiti.tb.IColorDecorator; |
| import org.eclipse.graphiti.tb.IDecorator; |
| import org.eclipse.graphiti.tb.IImageDecorator; |
| import org.eclipse.graphiti.tb.ITextDecorator; |
| import org.eclipse.graphiti.tb.IToolBehaviorProvider; |
| import org.eclipse.graphiti.ui.editor.DefaultRefreshBehavior; |
| import org.eclipse.graphiti.ui.editor.DiagramBehavior; |
| import org.eclipse.graphiti.ui.internal.IResourceRegistry; |
| import org.eclipse.graphiti.ui.internal.config.IConfigurationProviderInternal; |
| import org.eclipse.graphiti.ui.internal.figures.DecoratorImageFigure; |
| import org.eclipse.graphiti.ui.internal.figures.GFAbstractShape; |
| import org.eclipse.graphiti.ui.internal.figures.GFEllipse; |
| import org.eclipse.graphiti.ui.internal.figures.GFEllipseDecoration; |
| import org.eclipse.graphiti.ui.internal.figures.GFImageFigure; |
| import org.eclipse.graphiti.ui.internal.figures.GFMultilineText; |
| import org.eclipse.graphiti.ui.internal.figures.GFPolygon; |
| import org.eclipse.graphiti.ui.internal.figures.GFPolygonDecoration; |
| import org.eclipse.graphiti.ui.internal.figures.GFPolyline; |
| import org.eclipse.graphiti.ui.internal.figures.GFPolylineConnection; |
| import org.eclipse.graphiti.ui.internal.figures.GFPolylineDecoration; |
| import org.eclipse.graphiti.ui.internal.figures.GFRectangleFigure; |
| import org.eclipse.graphiti.ui.internal.figures.GFRoundedRectangle; |
| import org.eclipse.graphiti.ui.internal.figures.GFText; |
| import org.eclipse.graphiti.ui.internal.services.GraphitiUiInternal; |
| import org.eclipse.graphiti.ui.internal.util.DataTypeTransformation; |
| import org.eclipse.graphiti.ui.platform.IConfigurationProvider; |
| import org.eclipse.graphiti.ui.services.GraphitiUi; |
| import org.eclipse.graphiti.util.IColorConstant; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontData; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.model.IWorkbenchAdapter; |
| import org.eclipse.ui.model.IWorkbenchAdapter2; |
| |
| /** |
| * A class, which contains helper-methods, which are necessary to implement the |
| * interface IAnchorContainerEditPart. It is not possible to make this an |
| * EditPart itself, because of different inheritance-hierarchies used in the |
| * sub-classes. |
| * |
| * @noinstantiate This class is not intended to be instantiated by clients. |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class PictogramElementDelegate implements IPictogramElementDelegate { |
| |
| private boolean forceRefresh = false; |
| |
| private boolean valid = true; |
| |
| private IConfigurationProviderInternal configurationProvider; |
| |
| private final Hashtable<GraphicsAlgorithm, IFigure> elementFigureHash = new Hashtable<GraphicsAlgorithm, IFigure>(); |
| |
| private PictogramElement pictogramElement; |
| |
| private final HashMap<IFigure, List<IFigure>> decoratorMap = new HashMap<IFigure, List<IFigure>>(); |
| |
| // edit part which holds the instance of this delegate |
| private EditPart containerEditPart; |
| |
| /** |
| * The {@link IVisualState} of this pictogram element delegate. |
| */ |
| private IVisualState visualState; |
| |
| /** |
| * Creates a new PictogramElementDelegate. |
| * |
| * @param configurationProvider |
| * the configuration provider |
| * @param pictogramElement |
| * the pictogram element |
| * @param containerEditPart |
| * the container edit part |
| */ |
| public PictogramElementDelegate(IConfigurationProviderInternal configurationProvider, |
| PictogramElement pictogramElement, EditPart containerEditPart) { |
| setConfigurationProvider(configurationProvider); |
| setPictogramElement(pictogramElement); |
| setContainerEditPart(containerEditPart); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate |
| * #activate () |
| */ |
| public void activate() { |
| // register listener for changes in the bo model -> will be done |
| // globally in the DiagramEditorInternal |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate# |
| * createFigure() |
| */ |
| public IFigure createFigure() { |
| PictogramElement pe = getPictogramElement(); |
| IFigure ret = createFigureForPictogramElement(pe); |
| if (getDiagramBehavior().getRefreshBehavior().isMultipleRefreshSupressionActive()) { |
| return ret; |
| } else { |
| refreshFigureForPictogramElement(pe); |
| return ret; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate# |
| * deactivate() |
| */ |
| public void deactivate() { |
| |
| for (IFigure figure : elementFigureHash.values()) { |
| removeDecorators(figure); |
| if (figure instanceof ImageFigure) { |
| // Trigger disposal of currently displayed image (bug 464857) |
| ((ImageFigure) figure).setImage(null); |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) |
| */ |
| public Object getAdapter(@SuppressWarnings("rawtypes") Class key) { |
| Object ret = null; |
| if (key == IGFAdapter.class || key == IWorkbenchAdapter.class || key == IWorkbenchAdapter2.class) { |
| ret = new GFAdapter(); |
| } |
| return ret; |
| } |
| |
| /** |
| * Gets the configuration provider. |
| * |
| * @return Returns the configurationProvider. |
| */ |
| public IConfigurationProviderInternal getConfigurationProvider() { |
| return configurationProvider; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate# |
| * getFigureForGraphicsAlgorithm(org.eclipse.graphiti.mm.pictograms. |
| * GraphicsAlgorithm) |
| */ |
| public IFigure getFigureForGraphicsAlgorithm(GraphicsAlgorithm graphicsAlgorithm) { |
| IFigure ret = null; |
| if (graphicsAlgorithm == null) { |
| return ret; |
| } |
| ret = elementFigureHash.get(graphicsAlgorithm); |
| return ret; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate# |
| * getPictogramElement() |
| */ |
| public PictogramElement getPictogramElement() { |
| return pictogramElement; |
| } |
| |
| /** |
| * refresh edit parts for child pictogram elements. |
| * |
| * @param ep |
| * the ep |
| */ |
| public void refreshEditPartsForModelChildrenAndSourceConnections(EditPart ep) { |
| if (ep instanceof IPictogramElementEditPart) { |
| |
| IPictogramElementEditPart peep = (IPictogramElementEditPart) ep; |
| |
| List<PictogramElement> peList = new ArrayList<PictogramElement>(); |
| peList.addAll(peep.getModelChildren()); |
| peList.addAll(peep.getModelSourceConnections()); |
| // peList.addAll(peep.getModelTargetConnections()); |
| |
| if (ep.getParent() != null) { |
| EditPartViewer viewer = ep.getViewer(); |
| if (viewer != null) { |
| Map<?, ?> editPartRegistry = viewer.getEditPartRegistry(); |
| if (editPartRegistry != null) { |
| for (PictogramElement childPe : peList) { |
| Object object = editPartRegistry.get(childPe); |
| if (object instanceof EditPart) { |
| EditPart editPart = (EditPart) object; |
| try { |
| editPart.refresh(); |
| } catch (NullPointerException e) { |
| String message = "PictogramElementDelegate.refreshEditPartsForModelChildrenAndSourceConnections():\n editPart.refresh() threw NullPointerException\n editPart: " //$NON-NLS-1$ |
| + editPart; |
| T.racer().error(message, e); |
| }// try |
| }// if |
| }// for |
| }// if |
| }// if |
| }// if |
| }// if |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.graphiti.ui.internal.parts.IPictogramElementDelegate# |
| * refreshFigureForEditPart(org.eclipse.gef.EditPart) |
| */ |
| public void refreshFigureForEditPart() { |
| |
| // DR: Avoid multiple refresh of the same edit part |
| DefaultRefreshBehavior refreshBehavior = getDiagramBehavior().getRefreshBehavior(); |
| if (!isForceRefresh() && refreshBehavior.isMultipleRefreshSupressionActive()) { |
| if (!refreshBehavior.shouldRefresh(getContainerEditPart())) { |
| return; |
| } |
| } |
| |
| PictogramElement pe = getPictogramElement(); |
| |
| if (!GraphitiInternal.getEmfService().isObjectAlive(pe)) { |
| return; |
| } |
| |
| if (pe instanceof org.eclipse.graphiti.mm.pictograms.Shape || pe instanceof AdvancedAnchor) { |
| if (isRefreshPossible(pe)) { |
| refreshFigureForPictogramElement(pe); |
| } else { |
| EditPart parentEp = getContainerEditPart().getParent(); |
| if (parentEp instanceof IShapeEditPart) { |
| elementFigureHash.clear(); |
| IShapeEditPart parent = (IShapeEditPart) parentEp; |
| parent.deleteChildAndRefresh(getContainerEditPart()); |
| setValid(false); // invalidate current delegate |
| } |
| } |
| } else if (pe instanceof Connection) { |
| Connection connection = (Connection) pe; |
| if (!isConnectionRefreshPossible(connection)) { |
| // if refresh is not possible -> reset figure-tree |
| IFigure figure = getFigureForGraphicsAlgorithm(connection.getGraphicsAlgorithm()); |
| elementFigureHash.clear(); |
| |
| // clean passive decorators |
| if (figure instanceof GFPolylineConnection) { |
| GFPolylineConnection c = (GFPolylineConnection) figure; |
| c.removeAllDecorations(); |
| } |
| |
| addGraphicsAlgorithmForFigure(figure, connection.getGraphicsAlgorithm()); |
| // create passive decorators |
| createFiguresForPassiveDecorators(connection); |
| } |
| refreshFigureForPictogramElement(pe); |
| } else if (pe instanceof Anchor) { |
| refreshFigureForPictogramElement(pe); |
| } |
| } |
| |
| /** |
| * Gets the edit part which holds the instance of this delegate. |
| * |
| * @return the container edit part |
| */ |
| protected EditPart getContainerEditPart() { |
| return containerEditPart; |
| } |
| |
| /** |
| * Sets the edit part which holds the instance of this delegate. |
| * |
| * @param containerEditPart |
| * the new container edit part |
| */ |
| protected void setContainerEditPart(EditPart containerEditPart) { |
| this.containerEditPart = containerEditPart; |
| } |
| |
| /** |
| * Check if update needed. |
| * |
| * @param pe |
| * the pe |
| * @return the i reason |
| */ |
| IReason checkIfUpdateNeeded(PictogramElement pe) { |
| IReason ret = Reason.createFalseReason(); |
| IFeatureProvider featureProvider = getConfigurationProvider().getFeatureProvider(); |
| IUpdateContext updateCtx = new UpdateContext(pe); |
| IUpdateFeature updateFeature = featureProvider.getUpdateFeature(updateCtx); |
| if (updateFeature != null && updateFeature.canUpdate(updateCtx)) { |
| ret = updateFeature.updateNeeded(updateCtx); |
| } |
| |
| if (getPreferences().isRecursiveCheckForUpdateActive()) { |
| // check children as well |
| if (!ret.toBoolean()) { |
| Collection<PictogramElement> peChildren = Graphiti.getPeService().getPictogramElementChildren(pe); |
| for (PictogramElement peChild : peChildren) { |
| ret = checkIfUpdateNeeded(peChild); |
| if (ret.toBoolean()) { |
| break; |
| } |
| } |
| } |
| } |
| if (T.racer().info()) { |
| T.racer().info("returns " + ret.toString()); //$NON-NLS-1$ |
| } |
| return ret; |
| } |
| |
| /** |
| * Refresh figure for graphics algorithm. |
| * |
| * @param graphicsAlgorithm |
| * the graphics algorithm |
| * @param pe |
| * The pictogram-element to which the graphics-algorithm (or the |
| * parent-ga) belongs |
| * @param updateNeeded |
| * the update needed |
| */ |
| void refreshFigureForGraphicsAlgorithm(final GraphicsAlgorithm graphicsAlgorithm, final PictogramElement pe, |
| IReason updateNeeded) { |
| if (graphicsAlgorithm == null || pe == null) { |
| return; |
| } |
| final IFigure figure = getFigureForGraphicsAlgorithm(graphicsAlgorithm); |
| if (figure == null) { |
| return; |
| } |
| |
| DefaultRefreshBehavior refreshBehavior = getDiagramBehavior().getRefreshBehavior(); |
| if (!isForceRefresh() && refreshBehavior.isMultipleRefreshSupressionActive()) { |
| if (!refreshBehavior.shouldRefresh(graphicsAlgorithm)) { |
| return; |
| } |
| } |
| |
| // figure.getChildren().removeAll(figure.getChildren()); //? |
| |
| // refresh common figure data |
| figure.setOpaque(true); |
| figure.setVisible(pe.isVisible()); |
| figure.setBorder(null); |
| |
| // check whether the edit part is a connection edit part and the edit |
| // part is selected |
| // if yes, refresh of colors and shape style is not necessary |
| boolean selectedConnection = false; |
| |
| if (getContainerEditPart() instanceof ConnectionEditPart) { |
| int selectedState = getContainerEditPart().getSelected(); |
| if (selectedState == EditPart.SELECTED_PRIMARY || selectedState == EditPart.SELECTED) { |
| selectedConnection = true; |
| } |
| } |
| |
| // refresh figure colors |
| if (selectedConnection) { |
| Color bg = DataTypeTransformation.toSwtColor(getConfigurationProvider().getResourceRegistry(), Graphiti |
| .getGaService().getBackgroundColor(graphicsAlgorithm, true)); |
| figure.setBackgroundColor(bg); |
| } else { |
| refreshFigureColors(figure, graphicsAlgorithm); |
| } |
| |
| // refresh specific figure-data |
| if (graphicsAlgorithm instanceof Ellipse |
| && (figure instanceof org.eclipse.draw2d.Ellipse || figure instanceof GFEllipse || figure instanceof GFEllipseDecoration)) { |
| Shape f = (Shape) figure; |
| refreshShapeData(f, graphicsAlgorithm); |
| |
| } else if (graphicsAlgorithm instanceof Polygon |
| && (figure instanceof org.eclipse.draw2d.Polygon || figure instanceof GFPolygon || figure instanceof GFPolygonDecoration)) { |
| |
| Polygon polygon = (Polygon) graphicsAlgorithm; |
| ILocation polygonLocation = new LocationImpl(polygon.getX(), polygon.getY()); |
| PointList pointList = toAbsoluteDraw2dPoints(polygon.getPoints(), polygonLocation); |
| |
| if (figure instanceof GFPolygonDecoration) { |
| GFPolygonDecoration p = (GFPolygonDecoration) figure; |
| p.setSpecificBezierDistances(getBezierDistances(polygon.getPoints())); |
| p.setDecoratorTemplate(pointList); |
| } else if (figure instanceof GFPolygon) { |
| GFPolygon p = (GFPolygon) figure; |
| p.setSpecificBezierDistances(getBezierDistances(polygon.getPoints())); |
| p.setPoints(pointList); |
| } |
| |
| if (!selectedConnection) { |
| refreshShapeData((org.eclipse.draw2d.Shape) figure, graphicsAlgorithm); |
| } |
| |
| } else if (graphicsAlgorithm instanceof Polyline |
| && (figure instanceof org.eclipse.draw2d.Polyline || figure instanceof GFPolyline || figure instanceof GFPolylineDecoration)) { |
| |
| // if figure is a PolylineConnection then just a refreshShapeData is |
| // necessary |
| |
| Polyline polyline = (Polyline) graphicsAlgorithm; |
| ILocation polylineLocation = new LocationImpl(polyline.getX(), polyline.getY()); |
| PointList pointList = toAbsoluteDraw2dPoints(polyline.getPoints(), polylineLocation); |
| |
| if (figure instanceof GFPolylineConnection) { |
| if (!isDefaultBendPointRenderingActive() && (pe instanceof FreeFormConnection)) { |
| FreeFormConnection ffc = (FreeFormConnection) pe; |
| GFPolylineConnection p = (GFPolylineConnection) figure; |
| int[] bendpointBezierDistances = getBezierDistances(ffc.getBendpoints()); |
| // add default bendpoints for start and end |
| int[] allPointsBezierDistances = new int[bendpointBezierDistances.length + 4]; |
| allPointsBezierDistances[0] = 0; |
| allPointsBezierDistances[1] = 0; |
| for (int i = 0; i < bendpointBezierDistances.length; i++) { |
| allPointsBezierDistances[i + 2] = bendpointBezierDistances[i]; |
| } |
| allPointsBezierDistances[allPointsBezierDistances.length - 2] = 0; |
| allPointsBezierDistances[allPointsBezierDistances.length - 1] = 0; |
| p.setSpecificBezierDistances(allPointsBezierDistances); |
| } |
| } else if (figure instanceof GFPolylineDecoration) { |
| GFPolylineDecoration p = (GFPolylineDecoration) figure; |
| p.setSpecificBezierDistances(getBezierDistances(polyline.getPoints())); |
| p.setDecoratorTemplate(pointList); |
| } else if (figure instanceof GFPolyline) { |
| GFPolyline p = (GFPolyline) figure; |
| p.setSpecificBezierDistances(getBezierDistances(polyline.getPoints())); |
| p.setPoints(pointList); |
| } |
| |
| if (!selectedConnection) { |
| refreshShapeData((org.eclipse.draw2d.Shape) figure, graphicsAlgorithm); |
| } |
| |
| } else if (graphicsAlgorithm instanceof Rectangle && figure instanceof GFRectangleFigure) { |
| GFRectangleFigure f = (GFRectangleFigure) figure; |
| refreshShapeData(f, graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof RoundedRectangle) { |
| if (figure instanceof GFRoundedRectangle) { |
| GFRoundedRectangle f = (GFRoundedRectangle) figure; |
| refreshShapeData(f, graphicsAlgorithm); |
| RoundedRectangle rr = (RoundedRectangle) graphicsAlgorithm; |
| Dimension dimension = new Dimension(rr.getCornerWidth(), rr.getCornerHeight()); |
| |
| f.setCornerDimensions(dimension); |
| } |
| } else if (graphicsAlgorithm instanceof MultiText && figure instanceof GFMultilineText) { |
| MultiText text = (MultiText) graphicsAlgorithm; |
| GFMultilineText label = (GFMultilineText) figure; |
| label.setBorder(new MarginBorder(2)); |
| label.setText(text.getValue()); |
| refreshFlowTextAlignment(label, text); |
| refreshFont(text, label); |
| label.setOpaque(Graphiti.getGaService().isFilled(text, true)); |
| label.setRequestFocusEnabled(false); |
| label.invalidateTree(); |
| } else if (graphicsAlgorithm instanceof Text && figure instanceof GFText) { |
| Text text = (Text) graphicsAlgorithm; |
| GFText label = (GFText) figure; |
| label.setText(text.getValue()); |
| refreshTextOrientation(label, text); |
| refreshFont(text, label); |
| label.setOpaque(Graphiti.getGaService().isFilled(text, true)); |
| label.setRequestFocusEnabled(false); |
| } else if (graphicsAlgorithm instanceof Image && figure instanceof ImageFigure) { |
| ImageFigure imageFigure = (ImageFigure) figure; |
| Image pictogramImage = (Image) graphicsAlgorithm; |
| org.eclipse.swt.graphics.Image image = GraphitiUi.getImageService().getImageForId( |
| configurationProvider.getDiagramTypeProvider().getProviderId(), pictogramImage.getId()); |
| imageFigure.setImage(image); |
| imageFigure.setAlignment(PositionConstants.CENTER); |
| imageFigure.setOpaque(false); |
| } |
| // set location and size of figure |
| setFigureConstraint(figure, graphicsAlgorithm, pe); |
| |
| // refresh child GAs |
| Collection<GraphicsAlgorithm> graphicsAlgorithmChildren = graphicsAlgorithm.getGraphicsAlgorithmChildren(); |
| for (Iterator<GraphicsAlgorithm> iter = graphicsAlgorithmChildren.iterator(); iter.hasNext();) { |
| GraphicsAlgorithm childGA = iter.next(); |
| refreshFigureForGraphicsAlgorithm(childGA, pe, Reason.createFalseReason()); |
| } |
| |
| IDiagramTypeProvider diagramTypeProvider = getConfigurationProvider().getDiagramTypeProvider(); |
| IToolBehaviorProvider toolBehaviorProvider = diagramTypeProvider.getCurrentToolBehaviorProvider(); |
| |
| // decorators |
| addDecorators(graphicsAlgorithm, pe, figure, toolBehaviorProvider); |
| |
| GraphicsAlgorithm selectionGraphicsAlgorithm = toolBehaviorProvider.getSelectionBorder(pe); |
| IFigure selectionFigure = getFigureForGraphicsAlgorithm(selectionGraphicsAlgorithm); |
| if (selectionFigure == null) { |
| // Retreat to graphiti behavior. |
| selectionFigure = figure; |
| } |
| |
| // Create a tooltip label |
| IFigure tooltipFigure = null; |
| |
| // First check the need for an update needed tooltip |
| Label indicateUpdateNeedeTooltipLabel = null; |
| if (selectionFigure != null) { |
| // Indicate needed updates on selectionFigure (using figure would |
| // cause problems with invisible rectangles) |
| indicateUpdateNeedeTooltipLabel = indicateNeededUpdates(selectionFigure, updateNeeded); |
| } |
| |
| // Use the update needed tooltip in case it exists... |
| if (indicateUpdateNeedeTooltipLabel != null) { |
| // Use update needed tooltip in any case (tool provided tooltip |
| // would be probably invalid) |
| tooltipFigure = indicateUpdateNeedeTooltipLabel; |
| } else { |
| // ... if not get the tool provided tooltip (for performance reasons |
| // only called in case no update needed tooltip exists) |
| Object toolTip = toolBehaviorProvider.getToolTip(graphicsAlgorithm); |
| // null or empty string means no tooltip wanted |
| if (toolTip != null) { |
| if (toolTip instanceof String) { |
| String toolTipString = (String) toolTip; |
| if (toolTipString.length() > 0) { |
| tooltipFigure = new Label(toolTipString); |
| } |
| } else if (toolTip instanceof Text) { |
| Text text = (Text) toolTip; |
| if (text.getValue() != null && (text.getValue().length() > 0)) { |
| tooltipFigure = new GFText(this, text); |
| ((GFText) tooltipFigure).setText(text.getValue()); |
| } |
| } else if (toolTip instanceof MultiText) { |
| MultiText multiText = (MultiText) toolTip; |
| if (multiText.getValue() != null && (multiText.getValue().length() > 0)) { |
| tooltipFigure = new GFMultilineText(this, multiText); |
| } |
| } |
| } |
| } |
| |
| // Set the tooltip in any case, especially also when it's null to clean |
| // up a previously set tooltip (see Bugzilla 348662) |
| figure.setToolTip(tooltipFigure); |
| } |
| |
| private void refreshFont(AbstractText text, Figure label) { |
| if (text == null || label == null) { |
| return; |
| } |
| |
| // if valid font-information exists in the pictogram-model, then |
| // create/change swt-font of label |
| org.eclipse.graphiti.mm.algorithms.styles.Font font = Graphiti.getGaService().getFont(text, true); |
| if (font != null && font.getName() != null) { |
| IResourceRegistry resourceRegistry = getConfigurationProvider().getResourceRegistry(); |
| label.setFont(resourceRegistry.getSwtFont(DataTypeTransformation.toFontData(font))); |
| } |
| } |
| |
| private void addGraphicsAlgorithmForFigure(IFigure figure, GraphicsAlgorithm graphicsAlgorithm) { |
| if (figure != null && graphicsAlgorithm != null) { |
| elementFigureHash.put(graphicsAlgorithm, figure); |
| } |
| } |
| |
| private ILocation calculatePolylineLocation(Polyline polyline) { |
| Collection<org.eclipse.graphiti.mm.algorithms.styles.Point> points = polyline.getPoints(); |
| |
| int minX = points.isEmpty() ? 0 : ((org.eclipse.graphiti.mm.algorithms.styles.Point) points.toArray()[0]) |
| .getX(); |
| int minY = points.isEmpty() ? 0 : ((org.eclipse.graphiti.mm.algorithms.styles.Point) points.toArray()[0]) |
| .getY(); |
| |
| for (Iterator<org.eclipse.graphiti.mm.algorithms.styles.Point> iter = points.iterator(); iter.hasNext();) { |
| org.eclipse.graphiti.mm.algorithms.styles.Point point = iter.next(); |
| int x = point.getX(); |
| int y = point.getY(); |
| minX = Math.min(minX, x); |
| minY = Math.min(minY, y); |
| } |
| |
| int locX = polyline.getX(); |
| int locY = polyline.getY(); |
| |
| return new LocationImpl(minX + locX, minY + locY); |
| } |
| |
| /** |
| * @param graphicsAlgorithm |
| * @return TRUE, if a figure exists for the ga and for all child-ga's |
| */ |
| private boolean checkGA(GraphicsAlgorithm graphicsAlgorithm) { |
| |
| if (graphicsAlgorithm != null && GraphitiInternal.getEmfService().isObjectAlive(graphicsAlgorithm)) { |
| IFigure ret = getFigureForGraphicsAlgorithm(graphicsAlgorithm); |
| if (ret == null) { |
| return false; |
| } |
| Collection<GraphicsAlgorithm> children = graphicsAlgorithm.getGraphicsAlgorithmChildren(); |
| for (Iterator<GraphicsAlgorithm> iter = children.iterator(); iter.hasNext();) { |
| GraphicsAlgorithm childGraphicsAlgorithm = iter.next(); |
| if (!checkGA(childGraphicsAlgorithm)) { |
| return false; |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * returns TRUE, if a figure exists for each ga |
| */ |
| private boolean checkGAs(PictogramElement pe) { |
| |
| if (!GraphitiInternal.getEmfService().isObjectAlive(pe)) |
| return false; |
| |
| GraphicsAlgorithm graphicsAlgorithm = pe.getGraphicsAlgorithm(); |
| |
| if (!checkGA(graphicsAlgorithm)) { |
| return false; |
| } |
| |
| if (pe instanceof ContainerShape) { |
| ContainerShape containerShape = (ContainerShape) pe; |
| List<org.eclipse.graphiti.mm.pictograms.Shape> children = containerShape.getChildren(); |
| for (org.eclipse.graphiti.mm.pictograms.Shape childShape : children) { |
| if (!childShape.isActive()) { |
| if (!checkGAs(childShape)) { |
| return false; |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| private IFigure createFigureForGraphicsAlgorithm(PictogramElement pe, GraphicsAlgorithm graphicsAlgorithm) { |
| return createFigureForGraphicsAlgorithm(pe, graphicsAlgorithm, false); |
| } |
| |
| /** |
| * @param graphicsAlgorithm |
| * @return |
| */ |
| private IFigure createFigureForGraphicsAlgorithm(PictogramElement pe, GraphicsAlgorithm graphicsAlgorithm, |
| boolean specialSelectionHandlingForOuterGaFigures) { |
| IFigure ret = null; |
| if (graphicsAlgorithm != null) { |
| if (pe instanceof Connection) { |
| // special for connections |
| ret = new GFPolylineConnection(this, graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof Ellipse) { |
| if (pe instanceof ConnectionDecorator && !pe.isActive()) { |
| ret = new GFEllipseDecoration(this, graphicsAlgorithm); |
| } else { |
| ret = new GFEllipse(this, graphicsAlgorithm); |
| } |
| } else if (graphicsAlgorithm instanceof Polygon) { |
| // if graphics-algorithm belongs to an inactive decorator-shape |
| // use special polygon |
| if (pe instanceof ConnectionDecorator && !pe.isActive()) { |
| ret = new GFPolygonDecoration(this, graphicsAlgorithm); |
| } else { |
| ret = new GFPolygon(this, graphicsAlgorithm); |
| } |
| } else if (graphicsAlgorithm instanceof Polyline) { |
| // if graphics-algorithm belongs to an inactive decorator-shape |
| // use special polygon |
| if (pe instanceof ConnectionDecorator && !pe.isActive()) { |
| ret = new GFPolylineDecoration(this, graphicsAlgorithm); |
| } else { |
| ret = new GFPolyline(this, graphicsAlgorithm); |
| } |
| } else if (graphicsAlgorithm instanceof Rectangle) { |
| ret = new GFRectangleFigure(this, graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof RoundedRectangle) { |
| ret = new GFRoundedRectangle(this, graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof MultiText) { |
| ret = new GFMultilineText(this, (MultiText) graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof Text) { |
| ret = new GFText(this, (Text) graphicsAlgorithm); |
| } else if (graphicsAlgorithm instanceof PlatformGraphicsAlgorithm) { |
| PlatformGraphicsAlgorithm pga = (PlatformGraphicsAlgorithm) graphicsAlgorithm; |
| IGraphicsAlgorithmRendererFactory factory = getGraphicsAlgorithmRendererFactory(); |
| if (factory != null) { |
| IRendererContext rendererContext = new RendererContext(pga, getConfigurationProvider() |
| .getDiagramTypeProvider()); |
| IGraphicsAlgorithmRenderer pr = factory.createGraphicsAlgorithmRenderer(rendererContext); |
| if (pr instanceof IFigure) { |
| ret = (IFigure) pr; |
| } |
| } |
| } else if (graphicsAlgorithm instanceof Image) { |
| ret = new GFImageFigure(graphicsAlgorithm); |
| } |
| |
| if (ret != null) { |
| if (graphicsAlgorithm.getGraphicsAlgorithmChildren().size() > 0) { |
| // Bug 481619 - in case we have a platform graphics |
| // algorithm and a layout manager is set then do not |
| // override with XYLayout. |
| if (!(graphicsAlgorithm instanceof PlatformGraphicsAlgorithm) || ret.getLayoutManager() == null) { |
| ret.setLayoutManager(new XYLayout()); |
| } |
| } |
| |
| addGraphicsAlgorithmForFigure(ret, graphicsAlgorithm); |
| |
| List<GraphicsAlgorithm> graphicsAlgorithmChildren = graphicsAlgorithm.getGraphicsAlgorithmChildren(); |
| for (GraphicsAlgorithm childGa : graphicsAlgorithmChildren) { |
| ret.add(createFigureForGraphicsAlgorithm(null, childGa)); |
| } |
| } |
| } |
| if (specialSelectionHandlingForOuterGaFigures) { |
| if (ret instanceof GFAbstractShape) { |
| GFAbstractShape gfAbstractShape = (GFAbstractShape) ret; |
| IToolBehaviorProvider currentToolBehaviorProvider = getConfigurationProvider().getDiagramTypeProvider() |
| .getCurrentToolBehaviorProvider(); |
| gfAbstractShape.setSelectionBorder(currentToolBehaviorProvider |
| .getSelectionBorder(getPictogramElement())); |
| gfAbstractShape.setClickArea(currentToolBehaviorProvider.getClickArea(getPictogramElement())); |
| } |
| } |
| |
| return ret; |
| } |
| |
| private IFigure createFigureForPictogramElement(final PictogramElement pe) { |
| GraphicsAlgorithm graphicsAlgorithm = pe.getGraphicsAlgorithm(); |
| |
| IFigure ret = createFigureForGraphicsAlgorithm(pe, graphicsAlgorithm, pe.isActive()); |
| |
| if (ret == null) { |
| return ret; |
| } |
| |
| // _directEditPerformer = new |
| // DirectEditPerformer(getConfigurationProvider(), this, _labels, |
| // attributes); |
| |
| if (pe instanceof ContainerShape) { |
| // Bug 481619 - in case we have a platform graphics algorithm and a |
| // layout manager is set then do not override with XYLayout. |
| if (!(graphicsAlgorithm instanceof PlatformGraphicsAlgorithm) || ret.getLayoutManager() == null) { |
| ret.setLayoutManager(new XYLayout()); |
| } |
| ContainerShape containerShape = (ContainerShape) pe; |
| List<org.eclipse.graphiti.mm.pictograms.Shape> containersChildren = containerShape.getChildren(); |
| for (org.eclipse.graphiti.mm.pictograms.Shape shape : containersChildren) { |
| if (!shape.isActive()) { |
| IFigure f = createFigureForPictogramElement(shape); |
| ret.add(f); |
| } |
| } |
| } else if (pe instanceof Connection) { |
| createFiguresForPassiveDecorators((Connection) pe); |
| } |
| |
| return ret; |
| } |
| |
| private void createFiguresForPassiveDecorators(Connection connection) { |
| |
| IFigure figure = getFigureForGraphicsAlgorithm(connection.getGraphicsAlgorithm()); |
| if (figure instanceof GFPolylineConnection) { |
| GFPolylineConnection polylineConnection = (GFPolylineConnection) figure; |
| Collection<ConnectionDecorator> c = connection.getConnectionDecorators(); |
| for (ConnectionDecorator connectionDecorator : c) { |
| if (!connectionDecorator.isActive()) { |
| GraphicsAlgorithm graphicsAlgorithm = connectionDecorator.getGraphicsAlgorithm(); |
| IFigure newFigure = createFigureForGraphicsAlgorithm(connectionDecorator, graphicsAlgorithm); |
| RotatableDecoration rotatableDecoration = null; |
| if (newFigure instanceof RotatableDecoration) { |
| rotatableDecoration = (RotatableDecoration) newFigure; |
| } |
| if (connectionDecorator.isLocationRelative()) { |
| double relativeLocation = connectionDecorator.getLocation(); |
| // TODO: change metamodel to get rid of special handling |
| // for backward compability |
| if (relativeLocation != 1) { |
| polylineConnection.addDecoration(rotatableDecoration, true, relativeLocation, 0, 0); |
| } else { |
| polylineConnection.addDecoration(rotatableDecoration, false, 0.0, 0, 0); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * returns null if the decorator does not produce a figure of its own |
| */ |
| private IFigure decorateFigure(IFigure figure, IDecorator decorator) { |
| if (decorator == null) { |
| return null; |
| } |
| |
| String messageText = decorator.getMessage(); |
| |
| // Variable to store an additional figure for the decorator (needed in |
| // case of an image decorator. Cannot be created in the if for image |
| // decorators, because a shape can have more than one decorator (also of |
| // different kinds) |
| IFigure decoratorFigure = null; |
| org.eclipse.draw2d.geometry.Rectangle boundsForDecoratorFigure = new org.eclipse.draw2d.geometry.Rectangle(0, |
| 0, 16, 16); |
| |
| // Decorate with an image |
| if (decorator instanceof IImageDecorator) { |
| IImageDecorator imageDecorator = (IImageDecorator) decorator; |
| org.eclipse.swt.graphics.Image imageForId = GraphitiUi.getImageService().getImageForId( |
| configurationProvider.getDiagramTypeProvider().getProviderId(), |
| imageDecorator.getImageId()); |
| ImageFigure imageFigure = new DecoratorImageFigure(imageForId); |
| decoratorFigure = imageFigure; |
| org.eclipse.swt.graphics.Rectangle imageBounds = imageFigure.getImage().getBounds(); |
| boundsForDecoratorFigure.setSize(imageBounds.width, imageBounds.height); |
| |
| if (decorator instanceof ILocation) { |
| ILocation location = (ILocation) decorator; |
| boundsForDecoratorFigure.setLocation(location.getX(), location.getY()); |
| } |
| |
| IFigure parent = figure.getParent(); |
| if (parent != null) { |
| org.eclipse.draw2d.geometry.Rectangle ownerBounds = (org.eclipse.draw2d.geometry.Rectangle) parent |
| .getLayoutManager().getConstraint(figure); |
| boundsForDecoratorFigure.translate(ownerBounds.getLocation()); |
| } |
| |
| decoratorFigure.setVisible(true); |
| if (messageText != null && messageText.length() > 0) { |
| decoratorFigure.setToolTip(new Label(messageText)); |
| } |
| if (parent.getLayoutManager() == null) { |
| parent.setLayoutManager(new XYLayout()); |
| } |
| parent.add(decoratorFigure, boundsForDecoratorFigure, parent.getChildren().indexOf(figure) + 1); |
| } |
| |
| // Decorate with text |
| if (decorator instanceof ITextDecorator) { |
| ITextDecorator textDecorator = (ITextDecorator) decorator; |
| String text = textDecorator.getText(); |
| decoratorFigure = new Label(text); |
| |
| IResourceRegistry resourceRegistry = getConfigurationProvider().getResourceRegistry(); |
| final Font font = resourceRegistry |
| .getSwtFont(new FontData(textDecorator.getFontName(), textDecorator.getFontSize(), SWT.NORMAL)); |
| |
| Dimension dimension = TextUtilities.INSTANCE.getStringExtents(text, font); |
| boundsForDecoratorFigure.setSize(dimension.width, dimension.height); |
| |
| decoratorFigure.setFont(font); |
| |
| IColorConstant backgroundColor = textDecorator.getBackgroundColor(); |
| if (backgroundColor != null) { |
| decoratorFigure.setOpaque(true); |
| decoratorFigure.setBackgroundColor(resourceRegistry.getSwtColor(backgroundColor.getRed(), |
| backgroundColor.getGreen(), backgroundColor.getBlue())); |
| } |
| IColorConstant foregroundColor = textDecorator.getForegroundColor(); |
| if (foregroundColor != null) { |
| decoratorFigure.setForegroundColor(resourceRegistry.getSwtColor(foregroundColor.getRed(), |
| foregroundColor.getGreen(), foregroundColor.getBlue())); |
| } |
| |
| if (decorator instanceof ILocation) { |
| ILocation location = (ILocation) decorator; |
| boundsForDecoratorFigure.setLocation(location.getX(), location.getY()); |
| } |
| |
| IFigure parent = figure.getParent(); |
| if (parent != null) { |
| org.eclipse.draw2d.geometry.Rectangle ownerBounds = (org.eclipse.draw2d.geometry.Rectangle) parent |
| .getLayoutManager().getConstraint(figure); |
| boundsForDecoratorFigure.translate(ownerBounds.getLocation()); |
| } |
| |
| decoratorFigure.setVisible(true); |
| if (messageText != null && messageText.length() > 0) { |
| decoratorFigure.setToolTip(new Label(messageText)); |
| } |
| if (parent.getLayoutManager() == null) { |
| parent.setLayoutManager(new XYLayout()); |
| } |
| parent.add(decoratorFigure, boundsForDecoratorFigure, parent.getChildren().indexOf(figure) + 1); |
| } |
| |
| // Decorate the border of the shape |
| if (decorator instanceof IBorderDecorator) { |
| IBorderDecorator renderingDecorator = ((IBorderDecorator) decorator); |
| IResourceRegistry resourceRegistry = getConfigurationProvider().getResourceRegistry(); |
| |
| // Get the width for the border (or set to default) |
| Integer borderWidth = renderingDecorator.getBorderWidth(); |
| if (borderWidth == null || borderWidth < 1) { |
| borderWidth = 1; |
| } |
| |
| // Get the style for the border (or set to default) |
| Integer borderStyle = renderingDecorator.getBorderStyle(); |
| if (borderStyle == null |
| || (Graphics.LINE_DASH != borderStyle && Graphics.LINE_DASHDOT != borderStyle |
| && Graphics.LINE_DASHDOTDOT != borderStyle && Graphics.LINE_DOT != borderStyle && Graphics.LINE_SOLID != borderStyle)) { |
| borderStyle = Graphics.LINE_SOLID; |
| } |
| |
| // Get the color for the border (or set to default) |
| Color borderColor = null; |
| IColorConstant colorConstant = renderingDecorator.getBorderColor(); |
| if (colorConstant == null) { |
| colorConstant = IColorConstant.BLACK; |
| } |
| borderColor = resourceRegistry.getSwtColor(colorConstant.getRed(), colorConstant.getGreen(), |
| colorConstant.getBlue()); |
| |
| // Apply border decorations |
| figure.setBorder(new LineBorder(borderColor, borderWidth, borderStyle)); |
| } |
| |
| // Decorate using the colors of the shape |
| if (decorator instanceof IColorDecorator) { |
| IColorDecorator renderingDecorator = ((IColorDecorator) decorator); |
| IResourceRegistry resourceRegistry = getConfigurationProvider().getResourceRegistry(); |
| |
| // Get the background color (or set to default) |
| Color backgroundColor = null; |
| IColorConstant colorConstant = renderingDecorator.getBackgroundColor(); |
| if (colorConstant != null) { |
| backgroundColor = resourceRegistry.getSwtColor(colorConstant.getRed(), colorConstant.getGreen(), |
| colorConstant.getBlue()); |
| } |
| |
| // Get the foreground color (or set to default) |
| Color foregroundColor = null; |
| colorConstant = renderingDecorator.getForegroundColor(); |
| if (colorConstant != null) { |
| foregroundColor = resourceRegistry.getSwtColor(colorConstant.getRed(), colorConstant.getGreen(), |
| colorConstant.getBlue()); |
| } |
| |
| // Apply color decorations |
| if (foregroundColor != null) { |
| figure.setForegroundColor(foregroundColor); |
| } |
| if (backgroundColor != null) { |
| figure.setBackgroundColor(backgroundColor); |
| } |
| if (figure instanceof Shape) { |
| ((Shape) figure).setFill(true); |
| } |
| } |
| |
| // Return additionally created figure |
| return decoratorFigure; |
| } |
| |
| /** |
| * @param figure |
| * @param updateNeeded |
| */ |
| private Label indicateNeededUpdates(IFigure figure, IReason updateNeeded) { |
| Label ret = null; |
| if (figure != null && updateNeeded != null && updateNeeded.toBoolean()) { |
| // The figure needs an update, we indicate that with a red border |
| // and a tooltip showing the reason for the update |
| figure.setForegroundColor(ColorConstants.red); |
| if (figure instanceof Shape) { |
| Shape draw2dShape = (Shape) figure; |
| draw2dShape.setLineWidth(2); |
| draw2dShape.setLineStyle(Graphics.LINE_DOT); |
| |
| String updateNeededText = updateNeeded.getText(); |
| if (updateNeededText != null && updateNeededText.length() > 0) { |
| Label toolTipFigure = new Label(); |
| toolTipFigure.setText(updateNeededText); |
| org.eclipse.swt.graphics.Image image = PlatformUI.getWorkbench().getSharedImages() |
| .getImage(ISharedImages.IMG_OBJS_WARN_TSK); |
| toolTipFigure.setIcon(image); |
| ret = toolTipFigure; |
| } |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * returns TRUE if structure of connection-model (connection,passive |
| * decorators and ga's) are in sync with the current figure-tree |
| */ |
| private boolean isConnectionRefreshPossible(Connection connection) { |
| if (!GraphitiInternal.getEmfService().isObjectAlive(connection)) { |
| return false; |
| } |
| |
| // compare pictogram-model with figure-tree -> structural changes? |
| |
| List<GraphicsAlgorithm> gaList = new ArrayList<GraphicsAlgorithm>(); |
| Collection<ConnectionDecorator> c = connection.getConnectionDecorators(); |
| for (ConnectionDecorator connectionDecorator : c) { |
| if (!connectionDecorator.isActive()) { |
| GraphicsAlgorithm ga = connectionDecorator.getGraphicsAlgorithm(); |
| if (ga != null) { |
| gaList.add(ga); |
| } |
| } |
| } |
| |
| if (connection.getGraphicsAlgorithm() != null) { |
| gaList.add(connection.getGraphicsAlgorithm()); |
| } |
| |
| // do all ga's have a figure? |
| for (GraphicsAlgorithm graphicsAlgorithm : gaList) { |
| IFigure figure = getFigureForGraphicsAlgorithm(graphicsAlgorithm); |
| if (figure == null) { |
| return false; |
| } |
| } |
| |
| // are there any registered GA, which are not in use? |
| for (GraphicsAlgorithm graphicsAlgorithm : elementFigureHash.keySet()) { |
| if (!gaList.contains(graphicsAlgorithm)) { |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| |
| /** |
| * returns TRUE if structure of pictogram-model (shapes & ga's) are in sync |
| * with the current figure-tree |
| */ |
| private boolean isRefreshPossible(PictogramElement pe) { |
| // compare pictogram-model with figure-tree -> structural changes? |
| if (pe instanceof org.eclipse.graphiti.mm.pictograms.Shape || pe instanceof AdvancedAnchor) { |
| boolean ret = checkGAs(pe); |
| if (ret == false) { |
| return ret; |
| } |
| // invalid ga's in hashtable? |
| for (GraphicsAlgorithm graphicsAlgorithm : elementFigureHash.keySet()) { |
| if (!GraphitiInternal.getEmfService().isObjectAlive(graphicsAlgorithm)) { |
| return false; |
| } |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * @param figure |
| * @param graphicsAlgorithm |
| */ |
| private void refreshFigureColors(IFigure figure, GraphicsAlgorithm graphicsAlgorithm) { |
| Color fg = DataTypeTransformation.toSwtColor(getConfigurationProvider().getResourceRegistry(), Graphiti |
| .getGaService().getForegroundColor(graphicsAlgorithm, true)); |
| Color bg = DataTypeTransformation.toSwtColor(getConfigurationProvider().getResourceRegistry(), Graphiti |
| .getGaService().getBackgroundColor(graphicsAlgorithm, true)); |
| figure.setBackgroundColor(bg); |
| figure.setForegroundColor(fg); |
| } |
| |
| // private void refreshFigureColors(IFigure figure, GraphicsAlgorithm |
| // graphicsAlgorithm, int redShift) { |
| // if (redShift == 0) { |
| // refreshFigureColors(figure, graphicsAlgorithm); |
| // } else { |
| // Color fg = |
| // toSwtColor(Graphiti.getGaService()Internal.getForegroundColor(graphicsAlgorithm, |
| // true), redShift); |
| // Color bg = |
| // toSwtColor(Graphiti.getGaService()Internal.getBackgroundColor(graphicsAlgorithm, |
| // true), redShift); |
| // figure.setBackgroundColor(bg); |
| // figure.setForegroundColor(fg); |
| // } |
| // } |
| |
| /** |
| * @param figure |
| */ |
| private void refreshFigureForPictogramElement(PictogramElement pe) { |
| |
| if (pe != null) { |
| DefaultRefreshBehavior refreshBehavior = getDiagramBehavior().getRefreshBehavior(); |
| if (!isForceRefresh() && refreshBehavior.isMultipleRefreshSupressionActive()) { |
| if (!refreshBehavior.shouldRefresh(pe)) { |
| return; |
| } |
| } |
| |
| if (pe instanceof ContainerShape) { |
| ContainerShape containerShape = (ContainerShape) pe; |
| List<org.eclipse.graphiti.mm.pictograms.Shape> children = containerShape.getChildren(); |
| for (org.eclipse.graphiti.mm.pictograms.Shape shape : children) { |
| if (!shape.isActive()) { |
| refreshFigureForPictogramElement(shape); |
| } |
| } |
| } else if (pe instanceof Connection) { |
| Connection connection = (Connection) pe; |
| Collection<ConnectionDecorator> c = connection.getConnectionDecorators(); |
| for (ConnectionDecorator decorator : c) { |
| if (!decorator.isActive()) { |
| refreshFigureForPictogramElement(decorator); |
| } |
| } |
| } |
| |
| GraphicsAlgorithm ga = pe.getGraphicsAlgorithm(); |
| if (ga != null) { |
| IReason updateNeeded = checkIfUpdateNeeded(pe); |
| refreshFigureForGraphicsAlgorithm(ga, pe, updateNeeded); |
| } |
| } |
| } |
| |
| /** |
| * @param shape |
| * @param graphicsAlgorithm |
| */ |
| private void refreshShapeData(org.eclipse.draw2d.Shape shape, GraphicsAlgorithm graphicsAlgorithm) { |
| |
| if (shape == null || graphicsAlgorithm == null) { |
| return; |
| } |
| |
| // line width |
| int lineWidth = Graphiti.getGaService().getLineWidth(graphicsAlgorithm, true); |
| shape.setLineWidth(lineWidth); |
| |
| // line style |
| LineStyle lineStyle = Graphiti.getGaService().getLineStyle(graphicsAlgorithm, true); |
| int draw2dLineStyle = Graphics.LINE_SOLID; |
| if (lineStyle == LineStyle.DASH) { |
| draw2dLineStyle = Graphics.LINE_DASH; |
| } else if (lineStyle == LineStyle.DASHDOT) { |
| draw2dLineStyle = Graphics.LINE_DASHDOT; |
| } else if (lineStyle == LineStyle.DASHDOTDOT) { |
| draw2dLineStyle = Graphics.LINE_DASHDOTDOT; |
| } else if (lineStyle == LineStyle.DOT) { |
| draw2dLineStyle = Graphics.LINE_DOT; |
| } else if (lineStyle == LineStyle.SOLID) { |
| draw2dLineStyle = Graphics.LINE_SOLID; |
| } |
| shape.setLineStyle(draw2dLineStyle); |
| |
| // fill? |
| final boolean filled = Graphiti.getGaService().isFilled(graphicsAlgorithm, true); |
| shape.setFill(filled); |
| |
| // outline? |
| final boolean lineVisible = Graphiti.getGaService().isLineVisible(graphicsAlgorithm, true); |
| shape.setOutline(lineVisible); |
| } |
| |
| private void refreshTextOrientation(GFText label, Text text) { |
| |
| int draw2dOrientation = PositionConstants.LEFT; |
| |
| Orientation orientation = Graphiti.getGaService().getHorizontalAlignment(text, true); |
| if (orientation != null) { |
| if (orientation == Orientation.ALIGNMENT_BOTTOM) { |
| draw2dOrientation = PositionConstants.BOTTOM; |
| } else if (orientation == Orientation.ALIGNMENT_CENTER) { |
| draw2dOrientation = PositionConstants.CENTER; |
| } else if (orientation == Orientation.ALIGNMENT_LEFT) { |
| draw2dOrientation = PositionConstants.LEFT; |
| } else if (orientation == Orientation.ALIGNMENT_RIGHT) { |
| draw2dOrientation = PositionConstants.RIGHT; |
| } else if (orientation == Orientation.ALIGNMENT_TOP) { |
| draw2dOrientation = PositionConstants.TOP; |
| } |
| } |
| label.setLabelAlignment(draw2dOrientation); |
| } |
| |
| private void refreshFlowTextAlignment(GFMultilineText label, MultiText text) { |
| |
| int draw2dOrientation = PositionConstants.LEFT; |
| Orientation orientation = Graphiti.getGaService().getHorizontalAlignment(text, true); |
| if (orientation != null) { |
| if (orientation == Orientation.ALIGNMENT_RIGHT) { |
| draw2dOrientation = PositionConstants.RIGHT; |
| } else if (orientation == Orientation.ALIGNMENT_CENTER) { |
| draw2dOrientation = PositionConstants.CENTER; |
| } |
| } |
| label.setHorizontalAligment(draw2dOrientation); |
| |
| draw2dOrientation = PositionConstants.TOP; |
| orientation = Graphiti.getGaService().getVerticalAlignment(text, true); |
| if (orientation != null) { |
| if (orientation == Orientation.ALIGNMENT_BOTTOM) { |
| draw2dOrientation = PositionConstants.BOTTOM; |
| } else if (orientation == Orientation.ALIGNMENT_CENTER) { |
| draw2dOrientation = PositionConstants.MIDDLE; |
| } |
| } |
| label.setVerticalAligment(draw2dOrientation); |
| } |
| |
| // private void |
| // registerBusinessChangeListenersForPictogramElement(PictogramElement pe) { |
| // if (businessChangeListeners != null) { |
| // return; // throw new IllegalStateException("Listeners already |
| // // registered"); |
| // } |
| // EventRegistry eventRegistry = getEventRegistry(); |
| // if (eventRegistry != null) { |
| // IFeatureProvider featureProvider = |
| // getConfigurationProvider().getDiagramTypeProvider().getFeatureProvider(); |
| // if (featureProvider != null) { |
| // Object[] businessObjects = |
| // featureProvider.getAllBusinessObjectsForPictogramElement(pe); |
| // |
| // int boCount = businessObjects.length; |
| // businessChangeListeners = new BusinessChangeListener[boCount]; |
| // for (int i = 0; i < boCount; i++) { |
| // Object bo = businessObjects[i]; |
| // if (bo instanceof EObject) { |
| // EObject rbo = (EObject) bo; |
| // EventFilter filter = new CompositionHierarchyFilter(rbo); |
| // businessChangeListeners[i] = new BusinessChangeListener(); |
| // eventRegistry.registerUpdateListener(businessChangeListeners[i], filter); |
| // // register a partition change listener as well |
| // if (bo instanceof Partitionable) { |
| // Partitionable partitionlable = (Partitionable) bo; |
| // ModelPartition partition = partitionlable.get___Partition(); |
| // eventRegistry.registerUpdateListener(businessChangeListeners[i], new |
| // AndFilter(new EventTypeFilter( |
| // PartitionChangeEvent.class), new PartitionFilter(partition))); |
| // } |
| // } |
| // } |
| // } |
| // } |
| // } |
| |
| /** |
| * @param configurationProvider |
| * The configurationProvider to set. |
| */ |
| private void setConfigurationProvider(IConfigurationProviderInternal configurationProvider) { |
| this.configurationProvider = configurationProvider; |
| } |
| |
| private void setFigureConstraint(IFigure figure, GraphicsAlgorithm graphicsAlgorithm, PictogramElement pe) { |
| |
| // PolylineConnection's and RotatableDecoration's will be handled by the |
| // gef-framework |
| if ((figure instanceof PolylineConnection) || figure instanceof GFPolylineConnection |
| || (figure instanceof RotatableDecoration && !(figure instanceof GFText)) || figure.getParent() == null) { |
| return; |
| } |
| |
| IDimension gaSize = Graphiti.getGaService().calculateSize(graphicsAlgorithm); |
| |
| if (gaSize == null) { |
| return; |
| } |
| |
| Dimension dimension = new Dimension(gaSize.getWidth(), gaSize.getHeight()); |
| |
| // Special handling if a text is used in a passive connection decorator. |
| // In this case simply set the size. The location can not be set, |
| // because it will be overwritten later through the class |
| // FlexibleRotatableLocator |
| if (figure instanceof GFText && (pe instanceof ConnectionDecorator) && !pe.isActive() |
| && (figure.getParent() instanceof GFPolylineConnection)) { |
| GFText text = (GFText) figure; |
| text.setSize(dimension); |
| return; |
| } |
| |
| ILocation gaLocation = null; |
| |
| if (!(graphicsAlgorithm instanceof Polyline)) { |
| gaLocation = new LocationImpl(graphicsAlgorithm.getX(), graphicsAlgorithm.getY()); |
| } else { |
| gaLocation = calculatePolylineLocation((Polyline) graphicsAlgorithm); |
| } |
| |
| if (gaLocation == null) { |
| gaLocation = new LocationImpl(0, 0); |
| } |
| |
| Point point = null; |
| |
| if (pe instanceof ConnectionDecorator && pe.isActive()) { |
| |
| // get relative point on connection-figure |
| ConnectionDecorator connectionDecorator = (ConnectionDecorator) pe; |
| Connection connection = connectionDecorator.getConnection(); |
| if (connection == null) { |
| return; |
| } |
| Point pointAt = null; |
| double decoratorLocation = connectionDecorator.getLocation(); |
| if (connectionDecorator.isLocationRelative()) { |
| pointAt = GraphitiUiInternal.getGefService().getConnectionPointAt(connection, decoratorLocation); |
| } else { // location is absolute |
| pointAt = GraphitiUiInternal.getGefService() |
| .getAbsolutePointOnConnection(connection, decoratorLocation); |
| } |
| |
| if (pointAt == null) { |
| return; |
| } |
| point = new Point(pointAt.x + gaLocation.getX(), pointAt.y + gaLocation.getY()); |
| |
| // all decorator-shapes get the the dimension of the text which they |
| // contain |
| // TODO fix this hack; later the features are responsibles for |
| // providing the correct size |
| if (figure instanceof Label && connectionDecorator.getGraphicsAlgorithm() instanceof Text) { |
| Label label = (Label) figure; |
| if (label.getText() != null && label.getText().length() > 0) { |
| // if text was not set, getTextBounds() does not work |
| // correct |
| dimension = label.getTextBounds().getSize(); |
| // WORKAROUND: |
| // We had the problem, that the text-width was sometimes too |
| // small |
| // (depending on the zoom-level, text or installation?!) |
| // As an easy fix, we add one pixel per character |
| dimension.width += label.getText().length(); |
| } |
| } |
| |
| } else if (pe instanceof BoxRelativeAnchor && pe.equals(graphicsAlgorithm.getPictogramElement())) { |
| BoxRelativeAnchor bra = (BoxRelativeAnchor) pe; |
| IRectangle gaBoundsForAnchor = Graphiti.getLayoutService().getGaBoundsForAnchor(bra); |
| double newX = gaBoundsForAnchor.getX() + (gaBoundsForAnchor.getWidth() * bra.getRelativeWidth()) |
| + gaLocation.getX(); |
| double newY = gaBoundsForAnchor.getY() + (gaBoundsForAnchor.getHeight() * bra.getRelativeHeight()) |
| + gaLocation.getY(); |
| point = new PrecisionPoint(newX, newY); |
| |
| } else if (pe instanceof FixPointAnchor && pe.equals(graphicsAlgorithm.getPictogramElement())) { |
| FixPointAnchor fpa = (FixPointAnchor) pe; |
| IRectangle gaBoundsForAnchor = Graphiti.getLayoutService().getGaBoundsForAnchor(fpa); |
| org.eclipse.graphiti.mm.algorithms.styles.Point fpaLocation = fpa.getLocation(); |
| if (fpaLocation == null) { |
| return; |
| } |
| point = new Point(gaBoundsForAnchor.getX() + fpaLocation.getX() + gaLocation.getX(), |
| gaBoundsForAnchor.getY() + fpaLocation.getY() + gaLocation.getY()); |
| |
| } else { |
| point = new Point(gaLocation.getX(), gaLocation.getY()); |
| } |
| |
| if (point != null) { |
| IFigure parent = figure.getParent(); |
| if (parent != null) { |
| parent.setConstraint(figure, new org.eclipse.draw2d.geometry.Rectangle(point, dimension)); |
| } |
| } |
| } |
| |
| /** |
| * @param pictogramElement |
| * The pictogramElement to set. |
| */ |
| private void setPictogramElement(PictogramElement pictogramElement) { |
| this.pictogramElement = pictogramElement; |
| } |
| |
| private PointList toAbsoluteDraw2dPoints(Collection<org.eclipse.graphiti.mm.algorithms.styles.Point> points, |
| ILocation location) { |
| int deltaX = 0; |
| int deltaY = 0; |
| if (location != null) { |
| deltaX = location.getX(); |
| deltaY = location.getY(); |
| } |
| PointList pointList = new PointList(); |
| for (org.eclipse.graphiti.mm.algorithms.styles.Point dtp : points) { |
| pointList.addPoint(dtp.getX() + deltaX, dtp.getY() + deltaY); |
| } |
| return pointList; |
| } |
| |
| /** |
| * Returns the bezier-distances (distance-before and distance-after), which |
| * are calculated from the radius of the given points. |
| * |
| * @param points |
| * The points, for which to return the bezier-distances. |
| * |
| * @return The bezier-distances (distance-before and distance-after), which |
| * are calculated from the radius of the given points. |
| */ |
| private int[] getBezierDistances(Collection<org.eclipse.graphiti.mm.algorithms.styles.Point> points) { |
| if (getPreferences().getPolylineRounding() == 0 || getPreferences().getPolylineRounding() == 2) { |
| int i = 0; |
| int bezierDistances[] = new int[points.size() * 2]; |
| for (org.eclipse.graphiti.mm.algorithms.styles.Point dtp : points) { |
| if (getPreferences().getPolylineRounding() == 0) { // rounding |
| // on |
| bezierDistances[i++] = dtp.getBefore(); // bezierDistancesBefore |
| bezierDistances[i++] = dtp.getAfter(); // bezierDistancesAfter |
| } else if (getPreferences().getPolylineRounding() == 2) { // rounding |
| // always |
| bezierDistances[i++] = 15; // bezierDistancesBefore |
| bezierDistances[i++] = 15; // bezierDistancesAfter |
| } |
| } |
| return bezierDistances; |
| } |
| return null; // rounding off |
| } |
| |
| private IGraphicsAlgorithmRendererFactory getGraphicsAlgorithmRendererFactory() { |
| return getConfigurationProvider().getDiagramTypeProvider().getGraphicsAlgorithmRendererFactory(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.graphiti.features.IFeatureProviderHolder#getFeatureProvider() |
| */ |
| public IFeatureProvider getFeatureProvider() { |
| IConfigurationProvider cp = getConfigurationProvider(); |
| IFeatureProvider ret = null; |
| if (cp != null) { |
| ret = cp.getFeatureProvider(); |
| } |
| if (T.racer().info()) { |
| T.racer().info("PictogramElementDelegate", "getFeatureProvider", "returns " + ret.toString()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| } |
| return ret; |
| } |
| |
| public void setForceRefresh(boolean forceRefresh) { |
| this.forceRefresh = forceRefresh; |
| } |
| |
| protected boolean isForceRefresh() { |
| return forceRefresh; |
| } |
| |
| private DiagramBehavior getDiagramBehavior() { |
| return getConfigurationProvider().getDiagramBehavior(); |
| } |
| |
| protected void addDecorators(final GraphicsAlgorithm graphicsAlgorithm, final PictogramElement pe, |
| final IFigure figure, IToolBehaviorProvider toolBehaviorProvider) { |
| if (pe.isActive() && !(pe instanceof Anchor) && graphicsAlgorithm.equals(pe.getGraphicsAlgorithm())) { |
| |
| removeDecorators(figure); |
| refreshFigureColors(figure, graphicsAlgorithm); |
| figure.setBorder(null); |
| |
| IDecorator[] decorators = toolBehaviorProvider.getDecorators(pe); |
| |
| if (decorators.length > 0) { |
| List<IFigure> decList = new ArrayList<IFigure>(); |
| decoratorMap.put(figure, decList); |
| for (int i = 0; i < decorators.length; i++) { |
| if (pe instanceof Connection && !(decorators[i] instanceof IColorDecorator)) { |
| // For connections only color decorators are supported |
| continue; |
| } |
| IDecorator decorator = decorators[i]; |
| IFigure decorateFigure = decorateFigure(figure, decorator); |
| if (decorateFigure != null) { |
| decList.add(decorateFigure); |
| } |
| } |
| } |
| } |
| } |
| |
| private void removeDecorators(final IFigure figure) { |
| List<IFigure> decFigureList = decoratorMap.get(figure); |
| if (decFigureList != null) { |
| for (IFigure decFigure : decFigureList) { |
| IFigure parent = decFigure.getParent(); |
| if (parent != null) { |
| parent.remove(decFigure); |
| } |
| } |
| decFigureList.clear(); |
| decoratorMap.remove(figure); |
| } |
| } |
| |
| public boolean isValid() { |
| return valid; |
| } |
| |
| protected void setValid(boolean valid) { |
| this.valid = valid; |
| } |
| |
| /** |
| * Returns the visual state of this shape. |
| * |
| * @return The visual state of this shape. |
| */ |
| public IVisualState getVisualState() { |
| if (visualState == null) { |
| visualState = new VisualState(); |
| } |
| return visualState; |
| } |
| |
| private boolean isDefaultBendPointRenderingActive() { |
| boolean defaultBendPointRenderingActive = true; |
| IToolBehaviorProvider ctbp = getConfigurationProvider().getDiagramTypeProvider() |
| .getCurrentToolBehaviorProvider(); |
| if (ctbp instanceof DefaultToolBehaviorProvider) { |
| defaultBendPointRenderingActive = ((DefaultToolBehaviorProvider) ctbp).isDefaultBendPointRenderingActive(); |
| } |
| return defaultBendPointRenderingActive; |
| } |
| |
| public List<IFigure> getMainFiguresFromChildEditparts() { |
| List<IFigure> ret = new ArrayList<IFigure>(); |
| List<EditPart> children = GraphitiUiInternal.getGefService().getEditPartChildren(getContainerEditPart()); |
| for (EditPart ep : children) { |
| if (ep instanceof ShapeEditPart || ep instanceof AdvancedAnchorEditPart) { |
| GraphicalEditPart gep = (GraphicalEditPart) ep; |
| ret.add(gep.getFigure()); |
| } |
| } |
| return ret; |
| } |
| |
| protected GFPreferences getPreferences() { |
| return GFPreferences.getInstance(); |
| } |
| |
| public void refreshDecorators() { |
| PictogramElement pe = getPictogramElement(); |
| GraphicsAlgorithm ga = pe.getGraphicsAlgorithm(); |
| IToolBehaviorProvider tbp = getConfigurationProvider().getDiagramTypeProvider() |
| .getCurrentToolBehaviorProvider(); |
| addDecorators(ga, pe, getFigureForGraphicsAlgorithm(ga), tbp); |
| } |
| } |