use of ini.trakem2.display.Profile in project TrakEM2 by trakem2.
the class ProjectThing method getPopupItems.
public JMenuItem[] getPopupItems(final ActionListener listener) {
JMenuItem item = null;
ArrayList<JMenuItem> al_items = new ArrayList<JMenuItem>();
JMenu menu = new JMenu("Add...");
// call the project unique type
final ArrayList<TemplateThing> tc = project.getTemplateThing(template.getType()).getChildren();
if (null != tc) {
for (final TemplateThing tt : tc) {
item = new JMenuItem("new " + tt.getType());
item.addActionListener(listener);
menu.add(item);
}
item = new JMenuItem("many...");
item.addActionListener(listener);
menu.add(item);
}
if (0 != menu.getItemCount()) {
if (template.getType().equals("profile_list") && null != al_children && al_children.size() > 0) {
// can't add a new profile unless linked to another one.
item.setEnabled(false);
}
al_items.add(menu);
}
// generic for all:
// a 'Show' command on a non-basic type is a render preview.
addPopupItem("Unhide", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, Event.ALT_MASK, true));
addPopupItem("Hide", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, 0, true));
addPopupItem("Info", listener, al_items);
addPopupItem("Rename...", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0, true));
// enable duplicating for basic types only
if (Project.isBasicType(getType())) {
addPopupItem("Duplicate", listener, al_items);
}
addPopupItem("Select in display", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true));
if (null != object && object instanceof Displayable) {
addPopupItem("Show centered in Display", listener, al_items);
}
if (null != object && object instanceof Tree<?>) {
addPopupItem("Show tabular view", listener, al_items);
}
// plugins
JMenuItem plugin_menu = Utils.addPlugIns("Project Tree", project, new Callable<Displayable>() {
public Displayable call() {
if (object instanceof Displayable)
return (Displayable) object;
return null;
}
});
if (null != plugin_menu)
al_items.add(plugin_menu);
addPopupItem("Measure", listener, al_items);
addPopupItem("Show in 3D", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0, true));
addPopupItem("Remove from 3D view", listener, al_items);
if (template.getType().equals("project")) {
if (project.getLoader() instanceof DBLoader) {
addPopupItem("Export project...", listener, al_items);
} else if (project.getLoader() instanceof FSLoader) {
addPopupItem("Save", listener, al_items).setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true));
addPopupItem("Save as...", listener, al_items);
}
}
if (!(template.getType().equals("project") && project.getLoader() instanceof FSLoader)) {
addPopupItem("Delete...", listener, al_items);
}
JMenuItem[] items = new JMenuItem[al_items.size()];
al_items.toArray(items);
return items;
}
use of ini.trakem2.display.Profile in project TrakEM2 by trakem2.
the class ProjectThing method fixZOrdering.
/**
* If this is of type profile_list, order all children Profile by their layer's Z coordinate, ascending.
*/
public boolean fixZOrdering() {
if (!this.template.getType().equals("profile_list"))
return false;
// no need
if (null == al_children || al_children.size() < 2)
return true;
// fix Z ordering in the tree
final HashMap<Double, ArrayList<ProjectThing>> ht = new HashMap<Double, ArrayList<ProjectThing>>();
synchronized (al_children) {
for (ProjectThing child : al_children) {
Profile p = (Profile) child.object;
Layer layer = p.getLayer();
// contortions: there could be more than one profile in the same layer
Double z = new Double(layer.getZ());
ArrayList<ProjectThing> al = ht.get(z);
if (null == al) {
al = new ArrayList<ProjectThing>();
al.add(child);
ht.put(z, al);
} else {
al.add(child);
}
}
Double[] zs = new Double[ht.size()];
ht.keySet().toArray(zs);
Arrays.sort(zs);
al_children.clear();
for (int i = 0; i < zs.length; i++) {
al_children.addAll(ht.get(zs[i]));
}
}
return true;
}
use of ini.trakem2.display.Profile 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.Profile 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.display.Profile 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;
}
Aggregations