/******************************************************************************* | |
* Copyright (c) 2005, 2012 IBM Corporation and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License 2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/legal/epl-2.0/ | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* IBM Corporation - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.bpel.ui.editparts; | |
import org.eclipse.bpel.model.EventHandler; | |
import org.eclipse.bpel.model.FaultHandler; | |
import org.eclipse.bpel.model.Process; | |
import org.eclipse.bpel.ui.BPELUIPlugin; | |
import org.eclipse.bpel.ui.IBPELUIConstants; | |
import org.eclipse.bpel.ui.adapters.IEventHandlerHolder; | |
import org.eclipse.bpel.ui.adapters.IFaultHandlerHolder; | |
import org.eclipse.bpel.ui.adapters.ILabeledElement; | |
import org.eclipse.bpel.ui.editparts.policies.BPELSelectionEditPolicy; | |
import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor; | |
import org.eclipse.bpel.ui.figures.ILayoutAware; | |
import org.eclipse.bpel.ui.uiextensionmodel.StartNode; | |
import org.eclipse.bpel.ui.util.BPELDragEditPartsTracker; | |
import org.eclipse.bpel.ui.util.BPELUtil; | |
import org.eclipse.bpel.ui.util.ModelHelper; | |
import org.eclipse.draw2d.ConnectionAnchor; | |
import org.eclipse.draw2d.Graphics; | |
import org.eclipse.draw2d.IFigure; | |
import org.eclipse.draw2d.ImageFigure; | |
import org.eclipse.draw2d.MarginBorder; | |
import org.eclipse.draw2d.geometry.Insets; | |
import org.eclipse.draw2d.geometry.Point; | |
import org.eclipse.gef.ConnectionEditPart; | |
import org.eclipse.gef.DragTracker; | |
import org.eclipse.gef.EditPolicy; | |
import org.eclipse.gef.NodeEditPart; | |
import org.eclipse.gef.Request; | |
import org.eclipse.swt.graphics.Image; | |
import org.eclipse.swt.graphics.Rectangle; | |
public class StartNodeEditPart extends BPELEditPart implements NodeEditPart, ILayoutAware{ | |
protected Image image; | |
protected int imageWidth; | |
protected int imageHeight; | |
//Determines the border which will be added to both sides (left/right) | |
//As a result this value is the distance to any attached handlers. | |
public static final int BORDER_WIDTH = 8; | |
// Whether the process has a fault handler and event handler | |
protected boolean hasFH, hasEH; | |
// Whether to show each of the actual handlers. | |
// TODO: Initialize these from the preferences store | |
protected boolean showFH = false, showEH = false; | |
// Fault handler, Compensation handler and Event handler support | |
protected int faultImageWidth, faultImageHeight; | |
protected int eventImageWidth, eventImageHeight; | |
protected Image faultImage; | |
protected Image eventImage; | |
protected Rectangle rectFault; | |
protected Rectangle rectEvent; | |
private IFigure faultImageFigure; | |
private IFigure eventImageFigure; | |
private class StartNodeFigure extends ImageFigure { | |
/** | |
* | |
*/ | |
public StartNodeFigure() { | |
super(image); | |
} | |
/** | |
* @see org.eclipse.draw2d.Figure#paint(org.eclipse.draw2d.Graphics) | |
*/ | |
@Override | |
public void paint(Graphics graphics) { | |
super.paint(graphics); | |
computeHandlerIconPositions(ModelHelper.isHorizontalLayout(getModel())); | |
if (hasFH) { | |
graphics.pushState(); | |
graphics.setClip(faultImageFigure.getBounds().getCopy()); | |
faultImageFigure.paint(graphics); | |
graphics.popState(); | |
} | |
if (hasEH) { | |
graphics.pushState(); | |
graphics.setClip(eventImageFigure.getBounds().getCopy()); | |
eventImageFigure.paint(graphics); | |
graphics.popState(); | |
} | |
} | |
} | |
/** | |
* Brand new shiny start edit part. | |
*/ | |
public StartNodeEditPart() { | |
// Initialize images for fault and event handler decorations | |
this.faultImage = BPELUIPlugin.INSTANCE.getImage(IBPELUIConstants.ICON_FAULT_INDICATOR); | |
org.eclipse.swt.graphics.Rectangle r = faultImage.getBounds(); | |
this.faultImageWidth = r.width; | |
this.faultImageHeight = r.height; | |
this.eventImage = BPELUIPlugin.INSTANCE.getImage(IBPELUIConstants.ICON_EVENT_INDICATOR); | |
r = eventImage.getBounds(); | |
this.eventImageWidth = r.width; | |
this.eventImageHeight = r.height; | |
} | |
@Override | |
protected void addAllAdapters() { | |
super.addAllAdapters(); | |
adapter.addToObject(getProcess()); | |
} | |
@Override | |
protected void removeAllAdapters() { | |
adapter.removedFrom(getProcess()); | |
super.removeAllAdapters(); | |
} | |
@Override | |
protected IFigure createFigure() { | |
if (image == null) { | |
ILabeledElement element = BPELUtil.adapt(getStartNode(), ILabeledElement.class); | |
image = element.getSmallImage(getStartNode()); | |
Rectangle rect = image.getBounds(); | |
imageWidth = rect.width; | |
imageHeight = rect.height; | |
} | |
this.hasFH = getFaultHandler() != null; | |
this.hasEH = getEventHandler() != null; | |
// Cause the handlerIcons don't belong to the | |
// bounds of the StartNodeFigure (as a result of | |
// moving them a bit to the right in vertical layout and a bit to to the bottom | |
// in horizontal layout) hit testing | |
// doesn't reach the Startnode. So add an invisible | |
// border | |
StartNodeFigure snf = new StartNodeFigure(); | |
if(!ModelHelper.isHorizontalLayout(getModel())) | |
snf.setBorder(new MarginBorder(0,7+BORDER_WIDTH,0,7+BORDER_WIDTH)); | |
else | |
snf.setBorder(new MarginBorder(5,0,5,0)); | |
faultImageFigure = new ImageFigure(faultImage); | |
faultImageFigure.setParent(snf); | |
eventImageFigure = new ImageFigure(eventImage); | |
eventImageFigure.setParent(snf); | |
return snf; | |
} | |
/** | |
* @see org.eclipse.bpel.ui.editparts.BPELEditPart#refreshVisuals() | |
*/ | |
@Override | |
public void refreshVisuals() { | |
super.refreshVisuals(); | |
// Refresh any decorations on this edit part | |
this.hasFH = getFaultHandler() != null; | |
this.hasEH = getEventHandler() != null; | |
// Force a repaint, as the decorations. | |
getFigure().repaint(); | |
} | |
/** | |
* Return the start node. | |
* @return return the start node. | |
*/ | |
public StartNode getStartNode() { | |
return (StartNode)getModel(); | |
} | |
/** | |
* Return the process. | |
* @return the process | |
*/ | |
public Process getProcess() { | |
return getStartNode().getProcess(); | |
} | |
@Override | |
protected void createEditPolicies() { | |
// Don't call super because we don't want a component edit policy | |
// or a direct edit policy. | |
// Show the selection rectangle | |
installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new BPELSelectionEditPolicy(false, false){ | |
@Override | |
protected int getWestInset() { | |
Insets ins = ((StartNodeEditPart)getHost()).getFigure().getInsets(); | |
if(ins != null){ | |
return ins.left; | |
} | |
return super.getWestInset(); | |
} | |
@Override | |
protected int getEastInset() { | |
Insets ins = ((StartNodeEditPart)getHost()).getFigure().getInsets(); | |
if(ins != null){ | |
return ins.right; | |
} | |
return super.getEastInset(); | |
} | |
}); | |
} | |
public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connEditPart) { | |
// Start nodes cannot be the target of a connection. | |
return null; | |
} | |
public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connEditPart) { | |
// Start nodes can be the source of an implicit connection | |
// anchored at the bottom centre of the node. | |
return new CenteredConnectionAnchor(getFigure(), CenteredConnectionAnchor.BOTTOM, 0); | |
} | |
public ConnectionAnchor getSourceConnectionAnchor(Request request) { | |
// TODO: Translate point to figure, call other method | |
return getSourceConnectionAnchor((ConnectionEditPart)null); | |
} | |
public ConnectionAnchor getTargetConnectionAnchor(Request request) { | |
// TODO: Translate point to figure, call other method | |
return getTargetConnectionAnchor((ConnectionEditPart)null); | |
} | |
public void setShowFaultHandler(boolean showFaultHandler) { | |
this.showFH = showFaultHandler; | |
// Notify the process too. | |
ProcessEditPart processEditPart = (ProcessEditPart)getParent(); | |
processEditPart.setShowFaultHandler(showFaultHandler); | |
// Call refresh so that both refreshVisuals and refreshChildren will be called. | |
refresh(); | |
} | |
public void setShowEventHandler(boolean showEventHandler) { | |
this.showEH = showEventHandler; | |
// Notify the process too. | |
ProcessEditPart processEditPart = (ProcessEditPart)getParent(); | |
processEditPart.setShowEventHandler(showEventHandler); | |
// Call refresh so that both refreshVisuals and refreshChildren will be called. | |
refresh(); | |
} | |
public boolean getShowFaultHandler() { | |
return showFH; | |
} | |
public boolean getShowEventHandler() { | |
return showEH; | |
} | |
public FaultHandler getFaultHandler() { | |
IFaultHandlerHolder holder = BPELUtil.adapt(getProcess(), IFaultHandlerHolder.class); | |
if (holder != null) { | |
return holder.getFaultHandler(getProcess()); | |
} | |
return null; | |
} | |
public EventHandler getEventHandler() { | |
IEventHandlerHolder holder = BPELUtil.adapt(getProcess(), IEventHandlerHolder.class); | |
if (holder != null) { | |
return holder.getEventHandler(getProcess()); | |
} | |
return null; | |
} | |
/** | |
* Is point in fault image. | |
* @param x | |
* @param y | |
* @return true if it is, false if its not. | |
*/ | |
public boolean isPointInFaultImage(int x, int y) { | |
if (hasFH) { | |
Point p = new Point(x, y); | |
getFigure().translateToRelative(p); | |
return rectFault.contains(p.x, p.y); | |
} | |
return false; | |
} | |
/** | |
* Is point in event image. | |
* @param x | |
* @param y | |
* @return true if it is, false if its not. | |
*/ | |
public boolean isPointInEventImage(int x, int y) { | |
if (hasEH) { | |
Point p = new Point(x, y); | |
getFigure().translateToRelative(p); | |
return rectEvent.contains(p.x, p.y); | |
} | |
return false; | |
} | |
/** | |
* @see org.eclipse.bpel.ui.editparts.BPELEditPart#getDragTracker(org.eclipse.gef.Request) | |
*/ | |
@Override | |
public DragTracker getDragTracker(Request request) { | |
return new BPELDragEditPartsTracker(this) { | |
@Override | |
protected boolean handleDoubleClick(int button) { | |
return true; | |
} | |
@Override | |
protected boolean handleButtonDown(int button) { | |
Point point = getLocation(); | |
if (isPointInFaultImage(point.x, point.y)) { | |
setShowFaultHandler(!showFH); | |
return true; | |
} | |
if (isPointInEventImage(point.x, point.y)) { | |
setShowEventHandler(!showEH); | |
return true; | |
} | |
return super.handleButtonDown(button); | |
} | |
}; | |
} | |
private void computeHandlerIconPositions(boolean horizontal){ | |
org.eclipse.draw2d.geometry.Rectangle bounds = getFigure().getBounds(); | |
if(horizontal){ | |
rectFault = new Rectangle(bounds.x, bounds.y + bounds.height - faultImageHeight, faultImageWidth, faultImageHeight); | |
rectEvent = new Rectangle(bounds.x +faultImageWidth, bounds.y + bounds.height - eventImageHeight, eventImageWidth, eventImageHeight); | |
}else{ | |
rectFault = new Rectangle(bounds.x + bounds.width - faultImageWidth - BORDER_WIDTH, bounds.y-1, faultImageWidth, faultImageHeight); | |
rectEvent = new Rectangle(bounds.x + bounds.width - eventImageWidth - BORDER_WIDTH, bounds.y + bounds.height - eventImageHeight+1, eventImageWidth, eventImageHeight); | |
} | |
// Apply the bounds to the figures | |
faultImageFigure.setBounds(new org.eclipse.draw2d.geometry.Rectangle(rectFault.x,rectFault.y,rectFault.width,rectFault.height)); | |
eventImageFigure.setBounds(new org.eclipse.draw2d.geometry.Rectangle(rectEvent.x,rectEvent.y,rectEvent.width,rectEvent.height)); | |
} | |
public Rectangle getRectFault() { | |
return rectFault; | |
} | |
public Rectangle getRectEvent() { | |
return rectEvent; | |
} | |
public void switchLayout(boolean horizontal) { | |
if(horizontal){ | |
getFigure().setBorder(new MarginBorder(5,0,5,0)); | |
}else{ | |
getFigure().setBorder(new MarginBorder(0,7+BORDER_WIDTH,0,7+BORDER_WIDTH)); | |
} | |
} | |
public IFigure getFaultImageFigure() { | |
return faultImageFigure; | |
} | |
public IFigure getEventImageFigure() { | |
return eventImageFigure; | |
} | |
} |