Search in sources :

Example 1 with NodeEquation

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

the class ChangeEquation method apply.

public static void apply(List<String> path, String nameBefore, String nameAfter, String combinerAfter, String valueAfter) {
    NodeBase parent = NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotRedoException();
    NodeBase nodeBefore = parent.child(nameBefore);
    if (nodeBefore == null)
        throw new CannotRedoException();
    PanelModel mep = PanelModel.instance;
    JTree tree = mep.panelEquations.tree;
    FilteredTreeModel model = (FilteredTreeModel) tree.getModel();
    FontMetrics fm = nodeBefore.getFontMetrics(tree);
    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(nameAfter, valueAfter);
        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.filterLevel))
                model.nodeChanged(nodeBefore);
            else
                parent.hide(nodeBefore, model, true);
        }
    }
    if (parent.getChildCount() > 0) {
        NodeBase firstChild = (NodeBase) parent.getChildAt(0);
        if (firstChild.needsInitTabs())
            firstChild.initTabs(fm);
    }
    if (!parent.source.get().equals(combinerAfter)) {
        parent.source.set(combinerAfter);
        parent.updateColumnWidths(fm);
        NodeBase grandparent = (NodeBase) parent.getParent();
        grandparent.updateTabStops(fm);
        grandparent.allNodesChanged(model);
    }
    nodeAfter.updateColumnWidths(fm);
    parent.updateTabStops(fm);
    parent.allNodesChanged(model);
    mep.panelEquations.updateVisibility(nodeAfter.getPath());
}
Also used : NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) PanelModel(gov.sandia.n2a.ui.eq.PanelModel) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) JTree(javax.swing.JTree) MPart(gov.sandia.n2a.eqset.MPart) FontMetrics(java.awt.FontMetrics) CannotRedoException(javax.swing.undo.CannotRedoException) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Example 2 with NodeEquation

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

the class PanelEquationTree method updateHighlights.

// For now, this is fast enough to run on EDT, but larger models could bog down the UI.
// TODO: run this on a separate thread, if the need arises
public void updateHighlights(NodeBase node, String name) {
    // TODO: organize this code better, so that name is only stripped once.
    name = Variable.stripContextPrefix(name);
    int count = node.getChildCount();
    for (int i = 0; i < count; i++) {
        NodeBase n = (NodeBase) node.getChildAt(i);
        if (!n.visible())
            continue;
        boolean needsRepaint = false;
        if (n instanceof NodePart) {
            updateHighlights(n, name);
        } else if (n instanceof NodeVariable) {
            needsRepaint = ((NodeVariable) n).findHighlights(name);
            updateHighlights(n, name);
        } else if (n instanceof NodeEquation) {
            needsRepaint = ((NodeEquation) n).findHighlights(name);
        }
        if (!needsRepaint)
            continue;
        TreePath path = new TreePath(n.getPath());
        Rectangle pathBounds = tree.getPathBounds(path);
        if (pathBounds != null)
            tree.repaint(pathBounds);
    }
}
Also used : NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) TreePath(javax.swing.tree.TreePath) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) Rectangle(java.awt.Rectangle) NodePart(gov.sandia.n2a.ui.eq.tree.NodePart)

Example 3 with NodeEquation

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

the class PanelEquationTree method deleteSelected.

