Search in sources :

Example 46 with NodeContainerUI

use of org.knime.core.ui.node.workflow.NodeContainerUI in project knime-core by knime.

the class VerticAlignmentCenter method doLayout.

/**
 * @param wfm the manager holding the nodes to layout
 * @param nodeParts the nodes to align
 * @return a map with offsets for the nodes
 */
static Map<NodeContainerEditPart, Integer> doLayout(final WorkflowManagerUI wfm, final NodeContainerEditPart[] nodeParts) {
    if (nodeParts.length == 0) {
        return Collections.emptyMap();
    }
    NodeContainerEditPart[] nodes = nodeParts.clone();
    // sorts by the y position
    Arrays.sort(nodes, new Comparator<NodeContainerEditPart>() {

        @Override
        public int compare(final NodeContainerEditPart o1, final NodeContainerEditPart o2) {
            NodeUIInformation ui1 = o1.getNodeContainer().getUIInformation();
            NodeUIInformation ui2 = o2.getNodeContainer().getUIInformation();
            if (ui1 == null || ui2 == null) {
                return 0;
            }
            if (ui1.getBounds()[1] < ui2.getBounds()[1]) {
                return -1;
            } else {
                return (ui1.getBounds()[1] > ui2.getBounds()[1]) ? 1 : 0;
            }
        }
    });
    // most left node is the anchor that doesn't change
    HashMap<NodeContainerEditPart, Integer> offsets = new HashMap<NodeContainerEditPart, Integer>();
    NodeUIInformation nui = nodes[0].getNodeContainer().getUIInformation();
    if (nui == null) {
        LOGGER.warn("Only nodes with location information can be aligned.");
        return Collections.emptyMap();
    }
    int refX = nui.getBounds()[0];
    for (int i = 1; /* idx 0 is anchor */
    i < nodes.length; i++) {
        NodeContainerUI nc = nodes[i].getNodeContainer();
        NodeUIInformation ui = nc.getUIInformation();
        if (ui.getBounds()[0] != refX) {
            offsets.put(nodes[i], refX - ui.getBounds()[0]);
        }
    }
    return offsets;
}
Also used : NodeContainerUI(org.knime.core.ui.node.workflow.NodeContainerUI) NodeContainerEditPart(org.knime.workbench.editor2.editparts.NodeContainerEditPart) HashMap(java.util.HashMap) NodeUIInformation(org.knime.core.node.workflow.NodeUIInformation)

Example 47 with NodeContainerUI

use of org.knime.core.ui.node.workflow.NodeContainerUI in project knime-core by knime.

the class LayoutManager method doLayout.

/**
 * @param nodes the nodes that should be laid out. If null, all nodes of the
 *            workflow manager passed to the constructor are laid out.
 */
