/** Erases the guide and the feedback shown by the container of the elements. */
  protected void eraseSourceFeedback() {
    if (guideline.getParent() != null) {
      guideline.getParent().remove(guideline);
    }

    if (_container != null) {
      _container.eraseSourceFeedback(getSourceRequest());
    }

    ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_MOVE);
    request.setEditParts(Collections.emptyList());
    request.setSizeDelta(new Dimension(0, 0));
    request.setMoveDelta(new Point(0, 0));
    for (IGraphicalEditPart part : _movingShapes) {
      part.eraseSourceFeedback(request);
    }

    ChangeBoundsRequest spRequest = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
    spRequest.setEditParts(Collections.emptyList());
    spRequest.setSizeDelta(new Dimension(0, 0));
    spRequest.setMoveDelta(new Point(0, 0));
    for (IGraphicalEditPart sp : _subProcesses) {
      sp.eraseSourceFeedback(spRequest);
    }
  }
  /** Shows a nice guideline to show the move */
  protected void showSourceFeedback() {
    if (_container == null) {
      return;
    }
    if (guideline.getParent() == null) {
      addFeedback(guideline);
    }
    Rectangle bounds = Rectangle.SINGLETON.getCopy();
    bounds.y = getCurrentPositionZoomed();

    Rectangle containerBounds = _container.getFigure().getBounds().getCopy();

    _container.getFigure().translateToAbsolute(containerBounds);

    ((DiagramEditPart) getCurrentViewer().getContents())
        .getFigure()
        .translateToRelative(containerBounds);

    bounds.x = containerBounds.x;
    bounds.height = 1;
    bounds.width = containerBounds.width;

    ZoomManager zoomManager =
        ((DiagramRootEditPart) getCurrentViewer().getRootEditPart()).getZoomManager();
    bounds.performScale(zoomManager.getZoom());

    guideline.setBounds(bounds);
    guideline.setVisible(getState() == STATE_DRAG_IN_PROGRESS);

    ChangeBoundsRequest request = new ChangeBoundsRequest(RequestConstants.REQ_MOVE);
    request.setMoveDelta(((ChangeBoundsRequest) getSourceRequest()).getMoveDelta());
    request.setSizeDelta(new Dimension(0, 0));
    request.setEditParts(_movingShapes);

    for (IGraphicalEditPart part : _movingShapes) {
      part.showSourceFeedback(request);
    }

    ChangeBoundsRequest spRequest = new ChangeBoundsRequest(RequestConstants.REQ_RESIZE);
    Point moveDelta = ((ChangeBoundsRequest) getSourceRequest()).getMoveDelta().getCopy();
    Dimension spSizeDelta = new Dimension(moveDelta.x, moveDelta.y);
    spRequest.setSizeDelta(spSizeDelta);
    spRequest.setMoveDelta(new Point(0, 0));
    spRequest.setEditParts(_subProcesses);

    for (IGraphicalEditPart sp : _subProcesses) {
      sp.showSourceFeedback(spRequest);
    }
    ((DiagramEditPart) getCurrentViewer().getContents()).getRoot().refresh();
  }
 /** Test that GMF Text drop is not possible in a lifeline. */
 public void testGMFTextDropInALifelineNotPossible() {
   ChangeBoundsRequest changeBoundsRequest = new ChangeBoundsRequest(RequestConstants.REQ_ADD);
   changeBoundsRequest.setEditParts(textEditPart);
   Command dropGMFNoteInLifelineCmd = lifelineEditPart.getCommand(changeBoundsRequest);
   assertFalse(
       "The GMF Text should not be droppable in lifeline", dropGMFNoteInLifelineCmd.canExecute());
 }
  protected Command createNodeChangeBoundCommands(final List<ShapeEditPart> sortedNodes) {

    final CompoundCommand result = new CompoundCommand();
    final Iterator<ShapeEditPart> iterEditParts = sortedNodes.iterator();
    while (iterEditParts.hasNext()) {
      final ShapeEditPart shapeEditPart = iterEditParts.next();

      final ChangeBoundsRequest request =
          new ChangeBoundsRequest(org.eclipse.gef.RequestConstants.REQ_MOVE);
      request.setEditParts(shapeEditPart);
      final Point ptLocation = new Point(0, 0);
      // the zoom.
      double scale = 1.0;
      if (shapeEditPart.getRoot() instanceof DiagramRootEditPart) {
        final ZoomManager zoomManager =
            ((DiagramRootEditPart) shapeEditPart.getRoot()).getZoomManager();
        scale = zoomManager.getZoom();
      }
      // Compute request data.
      final Point ptOldLocation = shapeEditPart.getFigure().getBounds().getLocation();

      final Dimension delta = ptLocation.getDifference(ptOldLocation);

      request.setMoveDelta(new PrecisionPoint(delta.width * scale, delta.height * scale));
      request.setLocation(new PrecisionPoint(ptLocation.x * scale, ptLocation.y * scale));

      final Command cmd = this.buildCommandWrapper(request, shapeEditPart);
      result.add(cmd);
    }

    return result;
  }
  @Override
  protected void updateSourceRequest() {
    ChangeBoundsRequest request = (ChangeBoundsRequest) getSourceRequest();
    Dimension d = getDragMoveDelta();

    Point location = new Point(getLocation());
    Point moveDelta = new Point(0, 0);
    Dimension resizeDelta = new Dimension(0, 0);

    request.setConstrainedResize(false);

    request.setCenteredResize(getCurrentInput().isModKeyDown(SWT.MOD1));

    if ((getResizeDirection() & PositionConstants.NORTH) != 0) {
      moveDelta.y += d.height;
      resizeDelta.height -= d.height;
    }
    if ((getResizeDirection() & PositionConstants.SOUTH) != 0) {
      resizeDelta.height += d.height;
    }
    if ((getResizeDirection() & PositionConstants.WEST) != 0) {
      moveDelta.x += d.width;
      resizeDelta.width -= d.width;
    }
    if ((getResizeDirection() & PositionConstants.EAST) != 0) {
      resizeDelta.width += d.width;
    }

    request.setMoveDelta(moveDelta);
    request.setSizeDelta(resizeDelta);
    request.setLocation(location);
    request.setEditParts(getOperationSet());

    request.getExtendedData().clear();

    // TODO: snapping
  }
  private Collection<ChangeBoundsRequest> getConstrainedRegionRequests(
      ChangeBoundsRequest request) {
    Collection<ChangeBoundsRequest> constrainedRequests = Lists.newArrayList();

    RequestQuery query = new RequestQuery(request);
    Dimension sizeDelta = request.getSizeDelta().getCopy();
    Point moveDelta = request.getMoveDelta().getCopy();

    List<AbstractDiagramElementContainerEditPart> regionToResize = getRegionParts();
    int stackDirection = getStackDirection();
    // Handle first and last regions.
    Object resizePropagator = request.getExtendedData().get(REGION_RESIZE_PROPAGATOR);
    if (query.isResizeFromTop() && stackDirection == PositionConstants.NORTH_SOUTH
        || query.isResizeFromLeft() && stackDirection == PositionConstants.EAST_WEST) {
      Option<AbstractDiagramElementContainerEditPart> firstRegionPart = getFirstRegionPart();
      if (firstRegionPart.some()
          && (!request.isConstrainedResize() || resizePropagator != firstRegionPart.get())) {
        ChangeBoundsRequest req = initConstrainedRequest(request);
        req.setEditParts(firstRegionPart.get());
        req.setSizeDelta(sizeDelta.getCopy());
        constrainedRequests.add(req);
      }
      // shift all other regions.
      regionToResize.remove(firstRegionPart.get());
      if (!regionToResize.isEmpty()
          && (!request.isConstrainedResize() || !regionToResize.contains(resizePropagator))) {
        ChangeBoundsRequest req = initConstrainedRequest(request);
        req.setEditParts(Lists.newArrayList(regionToResize));

        if (stackDirection == PositionConstants.NORTH_SOUTH) {
          req.setSizeDelta(new Dimension(sizeDelta.width, 0));
          req.setMoveDelta(new Point(0, -moveDelta.y));
        } else if (stackDirection == PositionConstants.EAST_WEST) {
          req.setSizeDelta(new Dimension(0, sizeDelta.height));
          req.setMoveDelta(new Point(-moveDelta.x, 0));
        }
        constrainedRequests.add(req);
        regionToResize.clear();
      }
    } else if (query.isResizeFromBottom() && stackDirection == PositionConstants.NORTH_SOUTH
        || query.isResizeFromRight() && stackDirection == PositionConstants.EAST_WEST) {
      // Resize the last region.
      Option<AbstractDiagramElementContainerEditPart> lastRegionPart = getLastRegionPart();
      if (lastRegionPart.some()
          && (!request.isConstrainedResize() || resizePropagator != lastRegionPart.get())) {
        ChangeBoundsRequest req = initConstrainedRequest(request);
        req.setEditParts(lastRegionPart.get());
        req.setSizeDelta(sizeDelta.getCopy());
        constrainedRequests.add(req);
        regionToResize.remove(lastRegionPart.get());
      }
    }

    // Handle horizontal resize for vstacks and vertical resize for hstacks.
    if (request.isConstrainedResize() && resizePropagator != null) {
      regionToResize.remove(resizePropagator);
    }
    if (!regionToResize.isEmpty()) {
      if (stackDirection == PositionConstants.NORTH_SOUTH
          && (query.isResizeFromLeft() || query.isResizeFromRight())
          && sizeDelta.width != 0) {
        ChangeBoundsRequest req = initConstrainedRequest(request);
        req.setEditParts(Lists.newArrayList(regionToResize));
        req.setSizeDelta(new Dimension(sizeDelta.width, 0));
        constrainedRequests.add(req);
      } else if (stackDirection == PositionConstants.EAST_WEST
          && (query.isResizeFromTop() || query.isResizeFromBottom())
          && sizeDelta.height != 0) {
        ChangeBoundsRequest req = initConstrainedRequest(request);
        req.setEditParts(Lists.newArrayList(regionToResize));
        req.setSizeDelta(new Dimension(0, sizeDelta.height));
        constrainedRequests.add(req);
      }
    }

    return constrainedRequests;
  }