public void deleteSelected() {
    if (container.locked)
        return;
    // Collect and convert selection.
    TreePath[] paths = tree.getSelectionPaths();
    if (paths == null)
        return;
    TreePath leadPath = tree.getLeadSelectionPath();
    List<NodeBase> selection = new ArrayList<NodeBase>();
    for (TreePath path : paths) selection.add((NodeBase) path.getLastPathComponent());
    NodeBase leadNode = null;
    if (leadPath != null)
        leadNode = (NodeBase) leadPath.getLastPathComponent();
    // Pre-process selection to enforce constraints.
    // Detect if all equations under a variable are deleted. If so, ensure that the variable is marked for deletion.
    Map<NodeVariable, List<NodeEquation>> equations = new HashMap<NodeVariable, List<NodeEquation>>();
    for (NodeBase n : selection) {
        if (!(n instanceof NodeEquation))
            continue;
        NodeVariable v = (NodeVariable) n.getParent();
        List<NodeEquation> e = equations.get(v);
        if (e == null) {
            e = new ArrayList<NodeEquation>();
            equations.put(v, e);
        }
        e.add((NodeEquation) n);
    }
    for (NodeVariable v : equations.keySet()) {
        int count = 0;
        Enumeration<?> children = v.childrenFiltered();
        while (children.hasMoreElements()) {
            if (children.nextElement() instanceof NodeEquation)
                count++;
        }
        if (count == equations.get(v).size() && !selection.contains(v)) {
            // Delete containing variable instead. Equations will be removed from selection later.
            selection.add(v);
            // Needs to actually be in tree selection for parent detection.
            tree.addSelectionPath(new TreePath(v.getPath()));
        }
    }
    // Eliminate any selected node that is beneath some other selected node.
    NodeInherit inherit = null;
    List<NodeBase> filteredSelection = new ArrayList<NodeBase>();
    for (NodeBase n : selection) {
        if (n.hasSelectedAncestor(tree))
            continue;
        filteredSelection.add(n);
        if (n instanceof NodeInherit) {
            if (inherit == null || inherit.getLevel() > n.getLevel())
                inherit = (NodeInherit) n;
        }
    }
    selection = filteredSelection;
    if (// Since deleting $inherit rebuilds whole tree, don't allow any other deletes.
    inherit != null) {
        selection.clear();
        selection.add(inherit);
    } else if (leadNode != null) {
        if (!selection.contains(leadNode) && leadNode instanceof NodeEquation)
            leadNode = (NodeBase) leadNode.getParent();
        if (selection.contains(leadNode)) {
            // Ensure that leadNode is the final edit.
            selection.remove(leadNode);
            selection.add(leadNode);
        } else {
            leadNode = null;
        }
    }
    // Create transaction
    UndoManager um = MainFrame.instance.undoManager;
    CompoundEditView compound = null;
    int count = selection.size();
    boolean multi = count > 1;
    if (multi)
        um.addEdit(compound = new CompoundEditView(CompoundEditView.CLEAR_TREE));
    int i = 0;
    for (NodeBase n : selection) {
        i++;
        Undoable u = n.makeDelete(false);
        if (u == null)
            continue;
        if (u instanceof UndoableView) {
            UndoableView uv = (UndoableView) u;
            uv.setMulti(multi);
            if (multi && i == count)
                uv.setMultiLast(true);
        }
        if (multi && i == count)
            compound.leadPath = n.getKeyPath();
        um.apply(u);
    }
    um.endCompoundEdit();
}
Also used : Undoable(gov.sandia.n2a.ui.Undoable) NodeInherit(gov.sandia.n2a.ui.eq.tree.NodeInherit) HashMap(java.util.HashMap) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) ArrayList(java.util.ArrayList) NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) TreePath(javax.swing.tree.TreePath) UndoManager(gov.sandia.n2a.ui.UndoManager) UndoableView(gov.sandia.n2a.ui.eq.undo.UndoableView) List(java.util.List) ArrayList(java.util.ArrayList) CompoundEditView(gov.sandia.n2a.ui.eq.undo.CompoundEditView)

Example 4 with NodeEquation

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

the class AddEquation method destroy.

public static void destroy(List<String> path, int equationCount, boolean canceled, String name, String combinerBefore, boolean setSelection) {
    // Retrieve created node
    NodeBase parent = NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotUndoException();
    NodeBase createdNode = parent.child(name);
    PanelEquationTree pet = parent.getTree();
    FilteredTreeModel model = (FilteredTreeModel) pet.tree.getModel();
    TreeNode[] createdPath = createdNode.getPath();
    int index = parent.getIndexFiltered(createdNode);
    if (canceled)
        index--;
    // Update database
    MPart mparent = parent.source;
    mparent.clear(name);
    boolean parentChanged = false;
    if (!mparent.get().equals(combinerBefore)) {
        // This value may be replaced below if we switch back to single-line.
        mparent.set(combinerBefore);
        parentChanged = true;
    }
    if (// There is no overridden value, so this node goes away completely.
    mparent.child(name) == null) {
        model.removeNodeFromParent(createdNode);
        if (// The node used to be single-line, so fold the last equation back into it.
        equationCount == 0) {
            // The one remaining equation.
            NodeEquation lastEquation = null;
            // unfiltered
            Enumeration<?> i = parent.children();
            while (i.hasMoreElements()) {
                Object o = i.nextElement();
                if (o instanceof NodeEquation) {
                    lastEquation = (NodeEquation) o;
                    break;
                }
            }
            String lastCondition = lastEquation.source.key();
            String lastExpression = lastEquation.source.get();
            mparent.clear(lastCondition);
            if (lastCondition.equals("@"))
                mparent.set(combinerBefore + lastExpression);
            else
                mparent.set(combinerBefore + lastExpression + lastCondition);
            parentChanged = true;
            model.removeNodeFromParent(lastEquation);
        }
    } else // Just exposed an overridden value, so update.
    {
        createdNode.setUserObject();
    }
    if (// Update tabs among this variable's siblings
    parentChanged) {
        parent.setUserObject();
        NodeBase grandparent = (NodeBase) parent.getParent();
        grandparent.invalidateColumns(model);
    }
    parent.invalidateColumns(null);
    pet.updateOrder(createdPath);
    pet.updateVisibility(createdPath, index, setSelection);
    parent.allNodesChanged(model);
    pet.animate();
}
Also used : MPart(gov.sandia.n2a.eqset.MPart) NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) TreeNode(javax.swing.tree.TreeNode) CannotUndoException(javax.swing.undo.CannotUndoException) PanelEquationTree(gov.sandia.n2a.ui.eq.PanelEquationTree) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Example 5 with NodeEquation

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