public void doLayout(final Collection<NodeContainerUI> nodes) {
    int X_STRETCH = 100;
    int Y_STRETCH = 120;
    if (WorkflowEditor.getActiveEditorSnapToGrid()) {
        if (WorkflowEditor.getActiveEditorGridX() >= 70) {
            X_STRETCH = WorkflowEditor.getActiveEditorGridX();
        } else {
            X_STRETCH = WorkflowEditor.getActiveEditorGridXOffset(X_STRETCH);
        }
        Y_STRETCH = WorkflowEditor.getActiveEditorGridYOffset(Y_STRETCH);
    }
    // add all nodes that should be laid out to the graph
    Collection<NodeContainerUI> allNodes = nodes;
    if (allNodes == null || allNodes.size() <= 1) {
        allNodes = m_wfm.getNodeContainers();
    }
    // keep the left upper corner of the node cluster.
    // Nodes laid out are placed right and below
    int minX = Integer.MAX_VALUE;
    int minY = Integer.MAX_VALUE;
    // add all nodes that are to be laid out
    for (NodeContainerUI nc : allNodes) {
        Node gNode = createGraphNodeForNC(nc);
        m_workbenchToGraphNodes.put(nc, gNode);
        NodeUIInformation ui = nc.getUIInformation();
        minX = (ui.getBounds()[0] < minX) ? ui.getBounds()[0] : minX;
        minY = (ui.getBounds()[1] < minY) ? ui.getBounds()[1] : minY;
        if (WorkflowEditor.getActiveEditorSnapToGrid()) {
            Point nextGridLocation = WorkflowEditor.getActiveEditorNextGridLocation(new Point(minX, minY));
            minX = nextGridLocation.x;
            minY = nextGridLocation.y;
        }
    }
    // find all connections that connect from/to our nodes,
    // keep a flag that states: isClusterInternal
    HashMap<ConnectionContainerUI, Boolean> allConns = new HashMap<ConnectionContainerUI, Boolean>();
    for (ConnectionContainerUI conn : m_wfm.getConnectionContainers()) {
        Node src = null;
        if (!conn.getSource().equals(m_wfm.getID())) {
            // if it's not a meta node incoming connection
            src = m_workbenchToGraphNodes.get(m_wfm.getNodeContainer(conn.getSource()));
        }
        Node dest = null;
        if (!conn.getDest().equals(m_wfm.getID())) {
            // if it is not a meta node outgoing connection
            dest = m_workbenchToGraphNodes.get(m_wfm.getNodeContainer(conn.getDest()));
        }
        boolean isInternal = (src != null && dest != null);
        // if at least one node is auto laid out we need the connection
        if (src != null || dest != null) {
            allConns.put(conn, isInternal);
        }
    }
    // Add all connections (internal and leading in/out the cluster)
    // to the graph
    Edge gEdge;
    for (ConnectionContainerUI conn : allConns.keySet()) {
        Node srcGraphNode;
        Node destGraphNode;
        if (conn.getSource().equals(m_wfm.getID())) {
            // it connects to a meta node input port:
            int portIdx = conn.getSourcePort();
            srcGraphNode = m_workbenchWFMInports.get(portIdx);
            if (srcGraphNode == null) {
                srcGraphNode = m_g.createNode("Incoming " + portIdx, 0, portIdx * Y_STRETCH);
                m_workbenchWFMInports.put(portIdx, srcGraphNode);
            }
        } else {
            NodeContainerUI s = m_wfm.getNodeContainer(conn.getSource());
            srcGraphNode = m_workbenchToGraphNodes.get(s);
            if (srcGraphNode == null) {
                // then it connects to an "outside" node
                srcGraphNode = m_workbenchIncomingNodes.get(s);
                if (srcGraphNode == null) {
                    srcGraphNode = createGraphNodeForNC(s);
                    m_workbenchIncomingNodes.put(s, srcGraphNode);
                }
            }
        // else it is a connection inside the layout cluster
        }
        if (conn.getDest().equals(m_wfm.getID())) {
            // it connects to a meta node output port
            int portIdx = conn.getDestPort();
            destGraphNode = m_workbenchWFMOutports.get(portIdx);
            if (destGraphNode == null) {
                destGraphNode = m_g.createNode("Outgoing " + portIdx, 250, portIdx * Y_STRETCH);
                m_workbenchWFMOutports.put(portIdx, destGraphNode);
            }
        } else {
            NodeContainerUI d = m_wfm.getNodeContainer(conn.getDest());
            destGraphNode = m_workbenchToGraphNodes.get(d);
            if (destGraphNode == null) {
                // then it connects to an "outside" node
                destGraphNode = m_workbenchOutgoingNodes.get(d);
                if (destGraphNode == null) {
                    destGraphNode = createGraphNodeForNC(d);
                    m_workbenchOutgoingNodes.put(d, destGraphNode);
                }
            }
        // else it is a connection within the layout cluster
        }
        gEdge = m_g.createEdge(srcGraphNode, destGraphNode);
        if (gEdge != null) {
            m_workbenchToGraphEdges.put(conn, gEdge);
            m_parallelConns.put(gEdge, new LinkedList<ConnectionContainerUI>(Collections.singletonList(conn)));
        } else {
            // a connection between these node already exists in the graph
            Edge graphEdge = srcGraphNode.getEdge(destGraphNode);
            assert graphEdge != null;
            // add the connection to list of parallel connections.
            m_parallelConns.get(graphEdge).add(conn);
        }
    }
    // AFTER creating all nodes, mark the incoming/outgoing nodes as fixed
    boolean anchorsExist = false;
    Map<Node, Boolean> anchorNodes = m_g.createBoolNodeMap();
    for (Node n : m_workbenchIncomingNodes.values()) {
        anchorsExist = true;
        anchorNodes.put(n, Boolean.TRUE);
    }
    for (Node n : m_workbenchOutgoingNodes.values()) {
        anchorsExist = true;
        anchorNodes.put(n, Boolean.TRUE);
    }
    for (Node n : m_workbenchWFMInports.values()) {
        anchorsExist = true;
        anchorNodes.put(n, Boolean.TRUE);
    }
    for (Node n : m_workbenchWFMOutports.values()) {
        anchorsExist = true;
        anchorNodes.put(n, Boolean.TRUE);
    }
    SimpleLayeredLayouter layouter = new SimpleLayeredLayouter(m_initPlacementSeed);
    layouter.setBalanceBranchings(!WorkflowEditor.getActiveEditorSnapToGrid());
    if (anchorsExist) {
        layouter.doLayout(m_g, anchorNodes);
    } else {
        layouter.doLayout(m_g, null);
    }
    // preserver the old stuff for undoers
    m_oldBendpoints = new HashMap<ConnectionID, ConnectionUIInformation>();
    m_oldCoordinates = new HashMap<NodeID, NodeUIInformation>();
    // transfer new coordinates back to nodes
    // with fixed nodes (lots of) the new coordinates of the nodes may not
    // start at 0.
    double coordOffsetX = Integer.MAX_VALUE;
    double coordOffsetY = Integer.MAX_VALUE;
    for (NodeContainerUI nc : allNodes) {
        Node gNode = m_workbenchToGraphNodes.get(nc);
        coordOffsetX = Math.min(coordOffsetX, m_g.getX(gNode));
        coordOffsetY = Math.min(coordOffsetY, m_g.getY(gNode));
    }
    for (NodeContainerUI nc : allNodes) {
        NodeUIInformation uiInfo = nc.getUIInformation();
        if (uiInfo != null) {
            Node gNode = m_workbenchToGraphNodes.get(nc);
            int[] b = uiInfo.getBounds();
            int x = (int) Math.round((m_g.getX(gNode) - coordOffsetX) * X_STRETCH) + minX;
            int y = (int) Math.round((m_g.getY(gNode) - coordOffsetY) * Y_STRETCH) + minY;
            NodeUIInformation newCoord = NodeUIInformation.builder().setNodeLocation(x, y, b[2], b[3]).setHasAbsoluteCoordinates(uiInfo.hasAbsoluteCoordinates()).setSnapToGrid(WorkflowEditor.getActiveEditorSnapToGrid()).build();
            LOGGER.debug("Node " + nc + " gets auto-layout coordinates " + newCoord);
            // save old coordinates for undo
            m_oldCoordinates.put(nc.getID(), uiInfo);
            // triggers gui update
            nc.setUIInformation(newCoord);
        }
    }
    // delete old bendpoints - transfer new ones
    for (ConnectionContainerUI conn : allConns.keySet()) {
        // store old bendpoint for undo
        ConnectionUIInformation ui = conn.getUIInfo();
        if (ui != null) {
            m_oldBendpoints.put(conn.getID(), ui);
        } else {
            m_oldBendpoints.put(conn.getID(), null);
        }
        ConnectionUIInformation.Builder newUIBuilder = ConnectionUIInformation.builder();
        Edge e = m_workbenchToGraphEdges.get(conn);
        if (e == null) {
            // a parallel connection not represented by the edge
            continue;
        }
        List<ConnectionContainerUI> conns = m_parallelConns.get(e);
        assert conns.size() > 0;
        // that is how we created it!
        assert conns.get(0) == conn;
        ArrayList<Point2D> newBends = m_g.bends(e);
        if (newBends != null && !newBends.isEmpty()) {
            // half the node icon size...
            int extraX = 16;
            int extraY = 24;
            for (int i = 0; i < newBends.size(); i++) {
                Point2D b = newBends.get(i);
                newUIBuilder.addBendpoint((int) Math.round((b.getX() - coordOffsetX) * X_STRETCH) + extraX + minX, (int) Math.round((b.getY() - coordOffsetY) * Y_STRETCH) + extraY + minY, i);
            }
        }
        ConnectionUIInformation newUI = newUIBuilder.build();
        conn.setUIInfo(newUI);
        // compute bendpoints for parallel connections (slightly offset)
        for (int i = 1; i < conns.size(); i++) {
            // idx 0 == conn!
            ConnectionContainerUI parConn = conns.get(i);
            // destination port determines offset
            int yOffset = (parConn.getDestPort() - conn.getDestPort()) * 10;
            ConnectionUIInformation parUI = ConnectionUIInformation.builder(newUI).translate(new int[] { 0, yOffset }).build();
            parConn.setUIInfo(parUI);
        }
    }
}
Also used : NodeContainerUI(org.knime.core.ui.node.workflow.NodeContainerUI) HashMap(java.util.HashMap) Node(org.knime.workbench.ui.layout.Graph.Node) Point2D(java.awt.geom.Point2D) NodeID(org.knime.core.node.workflow.NodeID) SimpleLayeredLayouter(org.knime.workbench.ui.layout.layeredlayout.SimpleLayeredLayouter) Point(org.eclipse.draw2d.geometry.Point) Point(org.eclipse.draw2d.geometry.Point) ConnectionContainerUI(org.knime.core.ui.node.workflow.ConnectionContainerUI) ConnectionID(org.knime.core.node.workflow.ConnectionID) NodeUIInformation(org.knime.core.node.workflow.NodeUIInformation) ConnectionUIInformation(org.knime.core.node.workflow.ConnectionUIInformation) Edge(org.knime.workbench.ui.layout.Graph.Edge)

