Search in sources :

Example 26 with PanelEquationTree

use of gov.sandia.n2a.ui.eq.PanelEquationTree in project n2a by frothga.

the class ChangeAnnotation method apply.

public void apply(String nameBefore, String nameAfter, String prefixBefore) {
    NodeContainer parent = (NodeContainer) NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotRedoException();
    MPart mparent = parent.source;
    if (parent instanceof NodeVariable)
        mparent = (MPart) mparent.child("$metadata");
    // Update database
    String[] names = nameAfter.split("\\.");
    if (nameAfter.equals(nameBefore)) {
        // If name is unchanged, then node should already exist,
        // and we only need to change the direct value, not the subtree.
        String valueBefore = mparent.get(names);
        String valueAfter = savedTree.get();
        MPart partBefore = (MPart) mparent.child(names);
        MPart partAfter = (MPart) mparent.set(valueAfter, names);
        // If there was no change in value, then toggle override state.
        if (partBefore != null && valueAfter.equals(valueBefore)) {
            if (partAfter.isOverridden())
                partAfter.clearPath();
            else
                partAfter.override();
        }
    } else {
        if (!prefixBefore.isEmpty()) {
            String[] prefixes = prefixBefore.split("\\.");
            mparent.clear(prefixes);
        }
        MPart partAfter = (MPart) mparent.childOrCreate(names);
        if (valueBeforeRebase == null)
            valueBeforeRebase = partAfter.get();
        // saveTree may have children, or it might be a simple value with no children.
        partAfter.merge(savedTree);
    }
    // Update GUI
    PanelEquationTree pet = parent.getTree();
    FilteredTreeModel model = null;
    if (pet != null)
        model = (FilteredTreeModel) pet.tree.getModel();
    List<String> expanded = null;
    if (model != null)
        expanded = AddAnnotation.saveExpandedNodes(pet.tree, parent);
    parent.build();
    parent.filter();
    if (model != null && parent.visible()) {
        model.nodeStructureChanged(parent);
        AddAnnotation.restoreExpandedNodes(pet.tree, parent, expanded);
    }
    NodeBase nodeAfter = AddAnnotation.findClosest(parent, names);
    if (pet != null) {
        TreeNode[] afterPath = nodeAfter.getPath();
        TreeNode[] parentPath = parent.getPath();
        if (selectVariable)
            pet.updateVisibility(parentPath, -2, !multi);
        else
            pet.updateVisibility(afterPath, -2, !multi);
        if (multi) {
            if (// Assumes nodeAfter is directly under a NodeVariable.
            selectVariable)
                // Assumes nodeAfter is directly under a NodeVariable.
                pet.tree.addSelectionPath(new TreePath(parentPath));
            else
                pet.tree.addSelectionPath(new TreePath(afterPath));
        }
        pet.animate();
    }
    AddAnnotation.update(parent, touchesPin, touchesCategory);
}
Also used : MPart(gov.sandia.n2a.eqset.MPart) CannotRedoException(javax.swing.undo.CannotRedoException) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) NodeContainer(gov.sandia.n2a.ui.eq.tree.NodeContainer) NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) TreePath(javax.swing.tree.TreePath) TreeNode(javax.swing.tree.TreeNode) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Example 27 with PanelEquationTree

use of gov.sandia.n2a.ui.eq.PanelEquationTree in project n2a by frothga.

the class ChangeEquation method apply.