the class AddEquation method create.

public static NodeBase create(List<String> path, int equationCount, int index, String name, String combinerAfter, String value) {
    NodeBase parent = NodeBase.locateNode(path);
    if (parent == null)
        throw new CannotRedoException();
    PanelModel mep = PanelModel.instance;
    JTree tree = mep.panelEquations.tree;
    FilteredTreeModel model = (FilteredTreeModel) tree.getModel();
    // Update the database
    String parentValueBefore = parent.source.get();
    Variable.ParsedValue parentPiecesBefore = new Variable.ParsedValue(parentValueBefore);
    // The minimum number of equations is 2. There should never be exactly 1 equation, because that is single-line form, which should have no child equations at all.
    if (// We are about to switch from single-line form to multi-conditional, so make a tree node for the existing equation.
    equationCount == 0) {
        MPart equation = (MPart) parent.source.set("@" + parentPiecesBefore.condition, parentPiecesBefore.expression);
        model.insertNodeIntoUnfiltered(new NodeEquation(equation), parent, 0);
    }
    MPart createdPart = (MPart) parent.source.set(name, value == null ? "0" : value);
    boolean parentChanged = false;
    if (!combinerAfter.equals(parentValueBefore)) {
        parent.source.set(combinerAfter);
        parentChanged = true;
    }
    // Update the GUI
    NodeBase createdNode = parent.child(name);
    boolean alreadyExists = createdNode != null;
    if (!alreadyExists)
        createdNode = new NodeEquation(createdPart);
    FontMetrics fm = createdNode.getFontMetrics(tree);
    if (parent.getChildCount() > 0) {
        NodeBase firstChild = (NodeBase) parent.getChildAt(0);
        if (firstChild.needsInitTabs())
            firstChild.initTabs(fm);
    }
    if (value == null)
        createdNode.setUserObject("");
    // preempt initialization
    createdNode.updateColumnWidths(fm);
    if (!alreadyExists)
        model.insertNodeIntoUnfiltered(createdNode, parent, index);
    if (parentChanged) {
        parent.updateColumnWidths(fm);
        NodeBase grandparent = (NodeBase) parent.getParent();
        grandparent.updateTabStops(fm);
        grandparent.allNodesChanged(model);
    }
    if (// create was merged with change name/value
    value != null) {
        parent.updateTabStops(fm);
        parent.allNodesChanged(model);
        mep.panelEquations.updateVisibility(createdNode.getPath());
    }
    return createdNode;
}
Also used : MPart(gov.sandia.n2a.eqset.MPart) Variable(gov.sandia.n2a.eqset.Variable) NodeVariable(gov.sandia.n2a.ui.eq.tree.NodeVariable) CannotRedoException(javax.swing.undo.CannotRedoException) NodeBase(gov.sandia.n2a.ui.eq.tree.NodeBase) PanelModel(gov.sandia.n2a.ui.eq.PanelModel) NodeEquation(gov.sandia.n2a.ui.eq.tree.NodeEquation) JTree(javax.swing.JTree) FontMetrics(java.awt.FontMetrics) FilteredTreeModel(gov.sandia.n2a.ui.eq.FilteredTreeModel)

Aggregations

NodeBase (gov.sandia.n2a.ui.eq.tree.NodeBase)7 NodeEquation (gov.sandia.n2a.ui.eq.tree.NodeEquation)7 MPart (gov.sandia.n2a.eqset.MPart)5 FilteredTreeModel (gov.sandia.n2a.ui.eq.FilteredTreeModel)5 NodeVariable (gov.sandia.n2a.ui.eq.tree.NodeVariable)4 TreePath (javax.swing.tree.TreePath)4 CannotRedoException (javax.swing.undo.CannotRedoException)4 PanelEquationTree (gov.sandia.n2a.ui.eq.PanelEquationTree)3 TreeNode (javax.swing.tree.TreeNode)3 Variable (gov.sandia.n2a.eqset.Variable)2 PanelModel (gov.sandia.n2a.ui.eq.PanelModel)2 FontMetrics (java.awt.FontMetrics)2 JTree (javax.swing.JTree)2 UndoManager (gov.sandia.n2a.ui.UndoManager)1 Undoable (gov.sandia.n2a.ui.Undoable)1 NodeInherit (gov.sandia.n2a.ui.eq.tree.NodeInherit)1 NodePart (gov.sandia.n2a.ui.eq.tree.NodePart)1 CompoundEditView (gov.sandia.n2a.ui.eq.undo.CompoundEditView)1 UndoableView (gov.sandia.n2a.ui.eq.undo.UndoableView)1 Rectangle (java.awt.Rectangle)1