Example 48 with NodeContainerUI

use of org.knime.core.ui.node.workflow.NodeContainerUI in project knime-core by knime.

the class AutoLayoutAction method runOnNodes.

/**
 * {@inheritDoc}
 */
@Override
public synchronized void runOnNodes(final NodeContainerEditPart[] parts) {
    ScrollingGraphicalViewer provider = (ScrollingGraphicalViewer) getEditor().getEditorSite().getSelectionProvider();
    if (provider == null) {
        return;
    }
    ArrayList<NodeContainerUI> nodes = null;
    if (parts != null && parts.length > 0) {
        nodes = new ArrayList<NodeContainerUI>(parts.length);
        for (NodeContainerEditPart p : parts) {
            nodes.add(p.getNodeContainer());
        }
    }
    AutoLayoutCommand alc = new AutoLayoutCommand(getManager(), nodes);
    // enables undo
    getCommandStack().execute(alc);
    // update the actions
    getEditor().updateActions();
    // Give focus to the editor again. Otherwise the actions (selection)
    // is not updated correctly.
    getWorkbenchPart().getSite().getPage().activate(getWorkbenchPart());
}
Also used : ScrollingGraphicalViewer(org.eclipse.gef.ui.parts.ScrollingGraphicalViewer) NodeContainerUI(org.knime.core.ui.node.workflow.NodeContainerUI) NodeContainerEditPart(org.knime.workbench.editor2.editparts.NodeContainerEditPart) AutoLayoutCommand(org.knime.workbench.ui.layout.commands.AutoLayoutCommand)

