org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramContainerEditPartOperation.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.sirius.diagram.ui.edit.internal.part.DiagramContainerEditPartOperation.java

Source

/*******************************************************************************
 * Copyright (c) 2007, 2015 THALES GLOBAL SERVICES and others.
 * 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:
 *    Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.sirius.diagram.ui.edit.internal.part;

import java.util.BitSet;
import java.util.Collection;

import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RoundedRectangle;
import org.eclipse.draw2d.Shape;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.BackgroundStyle;
import org.eclipse.sirius.diagram.ContainerStyle;
import org.eclipse.sirius.diagram.DDiagramElement;
import org.eclipse.sirius.diagram.DDiagramElementContainer;
import org.eclipse.sirius.diagram.DNodeContainer;
import org.eclipse.sirius.diagram.FlatContainerStyle;
import org.eclipse.sirius.diagram.LineStyle;
import org.eclipse.sirius.diagram.ShapeContainerStyle;
import org.eclipse.sirius.diagram.WorkspaceImage;
import org.eclipse.sirius.diagram.description.style.ContainerStyleDescription;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramElementContainerEditPart;
import org.eclipse.sirius.diagram.ui.edit.api.part.DiagramNameEditPartOperation;
import org.eclipse.sirius.diagram.ui.edit.api.part.IDiagramNameEditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.AbstractDNodeContainerCompartmentEditPart;
import org.eclipse.sirius.diagram.ui.tools.api.figure.GradientRoundedRectangle;
import org.eclipse.sirius.diagram.ui.tools.api.figure.IWorkspaceImageFigure;
import org.eclipse.sirius.diagram.ui.tools.api.figure.OneLineMarginBorder;
import org.eclipse.sirius.diagram.ui.tools.api.figure.SVGWorkspaceImageFigure;
import org.eclipse.sirius.diagram.ui.tools.api.figure.ViewNodeContainerFigureDesc;
import org.eclipse.sirius.diagram.ui.tools.api.figure.ViewNodeContainerParallelogram;
import org.eclipse.sirius.diagram.ui.tools.api.figure.ViewNodeContainerRectangleFigureDesc;
import org.eclipse.sirius.diagram.ui.tools.api.figure.WorkspaceImageFigure;
import org.eclipse.sirius.diagram.ui.tools.api.graphical.edit.styles.IContainerLabelOffsets;
import org.eclipse.sirius.diagram.ui.tools.internal.figure.RegionRoundedGradientRectangle;
import org.eclipse.sirius.diagram.ui.tools.internal.figure.RoundedCornerMarginBorder;
import org.eclipse.sirius.ui.tools.api.color.VisualBindingManager;
import org.eclipse.sirius.viewpoint.DStylizable;
import org.eclipse.sirius.viewpoint.RGBValues;
import org.eclipse.sirius.viewpoint.Style;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * Common operations for container and list edit parts.
 * 
 * @author ymortier
 */
public final class DiagramContainerEditPartOperation {

    /**
     * Avoid instantiation.
     */
    private DiagramContainerEditPartOperation() {

    }

    /**
     * Refreshes the foreground color of the container.
     * 
     * @param self
     *            the edit part.
     */
    public static void refreshForegroundColor(final AbstractDiagramElementContainerEditPart self) {
        final EObject eObj = self.resolveSemanticElement();
        if (eObj instanceof DDiagramElementContainer) {
            final DDiagramElementContainer container = (DDiagramElementContainer) eObj;
            ContainerStyle style = container.getOwnedStyle();
            if (style != null) {
                RGBValues rgb = style.getBorderColor();
                if (rgb != null) {
                    self.getFigure()
                            .setForegroundColor(VisualBindingManager.getDefault().getColorFromRGBValues(rgb));
                }
            }
        }
    }

