use of ini.trakem2.tree.TemplateTree in project TrakEM2 by trakem2.
the class DefaultTreeTransferHandler method canPerformAction.
public boolean canPerformAction(DNDTree target, DefaultMutableTreeNode dragged_node, int action, Point location) {
// prevent drags from non-tree components
if (null == dragged_node)
return false;
// Can't drop onto a TemplateTree
if (target instanceof TemplateTree) {
return false;
}
// Can't drag a node that contains a Project!
if (dragged_node.getUserObject() instanceof ProjectThing && ((ProjectThing) dragged_node.getUserObject()).getObject() instanceof Project) {
return false;
}
// Can't drag basic object nodes from a template tree RECONSIDERED, I like it even if it looks inconsistent (but types are types!)
/*
if (dragged_node.getUserObject() instanceof TemplateThing && project.isBasicType(((Thing)dragged_node.getUserObject()).getType())) {
return false;
}
*/
// else, the target has to be not null
TreePath pathTarget = target.getPathForLocation(location.x, location.y);
if (pathTarget == null) {
target.setSelectionPath(null);
return false;
}
/* // debug
if (action == DnDConstants.ACTION_COPY) {
Utils.log("can drop: Action copy");
} else if (action == DnDConstants.ACTION_MOVE) {
Utils.log("can drop: Action move");
} else {
Utils.log("can drop: Unexpected action: " + action);
}
*/
target.setSelectionPath(pathTarget);
DefaultMutableTreeNode parent_node = (DefaultMutableTreeNode) pathTarget.getLastPathComponent();
// can be a Thing or an Attribute
Object parent_ob = parent_node.getUserObject();
Thing child_thing = (Thing) dragged_node.getUserObject();
if (DnDConstants.ACTION_MOVE == action || DnDConstants.ACTION_COPY == action) {
if (parent_ob instanceof ProjectThing) {
ProjectThing parent_thing = (ProjectThing) parent_ob;
// check if it's allowed to give to this parent such a child:
if (!parent_thing.uniquePathExists(child_thing.getType()) && !parent_thing.canHaveAsChild(child_thing)) {
// Utils.log("Not possible.");
return false;
}
// - the leaf that is going to be dropped into itself or any of its descendants.
if (parent_node == dragged_node.getParent() || dragged_node.isNodeDescendant(parent_node)) {
// Utils.log("preventing dragging onto itself or any of the self children.");
return false;
} else {
return true;
}
}
}
// default:
return false;
}
use of ini.trakem2.tree.TemplateTree in project TrakEM2 by trakem2.
the class Project method createNewProject.
private static Project createNewProject(Loader loader, boolean ask_for_template, TemplateThing template_root, boolean clone_ids) {
Project project = new Project(loader);
// Utils.log2("ask_for_template: " + ask_for_template);
if (ask_for_template)
template_root = project.loader.askForXMLTemplate(project);
if (null == template_root) {
template_root = new TemplateThing("anything");
} else if (clone_ids) {
// the given template_root belongs to another project from which we are cloning
template_root = template_root.clone(project, true);
}
// else, use the given template_root as is.
// create tree
project.template_tree = new TemplateTree(project, template_root);
project.root_tt = template_root;
// collect unique TemplateThing instances
synchronized (project.ht_unique_tt) {
project.ht_unique_tt.clear();
project.ht_unique_tt.putAll(template_root.getUniqueTypes(new HashMap<String, TemplateThing>()));
}
// add all TemplateThing objects to the database, recursively
if (!clone_ids)
template_root.addToDatabase(project);
// else already done when cloning the root_tt
// create a non-database bound template for the project Thing
TemplateThing project_template = new TemplateThing("project");
project.ht_unique_tt.put("project", project_template);
project_template.addChild(template_root);
// create the project Thing, to be root of the whole project thing tree
try {
project.root_pt = new ProjectThing(project_template, project, project);
} catch (Exception e) {
IJError.print(e);
}
// create the user objects tree
project.project_tree = new ProjectTree(project, project.root_pt);
// create the layer's tree
project.createLayerTemplates();
// initialized with default values, and null parent to signal 'root'
project.layer_set = new LayerSet(project, "Top Level", 0, 0, null, 2048, 2048);
try {
project.root_lt = new LayerThing(Project.layer_set_template, project, project.layer_set);
project.layer_tree = new LayerTree(project, project.root_lt);
} catch (Exception e) {
project.remove();
IJError.print(e);
}
// create the project control window, containing the trees in a double JSplitPane
// beware that this call is asynchronous, dispatched by the SwingUtilities.invokeLater to avoid havok with Swing components.
ControlWindow.add(project, project.template_tree, project.project_tree, project.layer_tree);
// register
al_open_projects.add(project);
return project;
}
use of ini.trakem2.tree.TemplateTree in project TrakEM2 by trakem2.
the class Project method openDBProject.
/**
* Open a TrakEM2 project from the database. Queries the database for existing projects and if more than one, asks which one to open.
*/
public static Project openDBProject() {
if (Utils.wrongImageJVersion())
return null;
DBLoader loader = new DBLoader();
if (!loader.isReady())
return null;
// check connection
if (!loader.isConnected()) {
Utils.showMessage("Can't talk to database.");
loader.destroy();
return null;
}
// query the database for existing projects
Project[] projects = loader.getProjects();
if (null == projects) {
Utils.showMessage("Can't talk to database (null list of projects).");
loader.destroy();
return null;
}
Project project = null;
if (0 == projects.length) {
Utils.showMessage("No projects in this database.");
loader.destroy();
return null;
} else if (1 == projects.length) {
project = projects[0];
} else {
// ask to choose one
String[] titles = new String[projects.length];
for (int i = 0; i < projects.length; i++) {
titles[i] = projects[i].title;
}
GenericDialog gd = new GenericDialog("Choose");
gd.addMessage("Choose project to open:");
gd.addChoice("project: ", titles, titles[titles.length - 1]);
gd.showDialog();
if (gd.wasCanceled()) {
loader.destroy();
return null;
}
project = projects[gd.getNextChoiceIndex()];
}
// check if the selected project is open already
for (final Project p : al_open_projects) {
if (loader.isIdenticalProjectSource(p.loader) && p.id == project.id && p.title.equals(project.title)) {
Utils.showMessage("A project with title " + p.title + " and id " + p.id + " from the same database is already open.");
loader.destroy();
return null;
}
}
// now, open the selected project
// assign loader
project.loader = loader;
// grab the XML template
TemplateThing template_root = loader.getTemplateRoot(project);
if (null == template_root) {
Utils.showMessage("Failed to retrieve the template tree.");
project.destroy();
return null;
}
project.template_tree = new TemplateTree(project, template_root);
synchronized (project.ht_unique_tt) {
project.ht_unique_tt.clear();
project.ht_unique_tt.putAll(template_root.getUniqueTypes(new HashMap<String, TemplateThing>()));
}
// create the project Thing, to be root of the whole user Thing tree (and load all its objects)
// to collect all created displayables, and then reassign to the proper layers.
HashMap<Long, Displayable> hs_d = new HashMap<Long, Displayable>();
try {
// create a template for the project Thing
TemplateThing project_template = new TemplateThing("project");
project.ht_unique_tt.put("project", project_template);
project_template.addChild(template_root);
project.root_pt = loader.getRootProjectThing(project, template_root, project_template, hs_d);
// restore parent/child and attribute ownership and values (now that all Things exist)
project.root_pt.setup();
} catch (Exception e) {
Utils.showMessage("Failed to retrieve the Thing tree for the project.");
IJError.print(e);
project.destroy();
return null;
}
// create the user objects tree
project.project_tree = new ProjectTree(project, project.root_pt);
// restore the expanded state of each node
loader.restoreNodesExpandedState(project);
// create the layers templates
project.createLayerTemplates();
// fetch the root layer thing and the root layer set (will load all layers and layer sets, with minimal contents of patches; gets the basic objects -profile, pipe, etc.- from the project.root_pt). Will open all existing displays for each layer.
LayerThing root_layer_thing = null;
try {
root_layer_thing = loader.getRootLayerThing(project, project.root_pt, Project.layer_set_template, Project.layer_template);
if (null == root_layer_thing) {
project.destroy();
Utils.showMessage("Could not retrieve the root layer thing.");
return null;
}
// set the child/parent relationships now that everything exists
root_layer_thing.setup();
project.layer_set = (LayerSet) root_layer_thing.getObject();
if (null == project.layer_set) {
project.destroy();
Utils.showMessage("Could not retrieve the root layer set.");
return null;
}
// set the active layer to each ZDisplayable
project.layer_set.setup();
// debug:
// Utils.log2("$$$ root_lt: " + root_layer_thing + " ob: " + root_layer_thing.getObject().getClass().getName() + "\n children: " + ((LayerSet)root_layer_thing.getObject()).getLayers().size());
project.layer_tree = new LayerTree(project, root_layer_thing);
project.root_lt = root_layer_thing;
} catch (Exception e) {
Utils.showMessage("Failed to retrieve the Layer tree for the project.");
IJError.print(e);
project.destroy();
return null;
}
// if all when well, register as open:
al_open_projects.add(project);
// create the project control window, containing the trees in a double JSplitPane
ControlWindow.add(project, project.template_tree, project.project_tree, project.layer_tree);
// now open the displays that were stored for later, if any:
Display.openLater();
return project;
}
use of ini.trakem2.tree.TemplateTree in project TrakEM2 by trakem2.
the class Project method createSubproject.
/**
* Create a new subproject for the given layer range and ROI.
* Create a new Project using the given project as template. This means the DTD of the given project is copied, as well as the storage and mipmaps folders; everything else is empty in the new project.
*/
public Project createSubproject(final Rectangle roi, final Layer first, final Layer last, final boolean ignore_hidden_patches) {
try {
// The order matters.
final Project pr = new Project(new FSLoader(this.getLoader().getStorageFolder()));
pr.id = this.id;
// copy properties
pr.title = this.title;
pr.ht_props.putAll(this.ht_props);
// copy template
pr.root_tt = this.root_tt.clone(pr, true);
pr.template_tree = new TemplateTree(pr, pr.root_tt);
synchronized (pr.ht_unique_tt) {
pr.ht_unique_tt.clear();
pr.ht_unique_tt.putAll(root_tt.getUniqueTypes(new HashMap<String, TemplateThing>()));
}
TemplateThing project_template = new TemplateThing("project");
project_template.addChild(pr.root_tt);
pr.ht_unique_tt.put("project", project_template);
// create the layers templates
pr.createLayerTemplates();
// copy LayerSet and all involved Displayable objects
// (A two-step process to provide the layer_set pointer and all Layer pointers to the ZDisplayable to copy and crop.)
pr.layer_set = (LayerSet) this.layer_set.clone(pr, first, last, roi, false, true, ignore_hidden_patches);
LayerSet.cloneInto(this.layer_set, first, last, pr, pr.layer_set, roi, true);
// create layer tree
pr.root_lt = new LayerThing(Project.layer_set_template, pr, pr.layer_set);
pr.layer_tree = new LayerTree(pr, pr.root_lt);
// add layer nodes to the layer tree (solving chicken-and-egg problem)
pr.layer_set.updateLayerTree();
// copy project tree
pr.root_pt = this.root_pt.subclone(pr);
pr.project_tree = new ProjectTree(pr, pr.root_pt);
// not copying node expanded state.
// register
al_open_projects.add(pr);
// add to gui:
ControlWindow.add(pr, pr.template_tree, pr.project_tree, pr.layer_tree);
// Above, the id of each object is preserved from this project into the subproject.
// The abstract structure should be copied in full regardless, without the basic objects
// included if they intersect the roi.
// Regenerate mipmaps (blocks GUI from interaction other than navigation)
pr.loader.regenerateMipMaps(pr.layer_set.getDisplayables(Patch.class));
pr.restartAutosaving();
return pr;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
use of ini.trakem2.tree.TemplateTree in project TrakEM2 by trakem2.
the class Project method openFSProject.
/**
* Opens a project from an .xml file. If the path is null it'll be asked for.
* Only one project may be opened at a time.
*/
@SuppressWarnings("unchecked")
public static synchronized Project openFSProject(final String path, final boolean open_displays) {
if (Utils.wrongImageJVersion())
return null;
final FSLoader loader = new FSLoader();
final Object[] data = loader.openFSProject(path, open_displays);
if (null == data) {
loader.destroy();
return null;
}
final TemplateThing root_tt = (TemplateThing) data[0];
final ProjectThing root_pt = (ProjectThing) data[1];
final LayerThing root_lt = (LayerThing) data[2];
final HashMap<ProjectThing, Boolean> ht_pt_expanded = (HashMap<ProjectThing, Boolean>) data[3];
final Project project = (Project) root_pt.getObject();
project.createLayerTemplates();
project.template_tree = new TemplateTree(project, root_tt);
project.root_tt = root_tt;
project.root_pt = root_pt;
project.project_tree = new ProjectTree(project, project.root_pt);
project.layer_tree = new LayerTree(project, root_lt);
project.root_lt = root_lt;
project.layer_set = (LayerSet) root_lt.getObject();
// if all when well, register as open:
al_open_projects.add(project);
// create the project control window, containing the trees in a double JSplitPane
ControlWindow.add(project, project.template_tree, project.project_tree, project.layer_tree);
// set ProjectThing nodes expanded state, now that the trees exist
try {
java.lang.reflect.Field f = JTree.class.getDeclaredField("expandedState");
f.setAccessible(true);
Hashtable<Object, Object> ht_exp = (Hashtable<Object, Object>) f.get(project.project_tree);
for (Map.Entry<ProjectThing, Boolean> entry : ht_pt_expanded.entrySet()) {
ProjectThing pt = entry.getKey();
Boolean expanded = entry.getValue();
// project.project_tree.expandPath(new TreePath(project.project_tree.findNode(pt, project.project_tree).getPath()));
// WARNING the above is wrong in that it will expand the whole thing, not just set the state of the node!!
// So the ONLY way to do it is to start from the child-most leafs of the tree, and apply the expanding to them upward. This is RIDICULOUS, how can it be so broken
// so, hackerous:
DefaultMutableTreeNode nd = DNDTree.findNode(pt, project.project_tree);
// else Utils.log2("path: " + new TreePath(nd.getPath()));
if (null == nd) {
Utils.log2("Can't find node for " + pt);
} else {
ht_exp.put(new TreePath(nd.getPath()), expanded);
}
}
// very important!!
project.project_tree.updateUILater();
} catch (Exception e) {
IJError.print(e);
}
// open any stored displays
if (open_displays) {
final Bureaucrat burro = Display.openLater();
if (null != burro) {
final Runnable ru = new Runnable() {
public void run() {
// wait until the Bureaucrat finishes
try {
burro.join();
} catch (InterruptedException ie) {
}
// restore to non-changes (crude, but works)
project.loader.setChanged(false);
Utils.log2("C set to false");
}
};
new Thread() {
public void run() {
setPriority(Thread.NORM_PRIORITY);
// avoiding "can't call invokeAndWait from the EventDispatch thread" error
try {
javax.swing.SwingUtilities.invokeAndWait(ru);
} catch (Exception e) {
Utils.log2("ERROR: " + e);
}
}
}.start();
// SO: WAIT TILL THE END OF TIME!
new Thread() {
public void run() {
try {
// ah, the pain in my veins. I can't take this shitty setup anymore.
Thread.sleep(4000);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
project.getLoader().setChanged(false);
Utils.log2("D set to false");
}
});
// repainting to fix gross errors in tree rendering
project.getTemplateTree().updateUILater();
// idem
project.getProjectTree().updateUILater();
} catch (Exception ie) {
}
}
}.start();
} else {
// help the helpless users
Display.createDisplay(project, project.layer_set.getLayer(0));
}
}
project.restartAutosaving();
return project;
}
Aggregations