Example 49 with NodeContainerUI

use of org.knime.core.ui.node.workflow.NodeContainerUI in project knime-core by knime.

the class DynamicNodeDescriptionCreator method addDescription.

/**
 * Adds the single line description for all nodes contained in the category
 * (and all sub categories) to the StringBuilder. It will separate the lines
 * by a HTML new line tag.
 *
 * @param cat the category to add the descriptions for.
 * @param bld the buffer to add the one line strings to.
 * @param idsDisplayed a set of IDs of categories and templates already
 *            displayed. Items appearing twice will be skipped.
 */
public void addDescription(final Category cat, final StringBuilder bld, final Set<String> idsDisplayed) {
    bld.append("<dl>");
    bld.append("<dt><h2>In <b>");
    bld.append(htmlString(cat.getName()));
    bld.append("</b>:</h2></dt> \n");
    if (!cat.hasChildren()) {
        bld.append("<dd> - contains no nodes - </dd>");
    } else {
        bld.append("<dd><dl>");
        for (IRepositoryObject child : cat.getChildren()) {
            if (child instanceof Category) {
                Category childCat = (Category) child;
                if (!idsDisplayed.contains(childCat.getID())) {
                    idsDisplayed.add(childCat.getID());
                    addDescription(childCat, bld, idsDisplayed);
                }
            } else if (child instanceof NodeTemplate) {
                NodeTemplate templ = (NodeTemplate) child;
                if (!idsDisplayed.contains(templ.getID())) {
                    idsDisplayed.add(templ.getID());
                    addDescription(templ, /* useSingleLine */
                    true, bld);
                }
            } else if (child instanceof MetaNodeTemplate) {
                MetaNodeTemplate templ = (MetaNodeTemplate) child;
                if (!idsDisplayed.contains(templ.getID())) {
                    idsDisplayed.add(templ.getID());
                    NodeContainerUI manager = ((MetaNodeTemplate) child).getManager();
                    addDescription(manager, /* useSingleLine */
                    true, bld);
                }
            } else {
                bld.append(" - contains unknown object (internal err!) -");
            }
        }
        bld.append("</dl></dd>");
    }
    bld.append("</dl>");
}
Also used : NodeContainerUI(org.knime.core.ui.node.workflow.NodeContainerUI) SubNodeContainerUI(org.knime.core.ui.node.workflow.SubNodeContainerUI) SingleNodeContainerUI(org.knime.core.ui.node.workflow.SingleNodeContainerUI) Category(org.knime.workbench.repository.model.Category) NodeTemplate(org.knime.workbench.repository.model.NodeTemplate) MetaNodeTemplate(org.knime.workbench.repository.model.MetaNodeTemplate) MetaNodeTemplate(org.knime.workbench.repository.model.MetaNodeTemplate) IRepositoryObject(org.knime.workbench.repository.model.IRepositoryObject)

