| /******************************************************************************* |
| * 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 v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * 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; |
| } |
| } |