Package org.eclipse.jst.pagedesigner.commands.nav

Source Code of org.eclipse.jst.pagedesigner.commands.nav.VerticalMoveCommand

/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. 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:
*     Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.pagedesigner.commands.nav;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
import org.eclipse.jst.pagedesigner.validation.caret.IMovementMediator;
import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingNavigationMediator;
import org.eclipse.jst.pagedesigner.validation.caret.Target;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.widgets.Caret;

/**
* @author mengbo
*/
public class VerticalMoveCommand extends Command {
  private static Logger _log = PDPlugin
      .getLogger(HorizontalMoveCommand.class);

  IHTMLGraphicalViewer _viewer;

  boolean _up;

  boolean _onlyMoveEnd;

  /**
   * @param viewer
   * @param up
   * @param c
   */
  public VerticalMoveCommand(IHTMLGraphicalViewer viewer, boolean up,
      boolean c) {
    _viewer = viewer;
    _up = up;
    _onlyMoveEnd = c;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.commands.Command#execute()
   */
  public void execute() {
    int OFFSET = 2;
    DesignRange range = _viewer.getRangeSelection();
    if (range == null || !range.isValid()) {
      _log.error("invalid range"); //$NON-NLS-1$
      return;
    }
    IMovementMediator moveMediator = new InlineEditingNavigationMediator(
        new ActionData(ActionData.KEYBOARD_NAVAGATION, null));
    DesignPosition position = range.getEndPosition();
    Caret caret = _viewer.getCaret();
    Point point = null;
    DesignPosition newPos = position;
    EditPart containerpart = null, rootpart1;
    if (_up) {
      point = new Point(((CaretPositionTracker) _viewer).getXoffset(),
          caret.getBounds().y);
    } else {
      point = new Point(((CaretPositionTracker) _viewer).getXoffset(),
          caret.getBounds().y + caret.getBounds().height);

    }
    rootpart1 = getRootEditablePart(position.getContainerPart(),
        moveMediator);// position.getContainerPart();
    if (rootpart1 == null) {
      return;
    }
       
        point = adjustLocation(rootpart1, point);
    Rectangle bound = EditPartPositionHelper.getAbsoluteBounds(rootpart1);
    // get current according to the point.
    // FlowBoxLine line =
    // getCurrentLine(moveMediator.getEditableContainer(new
    // Target(rootpart)), point, moveMediator);
    while (true) {
      // try to change offset and then to search for new point.
      if (_up) {
        point.y -= OFFSET;
        if (point.y <= bound.y) {
          newPos = position;
          break;
        }
      } else {
        point.y += OFFSET;
        if (point.y >= bound.y + bound.height) {
          newPos = position;
          break;
        }
      }
      containerpart = ((InlineEditingNavigationMediator) moveMediator)
          .getConstainedEditableContainer(position, point, _viewer);
      if (containerpart != null) {
        if (!EditModelQuery.isChild(Target.resolveNode(rootpart1),
            Target.resolveNode(containerpart))) {
          containerpart = rootpart1;
        }
        bound = EditPartPositionHelper.getAbsoluteBounds(rootpart1);
        newPos = EditPartPositionHelper
            .findEditPartPositionConstrained(containerpart, point,
                moveMediator);
      } else {
        newPos = position;
        break;
      }
      if (newPos != null) {
        if (found(newPos, position)) {
          break;
        }
      }
    }
    setRange(position, newPos);
  }

  private void setRange(DesignPosition position, DesignPosition newPos) {
    if (!EditModelQuery.isSame(position, newPos)) {
      {
        if (_onlyMoveEnd) {
          _viewer.setRangeEndPosition(newPos);
        } else {
          _viewer.setRange(newPos, newPos);
        }
      }
    }
  }

  /*
   * We should change this, it is too tricky to do in this way.
   */
  private Point adjustLocation(EditPart rootPart, Point point) {
    Point result = point.getCopy();
    Rectangle bounds = EditPartPositionHelper.getAbsoluteBounds(rootPart);
    if (!bounds.contains(point)) {
      if (bounds.getLeft().x > point.x) {
        result.x = bounds.getLeft().x;
      } else if (bounds.getRight().x < point.x) {
        result.x = bounds.getRight().x;
      }
    }
    return result;
  }

  private EditPart getRootEditablePart(EditPart part,
      IMovementMediator moveMediator) {
    EditPart rootpart = null;
    if ((rootpart = ((InlineEditingNavigationMediator) moveMediator)
        .getRootConstainedEditableContainer(new Target(part))) == null) {
      rootpart = moveMediator.getEditableContainer(new Target(part));
    }
    return rootpart;
  }

  private boolean found(DesignPosition newPos, DesignPosition prevPos) {
    Rectangle newRec = EditPartPositionHelper
        .convertToAbsoluteCaretRect(newPos);
    Rectangle prevRec = EditPartPositionHelper
        .convertToAbsoluteCaretRect(prevPos);
    if (_up) {
      return getYDistance(newRec, prevRec, _up) < 0;
    }
        return getYDistance(newRec, prevRec, _up) > 0;
  }

  /**
   * Distance from rec1 to rec2 at y coordination, if top, compare top,
   * otherwise compare bottom.
   *
   * @param rec1
   * @param rec2
   * @param up
   * @return
   */
  private int getYDistance(Rectangle rec1, Rectangle rec2, boolean top) {
    if (rec1.getCopy().intersect(rec2).height > 0) {
      return 0;
    }
        if (top) {
          return rec1.getTop().y - rec2.getTop().y;
        }
        return rec1.getBottom().y - rec2.getBottom().y;
  }
}
TOP

Related Classes of org.eclipse.jst.pagedesigner.commands.nav.VerticalMoveCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.