Example 50 with NodeContainerUI

use of org.knime.core.ui.node.workflow.NodeContainerUI in project knime-core by knime.

the class DynamicNodeDescriptionCreator method addSubWorkflowDescription.

private void addSubWorkflowDescription(final NodeContainerUI nc, final boolean useSingleLine, final StringBuilder bld) {
    WorkflowManagerUI wfm;
    if (nc instanceof SubNodeContainerUI) {
        wfm = ((SubNodeContainerUI) nc).getWorkflowManager();
    } else {
        wfm = (WorkflowManagerUI) nc;
    }
    if (!useSingleLine) {
        bld.append(getHeader());
        bld.append("<h1>");
        bld.append(nc.getName());
        bld.append("</h1>");
        if (nc.getCustomDescription() != null) {
            bld.append("<h2>Description:</h2>");
            bld.append("<p>" + nc.getCustomDescription() + "</p>");
        }
        bld.append("<h2>Contained nodes: </h2>");
        for (NodeContainerUI child : wfm.getNodeContainers()) {
            addDescription(child, true, bld);
        }
        bld.append("</body></html>");
    } else {
        bld.append("<dt><b>");
        bld.append(nc.getName() + " contained nodes:");
        bld.append("</b></dt>");
        bld.append("<dd>");
        bld.append("<dl>");
        for (NodeContainerUI child : wfm.getNodeContainers()) {
            addDescription(child, true, bld);
        }
        bld.append("</dl>");
        bld.append("</dd>");
    }
}
Also used : NodeContainerUI(org.knime.core.ui.node.workflow.NodeContainerUI) SubNodeContainerUI(org.knime.core.ui.node.workflow.SubNodeContainerUI) SingleNodeContainerUI(org.knime.core.ui.node.workflow.SingleNodeContainerUI) WorkflowManagerUI(org.knime.core.ui.node.workflow.WorkflowManagerUI) SubNodeContainerUI(org.knime.core.ui.node.workflow.SubNodeContainerUI)

Aggregations

NodeContainerUI (org.knime.core.ui.node.workflow.NodeContainerUI)59 NodeContainerEditPart (org.knime.workbench.editor2.editparts.NodeContainerEditPart)28 SubNodeContainerUI (org.knime.core.ui.node.workflow.SubNodeContainerUI)17 WorkflowManagerUI (org.knime.core.ui.node.workflow.WorkflowManagerUI)16 WorkflowManager (org.knime.core.node.workflow.WorkflowManager)10 NodeContainerFigure (org.knime.workbench.editor2.figures.NodeContainerFigure)9 SingleNodeContainerUI (org.knime.core.ui.node.workflow.SingleNodeContainerUI)8 NodeUIInformation (org.knime.core.node.workflow.NodeUIInformation)7 HashMap (java.util.HashMap)5 Point (org.eclipse.draw2d.geometry.Point)5 Image (org.eclipse.swt.graphics.Image)5 ConnectionUIInformation (org.knime.core.node.workflow.ConnectionUIInformation)5 NativeNodeContainer (org.knime.core.node.workflow.NativeNodeContainer)5 NodeID (org.knime.core.node.workflow.NodeID)5 ArrayList (java.util.ArrayList)4 EditPart (org.eclipse.gef.EditPart)4 LoopEndNode (org.knime.core.node.workflow.LoopEndNode)4 IContainer (org.eclipse.core.resources.IContainer)3 IPreferenceStore (org.eclipse.jface.preference.IPreferenceStore)3 IStructuredSelection (org.eclipse.jface.viewers.IStructuredSelection)3