    /**
     * Refreshes the background color of the container.
     * 
     * @param self
     *            the edit part.
     */
    public static void refreshBackgroundColor(final AbstractDiagramElementContainerEditPart self) {
        final EObject eObj = self.resolveSemanticElement();
        if (eObj instanceof DDiagramElementContainer) {
            final DDiagramElementContainer container = (DDiagramElementContainer) eObj;
            RGBValues rgb = null;
            ContainerStyle style = container.getOwnedStyle();
            if (style instanceof FlatContainerStyle) {
                rgb = ((FlatContainerStyle) style).getBackgroundColor();
            } else if (style instanceof ShapeContainerStyle) {
                rgb = ((ShapeContainerStyle) style).getBackgroundColor();
            }
            if (rgb != null) {
                self.getFigure().setBackgroundColor(VisualBindingManager.getDefault().getColorFromRGBValues(rgb));
            }
        }
    }

    /**
     * Refreshes the font of the container.
     * 
     * @param self
     *            the edit part.
     */
    public static void refreshFont(final AbstractDiagramElementContainerEditPart self) {
        if (!self.getChildren().isEmpty()) {
            Object firstChild = self.getChildren().get(0);
            if (firstChild instanceof IDiagramNameEditPart) {
                DiagramNameEditPartOperation.refreshFont((IDiagramNameEditPart) firstChild);
            }
        }
    }

    /**
     * Refreshes the visuals of the container.
     * 
     * @param self
     *            the edit part.
     */
    public static void refreshVisuals(final AbstractDiagramElementContainerEditPart self) {
        final DDiagramElement diagElement = self.resolveDiagramElement();
        if (diagElement instanceof DDiagramElementContainer) {
            final DDiagramElementContainer ddec = (DDiagramElementContainer) diagElement;
            final ContainerStyle style = ddec.getOwnedStyle();

            // Change the primary shape if needed.
            refreshBackgroundFigure(self, style);

            final ViewNodeContainerFigureDesc primaryShape = self.getPrimaryShape();
            refreshBorder(self, primaryShape, style);

            if (primaryShape instanceof GradientRoundedRectangle) {
                refreshGradient(style, (GradientRoundedRectangle) primaryShape);
            }

            refreshCorners(self, diagElement, primaryShape);
            DiagramElementEditPartOperation.refreshLabelAlignment(self.getContentPane(), style);
        }

        if (diagElement != null) {
            self.setTooltipText(diagElement.getTooltipText());
        }
    }

    /**
     * This method might refresh the background figure, or change it regarding
     * how the style has evolved.
     */
    private static void refreshBackgroundFigure(final AbstractDiagramElementContainerEditPart self,
            final ContainerStyle style) {
        // Update the background figure when the workspace image path changes.
        if (self.getBackgroundFigure() instanceof IWorkspaceImageFigure && style != null) {
            IWorkspaceImageFigure figure = (IWorkspaceImageFigure) self.getBackgroundFigure();
            // Check if the figure is the right one (SVGWorkspaceImageFigure for
            // SVG format, WorkspaceImageFigure for others kinds).
            boolean needFigureChange = false;
            if (style instanceof WorkspaceImage) {
                needFigureChange = DiagramContainerEditPartOperation.needFigureChange((WorkspaceImage) style,
                        figure);
            }
            if (needFigureChange) {
                // Replace the wrong IWorkspaceImageFigure kind by the new one.
                self.reInitFigure();
            } else {
                // Refresh the right IWorkspaceImageFigure kind
                ((IWorkspaceImageFigure) self.getBackgroundFigure()).refreshFigure(style);
            }
        }

        // Update the background figure when the background gradient style
        ViewNodeContainerFigureDesc primaryShape = self.getPrimaryShape();
        if (primaryShape instanceof GradientRoundedRectangle && style instanceof FlatContainerStyle) {
            if (((GradientRoundedRectangle) primaryShape).getBackgroundStyle() != ((FlatContainerStyle) style)
                    .getBackgroundStyle()) {
                self.reInitFigure();
            }
        }

        // Update background figure when the primary shape should change.
        if (isPrimaryShapeChanging(self, style)) {
            self.reInitFigure();
        }
    }

    private static void refreshGradient(final ContainerStyle style, GradientRoundedRectangle gradientRoundedShape) {
        // The gradient style
        if (style instanceof FlatContainerStyle) {
            final RGBValues rgb = ((FlatContainerStyle) style).getForegroundColor();
            if (rgb != null) {
                gradientRoundedShape.setGradientColor(VisualBindingManager.getDefault().getColorFromRGBValues(rgb));
            }
        }
    }