public void apply(String nameBefore, String nameAfter, String combinerAfter, String valueAfter, boolean multi, boolean multiLast) {
    NodeBase parent = NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotRedoException();
    NodeBase nodeBefore = parent.child(nameBefore);
    if (nodeBefore == null)
        throw new CannotRedoException();
    PanelEquationTree pet = parent.getTree();
    FilteredTreeModel model = (FilteredTreeModel) pet.tree.getModel();
    NodeBase nodeAfter;
    if (nameBefore.equals(nameAfter)) {
        nodeAfter = nodeBefore;
        nodeAfter.source.set(valueAfter);
    } else {
        // Update the database
        MPart mparent = parent.source;
        MPart newPart = (MPart) mparent.set(valueAfter, nameAfter);
        mparent.clear(nameBefore);
        MPart oldPart = (MPart) mparent.child(nameBefore);
        // Update GUI
        nodeAfter = parent.child(nameAfter);
        if (oldPart == null) {
            if (nodeAfter == null) {
                nodeAfter = nodeBefore;
                nodeAfter.source = newPart;
            } else {
                model.removeNodeFromParent(nodeBefore);
            }
        } else {
            if (nodeAfter == null) {
                int index = parent.getIndex(nodeBefore);
                nodeAfter = new NodeEquation(newPart);
                model.insertNodeIntoUnfiltered(nodeAfter, parent, index);
            }
            if (nodeBefore.visible())
                model.nodeChanged(nodeBefore);
            else
                parent.hide(nodeBefore, model);
        }
    }
    if (!parent.source.get().equals(combinerAfter)) {
        parent.source.set(combinerAfter);
        parent.setUserObject();
        NodeBase grandparent = (NodeBase) parent.getParent();
        grandparent.invalidateColumns(model);
    }
    nodeAfter.setUserObject();
    parent.invalidateColumns(null);
    TreeNode[] afterPath = nodeAfter.getPath();
    boolean killed = valueAfter.isEmpty();
    boolean setSelection;
    if (// Revoke, which hides the node, so like delete.
    killed)
        // Revoke, which hides the node, so like delete.
        setSelection = !multi || multiLast;
    else
        setSelection = !multi;
    pet.updateVisibility(afterPath, -2, setSelection);
    if (multi && !killed)
        pet.tree.addSelectionPath(new TreePath(afterPath));
    parent.allNodesChanged(model);
    pet.animate();
}
Also used : NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) MPart(gov.sandia.n2a.eqset.MPart) TreePath(javax.swing.tree.TreePath) TreeNode(javax.swing.tree.TreeNode) CannotRedoException(javax.swing.undo.CannotRedoException) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Example 28 with PanelEquationTree

use of gov.sandia.n2a.ui.eq.PanelEquationTree in project n2a by frothga.

the class ChangeVariable method apply.

