use of gov.sandia.n2a.ui.eq.tree.NodeAnnotations in project n2a by frothga.
the class ChangeAnnotations method apply.
public void apply(MNode add, MNode remove) {
NodeBase parent = NodeBase.locateNode(path);
if (parent == null)
throw new CannotUndoException();
PanelEquationTree pet = parent.getTree();
FilteredTreeModel model = null;
StoredPath sp = null;
if (pet != null) {
model = (FilteredTreeModel) pet.tree.getModel();
sp = new StoredPath(pet.tree);
}
// The immediate container of metadata items in the tree.
NodeContainer metadataNode;
// The $metadata node under which all changes are made.
MNode metadataSource = null;
if (parent instanceof NodeVariable) {
metadataNode = (NodeContainer) parent;
metadataSource = metadataNode.source.child("$metadata");
} else // NodePart is the default case
{
metadataNode = (NodeContainer) parent.child("$metadata");
if (metadataNode != null)
metadataSource = metadataNode.source;
}
boolean needBuild = true;
if (// This is an undo, and $metadata did not exist before, so remove it.
add == null) {
// We can safely assume that metadataSource is non-null, since we only get here during an undo.
metadataSource.parent().clear("$metadata");
if (parent instanceof NodePart) {
if (model == null)
FilteredTreeModel.removeNodeFromParentStatic(metadataNode);
else
model.removeNodeFromParent(metadataNode);
needBuild = false;
}
} else // Update $metadata node. Create if it doesn't exist.
{
if (metadataSource == null)
metadataSource = parent.source.childOrCreate("$metadata");
if (// only happens when parent is NodePart
metadataNode == null) {
metadataNode = new NodeAnnotations((MPart) metadataSource);
if (model == null)
FilteredTreeModel.insertNodeIntoUnfilteredStatic(metadataNode, parent, index);
else
model.insertNodeIntoUnfiltered(metadataNode, parent, index);
}
if (remove != null)
metadataSource.uniqueNodes(remove);
metadataSource.merge(add);
}
if (needBuild) {
List<String> expanded = null;
if (model != null)
expanded = AddAnnotation.saveExpandedNodes(pet.tree, metadataNode);
metadataNode.build();
metadataNode.filter();
if (model != null && metadataNode.visible()) {
model.nodeStructureChanged(metadataNode);
AddAnnotation.restoreExpandedNodes(pet.tree, metadataNode, expanded);
}
}
if (pet != null) {
TreeNode[] path = metadataNode.getPath();
PanelEquationTree.updateVisibility(pet, path, -2, !multi && !graph);
if (// We only care about viewing metadata tree if edit happened in the tree, not graphically.
!graph) {
if (multi)
pet.tree.addSelectionPath(new TreePath(path));
else
// This forces focus back to original location.
sp.restore(pet.tree, true);
}
pet.animate();
}
if (multi && parent instanceof NodePart) {
NodePart np = (NodePart) parent;
if (np.graph != null)
np.graph.setSelected(true);
}
AddAnnotation.update(parent, touchesPin, touchesCategory);
}
use of gov.sandia.n2a.ui.eq.tree.NodeAnnotations in project n2a by frothga.
the class AddAnnotation method create.
public static NodeBase create(List<String> path, int index, String name, MNode createSubtree, boolean nameIsGenerated, boolean multi, boolean selectVariable, boolean touchesPin, boolean touchesCategory) {
NodeBase parent = NodeBase.locateNode(path);
if (parent == null) {
int last = path.size() - 1;
if (path.get(last).equals("$metadata"))
parent = NodeBase.locateNode(path.subList(0, last));
}
if (parent == null)
throw new CannotRedoException();
// Update database
MPart mparent = parent.source;
if (parent instanceof NodePart || parent instanceof NodeVariable)
mparent = (MPart) mparent.childOrCreate("$metadata");
else if (parent instanceof NodeAnnotation)
mparent = ((NodeAnnotation) parent).folded;
// else parent is a NodeAnnotations, so mparent is $metadata, which can be used directly.
// For a simple add, name has only one path element. However, if a ChangeAnnotation was
// merged into this, then the name may have several path elements.
String[] names = name.split("\\.");
MPart createdPart = (MPart) mparent.childOrCreate(names);
createdPart.merge(createSubtree);
// Update GUI
PanelEquationTree pet = parent.getTree();
FilteredTreeModel model = null;
if (pet != null)
model = (FilteredTreeModel) pet.tree.getModel();
NodeContainer container = (NodeContainer) parent;
if (// If this is a part, then display special block.
parent instanceof NodePart) {
container = (NodeContainer) parent.child("$metadata");
if (container == null) {
container = new NodeAnnotations(mparent);
if (model == null)
FilteredTreeModel.insertNodeIntoUnfilteredStatic(container, parent, index);
else
model.insertNodeIntoUnfiltered(container, parent, index);
// TODO: update order?
index = 0;
}
}
NodeBase createdNode;
if (// pure create, going into edit mode
nameIsGenerated) {
// The given name should be unique, so don't bother checking for an existing node.
createdNode = new NodeAnnotation(createdPart);
// For edit mode. This should only happen on first application of the create action, and should only be possible if visibility is already correct.
createdNode.setUserObject("");
if (model == null)
FilteredTreeModel.insertNodeIntoUnfilteredStatic(createdNode, container, index);
else
model.insertNodeIntoUnfiltered(createdNode, container, index);
} else // create was merged with change name/value
{
List<String> expanded = null;
if (model != null)
expanded = saveExpandedNodes(pet.tree, container);
container.build();
container.filter();
if (model != null && container.visible()) {
model.nodeStructureChanged(container);
restoreExpandedNodes(pet.tree, container, expanded);
}
createdNode = findClosest(container, names);
if (pet != null) {
TreeNode[] parentPath = parent.getPath();
TreeNode[] createdPath = createdNode.getPath();
TreePath createdTreePath = new TreePath(createdPath);
pet.tree.expandPath(createdTreePath);
if (selectVariable)
pet.updateVisibility(parentPath, -2, !multi);
else
pet.updateVisibility(createdPath, -2, !multi);
if (multi) {
if (selectVariable)
pet.tree.addSelectionPath(new TreePath(parentPath));
else
pet.tree.addSelectionPath(createdTreePath);
}
pet.animate();
}
}
update(parent, touchesPin, touchesCategory);
return createdNode;
}
use of gov.sandia.n2a.ui.eq.tree.NodeAnnotations in project n2a by frothga.
the class AddAnnotation method destroy.
public static void destroy(List<String> path, boolean canceled, String name, String prefix, boolean multi, boolean multiLast, boolean selectVariable, boolean touchesPin, boolean touchesCategory) {
// Retrieve created node
NodeContainer parent = (NodeContainer) NodeBase.locateNode(path);
if (parent == null)
throw new CannotUndoException();
NodeBase createdNode = findClosest(parent, name.split("\\."));
if (createdNode == parent)
throw new CannotUndoException();
// Update database
MPart mparent = parent.source;
if (parent instanceof NodeVariable)
mparent = (MPart) mparent.child("$metadata");
else if (parent instanceof NodeAnnotation)
mparent = ((NodeAnnotation) parent).folded;
// else parent is a NodeAnnotations, so mparent is $metadata, which should be used directly.
boolean killBlock = false;
if (!prefix.isEmpty()) {
String[] names = prefix.split("\\.");
mparent.clear(names);
if (mparent.key().equals("$metadata") && mparent.size() == 0) {
mparent.parent().clear("$metadata");
killBlock = true;
}
}
// Update GUI
PanelEquationTree pet = parent.getTree();
FilteredTreeModel model = null;
if (pet != null)
model = (FilteredTreeModel) pet.tree.getModel();
TreeNode[] createdPath = createdNode.getPath();
int index = parent.getIndexFiltered(createdNode);
if (canceled)
index--;
if (// We just emptied $metadata, so remove the node.
killBlock && parent instanceof NodeAnnotations) {
if (model == null)
FilteredTreeModel.removeNodeFromParentStatic(parent);
else
model.removeNodeFromParent(parent);
// No need to update order, because we just destroyed $metadata, where order is stored.
// No need to update tab stops in grandparent, because block nodes don't offer any tab stops.
} else // Rebuild container (variable, metadata block, or annotation)
{
List<String> expanded = null;
if (model != null)
expanded = saveExpandedNodes(pet.tree, parent);
parent.build();
parent.filter();
if (model != null && parent.visible()) {
model.nodeStructureChanged(parent);
restoreExpandedNodes(pet.tree, parent, expanded);
}
}
if (pet != null) {
TreeNode[] parentPath = parent.getPath();
if (selectVariable)
pet.updateVisibility(parentPath, index, !multi);
else
pet.updateVisibility(createdPath, index, !multi || multiLast);
// Assumes nodeAfter is directly under a NodeVariable. Note that effect will be redundant with above when multiLast is true.
if (multi && selectVariable)
pet.tree.addSelectionPath(new TreePath(parentPath));
pet.animate();
}
update(parent, touchesPin, touchesCategory);
}
use of gov.sandia.n2a.ui.eq.tree.NodeAnnotations in project n2a by frothga.
the class ChangeCategory method apply.
public void apply(String key, List<String> selectionBefore, String categoryAfter, List<String> selectionAfter) {
MNode doc = AppData.models.child(key);
if (doc == null)
throw new CannotUndoException();
// Graph focus
PanelSearch ps = PanelModel.instance.panelSearch;
ps.lastSelection = selectionBefore;
ps.takeFocus();
// Update DB, and possibly equation tree.
PanelEquations pe = PanelModel.instance.panelEquations;
if (// direct to db
doc != pe.record) {
doc.set(categoryAfter, "$metadata", "gui", "category");
} else // got through MPart
{
MNode source = pe.root.source;
if (categoryAfter.isEmpty())
source.clear("$metadata", "gui", "category");
else
source.set(categoryAfter, "$metadata", "gui", "category");
PanelEquationTree pet = pe.root.getTree();
FilteredTreeModel model = null;
if (pet != null)
model = (FilteredTreeModel) pet.tree.getModel();
// See ChangeAnnotations for more general code.
// To simplify things, we always rebuild the metadata block, even though that is often overkill.
// For simplicity, assume this exists. DB models should always some metadata, such as "id". It is possible for the $metadata node to be deleted by user, so this is not guaranteed.
NodeAnnotations metadataNode = (NodeAnnotations) pe.root.child("$metadata");
List<String> expanded = null;
if (model != null)
expanded = AddAnnotation.saveExpandedNodes(pet.tree, metadataNode);
metadataNode.build();
metadataNode.filter();
if (model != null && metadataNode.visible()) {
model.nodeStructureChanged(metadataNode);
AddAnnotation.restoreExpandedNodes(pet.tree, metadataNode, expanded);
}
if (pet != null) {
TreeNode[] path = metadataNode.getPath();
pet.updateVisibility(path, -2, false);
pet.animate();
}
}
// Update search panel.
ps.lastSelection = selectionAfter;
// This will apply lastSelection when done.
ps.search();
}
use of gov.sandia.n2a.ui.eq.tree.NodeAnnotations in project n2a by frothga.
the class DeleteAnnotation method withName.
/**
* Constructs an edit action which removes the referenced metadata item from the given part.
* If the metadata item does not exist, then the return value is null.
* This method is a bit imprecise. If the given path appears in a folded child, then
* it is possible that the delete will go further up the tree than the specified path.
* This could damage metadata structures where the parents of the specified node are
* acting as flags merely by their existence.
*/
public static DeleteAnnotation withName(NodePart part, String... names) {
NodeAnnotations metadata = (NodeAnnotations) part.child("$metadata");
if (metadata == null)
return null;
NodeBase target = AddAnnotation.findExact(metadata, true, names);
if (target == null)
return null;
return new DeleteAnnotation((NodeAnnotation) target, false);
}
Aggregations