    private static void refreshCorners(final AbstractDiagramElementContainerEditPart self,
            DDiagramElement diagElement, ViewNodeContainerFigureDesc primaryShape) {
        Dimension cornerDimension = getCornerDimension(self);
        Dimension specificDimension = cornerDimension;
        BitSet specificCornerPosition = new BitSet(PositionConstants.NSEW);
        if (self.isRegion()) {
            // If the current stack is a Region, check and avoid overlap of the
            // region container border.
            DNodeContainer regionContainer = (DNodeContainer) diagElement.eContainer();
            Dimension regionContainerCornerDimension = getCornerDimension(regionContainer);
            if (!regionContainerCornerDimension.getShrinked(cornerDimension).isEmpty()) {
                int parentStackDirection = self.getParentStackDirection();
                boolean firstRegionPart = isFirstRegionPart(self);
                boolean lastRegionPart = isLastRegionPart(self);
                if (parentStackDirection == PositionConstants.NORTH_SOUTH && lastRegionPart) {
                    cornerDimension = Dimension.max(cornerDimension, regionContainerCornerDimension);
                    if (specificDimension != cornerDimension) {
                        specificCornerPosition.set(PositionConstants.NORTH_WEST);
                        specificCornerPosition.set(PositionConstants.NORTH_EAST);
                    }
                    updatePrecedingSiblingCorner(self, PositionConstants.SOUTH_WEST, PositionConstants.SOUTH_EAST);
                } else if (parentStackDirection == PositionConstants.EAST_WEST
                        && (firstRegionPart || lastRegionPart)) {
                    cornerDimension = Dimension.max(cornerDimension, regionContainerCornerDimension);

                    specificCornerPosition.set(PositionConstants.NORTH_WEST);
                    specificCornerPosition.set(PositionConstants.NORTH_EAST);
                    if (firstRegionPart && !lastRegionPart) {
                        specificCornerPosition.set(PositionConstants.SOUTH_EAST);
                    } else if (!firstRegionPart && lastRegionPart) {
                        specificCornerPosition.set(PositionConstants.SOUTH_WEST);
                    }

                    if (lastRegionPart && !firstRegionPart) {
                        updatePrecedingSiblingCorner(self, PositionConstants.SOUTH_EAST);
                    }
                }
            }
        }

        // Update the corner dimension.
        if (primaryShape instanceof RoundedRectangle) {
            ((RoundedRectangle) primaryShape).setCornerDimensions(cornerDimension);
            if (primaryShape instanceof RegionRoundedGradientRectangle) {
                ((RegionRoundedGradientRectangle) primaryShape).setAdditionalCornerDimensions(specificDimension,
                        specificCornerPosition);
            }
        }
    }

    private static void updatePrecedingSiblingCorner(final AbstractDiagramElementContainerEditPart self,
            int... cornerToCorrect) {
        // Update previous siblings: needed for the diagram
        // opening and the region container creation cases in
        // which each child will be the last element once.
        Collection<AbstractDiagramElementContainerEditPart> siblings = Lists.newArrayList(
                Iterables.filter(self.getParent().getChildren(), AbstractDiagramElementContainerEditPart.class));
        siblings.remove(self);
        AbstractDiagramElementContainerEditPart previous = siblings.isEmpty() ? null : Iterables.getLast(siblings);
        if (previous != null && previous.getPrimaryShape() instanceof RegionRoundedGradientRectangle) {
            RegionRoundedGradientRectangle gradientRoundedRectangle = (RegionRoundedGradientRectangle) previous
                    .getPrimaryShape();
            if (!gradientRoundedRectangle.getAdditionalCornerDimensions()
                    .equals(gradientRoundedRectangle.getCornerDimensions())) {
                for (int i : cornerToCorrect) {
                    gradientRoundedRectangle.getAdditionalDimensionCorners().set(i);
                }
            }

            if (gradientRoundedRectangle.getAdditionalDimensionCorners().cardinality() == 4) {
                // we do not need specific corner anymore
                gradientRoundedRectangle.getAdditionalDimensionCorners().clear();
                gradientRoundedRectangle
                        .setCornerDimensions(gradientRoundedRectangle.getAdditionalCornerDimensions());
            }
        }
    }