public void apply(String nameBefore, String nameAfter, boolean multi, boolean multiLast) {
    NodePart parent = (NodePart) NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotRedoException();
    NodeVariable nodeBefore = (NodeVariable) parent.child(nameBefore);
    if (nodeBefore == null)
        throw new CannotRedoException();
    PanelEquations pe = PanelModel.instance.panelEquations;
    PanelEquationTree pet = parent.getTree();
    FilteredTreeModel model = null;
    if (pet != null)
        model = (FilteredTreeModel) pet.tree.getModel();
    NodeVariable nodeAfter;
    boolean touchedBindings = false;
    // Key paths to each variable that references this one.
    List<List<String>> references = new ArrayList<List<String>>();
    if (nameBefore.equals(nameAfter)) {
        nodeAfter = nodeBefore;
        // Same as valueAfter. Sub-tree is not relevant here.
        nodeAfter.source.set(savedTree.get());
    } else {
        // Update database
        // Move the subtree
        MPart mparent = parent.source;
        mparent.clear(nameBefore);
        // Removes any reference changes in target node.
        mparent.clear(nameAfter);
        mparent.set(savedTree, nameAfter);
        MPart newPart = (MPart) mparent.child(nameAfter);
        MPart oldPart = (MPart) mparent.child(nameBefore);
        // See ChangePart.apply() for a similar procedure.
        try {
            // "doc" is a collated model, so changes will also be made to references from inherited nodes.
            // Such changes will be saved as an override.
            MPart doc = pe.root.source;
            // TODO: this is a potentially lengthy operation. For very large models, need to reduce load on EDT. Either maintain incremental compilation, or compile on separate thread.
            EquationSet compiled = new EquationSet(doc);
            compiled.name = doc.key();
            List<String> vkeypath = new ArrayList<String>(path.subList(1, path.size()));
            Variable vold;
            Variable vnew;
            if (oldPart == null) {
                EquationSet p = (EquationSet) compiled.getObject(vkeypath);
                vold = Variable.fromLHS(nameBefore);
                vold.equations = new TreeSet<EquationEntry>();
                if (nodeBefore.isBinding)
                    vold.equations.add(new EquationEntry(newPart.get()));
                p.add(vold);
                vkeypath.add(Variable.stripContextPrefix(nameAfter));
            } else {
                vkeypath.add(Variable.stripContextPrefix(nameBefore));
                vold = (Variable) compiled.getObject(vkeypath);
                vkeypath.set(vkeypath.size() - 1, nameAfter);
            }
            vnew = (Variable) compiled.getObject(vkeypath);
            try {
                // This will throw an AbortRun if any connection is not properly bound.
                // However, not every connection binding necessarily leads to this variable.
                compiled.resolveConnectionBindings();
            } catch (Exception e) {
            }
            try {
                compiled.resolveLHS();
            } catch (Exception e) {
            }
            try {
                // This will very likely throw an AbortRun exception to report unresolved variables.
                // This will do no harm. All we need is that other equations resolve to this variable.
                compiled.resolveRHS();
            } catch (Exception e) {
            }
            prepareConnections(compiled);
            List<Variable> users = new ArrayList<Variable>();
            if (vold.usedBy != null) {
                for (Object o : vold.usedBy) {
                    if (!(o instanceof Variable))
                        continue;
                    // On undo, don't touch savedTree or exposed node. They should return to their exact previous values.
                    if ((o == vnew || o == vold) && nameAfter.equals(this.nameBefore))
                        continue;
                    users.add((Variable) o);
                }
            }
            // This kind of relationship is not generally reciprocal, so we must check uses as well as usedBy.
            if (vold.uses != null) {
                for (Variable v : vold.uses.keySet()) {
                    if (v.reference.variable == vold)
                        users.add(v);
                }
            }
            vold.name = vnew.name;
            vold.order = vnew.order;
            for (Variable v : users) {
                // Don't modify expression on variable line itself. Instead, assume the user edited it exactly as intended.
                if (v == vnew && v.equations.size() == 1)
                    continue;
                List<String> ref = v.getKeyPath();
                MNode n = doc.child(ref.toArray());
                String oldKey = n.key();
                String newKey = changeReferences(vold, n, v);
                if (// Handle a change in variable name.
                !newKey.equals(oldKey)) {
                    NodeBase nb = pe.root.locateNodeFromHere(ref);
                    n.parent().move(oldKey, newKey);
                    ref.set(ref.size() - 1, newKey);
                    nb.source = (MPart) doc.child(ref.toArray());
                }
                // Queue GUI updates for nodes other than the primary ones.
                if (v != vnew && v != vold)
                    references.add(ref);
            }
        } catch (Exception e) {
        }
        // Update GUI
        nodeAfter = (NodeVariable) parent.child(nameAfter);
        if (oldPart == null) {
            if (nodeBefore.isBinding) {
                if (parent.graph != null)
                    parent.connectionBindings.remove(nameBefore);
                touchedBindings = true;
            }
            if (nodeAfter == null) {
                nodeAfter = nodeBefore;
                nodeAfter.source = newPart;
            } else {
                if (model == null)
                    FilteredTreeModel.removeNodeFromParentStatic(nodeBefore);
                else
                    model.removeNodeFromParent(nodeBefore);
            }
        } else {
            if (nodeAfter == null) {
                int index = parent.getIndex(nodeBefore);
                nodeAfter = new NodeVariable(newPart);
                if (model == null)
                    FilteredTreeModel.insertNodeIntoUnfilteredStatic(nodeAfter, parent, index);
                else
                    model.insertNodeIntoUnfiltered(nodeAfter, parent, index);
            }
            nodeBefore.build();
            nodeBefore.filter();
            if (nodeBefore.visible()) {
                if (model != null)
                    model.nodeStructureChanged(nodeBefore);
            } else {
                parent.hide(nodeBefore, model);
            }
        }
    }
    nodeAfter.build();
    nodeAfter.filter();
    Set<PanelEquationTree> needAnimate = new HashSet<PanelEquationTree>();
    if (pet != null) {
        needAnimate.add(pet);
        // Must be done before invalidateColumns(), because that function causes new columns to be fetched for renderer sizing.
        pet.updateHighlights(pet.root, nameAfter);
        parent.invalidateColumns(model);
        TreeNode[] nodePath = nodeAfter.getPath();
        pet.updateOrder(nodePath);
        boolean killed = savedTree.get().equals("$kill");
        boolean setSelection;
        if (killed)
            setSelection = !multi || multiLast;
        else
            setSelection = !multi;
        pet.updateVisibility(nodePath, -2, setSelection);
        if (multi && !killed)
            pet.tree.addSelectionPath(new TreePath(nodePath));
    }
    for (List<String> ref : references) {
        NodeVariable n = (NodeVariable) pe.root.locateNodeFromHere(ref);
        if (n == null)
            continue;
        // Rebuild n, because equations and/or their conditions may have changed.
        n.build();
        n.findConnections();
        n.filter();
        if (// n's visibility won't change
        n.visible()) {
            PanelEquationTree subpet = n.getTree();
            if (subpet == null)
                continue;
            JTree subtree = subpet.tree;
            FilteredTreeModel submodel = (FilteredTreeModel) subtree.getModel();
            NodeBase subparent = (NodeBase) n.getParent();
            boolean added = needAnimate.add(subpet);
            if (added)
                subpet.updateHighlights(subpet.root, nameAfter);
            else
                subpet.updateHighlights(n, nameAfter);
            subparent.invalidateColumns(null);
            // Node will collapse if it was open. Don't worry about this.
            submodel.nodeStructureChanged(n);
            subpet.updateVisibility(n.getPath(), -2, false);
            subparent.allNodesChanged(submodel);
        }
    }
    for (PanelEquationTree ap : needAnimate) ap.animate();
    if (parent.updateVariableConnections())
        touchedBindings = true;
    if (touchedBindings) {
        parent.updateSubpartConnections();
        // Update edges to pins, if present.
        PanelEquationGraph peg = pe.panelEquationGraph;
        if (parent.source.child("$metadata", "gui", "pin") != null) {
            parent.updatePins();
            peg.updatePins();
        }
        // Rebuild all edges on canvas, whether regular connection or pin.
        peg.reconnect();
        peg.repaint();
        MPart mparent = parent.source;
        if (mparent.root() == mparent)
            PanelModel.instance.panelSearch.updateConnectors(mparent);
    }
}
Also used : MPart(gov.sandia.n2a.eqset.MPart) AccessVariable(gov.sandia.n2a.language.AccessVariable) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) Variable(gov.sandia.n2a.eqset.Variable) PanelEquationGraph(gov.sandia.n2a.ui.eq.PanelEquationGraph) ArrayList(java.util.ArrayList) PanelEquations(gov.sandia.n2a.ui.eq.PanelEquations) MNode(gov.sandia.n2a.db.MNode) NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) TreeNode(javax.swing.tree.TreeNode) ArrayList(java.util.ArrayList) List(java.util.List) EquationEntry(gov.sandia.n2a.eqset.EquationEntry) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel) HashSet(java.util.HashSet) EquationSet(gov.sandia.n2a.eqset.EquationSet) CannotRedoException(javax.swing.undo.CannotRedoException) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) CannotRedoException(javax.swing.undo.CannotRedoException) JTree(javax.swing.JTree) TreePath(javax.swing.tree.TreePath) NodePart(gov.sandia.n2a.ui.eq.tree.NodePart)

