use of ini.trakem2.Project in project TrakEM2 by trakem2.
the class ProjectTree method actionPerformed.
public void actionPerformed(final ActionEvent ae) {
if (!project.isInputEnabled())
return;
super.dispatcher.exec(new Runnable() {
public void run() {
try {
if (null == selected_node)
return;
final Object ob = selected_node.getUserObject();
if (!(ob instanceof ProjectThing))
return;
final ProjectThing thing = (ProjectThing) ob;
int i_position = 0;
String command = ae.getActionCommand();
final Object obd = thing.getObject();
if (command.startsWith("new ") || command.equals("Duplicate")) {
ProjectThing new_thing = null;
if (command.startsWith("new ")) {
// if it's a Displayable, it will be added to whatever layer is in the front Display
new_thing = thing.createChild(command.substring(4));
} else if (command.equals("Duplicate")) {
// just to keep myself from screwing in the future
if (Project.isBasicType(thing.getType()) && null != thing.getParent()) {
new_thing = ((ProjectThing) thing.getParent()).createClonedChild(thing);
}
// adjust parent
selected_node = (DefaultMutableTreeNode) selected_node.getParent();
}
// add it to the tree
if (null != new_thing) {
DefaultMutableTreeNode new_node = new DefaultMutableTreeNode(new_thing);
((DefaultTreeModel) ProjectTree.this.getModel()).insertNodeInto(new_node, selected_node, i_position);
TreePath treePath = new TreePath(new_node.getPath());
ProjectTree.this.scrollPathToVisible(treePath);
ProjectTree.this.setSelectionPath(treePath);
}
// bring the display to front
if (new_thing.getObject() instanceof Displayable) {
Display.getFront().getFrame().toFront();
}
} else if (command.equals("many...")) {
ArrayList<TemplateThing> children = thing.getTemplate().getChildren();
if (null == children || 0 == children.size())
return;
String[] cn = new String[children.size()];
int i = 0;
for (final TemplateThing child : children) {
cn[i] = child.getType();
i++;
}
GenericDialog gd = new GenericDialog("Add many children");
gd.addNumericField("Amount: ", 1, 0);
gd.addChoice("New child: ", cn, cn[0]);
gd.addCheckbox("Recursive", true);
gd.showDialog();
if (gd.wasCanceled())
return;
int amount = (int) gd.getNextNumber();
if (amount < 1) {
Utils.showMessage("Makes no sense to create less than 1 child!");
return;
}
project.getRootLayerSet().addChangeTreesStep();
final ArrayList<ProjectThing> nc = thing.createChildren(cn[gd.getNextChoiceIndex()], amount, gd.getNextBoolean());
addLeafs(nc, new Runnable() {
public void run() {
project.getRootLayerSet().addChangeTreesStep();
}
});
} else if (command.equals("Unhide")) {
thing.setVisible(true);
} else if (command.equals("Select in display")) {
boolean shift_down = 0 != (ae.getModifiers() & ActionEvent.SHIFT_MASK);
selectInDisplay(thing, shift_down);
} else if (command.equals("Show centered in Display")) {
if (obd instanceof Displayable) {
Displayable displ = (Displayable) obd;
Display.showCentered(displ.getLayer(), displ, true, 0 != (ae.getModifiers() & ActionEvent.SHIFT_MASK));
}
} else if (command.equals("Show tabular view")) {
((Tree<?>) obd).createMultiTableView();
} else if (command.equals("Show in 3D")) {
Display3D.showAndResetView(thing);
} else if (command.equals("Remove from 3D view")) {
Display3D.removeFrom3D(thing);
} else if (command.equals("Hide")) {
// find all Thing objects in this subtree starting at Thing and hide their Displayable objects.
thing.setVisible(false);
} else if (command.equals("Delete...")) {
// store old state
project.getRootLayerSet().addChangeTreesStep();
remove(true, thing, selected_node);
// store new state
project.getRootLayerSet().addChangeTreesStep();
return;
} else if (command.equals("Rename...")) {
// if (!Project.isBasicType(thing.getType())) {
rename(thing);
// }
} else if (command.equals("Measure")) {
// block displays while measuring
Bureaucrat.createAndStart(new Worker("Measuring") {
public void run() {
startedWorking();
try {
thing.measure();
} catch (Throwable e) {
IJError.print(e);
} finally {
finishedWorking();
}
}
}, thing.getProject());
} else /* else if (command.equals("Export 3D...")) {
GenericDialog gd = ControlWindow.makeGenericDialog("Export 3D");
String[] choice = new String[]{".svg [preserves links and hierarchical grouping]", ".shapes [limited to one profile per layer per profile_list]"};
gd.addChoice("Export to: ", choice, choice[0]);
gd.addNumericField("Z scaling: ", 1, 2);
gd.showDialog();
if (gd.wasCanceled()) return;
double z_scale = gd.getNextNumber();
switch (gd.getNextChoiceIndex()) {
case 0:
Render.exportSVG(thing, z_scale);
break;
case 1:
new Render(thing).save(z_scale);
break;
}
}*/
if (command.equals("Export project...") || command.equals("Save as...")) {
// "Save as..." is for a FS project
Utils.log2("Calling export project at " + System.currentTimeMillis());
thing.getProject().getLoader().saveTask(thing.getProject(), "Save as...");
} else if (command.equals("Save")) {
// overwrite the xml file of a FSProject
// Just do the same as in "Save as..." but without saving the images and overwritting the XML file without asking.
thing.getProject().getLoader().saveTask(thing.getProject(), "Save");
} else if (command.equals("Info")) {
showInfo(thing);
return;
} else if (command.equals("Move up")) {
move(selected_node, -1);
} else if (command.equals("Move down")) {
move(selected_node, 1);
} else if (command.equals("Collapse nodes of children nodes")) {
if (null == selected_node)
return;
Enumeration<?> c = selected_node.children();
while (c.hasMoreElements()) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) c.nextElement();
if (child.isLeaf())
continue;
collapsePath(new TreePath(child.getPath()));
}
} else if (command.equals("Sibling project")) {
sendToSiblingProjectTask(selected_node);
} else {
Utils.log("ProjectTree.actionPerformed: don't know what to do with the command: " + command);
return;
}
} catch (Exception e) {
IJError.print(e);
}
}
});
}
use of ini.trakem2.Project in project TrakEM2 by trakem2.
the class ProjectTree method sendToSiblingProject.
/**
* When two or more people work on the same XML file, images may be the same but segmentations and the transformations of the images may diverge.
* This function provides the means to send VectorData instances, wrapped in tree nodes, from one project to another,
* transforming the VectorData as appropriate to fall onto the same locations on the images.
* The ids of the copied objects will be new and unique for the target project.
* A dialog opens asking for options.
*/
@SuppressWarnings("unchecked")
public boolean sendToSiblingProject(final DefaultMutableTreeNode node) {
ArrayList<Project> ps = Project.getProjects();
if (1 == ps.size()) {
Utils.log("There aren't any other projects open!");
return false;
}
final ProjectThing pt = (ProjectThing) node.getUserObject();
if (pt.getTemplate().getType().equals("project")) {
Utils.log("Cannot transfer the project node.");
return false;
}
final ArrayList<Project> psother = new ArrayList<Project>(ps);
psother.remove(this.project);
ps = null;
// Find all potential landing nodes for this node: those with a TemplateThing type like the parent of node:
final String parent_type = ((ProjectThing) pt.getParent()).getTemplate().getType();
final List<ProjectThing> landing_pt = new ArrayList<ProjectThing>(psother.get(0).getRootProjectThing().findChildrenOfTypeR(parent_type));
final Comparator<ProjectThing> comparator = new Comparator<ProjectThing>() {
public int compare(ProjectThing t1, ProjectThing t2) {
return t1.toString().compareTo(t2.toString());
}
public boolean equals(Object o) {
return this == o;
}
};
Collections.sort(landing_pt, comparator);
String[] landing = new String[landing_pt.size()];
int next = 0;
if (landing_pt.isEmpty()) {
landing = new String[] { "-- NONE --" };
} else
for (ProjectThing t : landing_pt) landing[next++] = t.toString();
// Suggest the first potential landing node that has the same title
String parentTitle = pt.getParent().toString();
int k = 0;
boolean matched = false;
// First search for exact match
for (final String candidate : landing) {
if (candidate.equals(parentTitle)) {
matched = true;
break;
}
k += 1;
}
// If not matched, find one that contains the string
if (!matched) {
k = 0;
for (final String candidate : landing) {
if (-1 != candidate.indexOf(parentTitle)) {
matched = true;
break;
}
k += 1;
}
}
if (!matched) {
k = 0;
}
// Ask:
GenericDialog gd = new GenericDialog("Send to sibling project");
gd.addMessage("Transfering node: " + pt);
final String[] trmode = new String[] { "As is", "Transformed as the images" };
gd.addChoice("Transfer:", trmode, trmode[0]);
String[] ptitles = new String[psother.size()];
for (int i = 0; i < ptitles.length; i++) ptitles[i] = psother.get(i).toString();
gd.addChoice("Target project:", ptitles, ptitles[0]);
gd.addChoice("Landing node:", landing, landing[k]);
final Vector<Choice> vc = (Vector<Choice>) gd.getChoices();
final Choice choice_project = vc.get(vc.size() - 2);
final Choice choice_landing = vc.get(vc.size() - 1);
choice_project.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ie) {
landing_pt.clear();
landing_pt.addAll(psother.get(choice_project.getSelectedIndex()).getRootProjectThing().findChildrenOfTypeR(parent_type));
Collections.sort(landing_pt, comparator);
choice_landing.removeAll();
if (landing_pt.isEmpty()) {
choice_landing.add("-- NONE --");
} else
for (ProjectThing t : landing_pt) choice_landing.add(t.toString());
}
});
gd.showDialog();
if (gd.wasCanceled())
return false;
if (choice_landing.getSelectedItem().equals("-- NONE --")) {
Utils.log("No valid landing nodes!");
return false;
}
final int transfer_mode = gd.getNextChoiceIndex();
final Project target_project = psother.get(gd.getNextChoiceIndex());
final ProjectThing landing_parent = landing_pt.get(gd.getNextChoiceIndex());
return rawSendToSiblingProject(pt, transfer_mode, target_project, landing_parent);
}
use of ini.trakem2.Project in project TrakEM2 by trakem2.
the class ProjectTree method rawSendToSiblingProject.
/**
* Assumes that both projects have the same TemplateThing structure,
* and assumes that the parent of the ({@code source_pt} and the {@code landing_parent}
* instances are of the same type.
*
* @param source_pt The {@link ProjectThing} to be cloned.
* @param transfer_mode Either 0 ("As is") or 1 ("Transformed with the images").
* @param target_project The sibling project into which insert a clone of the {@code source_pt}.
* @param landing_parent The ProjectThing in the sibling project that receives the cloned {@code source_pt}.
*/
public boolean rawSendToSiblingProject(// the source ProjectThing to copy to the target project
final ProjectThing source_pt, final int transfer_mode, final Project target_project, final ProjectThing landing_parent) {
try {
// Check that all the Layers used by the objects to transfer also exist in the target project!
// 1 - Cheap way: check if all layers in the target project exist in the source project, by id
HashSet<Long> lids = new HashSet<Long>();
for (final Layer layer : this.project.getRootLayerSet().getLayers()) {
lids.add(layer.getId());
}
HashSet<Long> tgt_lids = new HashSet<Long>(lids);
for (final Layer layer : target_project.getRootLayerSet().getLayers()) {
lids.remove(layer.getId());
tgt_lids.add(layer.getId());
}
List<Displayable> original_vdata = null;
final Set<Long> lids_to_operate = new HashSet<Long>();
if (0 != lids.size()) {
original_vdata = new ArrayList<Displayable>();
// All their layers MUST be in the target project.
for (final ProjectThing child : source_pt.findChildrenOfTypeR(Displayable.class)) {
final Displayable d = (Displayable) child.getObject();
if (!tgt_lids.containsAll(d.getLayerIds())) {
Utils.log("CANNOT transfer: not all required layers are present in the target project!\n First object that couldn't be transfered: \n " + d);
return false;
}
if (d instanceof VectorData) {
original_vdata.add(d);
lids_to_operate.addAll(d.getLayerIds());
}
}
}
// Deep cloning of the ProjectThing to transfer, then added to the landing_parent in the other tree.
ProjectThing copy;
try {
// new ids, taken from target_project
copy = source_pt.deepClone(target_project, false);
} catch (Exception ee) {
Utils.logAll("Can't send: " + ee.getMessage());
IJError.print(ee);
return false;
}
if (null == landing_parent.getChildTemplate(copy.getTemplate().getType())) {
// ensure a copy is there
landing_parent.getTemplate().addChild(copy.getTemplate().shallowCopy());
}
if (!landing_parent.addChild(copy)) {
Utils.log("Could NOT transfer the node!");
return false;
}
// Get the list of Profile instances in the source Project, in the same order
// that they will be in the target project:
final List<Profile> srcProfiles = new ArrayList<Profile>();
for (final ProjectThing profile_pt : source_pt.findChildrenOfTypeR(Profile.class)) {
srcProfiles.add((Profile) profile_pt.getObject());
}
final List<ProjectThing> copies = copy.findChildrenOfTypeR(Displayable.class);
final List<Profile> newProfiles = new ArrayList<Profile>();
// Utils.log2("copies size: " + copies.size());
final List<Displayable> vdata = new ArrayList<Displayable>();
final List<ZDisplayable> zd = new ArrayList<ZDisplayable>();
for (final ProjectThing t : copies) {
final Displayable d = (Displayable) t.getObject();
// all should be, this is just future-proof code.
if (d instanceof VectorData)
vdata.add(d);
if (d instanceof ZDisplayable) {
zd.add((ZDisplayable) d);
} else {
// profile: always special
newProfiles.add((Profile) d);
}
}
// Fix Profile instances: exploit that the order as been conserved when copying.
int profileIndex = 0;
for (final Profile newProfile : newProfiles) {
// Corresponding Profile:
final Profile srcProfile = srcProfiles.get(profileIndex++);
// Corresponding layer: layers have the same IDs by definition of what a sibling Project is.
final Layer newLayer = target_project.getRootLayerSet().getLayer(srcProfile.getLayer().getId());
newLayer.add(newProfile);
// Corresponding links
for (final Displayable srcLinkedProfile : srcProfile.getLinked(Profile.class)) {
newProfile.link(newProfiles.get(srcProfiles.indexOf(srcLinkedProfile)));
}
}
// add them all in one shot
target_project.getRootLayerSet().addAll(zd);
// could have changed
target_project.getTemplateTree().rebuild();
// When trying to rebuild just the landing_parent, it doesn't always work. Needs checking TODO
target_project.getProjectTree().rebuild();
// Open up the path to the landing parent node
final TreePath tp = new TreePath(DNDTree.findNode(landing_parent, target_project.getProjectTree()).getPath());
Utils.invokeLater(new Runnable() {
public void run() {
target_project.getProjectTree().scrollPathToVisible(tp);
target_project.getProjectTree().setSelectionPath(tp);
}
});
if (1 == transfer_mode) {
// Collect original vdata
if (null == original_vdata) {
original_vdata = new ArrayList<Displayable>();
for (final ProjectThing child : source_pt.findChildrenOfTypeR(Displayable.class)) {
final Displayable d = (Displayable) child.getObject();
if (d instanceof VectorData) {
original_vdata.add(d);
lids_to_operate.addAll(d.getLayerIds());
}
}
}
// Utils.log2("original vdata:", original_vdata);
// Utils.log2("vdata:", vdata);
// Transform with images
AlignTask.transformVectorData(AlignTask.createTransformPropertiesTable(original_vdata, vdata, lids_to_operate), vdata, target_project.getRootLayerSet());
}
return true;
} catch (Exception e) {
IJError.print(e);
}
return false;
}
use of ini.trakem2.Project in project TrakEM2 by trakem2.
the class DBLoader method getChildrenProjectThings.
private ArrayList<ProjectThing> getChildrenProjectThings(Project project, long parent_id, String parent_type, HashMap<String, TemplateThing> hs_tt, HashMap<Long, Displayable> hs_d) throws Exception {
final ArrayList<ProjectThing> al_children = new ArrayList<ProjectThing>();
ResultSet r = null;
if (-1 == parent_id)
Utils.log("parent_id = -1 for parent_type=" + parent_type);
if (parent_type.equals("profile_list")) {
// the project_id field is redundant
r = connection.prepareStatement("SELECT ab_things.* FROM ab_things,ab_displayables,ab_layers WHERE ab_things.parent_id=" + parent_id + " AND ab_things.object_id=ab_displayables.id AND ab_displayables.layer_id=ab_layers.id ORDER BY ab_layers.z,ab_things.id ASC").executeQuery();
} else {
r = connection.prepareStatement("SELECT * FROM ab_things WHERE parent_id=" + parent_id + " ORDER BY id").executeQuery();
}
while (r.next()) {
ProjectThing thing = getProjectThing(r, project, hs_tt, hs_d);
if (null != thing)
al_children.add(thing);
}
r.close();
return al_children;
}
use of ini.trakem2.Project in project TrakEM2 by trakem2.
the class DBLoader method fetchBall.
private Ball fetchBall(Project project, long id) throws Exception {
// strange query, but can't distinguish between pipes and balls otherwise
ResultSet r = connection.prepareStatement("SELECT ab_displayables.id, title, ab_displayables.width, height, alpha, visible, color_red, color_green, color_blue, ab_zdisplayables.id, ab_ball_points.ball_id, ab_displayables.locked, m00, m10, m01, m11, m02, m12 FROM ab_zdisplayables, ab_displayables, ab_ball_points WHERE ab_zdisplayables.id=ab_displayables.id AND ab_zdisplayables.id=ab_ball_points.ball_id AND ab_zdisplayables.id=" + id).executeQuery();
Ball b = null;
if (r.next()) {
b = new Ball(project, id, r.getString("title"), (float) r.getDouble("width"), (float) r.getDouble("height"), r.getFloat("alpha"), r.getBoolean("visible"), new Color(r.getInt("color_red"), r.getInt("color_green"), r.getInt("color_blue")), r.getBoolean("locked"), new AffineTransform(r.getDouble("m00"), r.getDouble("m10"), r.getDouble("m01"), r.getDouble("m11"), r.getDouble("m02"), r.getDouble("m12")));
}
r.close();
return b;
}
Aggregations