    private static ViewNodeContainerFigureDesc refreshBorder(final AbstractDiagramElementContainerEditPart self,
            final ViewNodeContainerFigureDesc primaryShape, final ContainerStyle style) {
        final int parentStackDirection = self.getParentStackDirection();

        LineStyle borderLineStyle = LineStyle.SOLID_LITERAL;
        int borderSize = 0;
        if (style != null) {
            borderLineStyle = style.getBorderLineStyle();
            if (style.getBorderSize() != null) {
                borderSize = style.getBorderSize().intValue();
            }
        }

        // Refresh border size and style of the primary shape.
        if (primaryShape instanceof Shape) {
            Shape shape = (Shape) primaryShape;
            shape.setLineWidth(borderSize);
            // Deactivate the outline of the shape if there is no border or if
            // this is a region.
            shape.setOutline(borderSize > 0 && parentStackDirection == PositionConstants.NONE);
            DiagramElementEditPartOperation.setLineStyle(shape, borderLineStyle, false);
        } else if (primaryShape instanceof NodeFigure) {
            NodeFigure nodeFigure = (NodeFigure) primaryShape;
            nodeFigure.setLineWidth(borderSize);
            DiagramElementEditPartOperation.setLineStyle(nodeFigure, borderLineStyle);
        }

        if (primaryShape != null) {
            // We might need to reinit the kind of border : LineBorder will
            // always display a 1 pix line even if we configure it with a 0 line
            // width.
            configureBorder(self, primaryShape, borderSize != 0);

            // Do not add the container label offset margin if there is no
            // visible label.
            int labelOffset = IContainerLabelOffsets.LABEL_OFFSET;
            if (primaryShape.getLabelFigure() == null || !primaryShape.getLabelFigure().isVisible()) {
                labelOffset = 0;
            }

            // Handle border line style, corner dimension and/or margin
            if (primaryShape.getBorder() instanceof LineBorder) {
                LineBorder lineBorder = (LineBorder) primaryShape.getBorder();
                lineBorder.setWidth(borderSize);
                DiagramElementEditPartOperation.setLineStyle(lineBorder, borderLineStyle);
                if (lineBorder instanceof OneLineMarginBorder) {
                    OneLineMarginBorder oneLineBorder = (OneLineMarginBorder) lineBorder;
                    oneLineBorder.setMargin(labelOffset, 0, 0, 0);

                    if (parentStackDirection == PositionConstants.NORTH_SOUTH) {
                        oneLineBorder.setPosition(PositionConstants.TOP);
                    } else if (parentStackDirection == PositionConstants.EAST_WEST) {
                        oneLineBorder.setPosition(PositionConstants.LEFT);
                    }

                    if (self.isRegion() && lineBorder instanceof RoundedCornerMarginBorder) {
                        ((RoundedCornerMarginBorder) lineBorder).setCornerDimensions(getCornerDimension(self));
                    }
                }
            } else if (primaryShape.getBorder() instanceof MarginBorder) {
                MarginBorder margin = null;
                int borderMagin = borderSize;
                switch (parentStackDirection) {
                case PositionConstants.NORTH_SOUTH:
                    borderMagin = isFirstRegionPart(self) ? 0 : Math.max(0, borderSize - 1);
                    margin = new MarginBorder(borderMagin + labelOffset, 0, 0, 0);
                    break;
                case PositionConstants.EAST_WEST:
                    borderMagin = isFirstRegionPart(self) ? 0 : borderSize;
                    margin = new MarginBorder(labelOffset, borderMagin, 0, 0);
                    break;
                case PositionConstants.NONE:
                default:
                    // Keep the old behavior : min margin size= 4
                    // The current container is not a region, the figure has
                    // been added to the content pane.
                    margin = new MarginBorder(borderMagin + labelOffset - 1, borderMagin, borderMagin, borderMagin);
                }
                primaryShape.setBorder(margin);
            }
        }
        return primaryShape;
    }

