fr.lip6.move.coloane.core.ui.commands.LocatedElementSetConstraintCmd.java Source code

Java tutorial

Introduction

Here is the source code for fr.lip6.move.coloane.core.ui.commands.LocatedElementSetConstraintCmd.java

Source

/**
 * Copyright (c) 2006-2010 MoVe - Laboratoire d'Informatique de Paris 6 (LIP6).
 * 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:
 *   Jean-Baptiste VORON (LIP6) - Project Head / Initial contributor
 *   Clment DMOULINS (LIP6) - Project Manager
 *
 * Official contacts:
 *   coloane@lip6.fr
 *   http://coloane.lip6.fr
 */
package fr.lip6.move.coloane.core.ui.commands;

import fr.lip6.move.coloane.core.model.interfaces.ILocatedElement;
import fr.lip6.move.coloane.core.ui.ColoaneEditor;
import fr.lip6.move.coloane.interfaces.model.IArc;
import fr.lip6.move.coloane.interfaces.model.IAttribute;
import fr.lip6.move.coloane.interfaces.model.IElement;
import fr.lip6.move.coloane.interfaces.model.INode;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.commands.Command;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.PlatformUI;

/**
 * Move an object (that is supposed to move : {@link ILocatedElement})
 *
 * @author Clment Dmoulins
 * @author Jean-Baptiste Voron
 */
public class LocatedElementSetConstraintCmd extends Command {

    /** New location */
    private final Point newLocation;
    /** Old location */
    private Point oldLocation;

    /** Difference between the new and the old locations */
    private Dimension delta;

    /** Model object to move */
    private final ILocatedElement element;

    /** List of arcs for which inflex points have to be moved too */
    private final List<IArc> arcsForPI = new ArrayList<IArc>();

    /** List of arcs for which attributes have to be moved too */
    private final List<IAttribute> arcsForAttr = new ArrayList<IAttribute>();
    private final Map<IArc, Dimension> arcsMiddleDelta = new HashMap<IArc, Dimension>();

    /** Attributes that have to be moved too */
    private final List<IAttribute> attributes = new ArrayList<IAttribute>();

    /**
     * Constructor
     * @param element Model object to move
     * @param newLocation New location for the model object
     */
    public LocatedElementSetConstraintCmd(ILocatedElement element, Point newLocation) {
        super(Messages.NodeSetConstraintCmd_0);
        if (element == null || newLocation == null) {
            throw new NullPointerException();
        }
        this.element = element;
        this.newLocation = newLocation.getCopy();
        this.newLocation.x = Math.max(this.newLocation.x, 0);
        this.newLocation.y = Math.max(this.newLocation.y, 0);

        // Need to get the current selection to control if arcs are involved in the move
        ColoaneEditor ce = (ColoaneEditor) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
                .getActiveEditor();
        GraphicalViewer viewer = (GraphicalViewer) ce.getAdapter(GraphicalViewer.class);

        // List of selected objects (try to know if arcs are involved in this move)
        StructuredSelection s = (StructuredSelection) PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                .getActivePage().getActiveEditor().getSite().getSelectionProvider().getSelection();
        List<?> selection = s.toList();

        // If the element is a node, some arcs may be involved in the move
        // If source node and target node are selected, arc has to be moved too (and also inflex point)
        if (element instanceof INode) {
            INode node = (INode) element;

            // Deal with incoming arcs.
            // Attributes have to be moved too.
            // Inflex point may be moved too.
            for (IArc in : node.getIncomingArcs()) {
                INode src = in.getSource();
                // If the source node is also moved, the arc will be moved automatically (but not its inflex point)
                if (selection.contains(viewer.getEditPartRegistry().get(src))) {
                    arcsForPI.add(in);
                }

                // If the target node is moved... The arc will be moved too (but not its attributes)
                for (IAttribute arcAttr : in.getAttributes()) {
                    if (!selection.contains(viewer.getEditPartRegistry().get(arcAttr))) {
                        arcsForAttr.add(arcAttr);
                    }
                }
            }

            // If the source node is moved... The outgoing arcs will be moved too (but not their attributes)
            for (IArc out : node.getOutgoingArcs()) {
                for (IAttribute arcAttr : out.getAttributes()) {
                    if (!selection.contains(viewer.getEditPartRegistry().get(arcAttr))) {
                        arcsForAttr.add(arcAttr);
                    }
                }
            }
        }

        // Generally, attributes of the moved element must be moved too
        if (element instanceof IElement) {
            IElement modelElement = (IElement) element;

            for (IAttribute attr : modelElement.getDrawableAttributes()) {
                if (!selection.contains(viewer.getEditPartRegistry().get(attr))) {
                    attributes.add(attr);
                }
            }
        }
    }

