/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * 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: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.config.graph.parts; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.draw2d.ConnectionAnchor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.draw2d.graph.CompoundDirectedGraph; import org.eclipse.draw2d.graph.Node; import org.eclipse.draw2d.graph.Subgraph; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gef.EditPart; import org.eclipse.gef.EditPolicy; import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.NodeEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.IViewPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.springframework.ide.eclipse.config.core.IConfigEditor; import org.springframework.ide.eclipse.config.graph.ConfigGraphPlugin; import org.springframework.ide.eclipse.config.graph.model.AbstractGefGraphModelElement; import org.springframework.ide.eclipse.config.graph.model.Activity; import org.springframework.ide.eclipse.config.graph.model.Transition; import org.springframework.ide.eclipse.config.graph.policies.ActivityDirectEditPolicy; import org.springframework.ide.eclipse.config.graph.policies.ActivityEditPolicy; import org.springframework.ide.eclipse.config.graph.policies.ActivityNodeEditPolicy; import org.springsource.ide.eclipse.commons.core.StatusHandler; /** * @author Leo Dos Santos * @author Christian Dupuis */ public abstract class ActivityPart extends AbstractGraphicalEditPart implements PropertyChangeListener, NodeEditPart { protected ActivityDirectEditManager manager; public ActivityPart(Activity activity) { setModel(activity); } /** * @see org.eclipse.gef.EditPart#activate() */ @Override public void activate() { super.activate(); getActivity().addPropertyChangeListener(this); } protected void applyBoundsResults(CompoundDirectedGraph graph, Map<AbstractGraphicalEditPart, Object> map) { Node n = (Node) map.get(this); getFigure().setBounds(new Rectangle(n.x, n.y, n.width, n.height)); } protected void applyGraphResults(CompoundDirectedGraph graph, Map<AbstractGraphicalEditPart, Object> map) { applyBoundsResults(graph, map); for (int i = 0; i < getSourceConnections().size(); i++) { TransitionPart trans = (TransitionPart) getSourceConnections().get(i); trans.applyGraphResults(graph, map); } } protected void contributeEdgesToGraph(CompoundDirectedGraph graph, Map<AbstractGraphicalEditPart, Object> map) { for (int i = 0; i < getSourceConnections().size(); i++) { TransitionPart part = (TransitionPart) getSourceConnections().get(i); part.contributeToGraph(graph, map); } for (int i = 0; i < getChildren().size(); i++) { ActivityPart child = (ActivityPart) getChildren().get(i); child.contributeEdgesToGraph(graph, map); } } protected abstract void contributeNodesToGraph(CompoundDirectedGraph graph, Subgraph s, Map<AbstractGraphicalEditPart, Object> map); /** * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies() */ @Override protected void createEditPolicies() { installEditPolicy(EditPolicy.COMPONENT_ROLE, new ActivityEditPolicy()); // installEditPolicy(EditPolicy.CONTAINER_ROLE, new // ActivitySourceEditPolicy()); installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new ActivityDirectEditPolicy()); installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new ActivityNodeEditPolicy()); } /** * @see org.eclipse.gef.EditPart#deactivate() */ @Override public void deactivate() { super.deactivate(); getActivity().removePropertyChangeListener(this); } /** * Returns the Activity model associated with this EditPart * @return the Activity model */ protected Activity getActivity() { return (Activity) getModel(); } protected abstract int getAnchorOffset(); public abstract Activity getModelElement(); /** * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections() */ @Override protected List<Transition> getModelSourceConnections() { return getActivity().getOutgoingTransitions(); } /** * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections() */ @Override protected List<Transition> getModelTargetConnections() { return getActivity().getIncomingTransitions(); } /** * @see NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef.ConnectionEditPart) */ public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection) { EditPart part = getViewer().getContents(); if (part instanceof ActivityDiagramPart) { ActivityDiagramPart diagram = (ActivityDiagramPart) part; if (diagram.getDirection() == PositionConstants.EAST) { return new RightAnchor(getFigure(), getAnchorOffset()); } } return new BottomAnchor(getFigure(), getAnchorOffset()); } /** * @see org.eclipse.gef.NodeEditPart#getSourceConnectionAnchor(org.eclipse.gef.Request) */ public ConnectionAnchor getSourceConnectionAnchor(Request request) { EditPart part = getViewer().getContents(); if (part instanceof ActivityDiagramPart) { ActivityDiagramPart diagram = (ActivityDiagramPart) part; if (diagram.getDirection() == PositionConstants.EAST) { return new RightAnchor(getFigure(), getAnchorOffset()); } } return new BottomAnchor(getFigure(), getAnchorOffset()); } /** * @see NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef.ConnectionEditPart) */ public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connection) { EditPart part = getViewer().getContents(); if (part instanceof ActivityDiagramPart) { ActivityDiagramPart diagram = (ActivityDiagramPart) part; if (diagram.getDirection() == PositionConstants.EAST) { return new LeftAnchor(getFigure(), getAnchorOffset()); } } return new TopAnchor(getFigure(), getAnchorOffset()); } /** * @see org.eclipse.gef.NodeEditPart#getTargetConnectionAnchor(org.eclipse.gef.Request) */ public ConnectionAnchor getTargetConnectionAnchor(Request request) { EditPart part = getViewer().getContents(); if (part instanceof ActivityDiagramPart) { ActivityDiagramPart diagram = (ActivityDiagramPart) part; if (diagram.getDirection() == PositionConstants.EAST) { return new LeftAnchor(getFigure(), getAnchorOffset()); } } return new TopAnchor(getFigure(), getAnchorOffset()); } protected void handleBoundsChange(PropertyChangeEvent event) { IFigure figure = getFigure(); Rectangle constraint = (Rectangle) event.getNewValue(); ActivityDiagramPart diagram = (ActivityDiagramPart) getParent(); diagram.setLayoutConstraint(this, figure, constraint); } public boolean isManualLayout() { EditPart part = getViewer().getContents(); if (part instanceof ActivityDiagramPart) { ActivityDiagramPart diagramPart = (ActivityDiagramPart) part; return diagramPart.isManualLayout(); } return false; } protected void performDirectEdit() { } protected void performOpen() { // IDOMElement element = getActivity().getInput(); // if (element != null) { // AbstractConfigFlowDiagram diagram = getActivity().getDiagram(); // IConfigEditor cEditor = diagram.getGraphicalEditor().getEditor(); // if (cEditor != null) { // cEditor.revealElement(element); // } // } showProperties(); } /** * @see org.eclipse.gef.EditPart#performRequest(org.eclipse.gef.Request) */ @Override public void performRequest(Request request) { if (request.getType() == RequestConstants.REQ_DIRECT_EDIT && getEditPolicy(EditPolicy.DIRECT_EDIT_ROLE) != null) { performDirectEdit(); } if (request.getType() == RequestConstants.REQ_OPEN) { performOpen(); } } /** * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { String prop = evt.getPropertyName(); if (AbstractGefGraphModelElement.CHILDREN.equals(prop)) { refreshChildren(); } else if (AbstractGefGraphModelElement.INCOMINGS.equals(prop)) { refreshTargetConnections(); } else if (AbstractGefGraphModelElement.OUTGOINGS.equals(prop)) { refreshSourceConnections(); } else if (Activity.NAME.equals(prop)) { refreshVisuals(); } else if (Activity.BOUNDS.equals(prop)) { handleBoundsChange(evt); } // Causes Graph to re-layout ((GraphicalEditPart) (getViewer().getContents())).getFigure().revalidate(); } public void refreshAll() { refresh(); List children = getChildren(); for (int i = 0; i < children.size(); i++) { if (children.get(i) instanceof ActivityPart) { ActivityPart child = (ActivityPart) children.get(i); child.refreshAll(); } } List sources = getSourceConnections(); for (int i = 0; i < sources.size(); i++) { if (sources.get(i) instanceof TransitionPart) { TransitionPart trans = (TransitionPart) sources.get(i); trans.refresh(); } } List targets = getTargetConnections(); for (int i = 0; i < targets.size(); i++) { if (targets.get(i) instanceof TransitionPart) { TransitionPart trans = (TransitionPart) targets.get(i); trans.refresh(); } } } protected abstract void refreshFigureVisuals(); protected void refreshTooltipVisuals() { if (getFigure() != null) { Label tooltip = (Label) getFigure().getToolTip(); if (tooltip == null) { tooltip = new Label(); getFigure().setToolTip(tooltip); } tooltip.setText(getActivity().getName()); } } @Override protected void refreshVisuals() { refreshFigureVisuals(); refreshTooltipVisuals(); } /** * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#setFigure(org.eclipse.draw2d.IFigure) */ @Override protected void setFigure(IFigure figure) { figure.getBounds().setSize(0, 0); super.setFigure(figure); } public void showProperties() { try { IViewPart props = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .showView("org.eclipse.ui.views.PropertySheet"); //$NON-NLS-1$ if (props instanceof ISelectionListener) { IConfigEditor editor = getModelElement().getDiagram().getGraphicalEditor().getEditor(); Object obj = editor.getAdapter(ISelectionProvider.class); if (obj instanceof ISelectionProvider) { ISelectionProvider provider = (ISelectionProvider) obj; ((ISelectionListener) props).selectionChanged(editor, provider.getSelection()); } } } catch (PartInitException e) { StatusHandler.log(new Status(IStatus.ERROR, ConfigGraphPlugin.PLUGIN_ID, Messages.StructuredActivityPart_ERROR_OPENING_VIEW, e)); } } /** * @see org.eclipse.gef.editparts.AbstractEditPart#toString() */ @Override public String toString() { return getModel().toString(); } }