    private static boolean isFirstRegionPart(AbstractDiagramElementContainerEditPart self) {
        EditPart parent = self.getParent();
        if (parent instanceof AbstractDNodeContainerCompartmentEditPart) {
            Iterable<AbstractDiagramElementContainerEditPart> regionParts = Iterables.filter(parent.getChildren(),
                    AbstractDiagramElementContainerEditPart.class);
            return !Iterables.isEmpty(regionParts) && regionParts.iterator().next() == self;
        }
        return false;
    }

    private static boolean isLastRegionPart(AbstractDiagramElementContainerEditPart self) {
        EditPart parent = self.getParent();
        if (parent instanceof AbstractDNodeContainerCompartmentEditPart) {
            Iterable<AbstractDiagramElementContainerEditPart> regionParts = Iterables.filter(parent.getChildren(),
                    AbstractDiagramElementContainerEditPart.class);
            return !Iterables.isEmpty(regionParts) && Iterables.getLast(regionParts) == self;
        }
        return false;
    }

    /**
     * 
     * @param self
     * @param style
     * @return if the shape has changed with the style
     */
    private static boolean isPrimaryShapeChanging(final AbstractDiagramElementContainerEditPart self,
            final Style style) {
        boolean result = false;

        // Test changed from ShapeContainerStyle
        result = self.getPrimaryShape() instanceof ViewNodeContainerParallelogram
                && (style instanceof FlatContainerStyle || style instanceof WorkspaceImage);
        if (!result) {
            // Test changed from FlatContainerStyle
            result = self.getPrimaryShape() instanceof GradientRoundedRectangle
                    && (style instanceof ShapeContainerStyle || style instanceof WorkspaceImage);
        }
        if (!result) {
            // Test changed from WorkspaceImage
            result = self.getPrimaryShape() instanceof ViewNodeContainerRectangleFigureDesc
                    && (style instanceof FlatContainerStyle || style instanceof ShapeContainerStyle);
        }
        if (!result) {
            // Test changed from WorkspaceImage.workspacePath
            result = style instanceof WorkspaceImage && (self.getBackgroundFigure() == null
                    ^ StringUtil.isEmpty(((WorkspaceImage) style).getWorkspacePath()));
        }
        return result;
    }

    /**
     * Creates the background image.
     * 
     * @param self
     *            the container edit part.
     * @return the created image.
     */
    public static IFigure createBackgroundFigure(final IGraphicalEditPart self) {
        final EObject eObj = self.resolveSemanticElement();
        if (eObj instanceof DDiagramElementContainer) {
            final DDiagramElementContainer container = (DDiagramElementContainer) eObj;
            if (container.getOwnedStyle() instanceof WorkspaceImage) {
                final WorkspaceImage img = (WorkspaceImage) container.getOwnedStyle();
                return createWkpImageFigure(img);
            }
        }
        return null;
    }

    private static IFigure createWkpImageFigure(final WorkspaceImage img) {
        IFigure imageFigure = null;
        if (img != null && !StringUtil.isEmpty(img.getWorkspacePath())) {
            String workspacePath = img.getWorkspacePath();
            if (WorkspaceImageFigure.isSvgImage(workspacePath)) {
                imageFigure = SVGWorkspaceImageFigure.createImageFigure(img);
            } else {
                imageFigure = WorkspaceImageFigure.createImageFigure(workspacePath);
            }
        }
        return imageFigure;
    }

    /**
     * Gets the corner dimensions.
     * 
     * @param self
     *            the container edit part.
     * @return the corner dimensions.
     */
    public static Dimension getCornerDimension(final IGraphicalEditPart self) {
        final EObject eObj = self.resolveSemanticElement();
        return getCornerDimension(eObj);
    }

