use of gov.sandia.n2a.ui.eq.PanelEquationGraph in project n2a by frothga.
the class AddInherit method destroy.
public static void destroy(List<String> path, boolean canceled) {
NodePart parent = (NodePart) NodeBase.locateNode(path);
if (parent == null)
throw new CannotUndoException();
NodePart grandparent = (NodePart) parent.getTrueParent();
NodeBase node = parent.child("$inherit");
TreeNode[] nodePath = node.getPath();
int index = parent.getIndexFiltered(node);
if (canceled)
index--;
PanelEquations pe = PanelModel.instance.panelEquations;
PanelEquationTree pet = parent.getTree();
FilteredTreeModel model = (FilteredTreeModel) pet.tree.getModel();
PanelEquationGraph peg = pe.panelEquationGraph;
MPart mparent = parent.source;
// Complex restructuring happens here.
mparent.clear("$inherit");
// Handles all cases (complete deletion or exposed hidden node)
parent.build();
if (grandparent == null)
parent.findConnections();
else
grandparent.findConnections();
parent.rebuildPins();
parent.filter();
if (parent == pe.part) {
// safely disconnects old nodes, even though parent has been rebuilt with new nodes
peg.reloadPart();
// Ensure that parts are not visible in parent panel.
parent.filter();
}
// Presumably, part node is still visible. Is there any harm in doing this if it is not?
model.nodeStructureChanged(parent);
pet.updateOrder(nodePath);
pet.updateVisibility(nodePath, index);
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();
}
}
use of gov.sandia.n2a.ui.eq.PanelEquationGraph in project n2a by frothga.
the class AddPart method create.
public static NodeBase create(List<String> path, int index, String name, MNode newPart, boolean nameIsGenerated, boolean multi, boolean multiLast, boolean multiShared, boolean touchesPin) {
NodePart parent = (NodePart) NodeBase.locateNode(path);
if (parent == null)
throw new CannotRedoException();
NodeBase n = parent.child(name);
// Should be blocked by GUI constraints, but this defends against ill-formed model on clipboard.
if (n != null && !(n instanceof NodePart))
throw new CannotUndoException();
NodePart createdNode = (NodePart) n;
// Update database
MPart createdPart = (MPart) parent.source.childOrCreate(name);
createdPart.merge(newPart);
// Update GUI
PanelEquations pe = PanelModel.instance.panelEquations;
boolean graphParent = parent == pe.part;
PanelEquationTree pet = graphParent ? null : parent.getTree();
FilteredTreeModel model = null;
if (pet != null)
model = (FilteredTreeModel) pet.tree.getModel();
PanelEquationGraph peg = pe.panelEquationGraph;
boolean addGraphNode = false;
if (createdNode == null) {
addGraphNode = true;
createdNode = new NodePart(createdPart);
createdNode.hide = graphParent;
if (index < 0)
index = parent.getChildCount();
if (model == null)
FilteredTreeModel.insertNodeIntoUnfilteredStatic(createdNode, parent, index);
else
model.insertNodeIntoUnfiltered(createdNode, parent, index);
}
createdNode.build();
// Other nodes besides immediate siblings can also refer to us, so to be strictly correct, should run findConnectins() on root of tree.
parent.findConnections();
createdNode.rebuildPins();
createdNode.filter();
// pure create, so about to go into edit mode. This should only happen on first application of the create action, and should only be possible if visibility is already correct.
if (nameIsGenerated)
createdNode.setUserObject("");
TreeNode[] createdPath = createdNode.getPath();
if (pet == null) {
if (!nameIsGenerated)
PanelEquationTree.updateOrder(null, createdPath);
PanelEquationTree.updateVisibility(null, createdPath, -2, false);
} else {
if (!nameIsGenerated)
pet.updateOrder(createdPath);
pet.updateVisibility(createdPath, -2, !multi);
if (multi)
pet.tree.addSelectionPath(new TreePath(createdPath));
pet.animate();
}
if (graphParent) {
if (addGraphNode) {
peg.addPart(createdNode);
} else // Existing graph node; content needs to be restructured.
{
PanelEquationTree subpet = createdNode.getTree();
if (subpet != null) {
FilteredTreeModel submodel = (FilteredTreeModel) subpet.tree.getModel();
submodel.nodeStructureChanged(createdNode);
subpet.animate();
}
}
createdNode.hide = false;
if (multi) {
if (!multiShared)
createdNode.graph.setSelected(true);
} else {
peg.clearSelection();
createdNode.graph.takeFocusOnTitle();
}
}
if (graphParent || touchesPin) {
if (!multi || multiLast) {
peg.updatePins();
peg.reconnect();
peg.repaint();
}
}
return createdNode;
}
use of gov.sandia.n2a.ui.eq.PanelEquationGraph 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);
}
}
use of gov.sandia.n2a.ui.eq.PanelEquationGraph 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();
}
}
use of gov.sandia.n2a.ui.eq.PanelEquationGraph in project n2a by frothga.
the class ChangeVariableToInherit method redo.
public void redo() {
super.redo();
NodePart parent = (NodePart) NodeBase.locateNode(path);
if (parent == null)
throw new CannotRedoException();
NodePart grandparent = (NodePart) parent.getTrueParent();
// Update database
MPart mparent = parent.source;
mparent.clear(treeBefore.key());
mparent.set(valueAfter, "$inherit");
// Update GUI
PanelEquations pe = PanelModel.instance.panelEquations;
PanelEquationTree pet = parent.getTree();
FilteredTreeModel model = (FilteredTreeModel) pet.tree.getModel();
PanelEquationGraph peg = pe.panelEquationGraph;
parent.build();
if (grandparent == null)
parent.findConnections();
else
grandparent.findConnections();
parent.rebuildPins();
parent.filter();
if (parent == pe.part) {
peg.reloadPart();
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();
}
}
Aggregations