Package org.eclipse.jst.pagedesigner.parts

Source Code of org.eclipse.jst.pagedesigner.parts.ElementEditPart

/*******************************************************************************
* 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.parts;

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

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.requests.LocationRequest;
import org.eclipse.gef.tools.DragEditPartsTracker;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.jsf.core.internal.tld.CMUtil;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
import org.eclipse.jst.pagedesigner.converter.IConverterFactory;
import org.eclipse.jst.pagedesigner.converter.ITagConverter;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
import org.eclipse.jst.pagedesigner.css2.layout.CSSWidgetLayout;
import org.eclipse.jst.pagedesigner.css2.style.AbstractStyle;
import org.eclipse.jst.pagedesigner.css2.widget.HiddenProvider;
import org.eclipse.jst.pagedesigner.dtmanager.DTManager;
import org.eclipse.jst.pagedesigner.editpolicies.ElementMenuBar;
import org.eclipse.jst.pagedesigner.editpolicies.ElementResizableEditPolicy;
import org.eclipse.jst.pagedesigner.editpolicies.IEnhancedSelectionEditPolicy;
import org.eclipse.jst.pagedesigner.elementedit.ElementEditFactoryRegistry;
import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
import org.eclipse.jst.pagedesigner.figurehandler.FigureFactory;
import org.eclipse.jst.pagedesigner.figurehandler.IFigureHandler;
import org.eclipse.jst.pagedesigner.jsp.core.IJSPCoreConstants;
import org.eclipse.jst.pagedesigner.range.RangeUtil;
import org.eclipse.jst.pagedesigner.requests.PageDesignerRequestConstants;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
* @author mengbo
* @version 1.5
*/
public class ElementEditPart extends SubNodeEditPart {
  private static Logger _log = PDPlugin.getLogger(ElementEditPart.class);

  private Element _elementNode;

  private ITagConverter _tagConverter;
   
