/******************************************************************************
* Copyright (c) 2016 Oracle
* 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:
* Shenxue Zhou - initial implementation and ongoing maintenance
* Ling Hao - [383924] Flexible diagram node shapes
******************************************************************************/
package org.eclipse.sapphire.ui.swt.gef.parts;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;
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.RequestConstants;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.gef.requests.SelectionRequest;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.sapphire.ui.diagram.editor.ContainerShapePart;
import org.eclipse.sapphire.ui.diagram.editor.ImagePart;
import org.eclipse.sapphire.ui.diagram.editor.ShapePart;
import org.eclipse.sapphire.ui.diagram.editor.TextPart;
import org.eclipse.sapphire.ui.swt.gef.DiagramConfigurationManager;
import org.eclipse.sapphire.ui.swt.gef.figures.TextFigure;
import org.eclipse.sapphire.ui.swt.gef.internal.DirectEditorManagerFactory;
import org.eclipse.sapphire.ui.swt.gef.model.ContainerShapeModel;
import org.eclipse.sapphire.ui.swt.gef.model.ShapeModel;
import org.eclipse.sapphire.ui.swt.gef.model.ShapeModelUtil;
import org.eclipse.sapphire.ui.swt.gef.policies.NodeLabelDirectEditPolicy;
import org.eclipse.sapphire.ui.swt.gef.presentation.ContainerShapePresentation;
import org.eclipse.sapphire.ui.swt.gef.presentation.ShapePresentation;
import org.eclipse.sapphire.ui.swt.gef.tools.SapphireDragEditPartsTracker;
/**
* @author <a href="mailto:shenxue.zhou@oracle.com">Shenxue Zhou</a>
* @author <a href="mailto:ling.hao@oracle.com">Ling Hao</a>
*/
public class ContainerShapeEditPart extends ShapeEditPart
{
public ContainerShapeEditPart(DiagramConfigurationManager configManager)
{
super(configManager);
}
@Override
protected void createEditPolicies()
{
ContainerShapeModel model = getCastedModel();
ContainerShapePart containerPart = (ContainerShapePart)model.getSapphirePart();
// Create direct edit policy if it contains non-active sapphire text part. Active
// Sapphire text part has its own GEF editpart.
if (containerPart.isEditable())
{
installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new NodeLabelDirectEditPolicy());
}
}
@Override
public boolean isSelectable() {
ContainerShapeModel model = getCastedModel();
if (model.getShapePresentation().part().isActive()) {
return true;
}
return false;
}
@Override
protected void addChildVisual(EditPart childEditPart, int index)
{
IFigure child = ((GraphicalEditPart) childEditPart).getFigure();
if (child == null)
return;
ShapeModel shapeModel = (ShapeModel)childEditPart.getModel();
ShapePresentation shapePresentation = shapeModel.getShapePresentation();
ContainerShapePresentation parentPresentation = getParentContainer(shapePresentation);
IFigure parentFigure = parentPresentation.getFigure();
Object layoutConstraint = ShapeUtil.getLayoutConstraint(shapePresentation,
parentPresentation.getLayout());
// find the offset for figure in presentation without an editpart
int offset = ShapeUtil.getPresentationCount(parentPresentation, shapePresentation);
parentFigure.add(child, layoutConstraint, index + offset);
}
@Override
protected void removeChildVisual(EditPart childEditPart)
{
IFigure child = ((GraphicalEditPart) childEditPart).getFigure();
if (child == null)
return;
ShapeModel shapeModel = (ShapeModel)childEditPart.getModel();
ContainerShapePresentation parentPresentation = getParentContainer(shapeModel.getShapePresentation());
IFigure parentFigure = parentPresentation.getFigure();
parentFigure.remove(child);
}
@Override
protected List<ShapeModel> getModelChildren()
{
List<ShapeModel> returnedModelChildren = new ArrayList<ShapeModel>();
ContainerShapeModel containerModel = getCastedModel();
returnedModelChildren.addAll(ShapeModelUtil.collectActiveChildrenRecursively(containerModel));
return returnedModelChildren;
}
public ContainerShapeModel getCastedModel()
{
return (ContainerShapeModel)getModel();
}
@Override
public void performRequest(Request request)
{
if (request.getType() == RequestConstants.REQ_DIRECT_EDIT)
{
if (!(request instanceof DirectEditRequest))
{
// Direct edit invoked using key command
performDirectEdit();
}
}
else if (request.getType().equals(REQ_OPEN) && (request instanceof SelectionRequest))
{
SelectionRequest selRequest = (SelectionRequest)request;
Point pt = selRequest.getLocation();
TextPart textPart = getTextPart(pt);
if (textPart != null)
{
performDirectEdit(textPart);
}
else
{
ImagePart imagePart = getImagePart(pt);
if (imagePart != null)
{
invokeDoubleTapAction(imagePart);
}
}
}
else
{
super.performRequest(request);
}
}
private void performDirectEdit()
{
List<TextPart> textParts = getContainedTextParts();
if (!textParts.isEmpty())
{
performDirectEdit(textParts.get(0));
}
}
private void performDirectEdit(TextPart textPart)
{
if (textPart.isEditable())
{
TextFigure textFigure = (TextFigure)getPartFigure(textPart);
if (textFigure != null)
{
DirectEditManager manager = DirectEditorManagerFactory.createDirectEditorManager(this, textPart,
new NodeCellEditorLocator(getConfigurationManager(), textFigure), textFigure);
manager.show();
}
}
}
@Override
public void propertyChange(PropertyChangeEvent evt)
{
String prop = evt.getPropertyName();
if (prop.equals(ShapeModel.SHAPE_START_EDITING))
{
if (evt.getNewValue() instanceof TextPart)
{
performDirectEdit((TextPart)evt.getNewValue());
}
else
{
performDirectEdit();
}
}
else if (ContainerShapeModel.SHAPE_VISIBILITY_UPDATES.equals(prop))
{
Object obj = evt.getNewValue();
if (obj instanceof ShapePart)
{
ShapePart shapePart = (ShapePart)obj;
ShapePresentation parentPresentation = getCastedModel().getShapePresentation();
ShapePresentation shapePresentation = ShapeModelUtil.getChildShapePresentation(parentPresentation, shapePart);
ShapeUtil.updateFigureForShape(shapePresentation, getCastedModel().getNodeModel().getDiagramModel().getResourceCache(),
getConfigurationManager());
refresh();
}
}
}
@Override
protected List<TextPart> getContainedTextParts()
{
ContainerShapePart containerPart = (ContainerShapePart)getCastedModel().getSapphirePart();
return (ShapePart.getContainedShapeParts(containerPart, TextPart.class));
}
@Override
protected List<ImagePart> getContainedImageParts()
{
ContainerShapePart containerPart = (ContainerShapePart)getCastedModel().getSapphirePart();
return (ShapePart.getContainedShapeParts(containerPart, ImagePart.class));
}
@Override
public DragTracker getDragTracker(Request request) {
return new SapphireDragEditPartsTracker(this);
}
}