use of ini.trakem2.display.Node in project TrakEM2 by trakem2.
the class ProjectTree method remove.
/**
* Remove the node, its Thing and the object hold by the thing from the database.
*/
public void remove(DefaultMutableTreeNode node, boolean check, boolean remove_empty_parents, int levels) {
Object uob = node.getUserObject();
if (!(uob instanceof ProjectThing))
return;
ProjectThing thing = (ProjectThing) uob;
Display3D.remove(thing);
ProjectThing parent = (ProjectThing) thing.getParent();
if (!thing.remove(check))
return;
((DefaultTreeModel) this.getModel()).removeNodeFromParent(node);
if (remove_empty_parents)
removeProjectThingLadder(parent, levels);
this.updateUILater();
}
use of ini.trakem2.display.Node in project TrakEM2 by trakem2.
the class ProjectTree method duplicateChild.
/**
* Implements the "Duplicate, link and send to next/previous layer" functionality. The 'position' can be zero (before) or 1 (after). The profile has no layer assigned.
*/
public Profile duplicateChild(Profile original, int position, Layer layer) {
Utils.log2("ProjectTree: Called duplicateChild " + System.currentTimeMillis() + " for original id = " + original.getId() + " at position " + position);
// find the Thing that holds it
Thing child = project.findProjectThing(original);
if (null == child) {
Utils.log("ProjectTree.duplicateChild: node not found for original " + original);
return null;
}
Profile copy = (Profile) original.clone();
// for the Z ordering
copy.setLayer(layer);
ProjectThing new_thing = null;
try {
new_thing = new ProjectThing(((ProjectThing) child.getParent()).getChildTemplate(child.getType()), original.getProject(), copy);
} catch (Exception e) {
IJError.print(e);
return null;
}
DefaultMutableTreeNode child_node = (DefaultMutableTreeNode) findNode(child, this);
DefaultMutableTreeNode parent_node = (DefaultMutableTreeNode) child_node.getParent();
ProjectThing parent_thing = (ProjectThing) parent_node.getUserObject();
// sanity check:
if (position < 0)
position = 0;
else if (position > 1)
position = 1;
int index = parent_node.getIndex(child_node) + position;
if (index < 0)
index = 0;
if (index > parent_node.getChildCount())
index = parent_node.getChildCount() - 1;
if (!parent_thing.addChild(new_thing, index))
return null;
DefaultMutableTreeNode new_node = new DefaultMutableTreeNode(new_thing);
((DefaultTreeModel) this.getModel()).insertNodeInto(new_node, parent_node, index);
// relist properly the nodes
updateList(parent_node);
TreePath treePath = new TreePath(new_node.getPath());
this.scrollPathToVisible(treePath);
this.setSelectionPath(treePath);
return copy;
}
use of ini.trakem2.display.Node 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.display.Node 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.display.Node in project TrakEM2 by trakem2.
the class Search method executeSearch.
private void executeSearch() {
final Project project = Project.getProjects().get(projects.getSelectedIndex());
if (null == project) {
// Should not happen
return;
}
Bureaucrat.createAndStart(new Worker.Task("Searching") {
public void exec() {
String pattern = search_field.getText();
if (null == pattern || 0 == pattern.length()) {
return;
}
// fix pattern
final String typed_pattern = pattern;
// I hate java
final StringBuilder sb = new StringBuilder();
if (!pattern.startsWith("^"))
sb.append("^.*");
for (int i = 0; i < pattern.length(); i++) {
sb.append(pattern.charAt(i));
}
if (!pattern.endsWith("$"))
sb.append(".*$");
pattern = sb.toString();
final Pattern pat = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
// Utils.log2("pattern after: " + pattern);
final ArrayList<DBObject> al = new ArrayList<DBObject>();
// Utils.log("types[pulldown] = " +
// types[pulldown.getSelectedIndex()]);
find(project.getRootLayerSet(), al, types[pulldown.getSelectedIndex()]);
// Utils.log2("found labels: " + al.size());
if (0 == al.size())
return;
final Vector<DBObject> v_obs = new Vector<DBObject>();
final Vector<String> v_txt = new Vector<String>();
final Vector<Coordinate<?>> v_co = new Vector<Coordinate<?>>();
Coordinate<?> co = null;
for (final DBObject dbo : al) {
if (Thread.currentThread().isInterrupted()) {
return;
}
boolean matched = false;
// Search in its title
Displayable d = null;
if (dbo instanceof Displayable) {
d = (Displayable) dbo;
}
String txt;
String meaningful_title = null;
if (null == d || Patch.class == d.getClass())
txt = dbo.getTitle();
else {
txt = meaningful_title = dbo.getProject().getMeaningfulTitle(d);
}
if (null == txt || 0 == txt.trim().length())
continue;
matched = pat.matcher(txt).matches();
if (!matched && null != d) {
// Search also in its annotation
txt = d.getAnnotation();
if (null != txt)
matched = pat.matcher(txt).matches();
}
if (!matched) {
// Search also in its toString()
txt = dbo.toString();
matched = pat.matcher(txt).matches();
}
if (!matched) {
// Search also in its id
txt = Long.toString(dbo.getId());
matched = pat.matcher(txt).matches();
if (matched)
txt = "id: #" + txt;
}
if (!matched && null != d) {
// Search also in its properties
Map<String, String> props = d.getProperties();
if (null != props) {
for (final Map.Entry<String, String> e : props.entrySet()) {
if (pat.matcher(e.getKey()).matches() || pat.matcher(e.getValue()).matches()) {
matched = true;
txt = e.getKey() + " => " + e.getValue() + " [property]";
break;
}
}
}
if (!matched) {
Map<Displayable, Map<String, String>> linked_props = ((Displayable) dbo).getLinkedProperties();
if (null != linked_props) {
for (final Map.Entry<Displayable, Map<String, String>> e : linked_props.entrySet()) {
for (final Map.Entry<String, String> ee : e.getValue().entrySet()) {
if (pat.matcher(ee.getKey()).matches() || pat.matcher(ee.getValue()).matches()) {
matched = true;
txt = ee.getKey() + " => " + e.getValue() + " [linked property]";
break;
}
}
}
}
}
}
if (!matched && dbo instanceof Tree<?>) {
// search Node tags
Node<?> root = ((Tree<?>) dbo).getRoot();
if (null == root)
continue;
for (final Node<?> nd : root.getSubtreeNodes()) {
Set<Tag> tags = nd.getTags();
if (null == tags)
continue;
for (final Tag tag : tags) {
if (pat.matcher(tag.toString()).matches()) {
v_obs.add(dbo);
v_txt.add(new StringBuilder(tag.toString()).append(" (").append(null == meaningful_title ? dbo.toString() : meaningful_title).append(')').toString());
v_co.add(createCoordinate((Tree<?>) dbo, nd));
}
}
}
// all added if any
continue;
}
if (!matched)
continue;
// txt = txt.length() > 30 ? txt.substring(0, 27) + "..." :
// txt;
v_obs.add(dbo);
v_txt.add(txt);
v_co.add(co);
}
if (0 == v_obs.size()) {
Utils.showMessage("Nothing found.");
return;
}
final JPanel result = new JPanel();
GridBagLayout gb = new GridBagLayout();
result.setLayout(gb);
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets = new Insets(5, 10, 5, 10);
String xml = "";
if (project.getLoader() instanceof FSLoader) {
String path = ((FSLoader) project.getLoader()).getProjectXMLPath();
if (null != path) {
xml = " [" + new File(path).getName() + "]";
}
}
JLabel projectTitle = new JLabel(project.getTitle() + xml);
gb.setConstraints(projectTitle, c);
result.add(projectTitle);
c.insets = new Insets(0, 0, 0, 0);
JPanel padding = new JPanel();
c.weightx = 1;
gb.setConstraints(padding, c);
result.add(padding);
c.gridy = 1;
c.gridwidth = 2;
c.fill = GridBagConstraints.BOTH;
c.weighty = 1;
JScrollPane jsp = makeTable(new DisplayableTableModel(v_obs, v_txt, v_co), project);
gb.setConstraints(jsp, c);
result.add(jsp);
search_tabs.addTab(typed_pattern, result);
search_tabs.setSelectedComponent(result);
synchronized (tabMap) {
List<JPanel> cs = tabMap.get(project);
if (null == cs) {
cs = new ArrayList<JPanel>();
tabMap.put(project, cs);
}
cs.add(result);
}
}
}, project);
}
Aggregations