    private ElementMenuBar  _nonVisualElementBar;

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.EditPart#setModel(java.lang.Object)
   */
  public void setModel(Object model) {
    super.setModel(model);
    _elementNode = (Element) model;
    _tagConverter = getTagConverter(_elementNode);
    _tagConverter.convertRefresh(null);
    adaptEditProxy();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#getDragTracker(org.eclipse.gef.Request)
   */
  public DragTracker getDragTracker(Request request)
    {
        EditPolicy policy = this
            .getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);

        if (PageDesignerRequestConstants.REQ_SELECTION_TRACKER.equals(request.getType())
                || org.eclipse.gef.RequestConstants.REQ_SELECTION.equals(request.getType()))
        {
            if (policy instanceof IEnhancedSelectionEditPolicy
                    && request instanceof LocationRequest)
            {
                return ((IEnhancedSelectionEditPolicy)policy).getSelectionDragTracker((LocationRequest)request);
            }
           
            return null;
        }
       
        // should not happen
        return new DragEditPartsTracker(this);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#createEditPolicies()
   */
  protected void createEditPolicies() {
    super.createEditPolicies();
    IElementEdit support = getElementEdit();
    if (support != null) {
      support.createEditPolicies(this);
    }

    // if ElementEdit didn't install special SELECTION_FEEDBACK_ROLE policy,
    // then default
    if (this.getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE) == null) {
      this.installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE,
          new ElementResizableEditPolicy());
    }
  }

  /**
   * @return the associated element edit
   */
  public IElementEdit getElementEdit() {
    // XXX: should we cache it?
    return ElementEditFactoryRegistry.getInstance().createElementEdit(
        _elementNode);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#addNotify()
   */
  public void addNotify() {
    if (_tagConverter == null) {
      _tagConverter = getTagConverter(_elementNode);
      _tagConverter.convertRefresh(null);
      adaptEditProxy();
    }
    super.addNotify();
  }

  /**
   * @param node
   * @return
   */
  private ITagConverter getTagConverter(Element node) {
    return DTManager.getInstance().getTagConverter(node,
        IConverterFactory.MODE_DESIGNER,
        this.getDestDocumentForDesign());
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeNotify()
   */
  public void removeNotify() {
    super.removeNotify();
    // if (_tagConverter != null)
    // {
    // _tagConverter.dispose();
    // _tagConverter = null;
    // }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractEditPart#getModelChildren()
   */
  protected List getModelChildren() {
    List children_ = new ArrayList(_tagConverter.getChildModeList());
       
        for (Iterator it = _tagConverter.getNonVisualChildren().iterator(); it.hasNext();)
        {
            Element nonVisualChild = (Element) it.next();
            children_.add(DTManager.getInstance().getTagConverter(nonVisualChild,
                IConverterFactory.MODE_DESIGNER,
                this.getDestDocumentForDesign()));
        }
        return children_;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
   */
  protected IFigure createFigure() {
    // if (_tagConverter.isVisualByHTML())
    // {
    // Element result = _tagConverter.getResultElement();
    // return FigureFactory.createFigure(result,
    // true);//_tagConverter.isMultiLevel());
    // }
    // else
    // {
    // CSSWidgetFigure figure = new CSSWidgetFigure(this._elementNode,
    // createHiddenProvider());
    // return figure;
    // }
    return new CSSFigure();
  }

  /**
   * @return
   */
  private HiddenProvider createHiddenProvider() {
    Element result = _tagConverter.getHostElement();
    String localName = result.getLocalName();
    String appendString = localName;
    if (localName.equalsIgnoreCase(IJSPCoreConstants.TAG_DIRECTIVE_TAGLIB)) {
      appendString = ((IDOMElement) result)
          .getAttribute(IJSPCoreConstants.ATTR_URI);
      if (appendString == null) {
        appendString = ((IDOMElement) result)
          .getAttribute(IJSPCoreConstants.ATTR_TAGDIR);
        if (appendString == null)
          appendString = ""; //$NON-NLS-1$
      }
    }
    Image image = _tagConverter.getVisualImage();
    HiddenProvider provider = new HiddenProvider(image, this);
    ((CSSFigure) getFigure()).setCSSStyle(provider.getCSSStyle());
    provider.setLabel(appendString);
    return provider;
  }

  /**
   * called by the
   * @param recursive
   *
   */
  public void refreshModelChange(boolean recursive) {
    IElementEdit support = getElementEdit();
    if (support == null
        || !support.handleModelChange(_elementNode, this, recursive)) {
      this.refresh(recursive);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#refresh()
   */
  public void refresh() {
    refresh(false);
  }

  /**
   * @param recursive
   */
  public void refresh(boolean recursive) {
    if (!_tagConverter.isVisualByHTML()) {
      _tagConverter.convertRefresh(null);
      ((CSSFigure) getFigure())
          .setFixedLayoutManager(new CSSWidgetLayout(
              (CSSFigure) getFigure(), createHiddenProvider()));
      // nothing to refresh
      // ((CSSWidgetFigure)
      // getFigure()).setProvider(createHiddenProvider());
      return;
    }
    EditPart editPart;
    Object model;

    Map modelToEditPart = new HashMap();
    List children1 = getChildren();

    for (int i = 0, n = children1.size(); i < n; i++) {
      editPart = (EditPart) children1.get(i);
      modelToEditPart.put(editPart.getModel(), editPart);
      // remove child visual, since we may reconstruct the figure
      // structure of this edit part
      removeChildVisual(editPart);
    }

    Element oldEle = _tagConverter.getResultElement();

    // link parent node.
    Node parent = oldEle.getParentNode();
    _tagConverter.convertRefresh(null);
    if (parent != null) {
      // a new element is generated. replace the old one.
      parent.replaceChild(_tagConverter.getResultElement(), oldEle);
    }

    adaptEditProxy();

    // XXX: comment out the if-else for always deep update.
    // this is for the case when a empty container generate child
    // text node, and then when user input data into the container,
    // the node change from "multiLevel" state to "non-multilevel"
    // state. We don't handle this very well yet, so always to deep
    // update for now. (lium)
    // if (_tagConverter.isMultiLevel())
    // {
    FigureFactory.updateDeepFigure(_tagConverter.getResultElement(),
        oldEle, (CSSFigure) this.getFigure());
    // }
    // else
    // {
    // FigureFactory.updateNonDeepFigure(_tagConverter.getResultElement(),
    // this.getFigure());
    // }

    List modelObjects = getModelChildren();
    if (!recursive) {
      for (int i = 0, n = modelObjects.size(); i < n; i++) {
        model = modelObjects.get(i);

        // Look to see if the EditPart is already around but in the
        // wrong location
        editPart = (EditPart) modelToEditPart.remove(model);

        if (editPart != null) {
          addChildVisual(editPart, i);
        } else {
          // An editpart for this model doesn't exist yet. Create and
          // insert one.
          editPart = createChild(model);
          addChild(editPart, i);
        }
      }
      for (Iterator iter = modelToEditPart.values().iterator(); iter
          .hasNext();) {
        EditPart part = (EditPart) iter.next();
        removeChild(part);
      }
    } else {
      // remove all child, and recreate them.
      for (Iterator iter = modelToEditPart.values().iterator(); iter
          .hasNext();) {
        EditPart part = (EditPart) iter.next();
        removeChild(part);
      }
      for (int i = 0, n = modelObjects.size(); i < n; i++) {
        model = modelObjects.get(i);

        // Look to see if the EditPart is already around but in the
        // wrong location
        // An editpart for this model doesn't exist yet. Create and
        // insert one.
        editPart = createChild(model);
        addChild(editPart, i);
      }
    }
  }

  /**
   *
   */
  private void adaptEditProxy() {
    Element resultEle = _tagConverter.getResultElement();
    if (resultEle instanceof IDOMElement) {
      INodeAdapter adapter = ((IDOMElement) resultEle)
          .getAdapterFor(EditProxyAdapter.class);
      if (adapter != null) {
        ((IDOMElement) resultEle).removeAdapter(adapter);
      }
      ((IDOMElement) resultEle).addAdapter(new EditProxyAdapter(this));
    }
  }

  /**
   * @return true if we are in range mode and this is in
   * the selection range
   */
  public boolean isRangeSelected() {
    IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) this.getViewer();
    if (viewer == null || !viewer.isInRangeMode()) {
      return false;
    }
    DesignRange range = viewer.getRangeSelection();
    if (range == null || !range.isValid()) {
      return false;
    }
    return RangeUtil.intersect(range, this);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isWidget()
   */
  public boolean isWidget() {
    return _tagConverter.isWidget();
  }

  /**
   * @return true if our model node can have direct text children
   */
  public boolean canHaveDirectTextChild() {
    return CMUtil.canHaveDirectTextChild(this._elementNode);
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.NodeEditPart#isResizable()
   */
  public boolean isResizable() {
    if (!_tagConverter.isVisualByHTML()) {
      return false;
    }
    IElementEdit edit = this.getElementEdit();
    if (edit != null) {
      return edit.isResizable(this._elementNode);
    }
        CMElementDeclaration decl = CMUtil
            .getElementDeclaration(this._elementNode);
        if (decl != null) {
          // XXX: default implementation, if this element support "style"
          // attribute,
          // then we think it support resize.
          return decl.getAttributes().getNamedItem("style") != null; //$NON-NLS-1$
        }
        return true;
  }

  /**
   * @param parent
   * @return
   */
  private IFigure getFigure(Node parent) {
    if (parent instanceof INodeNotifier) {
      IFigureHandler handler = (IFigureHandler) ((INodeNotifier) parent)
          .getAdapterFor(IFigureHandler.class);
      if (handler != null) {
        return handler.getFigure();
      }
    }
    return null;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#addChildVisual(org.eclipse.gef.EditPart,
   *      int)
   */
  protected void addChildVisual(EditPart childEditPart, int index) {
       
        boolean figureAdded = false;

        if (childEditPart instanceof NonVisualComponentEditPart)
        {
            getNonVisualElementBar().addNonVisualChild(((NonVisualComponentEditPart) childEditPart));
            figureAdded = true;
            //TODO: need better flow of control.
            return;
        }
       
    Node childNode = (Node) childEditPart.getModel();
    IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
    ConvertPosition position = _tagConverter
        .getChildVisualPosition(childNode);
    if (position != null) {
      Node parent = position.getParentNode();
      // link up figure.
      IFigure parentFigure = getFigure(parent);
      if (parentFigure != null) {
        parentFigure.add(childFigure, position.getIndex());
        figureAdded = true;
      }
      // link up style
      if (parent instanceof INodeNotifier) {
        ICSSStyle parentStyle = (ICSSStyle) ((INodeNotifier) parent)
            .getAdapterFor(ICSSStyle.class);
        if (parentStyle != null) {
          ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
              .getAdapterFor(ICSSStyle.class);
          if (childStyle instanceof AbstractStyle) {
            ((AbstractStyle) childStyle)
                .setParentStyle(parentStyle);
          }
        }
      }
      // link up the nodeForFigure
      if (childEditPart instanceof SubNodeEditPart) {
        Node nodeForFigure = ((SubNodeEditPart) childEditPart)
            .getNodeForFigure();
        if (nodeForFigure != null /*
                       * && !(nodeForFigure instanceof
                       * PseudoElement)
                       */) {
          parent.appendChild(nodeForFigure);
        }
      }
    } else {
        _log.error("getChildVisualPosition() return null"); //$NON-NLS-1$
    }

    if (!figureAdded) {
      super.addChildVisual(childEditPart, index);
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#removeChildVisual(org.eclipse.gef.EditPart)
   */
  protected void removeChildVisual(EditPart childEditPart) {
        // remove figure
        IFigure childFigure = ((GraphicalEditPart) childEditPart).getFigure();
        IFigure parent = childFigure.getParent();

    if (parent != null) {
      parent.remove(childFigure);
    }
       
        if (childEditPart instanceof NonVisualComponentEditPart)
        {
            _nonVisualElementBar.removeNonVisualChild((NonVisualComponentEditPart) childEditPart);
        }
        // this only applies to visual edit parts
        else
        {
        // de-link style
        Node childNode = (Node) childEditPart.getModel();
        ICSSStyle childStyle = (ICSSStyle) ((INodeNotifier) childNode)
            .getAdapterFor(ICSSStyle.class);
        if (childStyle instanceof AbstractStyle) {
          ((AbstractStyle) childStyle).setParentStyle(null);
        }
        // de-link nodeForFigure
        if (childEditPart instanceof SubNodeEditPart) {
          Node nodeForFigure = ((SubNodeEditPart) childEditPart)
              .getNodeForFigure();
          if (nodeForFigure != null && nodeForFigure.getParentNode() != null) {
            nodeForFigure.getParentNode().removeChild(nodeForFigure);
          }
        }
        }
  }

  /**
   * @return the associated tag converter
   */
  public ITagConverter getTagConvert() {
    return _tagConverter;
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.wst.sse.core.internal.provisional.INodeAdapter#notifyChanged(org.eclipse.wst.sse.core.internal.provisional.INodeNotifier,
   *      int, java.lang.Object, java.lang.Object, java.lang.Object, int)
   */
  public void notifyChanged(INodeNotifier notifier, int eventType,
      Object changedFeature, Object oldValue, Object newValue, int pos) {
        // XXX: this can cause multiple refreshes on the same edit part for the
        // same change.  I can also cause incorrect child refreshes...
    refresh();
  }

  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.jst.pagedesigner.parts.SubNodeEditPart#getNodeForFigure()
   */
  public Node getNodeForFigure() {
    return _tagConverter.getResultElement();
  }

  /**
   * @return true this part's node has non whitespace child nodes
   */
  public boolean haveNonWhitespaceTextChild() {
    List children1 = this.getChildren();
    for (int i = 0, size = children1.size(); i < size; i++) {
      if (children1.get(i) instanceof TextEditPart) {
        IDOMText xmltext = (IDOMText) ((TextEditPart) children1.get(i))
            .getIDOMNode();
        if (!xmltext.isElementContentWhitespace()) {
          return true;
        }
      }
    }
    return false;
  }

    private ElementMenuBar getNonVisualElementBar()
    {
        if (_nonVisualElementBar == null)
        {
            _nonVisualElementBar = new ElementMenuBar(this);
        }
        return _nonVisualElementBar;
    }

    /**
     * @return the element menu bar for this element
     */
    public ElementMenuBar getElementMenuBar() {
        return getNonVisualElementBar();
    }

    public void deactivate() {
        super.deactivate();
        if (_nonVisualElementBar != null)
        {
            _nonVisualElementBar.dispose();
            _nonVisualElementBar = null;
        }
        if (_tagConverter != null) {
          _tagConverter.dispose();
        }
    }

    public Cursor getCursor(Point mouseLocation) {
        // let the selection edit policy dictate
        EditPolicy  editPolicy = getEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE);
       
        if (editPolicy instanceof IEnhancedSelectionEditPolicy)
        {
            return  ((IEnhancedSelectionEditPolicy)editPolicy).getSelectionToolCursor(mouseLocation);
        }
        return super.getCursor(mouseLocation);
    }
   
   
}
TOP

Related Classes of org.eclipse.jst.pagedesigner.parts.ElementEditPart

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.