Example 29 with PanelEquationTree

use of gov.sandia.n2a.ui.eq.PanelEquationTree in project n2a by frothga.

the class CompoundEditView method selectLead.

public void selectLead() {
    if (leadPath == null)
        return;
    NodeBase n = NodeBase.locateNode(leadPath);
    if (n == null)
        return;
    if (clearSelection == CLEAR_GRAPH) {
        // CLEAR_GRAPH should only be used for compound operations on parts, so this should be a safe cast.
        NodePart p = (NodePart) n;
        if (p.graph != null) {
            p.graph.takeFocusOnTitle();
            return;
        }
    }
    // Otherwise, assume this is a compound operation on tree nodes.
    PanelEquationTree pet = n.getTree();
    if (pet != null)
        pet.tree.setLeadSelectionPath(new TreePath(n.getPath()));
}
Also used : NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) TreePath(javax.swing.tree.TreePath) NodePart(gov.sandia.n2a.ui.eq.tree.NodePart) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree)

Example 30 with PanelEquationTree

use of gov.sandia.n2a.ui.eq.PanelEquationTree in project n2a by frothga.

the class ChangeInherit method apply.

public void apply(String value) {
    NodeBase node = NodeBase.locateNode(path);
    if (node == null)
        throw new CannotRedoException();
    NodePart parent = (NodePart) node.getParent();
    NodePart grandparent = (NodePart) parent.getTrueParent();
    PanelEquations pe = PanelModel.instance.panelEquations;
    PanelEquationTree pet = node.getTree();
    FilteredTreeModel model = (FilteredTreeModel) pet.tree.getModel();
    PanelEquationGraph peg = pe.panelEquationGraph;
    // Complex restructuring happens here.
    node.source.set(value);
    parent.build();
    if (grandparent == null)
        parent.findConnections();
    else
        grandparent.findConnections();
    parent.rebuildPins();
    parent.filter();
    if (parent == pe.part) {
        peg.reloadPart();
        // Ensure that parts are not visible in parent panel.
        parent.filter();
    }
    model.nodeStructureChanged(parent);
    TreeNode[] nodePath = parent.child("$inherit").getPath();
    pet.updateOrder(nodePath);
    pet.updateVisibility(nodePath);
    pet.animate();
    if (parent != pe.part) {
        peg.updatePins();
        peg.reconnect();
        peg.repaint();
    }
    if (// root node, so update categories in search list
    parent.getTrueParent() == null) {
        PanelModel.instance.panelSearch.search();
    }
}
Also used : NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) PanelEquationGraph(gov.sandia.n2a.ui.eq.PanelEquationGraph) TreeNode(javax.swing.tree.TreeNode) CannotRedoException(javax.swing.undo.CannotRedoException) PanelEquations(gov.sandia.n2a.ui.eq.PanelEquations) NodePart(gov.sandia.n2a.ui.eq.tree.NodePart) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Aggregations

