blob: d434e4851ceaba215eeb6534c90645ad7f782a39 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2007 The University of Manchester
*
* Modifications to the initial code base are copyright of their
* respective authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package net.sf.taverna.t2.workbench.models.graph;
import static javax.swing.SwingUtilities.convertPointFromScreen;
import static javax.swing.SwingUtilities.invokeLater;
import static net.sf.taverna.t2.workbench.models.graph.GraphController.PortStyle.ALL;
import static net.sf.taverna.t2.workbench.models.graph.GraphController.PortStyle.NONE;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.net.URI;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import net.sf.taverna.t2.ui.menu.MenuManager;
import uk.org.taverna.scufl2.api.activity.Activity;
import uk.org.taverna.scufl2.api.common.Scufl2Tools;
import uk.org.taverna.scufl2.api.core.Processor;
import uk.org.taverna.scufl2.api.profiles.ProcessorBinding;
/**
* Manager for handling UI events on GraphElements.
*
* @author David Withers
*/
public class DefaultGraphEventManager implements GraphEventManager {
private static final URI NESTED_WORKFLOW_URI = URI
.create("http://ns.taverna.org.uk/2010/activity/nested-workflow");
private GraphController graphController;
private Component component;
private JPopupMenu menu;
private MenuManager menuManager;
private Scufl2Tools scufl2Tools = new Scufl2Tools();
/**
* Constructs a new instance of GraphEventManager.
*
* @param graphController
* @param component
* component to use when displaying popup menus
*/
public DefaultGraphEventManager(GraphController graphController, Component component,
MenuManager menuManager) {
this.graphController = graphController;
this.component = component;
this.menuManager = menuManager;
}
@Override
public void mouseClicked(final GraphElement graphElement, short button, boolean altKey,
boolean ctrlKey, boolean metaKey, final int x, final int y, int screenX, int screenY) {
Object dataflowObject = graphElement.getWorkflowBean();
// For both left and right click - add to selection model
if (graphController.getDataflowSelectionModel() != null)
graphController.getDataflowSelectionModel().addSelection(dataflowObject);
if ((button != 2) && !ctrlKey)return;
// If this was a right click - show a pop-up as well
if (dataflowObject == null)
menu = menuManager.createContextMenu(graphController.getWorkflow(),
graphController.getWorkflow(), component);
else {
menu = menuManager.createContextMenu(graphController.getWorkflow(),
dataflowObject, component);
if (dataflowObject instanceof Processor) {
final Processor processor = (Processor) dataflowObject;
ProcessorBinding processorBinding = scufl2Tools
.processorBindingForProcessor(processor,
graphController.getProfile());
final Activity activity = processorBinding.getBoundActivity();
if (menu == null)
menu = new JPopupMenu();
if (graphElement instanceof GraphNode) {
defineMenuForGraphElement(graphElement, x, y, processor,
activity);
} else if (graphElement instanceof Graph) {
defineMenuForGraphBackground(activity);
}
}
}
if (menu != null) {
final Point p = new Point(screenX, screenY);
convertPointFromScreen(p, component);
invokeLater(new Runnable() {
@Override
public void run() {
menu.show(component, p.x, p.y);
}
});
}
}
@SuppressWarnings("serial")
private void defineMenuForGraphBackground(final Activity activity) {
if (activity.getType().equals(NESTED_WORKFLOW_URI)) {
menu.addSeparator();
menu.add(new JMenuItem(new AbstractAction("Hide nested workflow") {
@Override
public void actionPerformed(ActionEvent ev) {
graphController.setExpandNestedDataflow(activity, false);
graphController.redraw();
}
}));
}
}
@SuppressWarnings("serial")
private void defineMenuForGraphElement(final GraphElement graphElement,
final int x, final int y, final Processor processor,
final Activity activity) {
if (graphController.getPortStyle(processor).equals(NONE)) {
menu.addSeparator();
menu.add(new JMenuItem(new AbstractAction("Show ports") {
@Override
public void actionPerformed(ActionEvent ev) {
graphController.setPortStyle(processor, ALL);
graphController.redraw();
}
}));
} else if (graphController.getPortStyle(processor).equals(ALL)) {
menu.addSeparator();
menu.add(new JMenuItem(new AbstractAction("Hide ports") {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.setPortStyle(processor, NONE);
graphController.redraw();
}
}));
}
if (activity.getType().equals(NESTED_WORKFLOW_URI)) {
menu.addSeparator();
menu.add(new JMenuItem(new AbstractAction("Show nested workflow") {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.setExpandNestedDataflow(activity, true);
graphController.redraw();
}
}));
}
menu.addSeparator();
GraphNode graphNode = (GraphNode) graphElement;
List<GraphNode> sourceNodes = graphNode.getSourceNodes();
if (sourceNodes.size() == 1) {
final GraphNode sourceNode = sourceNodes.get(0);
if (sourceNode.getLabel() != null) {
menu.add(new JMenuItem(new AbstractAction("Link from output '"
+ sourceNode.getLabel() + "'") {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.startEdgeCreation(sourceNode,
new Point(x, y));
}
}));
}
} else if (sourceNodes.size() > 0) {
JMenu linkMenu = new JMenu("Link from output...");
menu.add(linkMenu);
for (final GraphNode sourceNode : sourceNodes) {
linkMenu.add(new JMenuItem(new AbstractAction(sourceNode
.getLabel()) {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.startEdgeCreation(sourceNode,
new Point(x, y));
}
}));
}
}
List<GraphNode> sinkNodes = graphNode.getSinkNodes();
if (sinkNodes.size() == 1) {
final GraphNode sinkNode = sinkNodes.get(0);
if (sinkNode.getLabel() != null) {
menu.add(new JMenuItem(new AbstractAction("Link to input '"
+ sinkNode.getLabel() + "'") {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.startEdgeCreation(sinkNode, new Point(
x, y));
}
}));
}
} else if (sinkNodes.size() > 0) {
JMenu linkMenu = new JMenu("Link to input...");
menu.add(linkMenu);
for (final GraphNode sinkNode : sinkNodes) {
linkMenu.add(new JMenuItem(new AbstractAction(sinkNode
.getLabel()) {
@Override
public void actionPerformed(ActionEvent arg0) {
graphController.startEdgeCreation(sinkNode, new Point(
x, y));
}
}));
}
}
}
@Override
public void mouseDown(GraphElement graphElement, short button,
boolean altKey, boolean ctrlKey, boolean metaKey, int x, int y,
int screenX, int screenY) {
if (button == 0)
graphController.startEdgeCreation(graphElement, new Point(x, y));
}
@Override
public void mouseUp(GraphElement graphElement, short button,
boolean altKey, boolean ctrlKey, boolean metaKey, final int x,
final int y, int screenX, int screenY) {
if (button == 0)
graphController.stopEdgeCreation(graphElement, new Point(screenX,
screenY));
}
@Override
public void mouseMoved(GraphElement graphElement, short button,
boolean altKey, boolean ctrlKey, boolean metaKey, int x, int y,
int screenX, int screenY) {
graphController.moveEdgeCreationTarget(graphElement, new Point(x, y));
}
@Override
public void mouseOver(GraphElement graphElement, short button,
boolean altKey, boolean ctrlKey, boolean metaKey, int x, int y,
int screenX, int screenY) {
if (graphElement.getWorkflowBean() != null)
graphElement.setActive(true);
}
@Override
public void mouseOut(GraphElement graphElement, short button,
boolean altKey, boolean ctrlKey, boolean metaKey, int x, int y,
int screenX, int screenY) {
if (graphElement.getWorkflowBean() != null)
graphElement.setActive(false);
}
}