    /**
     * A node can always be moved
     * @return true
     */
    @Override
    public final boolean canExecute() {
        return true;
    }

    /** {@inheritDoc} */
    @Override
    public final void execute() {
        oldLocation = new Point(element.getLocationInfo().getLocation());
        delta = newLocation.getDifference(oldLocation);

        // Update middle point of arcs where attributes will  be moved
        for (IAttribute arcAttr : arcsForAttr) {
            if (arcAttr.getReference() instanceof IArc) {
                IArc arc = (IArc) arcAttr.getReference();
                arc.getGraphicInfo().updateMiddlePoint();
            }
        }

        // Build a map of delta move for arcs's attributes (needed for the undo operation)
        for (IAttribute arcAttr : arcsForAttr) {
            if (arcAttr.getReference() instanceof IArc) {
                IArc arc = (IArc) arcAttr.getReference();
                Point oldMiddle = arc.getGraphicInfo().getMiddlePoint();
                Point newMiddle = arc.getGraphicInfo().findMiddlePoint();
                Dimension middleDelta = newMiddle.getDifference(oldMiddle);
                arcsMiddleDelta.put(arc, middleDelta);
            }
        }

        this.redo();
    }

    /** {@inheritDoc} */
    @Override
    public final void redo() {
        element.getLocationInfo().setLocation(newLocation);

        // Move inflex points
        for (IArc arc : arcsForPI) {
            arc.modifyInflexPoints(delta.width, delta.height);
        }

        // Move arc's attributes
        for (IAttribute arcAttr : arcsForAttr) {
            if (arcAttr.getReference() instanceof IArc) {
                IArc arc = (IArc) arcAttr.getReference();
                Dimension middleDelta = arcsMiddleDelta.get(arc);
                if (middleDelta != null) {
                    arcAttr.getGraphicInfo()
                            .setLocation(arcAttr.getGraphicInfo().getLocation().getTranslated(middleDelta));
                }
            }
        }

        // Move node attributes
        for (IAttribute attr : attributes) {
            attr.getGraphicInfo().setLocation(attr.getGraphicInfo().getLocation().getTranslated(delta));
        }
    }

    /** {@inheritDoc} */
    @Override
    public final void undo() {
        // Undo the move of the node
        element.getLocationInfo().setLocation(oldLocation);

        // The move of inflex points
        for (IArc arc : arcsForPI) {
            arc.modifyInflexPoints(-delta.width, -delta.height);
        }

        // Arc's attribute
        for (IAttribute arcAttr : arcsForAttr) {
            if (arcAttr.getReference() instanceof IArc) {
                IArc arc = (IArc) arcAttr.getReference();
                Dimension middleDelta = arcsMiddleDelta.get(arc);
                if (middleDelta != null) {
                    arcAttr.getGraphicInfo().setLocation(
                            arcAttr.getGraphicInfo().getLocation().getTranslated(middleDelta.getNegated()));
                }
            }
        }
        // Node's attribute
        for (IAttribute attr : attributes) {
            attr.getGraphicInfo()
                    .setLocation(attr.getGraphicInfo().getLocation().getTranslated(delta.getNegated()));
        }
    }
}