PanelEquationTree (gov.sandia.n2a.ui.eq.PanelEquationTree)31 FilteredTreeModel (gov.sandia.n2a.ui.eq.FilteredTreeModel)29 TreeNode (javax.swing.tree.TreeNode)28 MPart (gov.sandia.n2a.eqset.MPart)25 NodeBase (gov.sandia.n2a.ui.eq.tree.NodeBase)24 NodePart (gov.sandia.n2a.ui.eq.tree.NodePart)19 CannotRedoException (javax.swing.undo.CannotRedoException)18 TreePath (javax.swing.tree.TreePath)13 CannotUndoException (javax.swing.undo.CannotUndoException)13 NodeVariable (gov.sandia.n2a.ui.eq.tree.NodeVariable)12 PanelEquations (gov.sandia.n2a.ui.eq.PanelEquations)11 PanelEquationGraph (gov.sandia.n2a.ui.eq.PanelEquationGraph)9 NodeContainer (gov.sandia.n2a.ui.eq.tree.NodeContainer)7 MNode (gov.sandia.n2a.db.MNode)6 NodeAnnotations (gov.sandia.n2a.ui.eq.tree.NodeAnnotations)5 JTree (javax.swing.JTree)4 Variable (gov.sandia.n2a.eqset.Variable)3 NodeAnnotation (gov.sandia.n2a.ui.eq.tree.NodeAnnotation)3 NodeEquation (gov.sandia.n2a.ui.eq.tree.NodeEquation)3 EquationSet (gov.sandia.n2a.eqset.EquationSet)2