    private static Dimension getCornerDimension(EObject eObj) {
        final Dimension corner = new Dimension(0, 0);
        if (eObj instanceof DStylizable) {
            final Style style = ((DStylizable) eObj).getStyle();
            if (style != null && style.getDescription() instanceof ContainerStyleDescription) {
                final ContainerStyleDescription description = (ContainerStyleDescription) style.getDescription();
                if (description.isRoundedCorner()) {
                    corner.height = description.getArcHeight();
                    corner.width = description.getArcWidth();
                }
            }
        }
        return corner;
    }

    /**
     * Gets the background style.
     * 
     * @param self
     *            the container edit part.
     * @return the background style.
     */
    public static BackgroundStyle getBackgroundStyle(final IGraphicalEditPart self) {
        BackgroundStyle bgStyle = BackgroundStyle.GRADIENT_LEFT_TO_RIGHT_LITERAL;
        final EObject eObj = self.resolveSemanticElement();
        if (eObj instanceof DStylizable) {
            final Style style = ((DStylizable) eObj).getStyle();
            if (style instanceof FlatContainerStyle) {
                bgStyle = ((FlatContainerStyle) style).getBackgroundStyle();
            }
        }
        return bgStyle;
    }

    /**
     * Configure the border : set or replace the border when it needs to be
     * changed. This can occurs for Regions when the region position changes or
     * when the border size changes from 0 or to 0.
     * 
     * The refreshBorder method will then update all the border features during
     * refreshVisual().
     * 
     * @param self
     *            the current part
     * @param shapeFigure
     *            the shape to configure
     */
    public static void configureBorder(AbstractDiagramElementContainerEditPart self, IFigure shapeFigure) {
        boolean border = true;
        final DDiagramElement diagElement = self.resolveDiagramElement();
        if (diagElement instanceof DDiagramElementContainer) {
            final DDiagramElementContainer ddec = (DDiagramElementContainer) diagElement;
            final ContainerStyle style = ddec.getOwnedStyle();
            if (style != null && style.getBorderSize() != null) {
                border = style.getBorderSize().intValue() != 0;
            }
        }
        configureBorder(self, shapeFigure, border);
    }

    private static void configureBorder(AbstractDiagramElementContainerEditPart self, IFigure shapeFigure,
            boolean border) {
        if (self.isRegion() && shapeFigure != null) {
            Border newBorder = null;
            if (isFirstRegionPart(self) || !border) {
                if (!(shapeFigure.getBorder() instanceof MarginBorder)) {
                    newBorder = new MarginBorder(IContainerLabelOffsets.LABEL_OFFSET, 0, 0, 0);
                }
            } else if (!(shapeFigure.getBorder() instanceof RoundedCornerMarginBorder)) {
                int position = PositionConstants.TOP;
                if (self.getParentStackDirection() == PositionConstants.EAST_WEST) {
                    position = PositionConstants.LEFT;
                }

                RoundedCornerMarginBorder oneLineBorder = new RoundedCornerMarginBorder(position);
                oneLineBorder.setCornerDimensions(getCornerDimension(self));
                oneLineBorder.setMargin(IContainerLabelOffsets.LABEL_OFFSET, 0, 0, 0);

                newBorder = oneLineBorder;
            }

            if (newBorder != null) {
                shapeFigure.setBorder(newBorder);
            }
        }
    }

    /**
     * Check if the current <code>figure</code> is the right one
     * (SVGWorkspaceImageFigure for SVG format, WorkspaceImageFigure for others
     * kinds) according to the {@link WorkspaceImage} style.
     * 
     * @param bundledImage
     *            the {@link WorkspaceImage} style
     * @param figure
     *            The figure to check.
     * @return true if a new figure must be create according to style
     *         <code>bundledImage</code>, false if the current figure can be
     *         used.
     */
    public static boolean needFigureChange(final WorkspaceImage bundledImage, IWorkspaceImageFigure figure) {
        boolean result = false;
        String workspacePath = bundledImage.getWorkspacePath();
        if (!StringUtil.isEmpty(workspacePath) && WorkspaceImageFigure.isSvgImage(workspacePath)) {
            result = !(figure instanceof SVGWorkspaceImageFigure);
        } else {
            result = !(figure instanceof WorkspaceImageFigure);
        }
        return result;
    }
}