use of ini.trakem2.display.YesNoDialog in project TrakEM2 by trakem2.
the class AmiraImporter method importAmiraLabels.
/**
* Returns the array of AreaList or null if the file dialog is canceled. The xo,yo is the pivot of reference.
*/
public static Collection<AreaList> importAmiraLabels(Layer first_layer, double xo, double yo, final String default_dir) {
// open file
OpenDialog od = new OpenDialog("Choose Amira Labels File", default_dir, "");
String filename = od.getFileName();
if (null == filename || 0 == filename.length())
return null;
String dir = od.getDirectory();
if (IJ.isWindows())
dir = dir.replace('\\', '/');
if (!dir.endsWith("/"))
dir += "/";
String path = dir + filename;
AmiraMeshDecoder dec = new AmiraMeshDecoder();
if (!dec.open(path)) {
YesNoDialog yn = new YesNoDialog("Error", "File was not an Amira labels file.\nChoose another one?");
if (yn.yesPressed())
return importAmiraLabels(first_layer, xo, yo, default_dir);
return null;
}
ImagePlus imp = null;
if (dec.isTable()) {
Utils.showMessage("Select the other file (the labels)!");
return null;
} else {
FileInfo fi = new FileInfo();
fi.fileName = filename;
fi.directory = dir;
imp = new ImagePlus("Amira", dec.getStack());
dec.parameters.setParameters(imp);
}
return extractAmiraLabels(imp, dec.parameters, first_layer, xo, yo);
}
use of ini.trakem2.display.YesNoDialog in project TrakEM2 by trakem2.
the class Display method actionPerformed.
@Override
public void actionPerformed(final ActionEvent ae) {
dispatcher.exec(new Runnable() {
@Override
public void run() {
final String command = ae.getActionCommand();
if (command.startsWith("Job")) {
if (Utils.checkYN("Really cancel job?")) {
project.getLoader().quitJob(command);
repairGUI();
}
return;
} else if (command.equals("Move to top")) {
if (null == active)
return;
canvas.setUpdateGraphics(true);
getLayerSet().addUndoMoveStep(active);
layer.getParent().move(LayerSet.TOP, active);
getLayerSet().addUndoMoveStep(active);
Display.repaint(layer.getParent(), active, 5);
// Display.updatePanelIndex(layer, active);
} else if (command.equals("Move up")) {
if (null == active)
return;
canvas.setUpdateGraphics(true);
getLayerSet().addUndoMoveStep(active);
layer.getParent().move(LayerSet.UP, active);
getLayerSet().addUndoMoveStep(active);
Display.repaint(layer.getParent(), active, 5);
// Display.updatePanelIndex(layer, active);
} else if (command.equals("Move down")) {
if (null == active)
return;
canvas.setUpdateGraphics(true);
getLayerSet().addUndoMoveStep(active);
layer.getParent().move(LayerSet.DOWN, active);
getLayerSet().addUndoMoveStep(active);
Display.repaint(layer.getParent(), active, 5);
// Display.updatePanelIndex(layer, active);
} else if (command.equals("Move to bottom")) {
if (null == active)
return;
canvas.setUpdateGraphics(true);
getLayerSet().addUndoMoveStep(active);
layer.getParent().move(LayerSet.BOTTOM, active);
getLayerSet().addUndoMoveStep(active);
Display.repaint(layer.getParent(), active, 5);
// Display.updatePanelIndex(layer, active);
} else if (command.equals("Duplicate, link and send to next layer")) {
duplicateLinkAndSendTo(active, 1, layer.getParent().next(layer));
} else if (command.equals("Duplicate, link and send to previous layer")) {
duplicateLinkAndSendTo(active, 0, layer.getParent().previous(layer));
} else if (command.equals("Duplicate, link and send to...")) {
// fix non-scrolling popup menu
Utils.invokeLater(new Runnable() {
@Override
public void run() {
final GenericDialog gd = new GenericDialog("Send to");
gd.addMessage("Duplicate, link and send to...");
final String[] sl = new String[layer.getParent().size()];
int next = 0;
for (final Layer la : layer.getParent().getLayers()) {
sl[next++] = project.findLayerThing(la).toString();
}
gd.addChoice("Layer: ", sl, sl[layer.getParent().indexOf(layer)]);
gd.showDialog();
if (gd.wasCanceled())
return;
final Layer la = layer.getParent().getLayer(gd.getNextChoiceIndex());
if (layer == la) {
Utils.showMessage("Can't duplicate, link and send to the same layer.");
return;
}
duplicateLinkAndSendTo(active, 0, la);
}
});
} else if (-1 != command.indexOf("z = ")) {
// this is an item from the "Duplicate, link and send to" menu of layer z's
final Layer target_layer = layer.getParent().getLayer(Double.parseDouble(command.substring(command.lastIndexOf(' ') + 1)));
Utils.log2("layer: __" + command.substring(command.lastIndexOf(' ') + 1) + "__");
if (null == target_layer)
return;
duplicateLinkAndSendTo(active, 0, target_layer);
} else if (-1 != command.indexOf("z=")) {
// WARNING the indexOf is very similar to the previous one
// Send the linked group to the selected layer
final int iz = command.indexOf("z=") + 2;
Utils.log2("iz=" + iz + " other: " + command.indexOf(' ', iz + 2));
int end = command.indexOf(' ', iz);
if (-1 == end)
end = command.length();
final double lz = Double.parseDouble(command.substring(iz, end));
final Layer target = layer.getParent().getLayer(lz);
// TODO what happens when ZDisplayable are selected?
layer.getParent().move(selection.getAffected(), active.getLayer(), target);
} else if (command.equals("Unlink")) {
if (null == active || active instanceof Patch)
return;
active.unlink();
// selection.update();
updateSelection();
} else if (command.equals("Unlink from images")) {
if (null == active)
return;
try {
for (final Displayable displ : selection.getSelected()) {
displ.unlinkAll(Patch.class);
}
// selection.update();
updateSelection();
} catch (final Exception e) {
IJError.print(e);
}
} else if (command.equals("Unlink slices")) {
final YesNoCancelDialog yn = new YesNoCancelDialog(frame, "Attention", "Really unlink all slices from each other?\nThere is no undo.");
if (!yn.yesPressed())
return;
final ArrayList<Patch> pa = ((Patch) active).getStackPatches();
for (int i = pa.size() - 1; i > 0; i--) {
pa.get(i).unlink(pa.get(i - 1));
}
} else if (command.equals("Send to next layer")) {
final Rectangle box = selection.getBox();
try {
// unlink Patch instances
for (final Displayable displ : selection.getSelected()) {
displ.unlinkAll(Patch.class);
}
// selection.update();
updateSelection();
} catch (final Exception e) {
IJError.print(e);
}
// layer.getParent().moveDown(layer, active); // will repaint whatever appropriate layers
selection.moveDown();
repaint(layer.getParent(), box);
} else if (command.equals("Send to previous layer")) {
final Rectangle box = selection.getBox();
try {
// unlink Patch instances
for (final Displayable displ : selection.getSelected()) {
displ.unlinkAll(Patch.class);
}
// selection.update();
updateSelection();
} catch (final Exception e) {
IJError.print(e);
}
// layer.getParent().moveUp(layer, active); // will repaint whatever appropriate layers
selection.moveUp();
repaint(layer.getParent(), box);
} else if (command.equals("Show centered")) {
if (active == null)
return;
showCentered(active);
} else if (command.equals("Delete...")) {
// remove all selected objects
selection.deleteAll();
} else if (command.equals("Color...")) {
IJ.doCommand("Color Picker...");
} else if (command.equals("Revert")) {
if (null == active || active.getClass() != Patch.class)
return;
final Patch p = (Patch) active;
if (!p.revert()) {
if (null == p.getOriginalPath())
Utils.log("No editions to save for patch " + p.getTitle() + " #" + p.getId());
else
Utils.log("Could not revert Patch " + p.getTitle() + " #" + p.getId());
}
} else if (command.equals("Remove alpha mask")) {
Display.removeAlphaMasks(selection.get(Patch.class));
} else if (command.equals("Undo")) {
Bureaucrat.createAndStart(new Worker.Task("Undo") {
@Override
public void exec() {
layer.getParent().undoOneStep();
Display.repaint(layer.getParent());
}
}, project);
} else if (command.equals("Redo")) {
Bureaucrat.createAndStart(new Worker.Task("Redo") {
@Override
public void exec() {
layer.getParent().redoOneStep();
Display.repaint(layer.getParent());
}
}, project);
} else if (command.equals("Apply transform")) {
canvas.applyTransform();
} else if (command.equals("Apply transform propagating to last layer")) {
if (mode.getClass() == AffineTransformMode.class || mode.getClass() == NonLinearTransformMode.class) {
final LayerSet ls = getLayerSet();
// +1 to exclude current layer
final HashSet<Layer> subset = new HashSet<Layer>(ls.getLayers(ls.indexOf(Display.this.layer) + 1, ls.size() - 1));
if (mode.getClass() == AffineTransformMode.class)
((AffineTransformMode) mode).applyAndPropagate(subset);
else if (mode.getClass() == NonLinearTransformMode.class)
((NonLinearTransformMode) mode).apply(subset);
setMode(new DefaultMode(Display.this));
}
} else if (command.equals("Apply transform propagating to first layer")) {
if (mode.getClass() == AffineTransformMode.class || mode.getClass() == NonLinearTransformMode.class) {
final LayerSet ls = getLayerSet();
// -1 to exclude current layer
final HashSet<Layer> subset = new HashSet<Layer>(ls.getLayers(0, ls.indexOf(Display.this.layer) - 1));
if (mode.getClass() == AffineTransformMode.class)
((AffineTransformMode) mode).applyAndPropagate(subset);
else if (mode.getClass() == NonLinearTransformMode.class)
((NonLinearTransformMode) mode).apply(subset);
setMode(new DefaultMode(Display.this));
}
} else if (command.equals("Cancel transform")) {
// calls getMode().cancel()
canvas.cancelTransform();
} else if (command.equals("Specify transform...")) {
if (null == active)
return;
selection.specify();
} else if (command.equals("Exit inspection")) {
getMode().cancel();
setMode(new DefaultMode(Display.this));
} else if (command.equals("Inspect image mesh triangles")) {
setMode(new InspectPatchTrianglesMode(Display.this));
} else if (command.equals("Hide all but images")) {
final ArrayList<Class<?>> type = new ArrayList<Class<?>>();
type.add(Patch.class);
type.add(Stack.class);
final Collection<Displayable> col = layer.getParent().hideExcept(type, false);
selection.removeAll(col);
Display.updateCheckboxes(col, DisplayablePanel.VISIBILITY_STATE);
Display.update(layer.getParent(), false);
} else if (command.equals("Unhide all")) {
Display.updateCheckboxes(layer.getParent().setAllVisible(false), DisplayablePanel.VISIBILITY_STATE);
Display.update(layer.getParent(), false);
} else if (command.startsWith("Hide all ")) {
// skip the ending plural 's'
final String type = command.substring(9, command.length() - 1);
final Collection<Displayable> col = layer.getParent().setVisible(type, false, true);
selection.removeAll(col);
Display.updateCheckboxes(col, DisplayablePanel.VISIBILITY_STATE);
} else if (command.startsWith("Unhide all ")) {
// skip the ending plural 's'
String type = command.substring(11, command.length() - 1);
type = type.substring(0, 1).toUpperCase() + type.substring(1);
updateCheckboxes(layer.getParent().setVisible(type, true, true), DisplayablePanel.VISIBILITY_STATE);
} else if (command.equals("Hide deselected")) {
hideDeselected(0 != (ActionEvent.ALT_MASK & ae.getModifiers()));
} else if (command.equals("Hide deselected except images")) {
hideDeselected(true);
} else if (command.equals("Hide selected")) {
// TODO should deselect them too? I don't think so.
selection.setVisible(false);
Display.updateCheckboxes(selection.getSelected(), DisplayablePanel.VISIBILITY_STATE);
} else if (command.equals("Resize canvas/LayerSet...")) {
resizeCanvas();
} else if (command.equals("Autoresize canvas/LayerSet")) {
layer.getParent().setMinimumDimensions();
} else if (command.equals("Resize canvas/LayerSet to ROI")) {
final Roi roi = canvas.getFakeImagePlus().getRoi();
if (null == roi) {
Utils.log("No ROI present!");
return;
}
resizeCanvas(roi.getBounds());
} else if (command.equals("Import image")) {
importImage();
} else if (command.equals("Import next image")) {
importNextImage();
} else if (command.equals("Import stack...")) {
Display.this.getLayerSet().addChangeTreesStep();
final Rectangle sr = getCanvas().getSrcRect();
final Bureaucrat burro = project.getLoader().importStack(layer, sr.x + sr.width / 2, sr.y + sr.height / 2, null, true, null, false);
burro.addPostTask(new Runnable() {
@Override
public void run() {
Display.this.getLayerSet().addChangeTreesStep();
}
});
} else if (command.equals("Import stack with landmarks...")) {
// 1 - Find out if there's any other project open
final List<Project> pr = Project.getProjects();
if (1 == pr.size()) {
Utils.logAll("Need another project open!");
return;
}
// 2 - Ask for a "landmarks" type
final GenericDialog gd = new GenericDialog("Landmarks");
gd.addStringField("landmarks type:", "landmarks");
final String[] none = { "-- None --" };
final Hashtable<String, Project> mpr = new Hashtable<String, Project>();
for (final Project p : pr) {
if (p == project)
continue;
mpr.put(p.toString(), p);
}
final String[] project_titles = mpr.keySet().toArray(new String[0]);
final Hashtable<String, ProjectThing> map_target = findLandmarkNodes(project, "landmarks");
final String[] target_landmark_titles = map_target.isEmpty() ? none : map_target.keySet().toArray(new String[0]);
gd.addChoice("Landmarks node in this project:", target_landmark_titles, target_landmark_titles[0]);
gd.addMessage("");
gd.addChoice("Source project:", project_titles, project_titles[0]);
final Hashtable<String, ProjectThing> map_source = findLandmarkNodes(mpr.get(project_titles[0]), "landmarks");
final String[] source_landmark_titles = map_source.isEmpty() ? none : map_source.keySet().toArray(new String[0]);
gd.addChoice("Landmarks node in source project:", source_landmark_titles, source_landmark_titles[0]);
final List<Patch> stacks = Display.getPatchStacks(mpr.get(project_titles[0]).getRootLayerSet());
String[] stack_titles;
if (stacks.isEmpty()) {
if (1 == mpr.size()) {
IJ.showMessage("Project " + project_titles[0] + " does not contain any Stack.");
return;
}
stack_titles = none;
} else {
stack_titles = new String[stacks.size()];
int next = 0;
for (final Patch pa : stacks) stack_titles[next++] = pa.toString();
}
gd.addChoice("Stacks:", stack_titles, stack_titles[0]);
final Vector<?> vc = gd.getChoices();
final Choice choice_target_landmarks = (Choice) vc.get(0);
final Choice choice_source_projects = (Choice) vc.get(1);
final Choice choice_source_landmarks = (Choice) vc.get(2);
final Choice choice_stacks = (Choice) vc.get(3);
final TextField input = (TextField) gd.getStringFields().get(0);
input.addTextListener(new TextListener() {
@Override
public void textValueChanged(final TextEvent te) {
final String text = input.getText();
update(choice_target_landmarks, Display.this.project, text, map_target);
update(choice_source_landmarks, mpr.get(choice_source_projects.getSelectedItem()), text, map_source);
}
private void update(final Choice c, final Project p, final String type, final Hashtable<String, ProjectThing> table) {
table.clear();
table.putAll(findLandmarkNodes(p, type));
c.removeAll();
if (table.isEmpty())
c.add(none[0]);
else
for (final String t : table.keySet()) c.add(t);
}
});
choice_source_projects.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
final String item = (String) e.getItem();
final Project p = mpr.get(choice_source_projects.getSelectedItem());
// 1 - Update choice of landmark items
map_source.clear();
map_source.putAll(findLandmarkNodes(p, input.getText()));
choice_target_landmarks.removeAll();
if (map_source.isEmpty())
choice_target_landmarks.add(none[0]);
else
for (final String t : map_source.keySet()) choice_target_landmarks.add(t);
// 2 - Update choice of Stack items
stacks.clear();
choice_stacks.removeAll();
stacks.addAll(Display.getPatchStacks(mpr.get(project_titles[0]).getRootLayerSet()));
if (stacks.isEmpty())
choice_stacks.add(none[0]);
else
for (final Patch pa : stacks) choice_stacks.add(pa.toString());
}
});
gd.showDialog();
if (gd.wasCanceled())
return;
final String type = gd.getNextString();
if (null == type || 0 == type.trim().length()) {
Utils.log("Invalid landmarks node type!");
return;
}
final ProjectThing target_landmarks_node = map_target.get(gd.getNextChoice());
final Project source = mpr.get(gd.getNextChoice());
final ProjectThing source_landmarks_node = map_source.get(gd.getNextChoice());
final Patch stack_patch = stacks.get(gd.getNextChoiceIndex());
// Store current state
Display.this.getLayerSet().addLayerContentStep(layer);
// Insert stack
insertStack(target_landmarks_node, source, source_landmarks_node, stack_patch);
// Store new state
Display.this.getLayerSet().addChangeTreesStep();
} else if (command.equals("Import grid...")) {
Display.this.getLayerSet().addLayerContentStep(layer);
final Bureaucrat burro = project.getLoader().importGrid(layer);
if (null != burro)
burro.addPostTask(new Runnable() {
@Override
public void run() {
Display.this.getLayerSet().addLayerContentStep(layer);
}
});
} else if (command.equals("Import sequence as grid...")) {
Display.this.getLayerSet().addChangeTreesStep();
final Bureaucrat burro = project.getLoader().importSequenceAsGrid(layer);
if (null != burro)
burro.addPostTask(new Runnable() {
@Override
public void run() {
Display.this.getLayerSet().addChangeTreesStep();
}
});
} else if (command.equals("Import from text file...")) {
Display.this.getLayerSet().addChangeTreesStep();
final Bureaucrat burro = project.getLoader().importImages(layer);
if (null != burro)
burro.addPostTask(new Runnable() {
@Override
public void run() {
Display.this.getLayerSet().addChangeTreesStep();
}
});
} else if (command.equals("Import labels as arealists...")) {
Display.this.getLayerSet().addChangeTreesStep();
final Bureaucrat burro = project.getLoader().importLabelsAsAreaLists(layer, null, Double.MAX_VALUE, 0, 0.4f, false);
burro.addPostTask(new Runnable() {
@Override
public void run() {
Display.this.getLayerSet().addChangeTreesStep();
}
});
} else if (command.equals("Make flat image...")) {
// if there's a ROI, just use that as cropping rectangle
Rectangle srcRect = null;
final Roi roi = canvas.getFakeImagePlus().getRoi();
if (null != roi) {
srcRect = roi.getBounds();
} else {
// otherwise, whatever is visible
// srcRect = canvas.getSrcRect();
// The above is confusing. That is what ROIs are for. So paint all:
srcRect = new Rectangle(0, 0, (int) Math.ceil(layer.getParent().getLayerWidth()), (int) Math.ceil(layer.getParent().getLayerHeight()));
}
double scale = 1.0;
final String[] types = new String[] { "8-bit grayscale", "RGB Color" };
int the_type = ImagePlus.GRAY8;
final GenericDialog gd = new GenericDialog("Choose", frame);
gd.addSlider("Scale: ", 1, 100, 100);
gd.addNumericField("Width: ", srcRect.width, 0);
gd.addNumericField("height: ", srcRect.height, 0);
// connect the above 3 fields:
final Vector<?> numfields = gd.getNumericFields();
final UpdateDimensionField udf = new UpdateDimensionField(srcRect.width, srcRect.height, (TextField) numfields.get(1), (TextField) numfields.get(2), (TextField) numfields.get(0), (Scrollbar) gd.getSliders().get(0));
for (final Object ob : numfields) ((TextField) ob).addTextListener(udf);
gd.addChoice("Type: ", types, types[0]);
if (layer.getParent().size() > 1) {
// / $#%! where are my lisp macros
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.addCheckbox("Include non-empty layers only", true);
}
gd.addMessage("Background color:");
Utils.addRGBColorSliders(gd, Color.black);
gd.addCheckbox("Best quality", false);
gd.addMessage("");
final String[] choices = new String[] { "Show", "Save to file", "Save for web (CATMAID)" };
gd.addChoice("Export:", choices, choices[0]);
final String[] formats = Saver.formats();
gd.addChoice("Format:", formats, formats[0]);
gd.addNumericField("Tile_side", 256, 0);
final Choice cformats = (Choice) gd.getChoices().get(gd.getChoices().size() - 1);
cformats.setEnabled(false);
final Choice cchoices = (Choice) gd.getChoices().get(gd.getChoices().size() - 2);
final TextField tf = (TextField) gd.getNumericFields().get(gd.getNumericFields().size() - 1);
tf.setEnabled(false);
cchoices.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
cformats.setEnabled(cchoices.getSelectedIndex() > 0);
if (2 == cchoices.getSelectedIndex()) {
cformats.select(".jpg");
tf.setEnabled(true);
} else {
tf.setEnabled(false);
}
}
});
gd.addCheckbox("Use original images", true);
gd.showDialog();
if (gd.wasCanceled())
return;
scale = gd.getNextNumber() / 100;
the_type = (0 == gd.getNextChoiceIndex() ? ImagePlus.GRAY8 : ImagePlus.COLOR_RGB);
if (Double.isNaN(scale) || scale <= 0.0) {
Utils.showMessage("Invalid scale.");
return;
}
// consuming and ignoring width and height:
gd.getNextNumber();
gd.getNextNumber();
Layer[] layer_array = null;
boolean non_empty_only = false;
if (layer.getParent().size() > 1) {
non_empty_only = gd.getNextBoolean();
final int i_start = gd.getNextChoiceIndex();
final int i_end = gd.getNextChoiceIndex();
final ArrayList<Layer> al = new ArrayList<Layer>();
final ArrayList<ZDisplayable> al_zd = layer.getParent().getZDisplayables();
final ZDisplayable[] zd = new ZDisplayable[al_zd.size()];
al_zd.toArray(zd);
for (int i = i_start, j = 0; i <= i_end; i++, j++) {
final Layer la = layer.getParent().getLayer(i);
// checks both the Layer and the ZDisplayable objects in the parent LayerSet
if (!la.isEmpty() || !non_empty_only)
al.add(la);
}
if (0 == al.size()) {
Utils.showMessage("All layers are empty!");
return;
}
layer_array = new Layer[al.size()];
al.toArray(layer_array);
} else {
layer_array = new Layer[] { Display.this.layer };
}
final Color background = new Color((int) gd.getNextNumber(), (int) gd.getNextNumber(), (int) gd.getNextNumber());
final boolean quality = gd.getNextBoolean();
final int choice = gd.getNextChoiceIndex();
final boolean save_to_file = 1 == choice;
final boolean save_for_web = 2 == choice;
final String format = gd.getNextChoice();
final Saver saver = new Saver(format);
final int tile_side = (int) gd.getNextNumber();
final boolean use_original_images = gd.getNextBoolean();
// in its own thread
if (save_for_web)
project.getLoader().makePrescaledTiles(layer_array, Patch.class, srcRect, scale, c_alphas, the_type, null, use_original_images, saver, tile_side);
else
project.getLoader().makeFlatImage(layer_array, srcRect, scale, c_alphas, the_type, save_to_file, format, quality, background);
} else if (command.equals("Lock")) {
selection.setLocked(true);
Utils.revalidateComponent(tabs.getSelectedComponent());
} else if (command.equals("Unlock")) {
selection.setLocked(false);
Utils.revalidateComponent(tabs.getSelectedComponent());
} else if (command.equals("Properties...")) {
switch(selection.getSelected().size()) {
case 0:
return;
case 1:
active.adjustProperties();
break;
default:
adjustGroupProperties(selection.getSelected());
break;
}
updateSelection();
} else if (command.equals("Measurement options...")) {
adjustMeasurementOptions();
} else if (command.equals("Show current 2D position in 3D")) {
final Point p = canvas.consumeLastPopupPoint();
if (null == p)
return;
Display3D.addFatPoint("Current 2D Position", getLayerSet(), p.x, p.y, layer.getZ(), 10, Color.magenta);
} else if (command.equals("Show layers as orthoslices in 3D")) {
final GenericDialog gd = new GenericDialog("Options");
final Roi roi = canvas.getFakeImagePlus().getRoi();
final Rectangle r = null == roi ? getLayerSet().get2DBounds() : roi.getBounds();
gd.addMessage("ROI 2D bounds:");
gd.addNumericField("x:", r.x, 0, 30, "pixels");
gd.addNumericField("y:", r.y, 0, 30, "pixels");
gd.addNumericField("width:", r.width, 0, 30, "pixels");
gd.addNumericField("height:", r.height, 0, 30, "pixels");
gd.addMessage("Layers to include:");
Utils.addLayerRangeChoices(layer, gd);
gd.addMessage("Constrain dimensions to:");
gd.addNumericField("max width and height:", getLayerSet().getPixelsMaxDimension(), 0, 30, "pixels");
gd.addMessage("Options:");
final String[] types = { "Greyscale", "Color RGB" };
gd.addChoice("Image type:", types, types[0]);
gd.addCheckbox("Invert images", false);
gd.showDialog();
if (gd.wasCanceled())
return;
final int x = (int) gd.getNextNumber(), y = (int) gd.getNextNumber(), width = (int) gd.getNextNumber(), height = (int) gd.getNextNumber();
final int first = gd.getNextChoiceIndex(), last = gd.getNextChoiceIndex();
final List<Layer> layers = getLayerSet().getLayers(first, last);
final int max_dim = Math.min((int) gd.getNextNumber(), Math.max(width, height));
float scale = 1;
if (max_dim < Math.max(width, height)) {
scale = max_dim / (float) Math.max(width, height);
}
final int type = 0 == gd.getNextChoiceIndex() ? ImagePlus.GRAY8 : ImagePlus.COLOR_RGB;
final boolean invert = gd.getNextBoolean();
final LayerStack stack = new LayerStack(layers, new Rectangle(x, y, width, height), scale, type, Patch.class, max_dim, invert);
Display3D.showOrthoslices(stack.getImagePlus(), "LayerSet [" + x + "," + y + "," + width + "," + height + "] " + first + "--" + last, x, y, scale, layers.get(0));
} else if (command.equals("Align stack slices")) {
if (getActive() instanceof Patch) {
final Patch slice = (Patch) getActive();
if (slice.isStack()) {
// check linked group
final HashSet hs = slice.getLinkedGroup(new HashSet());
for (final Iterator it = hs.iterator(); it.hasNext(); ) {
if (it.next().getClass() != Patch.class) {
// labels should be fine, need to check that
Utils.showMessage("Images are linked to other objects, can't proceed to cross-correlate them.");
return;
}
}
final LayerSet ls = slice.getLayerSet();
final HashSet<Displayable> linked = slice.getLinkedGroup(null);
ls.addTransformStepWithData(linked);
// will repaint
final Bureaucrat burro = AlignTask.registerStackSlices((Patch) getActive());
burro.addPostTask(new Runnable() {
@Override
public void run() {
ls.enlargeToFit(linked);
// The current state when done
ls.addTransformStepWithData(linked);
}
});
} else {
Utils.log("Align stack slices: selected image is not part of a stack.");
}
}
} else if (command.equals("Align layers manually with landmarks")) {
setMode(new ManualAlignMode(Display.this));
} else if (command.equals("Align layers")) {
Roi roi = canvas.getFakeImagePlus().getRoi();
if (null != roi) {
final YesNoCancelDialog yn = new YesNoCancelDialog(frame, "Use ROI?", "Snapshot layers using the ROI bounds?\n" + roi.getBounds());
if (yn.cancelPressed())
return;
if (!yn.yesPressed()) {
roi = null;
}
}
// caching, since scroll wheel may change it
final Layer la = layer;
la.getParent().addTransformStep(la.getParent().getLayers());
final Bureaucrat burro = AlignLayersTask.alignLayersTask(la, null == roi ? null : roi.getBounds());
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().enlargeToFit(getLayerSet().getDisplayables(Patch.class));
la.getParent().addTransformStep(la.getParent().getLayers());
}
});
} else if (command.equals("Align multi-layer mosaic")) {
// caching, since scroll wheel may change it
final Layer la = layer;
la.getParent().addTransformStep();
final Bureaucrat burro = AlignTask.alignMultiLayerMosaicTask(la, active instanceof Patch ? (Patch) active : null);
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().enlargeToFit(getLayerSet().getDisplayables(Patch.class));
la.getParent().addTransformStep();
}
});
} else if (command.equals("Montage all images in this layer")) {
final Layer la = layer;
final List<Patch> patches = new ArrayList<Patch>((List<Patch>) (List) la.getDisplayables(Patch.class, true));
if (patches.size() < 2) {
Utils.showMessage("Montage needs 2 or more visible images");
return;
}
final Collection<Displayable> col = la.getParent().addTransformStepWithDataForAll(Arrays.asList(new Layer[] { la }));
// find any locked or selected patches
final HashSet<Patch> fixed = new HashSet<Patch>();
for (final Patch p : patches) {
if (p.isLocked2() || selection.contains(p))
fixed.add(p);
}
if (patches.size() == fixed.size()) {
Utils.showMessage("Can't do", "No montage possible: all images are selected,\nand hence all are considered locked.\nSelect only one image to be used as reference, or none.");
return;
}
Utils.log("Using " + fixed.size() + " image" + (fixed.size() == 1 ? "" : "s") + " as reference.");
final Bureaucrat burro = AlignTask.alignPatchesTask(patches, fixed);
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().enlargeToFit(patches);
la.getParent().addTransformStepWithData(col);
}
});
} else if (command.equals("Montage selected images")) {
final Layer la = layer;
if (selection.getSelected(Patch.class).size() < 2) {
Utils.showMessage("Montage needs 2 or more images selected");
return;
}
final Collection<Displayable> col = la.getParent().addTransformStepWithDataForAll(Arrays.asList(new Layer[] { la }));
final Bureaucrat burro = AlignTask.alignSelectionTask(selection);
if (null == burro)
return;
burro.addPostTask(new Runnable() {
@Override
public void run() {
la.getParent().enlargeToFit(selection.getAffected());
la.getParent().addTransformStepWithData(col);
}
});
} else if (command.equals("Montage multiple layers")) {
final GenericDialog gd = new GenericDialog("Choose range");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.showDialog();
if (gd.wasCanceled())
return;
final List<Layer> layers = getLayerSet().getLayers(gd.getNextChoiceIndex(), gd.getNextChoiceIndex());
final Collection<Displayable> col = getLayerSet().addTransformStepWithDataForAll(layers);
final Bureaucrat burro = AlignTask.montageLayersTask(layers);
burro.addPostTask(new Runnable() {
@Override
public void run() {
final Collection<Displayable> ds = new ArrayList<Displayable>();
for (final Layer la : layers) ds.addAll(la.getDisplayables(Patch.class));
getLayerSet().enlargeToFit(ds);
getLayerSet().addTransformStepWithData(col);
}
});
} else if (command.equals("Properties ...")) {
// NOTE the space before the dots, to distinguish from the "Properties..." command that works on Displayable objects.
adjustProperties();
} else if (command.equals("Adjust snapping parameters...")) {
AlignTask.p_snap.setup("Snap");
} else if (command.equals("Adjust fast-marching parameters...")) {
Segmentation.fmp.setup();
} else if (command.equals("Adjust arealist paint parameters...")) {
AreaWrapper.PP.setup();
} else if (command.equals("Fill ROI in alpha mask")) {
if (active.getClass() == Patch.class) {
((Patch) active).keyPressed(new KeyEvent(getCanvas(), -1, System.currentTimeMillis(), 0, KeyEvent.VK_F, 'f'));
}
} else if (command.equals("Fill inverse ROI in alpha mask")) {
if (active.getClass() == Patch.class) {
((Patch) active).keyPressed(new KeyEvent(getCanvas(), -1, System.currentTimeMillis(), Event.SHIFT_MASK, KeyEvent.VK_F, 'f'));
}
} else if (command.equals("Search...")) {
Search.showWindow();
} else if (command.equals("Select all")) {
selection.selectAll();
repaint(Display.this.layer, selection.getBox(), 0);
} else if (command.equals("Select all visible")) {
selection.selectAllVisible();
repaint(Display.this.layer, selection.getBox(), 0);
} else if (command.equals("Select all that match...")) {
final List<Displayable> ds = find();
selection.selectAll(ds);
Utils.showStatus("Added " + ds.size() + " to selection.");
} else if (command.equals("Select none")) {
final Rectangle box = selection.getBox();
selection.clear();
repaint(Display.this.layer, box, 0);
} else if (command.equals("Restore selection")) {
selection.restore();
} else if (command.equals("Select under ROI")) {
final Roi roi = canvas.getFakeImagePlus().getRoi();
if (null == roi)
return;
selection.selectAll(roi, true);
} else if (command.equals("Merge") || command.equals("Split")) {
final Bureaucrat burro = Bureaucrat.create(new Worker.Task(command + "ing AreaLists") {
@Override
public void exec() {
final ArrayList<Displayable> al_sel = selection.getSelected(AreaList.class);
// put active at the beginning, to work as the base on which other's will get merged
al_sel.remove(Display.this.active);
al_sel.add(0, Display.this.active);
final Set<DoStep> dataedits = new HashSet<DoStep>();
if (command.equals("Merge")) {
// Add data undo for active only, which will be edited
dataedits.add(new Displayable.DoEdit(Display.this.active).init(Display.this.active, new String[] { "data" }));
getLayerSet().addChangeTreesStep(dataedits);
final AreaList ali = AreaList.merge(al_sel);
if (null != ali) {
// remove all but the first from the selection
for (int i = 1; i < al_sel.size(); i++) {
final Object ob = al_sel.get(i);
if (ob.getClass() == AreaList.class) {
selection.remove((Displayable) ob);
}
}
selection.updateTransform(ali);
repaint(ali.getLayerSet(), ali, 0);
}
} else if (command.equals("Split")) {
// Add data undo for every AreaList
for (final Displayable d : al_sel) {
if (d.getClass() != AreaList.class)
continue;
dataedits.add(new Displayable.DoEdit(d).init(d, new String[] { "data" }));
}
getLayerSet().addChangeTreesStep(dataedits);
try {
List<AreaList> alis = AreaList.split(al_sel);
for (AreaList ali : alis) {
if (selection.contains(ali))
continue;
selection.add(ali);
}
} catch (Exception e) {
IJError.print(e);
getLayerSet().undoOneStep();
}
}
}
}, Display.this.project);
burro.addPostTask(new Runnable() {
@Override
public void run() {
final Set<DoStep> dataedits = new HashSet<DoStep>();
dataedits.add(new Displayable.DoEdit(Display.this.active).init(Display.this.active, new String[] { "data" }));
getLayerSet().addChangeTreesStep(dataedits);
}
});
burro.goHaveBreakfast();
} else if (command.equals("Reroot")) {
if (!(active instanceof Tree<?>))
return;
getLayerSet().addDataEditStep(active);
if (((Tree) active).reRoot(((Tree) active).getLastVisited())) {
getLayerSet().addDataEditStep(active);
Display.repaint(getLayerSet());
} else {
getLayerSet().removeLastUndoStep();
}
} else if (command.equals("Part subtree")) {
if (!(active instanceof Tree<?>))
return;
if (!Utils.check("Really part the subtree?"))
return;
final LayerSet.DoChangeTrees step = getLayerSet().addChangeTreesStep();
final Set<DoStep> deps = new HashSet<DoStep>();
// I hate java
deps.add(new Displayable.DoEdit(active).init(active, new String[] { "data" }));
step.addDependents(deps);
final List<ZDisplayable> ts = ((Tree) active).splitAt(((Tree) active).getLastVisited());
if (null == ts) {
getLayerSet().removeLastUndoStep();
return;
}
final Displayable elder = Display.this.active;
final HashSet<DoStep> deps2 = new HashSet<DoStep>();
for (final ZDisplayable t : ts) {
deps2.add(new Displayable.DoEdit(t).init(t, new String[] { "data" }));
if (t == elder)
continue;
// will change Display.this.active !
getLayerSet().add(t);
project.getProjectTree().addSibling(elder, t);
}
selection.clear();
selection.selectAll(ts);
selection.add(elder);
final LayerSet.DoChangeTrees step2 = getLayerSet().addChangeTreesStep();
step2.addDependents(deps2);
Display.repaint(getLayerSet());
} else if (command.equals("Show tabular view")) {
if (!(active instanceof Tree<?>))
return;
((Tree<?>) active).createMultiTableView();
} else if (command.equals("Mark")) {
if (!(active instanceof Tree<?>))
return;
final Point p = canvas.consumeLastPopupPoint();
if (null == p)
return;
if (((Tree<?>) active).markNear(p.x, p.y, layer, canvas.getMagnification())) {
Display.repaint(getLayerSet());
}
} else if (command.equals("Clear marks (selected Trees)")) {
for (final Tree<?> t : selection.get(Tree.class)) {
t.unmark();
}
Display.repaint(getLayerSet());
} else if (command.equals("Join")) {
if (!(active instanceof Tree<?>))
return;
final List<Tree<?>> tlines = (List<Tree<?>>) selection.get(active.getClass());
if (((Tree) active).canJoin(tlines)) {
final int nNodes_active = ((Tree) active).getRoot().getSubtreeNodes().size();
String warning = "";
for (final Tree<?> t : tlines) {
if (active == t)
continue;
if (null == t.getRoot()) {
Utils.log("Removed empty tree #" + t.getId() + " from those to join.");
tlines.remove(t);
continue;
}
if (t.getRoot().getSubtreeNodes().size() > nNodes_active) {
warning = "\nWARNING joining into a tree that is not the largest!";
break;
}
}
if (!Utils.check("Join these " + tlines.size() + " trees into the tree " + active + " ?" + warning))
return;
// Record current state
final Set<DoStep> dataedits = new HashSet<DoStep>(tlines.size());
for (final Tree<?> tl : tlines) {
dataedits.add(new Displayable.DoEdit(tl).init(tl, new String[] { "data" }));
}
getLayerSet().addChangeTreesStep(dataedits);
//
((Tree) active).join(tlines);
for (final Tree<?> tl : tlines) {
if (tl == active)
continue;
tl.remove2(false);
}
Display.repaint(getLayerSet());
// Again, to record current state (just the joined tree this time)
final Set<DoStep> dataedits2 = new HashSet<DoStep>(1);
dataedits2.add(new Displayable.DoEdit(active).init(active, new String[] { "data" }));
getLayerSet().addChangeTreesStep(dataedits2);
} else {
Utils.showMessage("Can't do", "Only one tree is selected.\nSelect more than one tree to perform a join operation!");
}
} else if (command.equals("Previous branch node or start")) {
if (!(active instanceof Tree<?>))
return;
final Point p = canvas.consumeLastPopupPoint();
if (null == p)
return;
center(((Treeline) active).findPreviousBranchOrRootPoint(p.x, p.y, layer, canvas));
} else if (command.equals("Next branch node or end")) {
if (!(active instanceof Tree<?>))
return;
final Point p = canvas.consumeLastPopupPoint();
if (null == p)
return;
center(((Tree<?>) active).findNextBranchOrEndPoint(p.x, p.y, layer, canvas));
} else if (command.equals("Root")) {
if (!(active instanceof Tree<?>))
return;
final Point p = canvas.consumeLastPopupPoint();
if (null == p)
return;
center(((Tree) active).createCoordinate(((Tree<?>) active).getRoot()));
} else if (command.equals("Last added node")) {
if (!(active instanceof Tree<?>))
return;
center(((Treeline) active).getLastAdded());
} else if (command.equals("Last edited node")) {
if (!(active instanceof Tree<?>))
return;
center(((Treeline) active).getLastEdited());
} else if (command.equals("Reverse point order")) {
if (!(active instanceof Pipe))
return;
getLayerSet().addDataEditStep(active);
((Pipe) active).reverse();
Display.repaint(Display.this.layer);
getLayerSet().addDataEditStep(active);
} else if (command.equals("View orthoslices")) {
if (!(active instanceof Patch))
return;
Display3D.showOrthoslices(((Patch) active));
} else if (command.equals("View volume")) {
if (!(active instanceof Patch))
return;
Display3D.showVolume(((Patch) active));
} else if (command.equals("Show in 3D")) {
for (final ZDisplayable zd : selection.get(ZDisplayable.class)) {
Display3D.show(zd.getProject().findProjectThing(zd));
}
// handle profile lists ...
final HashSet<ProjectThing> hs = new HashSet<ProjectThing>();
for (final Profile d : selection.get(Profile.class)) {
final ProjectThing profile_list = (ProjectThing) d.getProject().findProjectThing(d).getParent();
if (!hs.contains(profile_list)) {
Display3D.show(profile_list);
hs.add(profile_list);
}
}
} else if (command.equals("Snap")) {
// Take the active if it's a Patch
if (!(active instanceof Patch))
return;
Display.snap((Patch) active);
} else if (command.equals("Blend") || command.equals("Blend (selected images)...")) {
final HashSet<Patch> patches = new HashSet<Patch>(selection.get(Patch.class));
if (patches.size() > 1) {
final GenericDialog gd = new GenericDialog("Blending");
gd.addCheckbox("Respect current alpha mask", true);
gd.showDialog();
if (gd.wasCanceled())
return;
Blending.blend(patches, gd.getNextBoolean());
} else {
IJ.log("Please select more than one overlapping image.");
}
} else if (command.equals("Blend (layer-wise)...")) {
final GenericDialog gd = new GenericDialog("Blending");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.addCheckbox("Respect current alpha mask", true);
gd.addMessage("Filter:");
gd.addStringField("Use only images whose title matches:", "", 30);
gd.addCheckbox("Blend visible patches only", true);
gd.showDialog();
if (gd.wasCanceled())
return;
final boolean respect_alpha_mask = gd.getNextBoolean();
final String toMatch = gd.getNextString().trim();
final String regex = 0 == toMatch.length() ? null : ".*" + toMatch + ".*";
final boolean visible_only = gd.getNextBoolean();
Blending.blendLayerWise(getLayerSet().getLayers(gd.getNextChoiceIndex(), gd.getNextChoiceIndex()), respect_alpha_mask, new Filter<Patch>() {
@Override
public final boolean accept(final Patch patch) {
if (visible_only && !patch.isVisible())
return false;
if (null == regex)
return true;
return patch.getTitle().matches(regex);
}
});
} else if (command.equals("Match intensities (layer-wise)...")) {
Bureaucrat.createAndStart(new Worker.Task("Match intensities") {
@Override
public void exec() {
final MatchIntensities matching = new MatchIntensities();
matching.invoke(getActive());
}
}, project);
} else if (command.equals("Remove intensity maps (layer-wise)...")) {
final GenericDialog gd = new GenericDialog("Remove intensity maps");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.showDialog();
if (gd.wasCanceled())
return;
Bureaucrat.createAndStart(new Worker.Task("Match intensities") {
@Override
public void exec() {
for (final Layer layer : getLayerSet().getLayers(gd.getNextChoiceIndex(), gd.getNextChoiceIndex())) {
for (final Displayable p : layer.getDisplayables(Patch.class)) {
final Patch patch = (Patch) p;
if (patch.clearIntensityMap()) {
patch.updateMipMaps();
}
}
}
}
}, project);
} else if (command.equals("Montage")) {
final Set<Displayable> affected = new HashSet<Displayable>(selection.getAffected());
// make an undo step!
final LayerSet ls = layer.getParent();
ls.addTransformStepWithData(affected);
final Bureaucrat burro = AlignTask.alignSelectionTask(selection);
burro.addPostTask(new Runnable() {
@Override
public void run() {
ls.enlargeToFit(affected);
ls.addTransformStepWithData(affected);
}
});
} else if (command.equals("Lens correction")) {
final Layer la = layer;
la.getParent().addDataEditStep(new HashSet<Displayable>(la.getParent().getDisplayables()));
final Bureaucrat burro = DistortionCorrectionTask.correctDistortionFromSelection(selection);
burro.addPostTask(new Runnable() {
@Override
public void run() {
// no means to know which where modified and from which layers!
la.getParent().addDataEditStep(new HashSet<Displayable>(la.getParent().getDisplayables()));
}
});
} else if (command.equals("Link images...")) {
final GenericDialog gd = new GenericDialog("Options");
gd.addMessage("Linking images to images (within their own layer only):");
final String[] options = { "all images to all images", "each image with any other overlapping image" };
gd.addChoice("Link: ", options, options[1]);
final String[] options2 = { "selected images only", "all images in this layer", "all images in all layers, within the layer only", "all images in all layers, within and across consecutive layers" };
gd.addChoice("Apply to: ", options2, options2[0]);
gd.showDialog();
if (gd.wasCanceled())
return;
final Layer lay = layer;
final HashSet<Displayable> ds = new HashSet<Displayable>(lay.getParent().getDisplayables());
lay.getParent().addDataEditStep(ds, new String[] { "data" });
final boolean overlapping_only = 1 == gd.getNextChoiceIndex();
Collection<Displayable> coll = null;
switch(gd.getNextChoiceIndex()) {
case 0:
coll = selection.getSelected(Patch.class);
Patch.crosslink(coll, overlapping_only);
break;
case 1:
coll = lay.getDisplayables(Patch.class);
Patch.crosslink(coll, overlapping_only);
break;
case 2:
coll = new ArrayList<Displayable>();
for (final Layer la : lay.getParent().getLayers()) {
final Collection<Displayable> acoll = la.getDisplayables(Patch.class);
Patch.crosslink(acoll, overlapping_only);
coll.addAll(acoll);
}
break;
case 3:
final ArrayList<Layer> layers = lay.getParent().getLayers();
Collection<Displayable> lc1 = layers.get(0).getDisplayables(Patch.class);
if (lay == layers.get(0))
coll = lc1;
for (int i = 1; i < layers.size(); i++) {
final Collection<Displayable> lc2 = layers.get(i).getDisplayables(Patch.class);
if (null == coll && Display.this.layer == layers.get(i))
coll = lc2;
final Collection<Displayable> both = new ArrayList<Displayable>();
both.addAll(lc1);
both.addAll(lc2);
Patch.crosslink(both, overlapping_only);
lc1 = lc2;
}
break;
}
if (null != coll)
Display.updateCheckboxes(coll, DisplayablePanel.LINK_STATE, true);
lay.getParent().addDataEditStep(ds);
} else if (command.equals("Unlink all selected images")) {
if (Utils.check("Really unlink selected images?")) {
final Collection<Displayable> ds = selection.getSelected(Patch.class);
for (final Displayable d : ds) {
d.unlink();
}
Display.updateCheckboxes(ds, DisplayablePanel.LINK_STATE);
}
} else if (command.equals("Unlink all")) {
if (Utils.check("Really unlink all objects from all layers?")) {
final Collection<Displayable> ds = layer.getParent().getDisplayables();
for (final Displayable d : ds) {
d.unlink();
}
Display.updateCheckboxes(ds, DisplayablePanel.LINK_STATE);
}
} else if (command.equals("Calibration...")) {
try {
IJ.run(canvas.getFakeImagePlus(), "Properties...", "");
Display.updateTitle(getLayerSet());
// repaint layer names
project.getLayerTree().updateUILater();
} catch (final RuntimeException re) {
Utils.log2("Calibration dialog canceled.");
}
} else if (command.equals("Grid overlay...")) {
if (null == gridoverlay)
gridoverlay = new GridOverlay();
gridoverlay.setup(canvas.getFakeImagePlus().getRoi());
canvas.repaint(false);
} else if (command.equals("Enhance contrast (selected images)...")) {
final Layer la = layer;
final ArrayList<Displayable> selected = selection.getSelected(Patch.class);
final HashSet<Displayable> ds = new HashSet<Displayable>(selected);
la.getParent().addDataEditStep(ds);
final Displayable active = Display.this.getActive();
final Patch ref = active.getClass() == Patch.class ? (Patch) active : null;
final Bureaucrat burro = getProject().getLoader().enhanceContrast(selected, ref);
burro.addPostTask(new Runnable() {
@Override
public void run() {
la.getParent().addDataEditStep(ds);
}
});
} else if (command.equals("Enhance contrast layer-wise...")) {
// ask for range of layers
final GenericDialog gd = new GenericDialog("Choose range");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.showDialog();
if (gd.wasCanceled())
return;
// exclusive end
final java.util.List<Layer> layers = layer.getParent().getLayers().subList(gd.getNextChoiceIndex(), gd.getNextChoiceIndex() + 1);
final HashSet<Displayable> ds = new HashSet<Displayable>();
for (final Layer l : layers) ds.addAll(l.getDisplayables(Patch.class));
getLayerSet().addDataEditStep(ds);
final Bureaucrat burro = project.getLoader().enhanceContrast(layers);
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().addDataEditStep(ds);
}
});
} else if (command.equals("Adjust image filters (selected images)")) {
if (selection.isEmpty() || !(active instanceof Patch))
return;
FilterEditor.GUI(selection.get(Patch.class), (Patch) active);
} else if (command.equals("Set Min and Max layer-wise...")) {
final Displayable active = getActive();
double min = 0;
double max = 0;
if (null != active && active.getClass() == Patch.class) {
min = ((Patch) active).getMin();
max = ((Patch) active).getMax();
}
final GenericDialog gd = new GenericDialog("Min and Max");
gd.addMessage("Set min and max to all images in the layer range");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.addNumericField("min: ", min, 2);
gd.addNumericField("max: ", max, 2);
gd.showDialog();
if (gd.wasCanceled())
return;
//
min = gd.getNextNumber();
max = gd.getNextNumber();
final ArrayList<Displayable> al = new ArrayList<Displayable>();
for (final Layer la : layer.getParent().getLayers().subList(gd.getNextChoiceIndex(), gd.getNextChoiceIndex() + 1)) {
// exclusive end
al.addAll(la.getDisplayables(Patch.class));
}
final HashSet<Displayable> ds = new HashSet<Displayable>(al);
getLayerSet().addDataEditStep(ds);
final Bureaucrat burro = project.getLoader().setMinAndMax(al, min, max);
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().addDataEditStep(ds);
}
});
} else if (command.equals("Set Min and Max (selected images)...")) {
final Displayable active = getActive();
double min = 0;
double max = 0;
if (null != active && active.getClass() == Patch.class) {
min = ((Patch) active).getMin();
max = ((Patch) active).getMax();
}
final GenericDialog gd = new GenericDialog("Min and Max");
gd.addMessage("Set min and max to all selected images");
gd.addNumericField("min: ", min, 2);
gd.addNumericField("max: ", max, 2);
gd.showDialog();
if (gd.wasCanceled())
return;
//
min = gd.getNextNumber();
max = gd.getNextNumber();
final HashSet<Displayable> ds = new HashSet<Displayable>(selection.getSelected(Patch.class));
getLayerSet().addDataEditStep(ds);
final Bureaucrat burro = project.getLoader().setMinAndMax(selection.getSelected(Patch.class), min, max);
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().addDataEditStep(ds);
}
});
} else if (command.equals("Adjust min and max (selected images)...")) {
adjustMinAndMaxGUI();
} else if (command.equals("Mask image borders (layer-wise)...")) {
final GenericDialog gd = new GenericDialog("Mask borders");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.addMessage("Borders:");
gd.addNumericField("left: ", 6, 2);
gd.addNumericField("top: ", 6, 2);
gd.addNumericField("right: ", 6, 2);
gd.addNumericField("bottom: ", 6, 2);
gd.showDialog();
if (gd.wasCanceled())
return;
final Collection<Layer> layers = layer.getParent().getLayers().subList(gd.getNextChoiceIndex(), gd.getNextChoiceIndex() + 1);
final HashSet<Displayable> ds = new HashSet<Displayable>();
for (final Layer l : layers) ds.addAll(l.getDisplayables(Patch.class));
getLayerSet().addDataEditStep(ds);
final Bureaucrat burro = project.getLoader().maskBordersLayerWise(layers, (int) gd.getNextNumber(), (int) gd.getNextNumber(), (int) gd.getNextNumber(), (int) gd.getNextNumber());
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().addDataEditStep(ds);
}
});
} else if (command.equals("Mask image borders (selected images)...")) {
final GenericDialog gd = new GenericDialog("Mask borders");
gd.addMessage("Borders:");
gd.addNumericField("left: ", 6, 2);
gd.addNumericField("top: ", 6, 2);
gd.addNumericField("right: ", 6, 2);
gd.addNumericField("bottom: ", 6, 2);
gd.showDialog();
if (gd.wasCanceled())
return;
final Collection<Displayable> patches = selection.getSelected(Patch.class);
final HashSet<Displayable> ds = new HashSet<Displayable>(patches);
getLayerSet().addDataEditStep(ds);
final Bureaucrat burro = project.getLoader().maskBorders(patches, (int) gd.getNextNumber(), (int) gd.getNextNumber(), (int) gd.getNextNumber(), (int) gd.getNextNumber());
burro.addPostTask(new Runnable() {
@Override
public void run() {
getLayerSet().addDataEditStep(ds);
}
});
} else if (command.equals("Remove alpha masks (layer-wise)...")) {
final GenericDialog gd = new GenericDialog("Remove alpha masks");
Utils.addLayerRangeChoices(Display.this.layer, gd);
gd.addCheckbox("Visible only", true);
gd.showDialog();
if (gd.wasCanceled())
return;
final Collection<Layer> layers = layer.getParent().getLayers().subList(gd.getNextChoiceIndex(), gd.getNextChoiceIndex() + 1);
final boolean visible_only = gd.getNextBoolean();
final Collection<Patch> patches = new ArrayList<Patch>();
for (final Layer l : layers) {
patches.addAll((Collection<Patch>) (Collection) l.getDisplayables(Patch.class, visible_only));
}
Display.removeAlphaMasks(patches);
} else if (command.equals("Remove alpha masks (selected images)...")) {
Display.removeAlphaMasks(selection.get(Patch.class));
} else if (command.equals("Split images under polyline ROI")) {
final Roi roi = canvas.getFakeImagePlus().getRoi();
if (null == roi)
return;
if (!(roi.getType() == Roi.POLYLINE || roi.getType() == Roi.FREELINE)) {
Utils.showMessage("Need a polyline or freeline ROI, not just any ROI!");
return;
}
if (!Utils.check("Really split images under the ROI?")) {
return;
}
// OK identify images whose contour intersects the ROI
final Set<Displayable> col = new HashSet<Displayable>();
// FreehandRoi is a subclass of PolygonRoi
final PolygonRoi proi = (PolygonRoi) roi;
final int[] x = proi.getXCoordinates(), y = proi.getYCoordinates();
final Rectangle b = proi.getBounds();
final Polygon[] pols = new Polygon[proi.getNCoordinates() - 1];
for (int i = 0; i < pols.length; i++) {
pols[i] = new Polygon(new int[] { b.x + x[i], b.x + x[i] + 1, b.x + x[i + 1], b.x + x[i + 1] + 1 }, new int[] { b.y + y[i], b.y + y[i], b.y + y[i + 1], b.y + y[i + 1] }, 4);
}
for (final Patch p : getLayer().getAll(Patch.class)) {
if (!p.isVisible())
continue;
final Area a = p.getArea();
for (int i = 0; i < pols.length; i++) {
final Area c = new Area(pols[i]);
c.intersect(a);
if (M.isEmpty(c))
continue;
// Else, add it:
col.add(p);
break;
}
}
if (col.isEmpty()) {
Utils.showMessage("No images intersect the ROI!");
return;
}
for (int i = 1; i < proi.getNCoordinates(); i++) {
for (int k = i + 2; k < proi.getNCoordinates(); k++) {
// check if the two segments intersect
if (null != M.computeSegmentsIntersection(x[i - 1], y[i - 1], x[i], y[i], x[k - 1], y[k - 1], x[k], y[k])) {
Utils.showMessage("Cannot split images with a polygon ROI that intersects itself!");
return;
}
}
}
final Area[] as = M.splitArea(new Area(getLayerSet().get2DBounds()), proi, getLayerSet().get2DBounds());
final Color[] c = new Color[] { Color.blue, Color.red };
int i = 0;
for (final Area a : as) {
// Utils.log2("Added overlay " + i + " with color " + c[i] + " and area " + AreaCalculations.area(a.getPathIterator(null)));
getLayer().getOverlay().add(a, c[i++], null, true, false, 0.4f);
}
Display.repaint(getLayer());
final YesNoDialog yn = new YesNoDialog(frame, "Check", "Does the splitting match your expectations?\nPush 'yes' to split the images.", false);
yn.setModal(false);
for (final WindowListener wl : yn.getWindowListeners()) yn.removeWindowListener(wl);
yn.setClosingTask(new Runnable() {
@Override
public void run() {
try {
// Remove overlay shapes
for (final Area a : as) {
getLayer().getOverlay().remove(a);
}
if (!yn.yesPressed()) {
Utils.log2("Pushed 'no'");
return;
}
// Split intersecting patches
// Duplicate each intersecting patch, and assign a[0] to the original and a[1] to the copy, as mask.
Bureaucrat.createAndStart(new Worker.Task("Spliting images") {
@Override
public void exec() {
final Roi r1 = new ShapeRoi(as[0]), r2 = new ShapeRoi(as[1]);
final ArrayList<Future<?>> fus = new ArrayList<Future<?>>();
for (final Patch p : (Collection<Patch>) (Collection) col) {
final Patch copy = (Patch) p.clone(p.getProject(), false);
p.addAlphaMask(r1, 0);
copy.addAlphaMask(r2, 0);
fus.add(p.updateMipMaps());
fus.add(copy.updateMipMaps());
// after submitting mipmaps, since it will get added to all Displays and repainted.
p.getLayer().add(copy);
}
Utils.wait(fus);
}
}, project);
} catch (final Throwable t) {
IJError.print(t);
} finally {
yn.dispose();
Display.repaint(getLayer());
}
}
});
yn.setVisible(true);
} else if (command.equals("Duplicate")) {
// only Patch and DLabel, i.e. Layer-only resident objects that don't exist in the Project Tree
final HashSet<Class> accepted = new HashSet<Class>();
accepted.add(Patch.class);
accepted.add(DLabel.class);
accepted.add(Stack.class);
final ArrayList<Displayable> originals = new ArrayList<Displayable>();
final ArrayList<Displayable> selected = selection.getSelected();
for (final Displayable d : selected) {
if (accepted.contains(d.getClass())) {
originals.add(d);
}
}
if (originals.size() > 0) {
getLayerSet().addChangeTreesStep();
for (final Displayable d : originals) {
if (d instanceof ZDisplayable) {
d.getLayerSet().add((ZDisplayable) d.clone());
} else {
d.getLayer().add(d.clone());
}
}
getLayerSet().addChangeTreesStep();
} else if (selected.size() > 0) {
Utils.log("Can only duplicate images and text labels.\nDuplicate *other* objects in the Project Tree.\n");
}
} else if (command.equals("Create subproject")) {
// Choose a 2D rectangle
final Roi roi = canvas.getFakeImagePlus().getRoi();
Rectangle bounds;
if (null != roi) {
if (!Utils.check("Use bounds as defined by the ROI:\n" + roi.getBounds() + " ?"))
return;
bounds = roi.getBounds();
} else
bounds = getLayerSet().get2DBounds();
// Choose a layer range, and whether to ignore hidden images
final GenericDialog gd = new GenericDialog("Choose layer range");
Utils.addLayerRangeChoices(layer, gd);
gd.addCheckbox("Ignore hidden images", true);
gd.showDialog();
if (gd.wasCanceled())
return;
final Layer first = layer.getParent().getLayer(gd.getNextChoiceIndex());
final Layer last = layer.getParent().getLayer(gd.getNextChoiceIndex());
final boolean ignore_hidden_patches = gd.getNextBoolean();
final Project sub = getProject().createSubproject(bounds, first, last, ignore_hidden_patches);
if (null == sub) {
Utils.log("ERROR: failed to create subproject.");
return;
}
final LayerSet subls = sub.getRootLayerSet();
Display.createDisplay(sub, subls.getLayer(0));
} else if (command.startsWith("Image stack under selected Arealist")) {
if (null == active || active.getClass() != AreaList.class)
return;
final GenericDialog gd = new GenericDialog("Stack options");
final String[] types = { "8-bit", "16-bit", "32-bit", "RGB" };
gd.addChoice("type:", types, types[0]);
gd.addSlider("Scale: ", 1, 100, 100);
gd.showDialog();
if (gd.wasCanceled())
return;
final int type;
switch(gd.getNextChoiceIndex()) {
case 0:
type = ImagePlus.GRAY8;
break;
case 1:
type = ImagePlus.GRAY16;
break;
case 2:
type = ImagePlus.GRAY32;
break;
case 3:
type = ImagePlus.COLOR_RGB;
break;
default:
type = ImagePlus.GRAY8;
break;
}
final ImagePlus imp = ((AreaList) active).getStack(type, gd.getNextNumber() / 100);
if (null != imp)
imp.show();
} else if (command.equals("Fly through selected Treeline/AreaTree")) {
if (null == active || !(active instanceof Tree<?>))
return;
Bureaucrat.createAndStart(new Worker.Task("Creating fly through", true) {
@Override
public void exec() {
final GenericDialog gd = new GenericDialog("Fly through");
gd.addNumericField("Width", 512, 0);
gd.addNumericField("Height", 512, 0);
final String[] types = new String[] { "8-bit gray", "Color RGB" };
gd.addChoice("Image type", types, types[0]);
gd.addSlider("scale", 0, 100, 100);
gd.addCheckbox("save to file", false);
gd.showDialog();
if (gd.wasCanceled())
return;
final int w = (int) gd.getNextNumber();
final int h = (int) gd.getNextNumber();
final int type = 0 == gd.getNextChoiceIndex() ? ImagePlus.GRAY8 : ImagePlus.COLOR_RGB;
final double scale = gd.getNextNumber();
if (w <= 0 || h <= 0) {
Utils.log("Invalid width or height: " + w + ", " + h);
return;
}
if (0 == scale || Double.isNaN(scale)) {
Utils.log("Invalid scale: " + scale);
return;
}
String dir = null;
if (gd.getNextBoolean()) {
final DirectoryChooser dc = new DirectoryChooser("Target directory");
dir = dc.getDirectory();
// canceled
if (null == dir)
return;
dir = Utils.fixDir(dir);
}
final ImagePlus imp = ((Tree<?>) active).flyThroughMarked(w, h, scale / 100, type, dir);
if (null == imp) {
Utils.log("Mark a node first!");
return;
}
imp.show();
}
}, project);
} else if (command.startsWith("Arealists as labels")) {
final GenericDialog gd = new GenericDialog("Export labels");
gd.addSlider("Scale: ", 1, 100, 100);
final String[] options = { "All area list", "Selected area lists" };
gd.addChoice("Export: ", options, options[0]);
Utils.addLayerRangeChoices(layer, gd);
gd.addCheckbox("Visible only", true);
gd.showDialog();
if (gd.wasCanceled())
return;
final float scale = (float) (gd.getNextNumber() / 100);
final java.util.List<Displayable> al = (java.util.List<Displayable>) (0 == gd.getNextChoiceIndex() ? layer.getParent().getZDisplayables(AreaList.class) : selection.getSelectedSorted(AreaList.class));
if (null == al) {
Utils.log("No area lists found to export.");
return;
}
// Generics are ... a pain? I don't understand them? They fail when they shouldn't? And so easy to workaround that they are a shame?
final int first = gd.getNextChoiceIndex();
final int last = gd.getNextChoiceIndex();
final boolean visible_only = gd.getNextBoolean();
if (-1 != command.indexOf("(amira)")) {
AreaList.exportAsLabels(al, canvas.getFakeImagePlus().getRoi(), scale, first, last, visible_only, true, true);
} else if (-1 != command.indexOf("(tif)")) {
AreaList.exportAsLabels(al, canvas.getFakeImagePlus().getRoi(), scale, first, last, visible_only, false, false);
}
} else if (command.equals("Project properties...")) {
project.adjustProperties();
} else if (command.equals("Release memory...")) {
Bureaucrat.createAndStart(new Worker("Releasing memory") {
@Override
public void run() {
startedWorking();
try {
final GenericDialog gd = new GenericDialog("Release Memory");
final int max = (int) (IJ.maxMemory() / 1000000);
gd.addSlider("Megabytes: ", 0, max, max / 2);
gd.showDialog();
if (!gd.wasCanceled()) {
final int n_mb = (int) gd.getNextNumber();
project.getLoader().releaseToFit((long) n_mb * 1000000);
}
} catch (final Throwable e) {
IJError.print(e);
} finally {
finishedWorking();
}
}
}, project);
} else if (command.equals("Create sibling project with retiled layers")) {
final GenericDialog gd = new GenericDialog("Export flattened layers");
gd.addNumericField("Tile_width", 2048, 0);
gd.addNumericField("Tile_height", 2048, 0);
final String[] types = new String[] { "16-bit", "RGB color" };
gd.addChoice("Export_image_type", types, types[0]);
gd.addCheckbox("Create mipmaps", true);
gd.addNumericField("Number_of_threads_to_use", Runtime.getRuntime().availableProcessors(), 0);
gd.showDialog();
if (gd.wasCanceled())
return;
final DirectoryChooser dc = new DirectoryChooser("Choose target folder");
final String folder = dc.getDirectory();
if (null == folder)
return;
final int tileWidth = (int) gd.getNextNumber(), tileHeight = (int) gd.getNextNumber();
if (tileWidth < 0 || tileHeight < 0) {
Utils.showMessage("Invalid tile sizes: " + tileWidth + ", " + tileHeight);
return;
}
if (tileWidth != tileHeight) {
if (!Utils.check("The tile width (" + tileWidth + ") differs from the tile height (" + tileHeight + ").\nContinue anyway?")) {
return;
}
}
final int imageType = 0 == gd.getNextChoiceIndex() ? ImagePlus.GRAY16 : ImagePlus.COLOR_RGB;
final boolean createMipMaps = gd.getNextBoolean();
final int nThreads = (int) gd.getNextNumber();
Bureaucrat.createAndStart(new Worker.Task("Export flattened sibling project") {
@Override
public void exec() {
try {
ProjectTiler.createRetiledSibling(project, folder, tileWidth, tileHeight, imageType, true, nThreads, createMipMaps);
} catch (final Throwable t) {
Utils.showMessage("ERROR: " + t);
IJError.print(t);
}
}
}, project);
} else if (command.equals("Flush image cache")) {
Loader.releaseAllCaches();
} else if (command.equals("Regenerate all mipmaps")) {
project.getLoader().regenerateMipMaps(getLayerSet().getDisplayables(Patch.class));
} else if (command.equals("Regenerate mipmaps (selected images)")) {
project.getLoader().regenerateMipMaps(selection.getSelected(Patch.class));
} else if (command.equals("Tags...")) {
// get a file first
final File f = Utils.chooseFile(null, "tags", ".xml");
if (null == f)
return;
if (!Utils.saveToFile(f, getLayerSet().exportTags())) {
Utils.logAll("ERROR when saving tags to file " + f.getAbsolutePath());
}
} else if (command.equals("Tags ...")) {
final String[] ff = Utils.selectFile("Import tags");
if (null == ff)
return;
final GenericDialog gd = new GenericDialog("Import tags");
final String[] modes = new String[] { "Append to current tags", "Replace current tags" };
gd.addChoice("Import tags mode:", modes, modes[0]);
gd.addMessage("Replacing current tags\nwill remove all tags\n from all nodes first!");
gd.showDialog();
if (gd.wasCanceled())
return;
getLayerSet().importTags(new StringBuilder(ff[0]).append('/').append(ff[1]).toString(), 1 == gd.getNextChoiceIndex());
} else if (command.equals("Connectivity graph...")) {
Bureaucrat.createAndStart(new Worker.Task("Connectivity graph") {
@Override
public void exec() {
Graph.extractAndShowGraph(getLayerSet());
}
}, getProject());
} else if (command.equals("NeuroML...")) {
final GenericDialog gd = new GenericDialog("Export NeuroML");
final String[] a = new String[] { "NeuroML (arbors and synapses)", "MorphML (arbors)" };
gd.addChoice("Type:", a, a[0]);
final String[] b = new String[] { "All treelines and areatrees", "Selected treelines and areatrees" };
gd.addChoice("Export:", b, b[0]);
gd.showDialog();
if (gd.wasCanceled())
return;
final int type = gd.getNextChoiceIndex();
final int export = gd.getNextChoiceIndex();
//
final SaveDialog sd = new SaveDialog("Choose .mml file", null, ".mml");
final String filename = sd.getFileName();
// canceled
if (null == filename)
return;
final File f = new File(sd.getDirectory() + filename);
//
Bureaucrat.createAndStart(new Worker.Task("Export NeuroML") {
@Override
public void exec() {
OutputStreamWriter w = null;
try {
final Set<Tree<?>> trees = new HashSet<Tree<?>>();
Collection<? extends Displayable> ds = null;
switch(export) {
case 0:
ds = getLayerSet().getZDisplayables();
break;
case 1:
ds = selection.getSelected();
break;
}
for (final Displayable d : ds) {
if (d.getClass() == Treeline.class || d.getClass() == AreaTree.class) {
trees.add((Tree<?>) d);
}
}
if (trees.isEmpty()) {
Utils.showMessage("No trees to export!");
return;
}
//
// encoding in Latin 1 (for macosx not to mess around
w = new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(f), 65536), "8859_1");
//
switch(type) {
case 0:
NeuroML.exportNeuroML(trees, w);
break;
case 1:
NeuroML.exportMorphML(trees, w);
break;
}
//
w.flush();
w.close();
//
} catch (final Throwable t) {
IJError.print(t);
try {
if (null != w)
w.close();
} catch (final Exception ee) {
IJError.print(ee);
}
}
}
}, getProject());
} else if (command.equals("Measure")) {
if (selection.isEmpty()) {
Utils.log("Nothing selected to measure!");
return;
}
selection.measure();
} else if (command.equals("Area interpolation options...")) {
final GenericDialog gd = new GenericDialog("Area interpolation");
final boolean a = project.getBooleanProperty(AreaUtils.always_interpolate_areas_with_distance_map);
gd.addCheckbox("Always use distance map method", a);
gd.showDialog();
if (gd.wasCanceled())
return;
project.setProperty(AreaUtils.always_interpolate_areas_with_distance_map, gd.getNextBoolean() ? "true" : null);
} else {
Utils.log2("Display: don't know what to do with command " + command);
}
}
});
}
use of ini.trakem2.display.YesNoDialog in project TrakEM2 by trakem2.
the class Loader method importStack.
/**
* Imports an image stack from a multitiff file and places each slice in the proper layer, creating new layers as it goes. If the given stack is null, popup a file dialog to choose one
*/
public Bureaucrat importStack(final Layer first_layer, final double x, final double y, final ImagePlus imp_stack_, final boolean ask_for_data, final String filepath_, final boolean one_patch_per_layer_) {
Utils.log2("Loader.importStack filepath: " + filepath_);
if (null == first_layer)
return null;
final Worker worker = new Worker("import stack") {
@Override
public void run() {
startedWorking();
try {
String filepath = filepath_;
boolean one_patch_per_layer = one_patch_per_layer_;
/* On drag and drop the stack is not null! */
// Utils.log2("imp_stack_ is " + imp_stack_);
ImagePlus[] stks = null;
boolean choose = false;
if (null == imp_stack_) {
stks = Utils.findOpenStacks();
choose = null == stks || stks.length > 0;
} else {
stks = new ImagePlus[] { imp_stack_ };
}
ImagePlus imp_stack = null;
// ask to open a stack if it's null
if (null == stks) {
// choose one
imp_stack = openStack();
} else if (choose) {
// choose one from the list
final GenericDialog gd = new GenericDialog("Choose one");
gd.addMessage("Choose a stack from the list or 'open...' to bring up a file chooser dialog:");
final String[] list = new String[stks.length + 1];
for (int i = 0; i < list.length - 1; i++) {
list[i] = stks[i].getTitle();
}
list[list.length - 1] = "[ Open stack... ]";
gd.addChoice("choose stack: ", list, list[0]);
gd.showDialog();
if (gd.wasCanceled()) {
finishedWorking();
return;
}
final int i_choice = gd.getNextChoiceIndex();
if (list.length - 1 == i_choice) {
// the open... command
imp_stack = first_layer.getProject().getLoader().openStack();
} else {
imp_stack = stks[i_choice];
}
} else {
imp_stack = imp_stack_;
}
// check:
if (null == imp_stack) {
finishedWorking();
return;
}
final String props = (String) imp_stack.getProperty("Info");
// check if it's amira labels stack to prevent missimports
if (null != props && -1 != props.indexOf("Materials {")) {
final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "Warning", "You are importing a stack of Amira labels as a regular image stack. Continue anyway?");
if (!yn.yesPressed()) {
finishedWorking();
return;
}
}
// String dir = imp_stack.getFileInfo().directory;
final double layer_width = first_layer.getLayerWidth();
final double layer_height = first_layer.getLayerHeight();
final double current_thickness = first_layer.getThickness();
double thickness = current_thickness;
boolean expand_layer_set = false;
boolean lock_stack = false;
// int anchor = LayerSet.NORTHWEST; //default
if (ask_for_data) {
// ask for slice separation in pixels
final GenericDialog gd = new GenericDialog("Slice separation?");
gd.addMessage("Please enter the slice thickness, in pixels");
// assuming pixelWidth == pixelHeight
gd.addNumericField("slice_thickness: ", Math.abs(imp_stack.getCalibration().pixelDepth / imp_stack.getCalibration().pixelHeight), 3);
if (layer_width != imp_stack.getWidth() || layer_height != imp_stack.getHeight()) {
gd.addCheckbox("Resize canvas to fit stack", true);
// gd.addChoice("Anchor: ", LayerSet.ANCHORS, LayerSet.ANCHORS[0]);
}
gd.addCheckbox("Lock stack", false);
final String[] importStackTypes = { "One slice per layer (Patches)", "Image volume (Stack)" };
if (imp_stack.getStack().isVirtual()) {
one_patch_per_layer = true;
}
gd.addChoice("Import stack as:", importStackTypes, importStackTypes[0]);
((Component) gd.getChoices().get(0)).setEnabled(!imp_stack.getStack().isVirtual());
gd.showDialog();
if (gd.wasCanceled()) {
if (null == stks) {
// flush only if it was not open before
flush(imp_stack);
}
finishedWorking();
return;
}
if (layer_width != imp_stack.getWidth() || layer_height != imp_stack.getHeight()) {
expand_layer_set = gd.getNextBoolean();
// anchor = gd.getNextChoiceIndex();
}
lock_stack = gd.getNextBoolean();
thickness = gd.getNextNumber();
// check provided thickness with that of the first layer:
if (thickness != current_thickness) {
if (1 == first_layer.getParent().size() && first_layer.isEmpty()) {
final YesNoCancelDialog yn = new YesNoCancelDialog(IJ.getInstance(), "Mismatch!", "The current layer's thickness is " + current_thickness + "\nwhich is " + (thickness < current_thickness ? "larger" : "smaller") + " than\nthe desired " + thickness + " for each stack slice.\nAdjust current layer's thickness to " + thickness + " ?");
if (yn.cancelPressed()) {
// was opened new
if (null != imp_stack_)
flush(imp_stack);
finishedWorking();
return;
} else if (yn.yesPressed()) {
first_layer.setThickness(thickness);
// The rest of layers, created new, will inherit the same thickness
}
} else {
final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "WARNING", "There's more than one layer or the current layer is not empty\nso the thickness cannot be adjusted. Proceed anyway?");
if (!yn.yesPressed()) {
finishedWorking();
return;
}
}
}
one_patch_per_layer = imp_stack.getStack().isVirtual() || 0 == gd.getNextChoiceIndex();
}
if (null == imp_stack.getStack()) {
Utils.showMessage("Not a stack.");
finishedWorking();
return;
}
// WARNING: there are fundamental issues with calibration, because the Layer thickness is disconnected from the Calibration pixelDepth
// set LayerSet calibration if there is no calibration
boolean calibrate = true;
if (ask_for_data && first_layer.getParent().isCalibrated()) {
if (!ControlWindow.isGUIEnabled()) {
Utils.log2("Loader.importStack: overriding LayerSet calibration with that of the imported stack.");
} else {
final YesNoDialog yn = new YesNoDialog("Calibration", "The layer set is already calibrated. Override with the stack calibration values?");
if (!yn.yesPressed()) {
calibrate = false;
}
}
}
if (calibrate) {
first_layer.getParent().setCalibration(imp_stack.getCalibration());
}
if (layer_width < imp_stack.getWidth() || layer_height < imp_stack.getHeight()) {
expand_layer_set = true;
}
if (imp_stack.getStack().isVirtual()) {
// do nothing
} else if (null == filepath) {
// try to get it from the original FileInfo
final FileInfo fi = imp_stack.getOriginalFileInfo();
if (null != fi && null != fi.directory && null != fi.fileName) {
filepath = fi.directory.replace('\\', '/');
if (!filepath.endsWith("/"))
filepath += '/';
filepath += fi.fileName;
}
Utils.log2("Getting filepath from FileInfo: " + filepath);
// check that file exists, otherwise save a copy in the storage folder
if (null == filepath || (!filepath.startsWith("http://") && !new File(filepath).exists())) {
filepath = handlePathlessImage(imp_stack);
}
} else {
filepath = filepath.replace('\\', '/');
}
// Import as Stack ZDisplayable object:
if (!one_patch_per_layer) {
final Stack st = new Stack(first_layer.getProject(), new File(filepath).getName(), x, y, first_layer, filepath);
first_layer.getParent().add(st);
finishedWorking();
return;
}
// Place the first slice in the current layer, and then query the parent LayerSet for subsequent layers, and create them if not present.
final Patch last_patch = Loader.this.importStackAsPatches(first_layer.getProject(), first_layer, x, y, imp_stack, null != imp_stack_ && null != imp_stack_.getCanvas(), filepath);
if (null != last_patch) {
last_patch.setLocked(lock_stack);
Display.updateCheckboxes(last_patch.getLinkedGroup(null), DisplayablePanel.LOCK_STATE, true);
}
if (expand_layer_set) {
last_patch.getLayer().getParent().setMinimumDimensions();
}
Utils.log2("props: " + props);
// check if it's an amira stack, then ask to import labels
if (null != props && -1 == props.indexOf("Materials {") && -1 != props.indexOf("CoordType")) {
final YesNoDialog yn = new YesNoDialog(IJ.getInstance(), "Amira Importer", "Import labels as well?");
if (yn.yesPressed()) {
// select labels
final Collection<AreaList> alis = AmiraImporter.importAmiraLabels(first_layer, last_patch.getX(), last_patch.getY(), imp_stack.getOriginalFileInfo().directory);
if (null != alis) {
// import all created AreaList as nodes in the ProjectTree under a new imported_segmentations node
first_layer.getProject().getProjectTree().insertSegmentations(alis);
// link them to the images
for (final AreaList ali : alis) {
ali.linkPatches();
}
}
}
}
// it is safe not to flush the imp_stack, because all its resources are being used anyway (all the ImageProcessor), and it has no awt.Image. Unless it's being shown in ImageJ, and then it will be flushed on its own when the user closes its window.
} catch (final Exception e) {
IJError.print(e);
}
finishedWorking();
}
};
return Bureaucrat.createAndStart(worker, first_layer.getProject());
}
use of ini.trakem2.display.YesNoDialog in project TrakEM2 by trakem2.
the class FilePathRepair method fixPath.
private static void fixPath(final JTable table, final PathTableModel data, final int row, final boolean fix_similar, final boolean fix_all, final boolean update_mipmaps) throws Exception {
synchronized (projects) {
final Patch patch = data.vp.get(row);
if (null == patch)
return;
final String old_path = patch.getImageFilePath();
final File f = new File(old_path);
if (f.exists()) {
Utils.log("File exists for " + patch + " at " + f.getAbsolutePath() + "\n --> not updating path.");
data.remove(row);
return;
}
// Else, pop up file dialog
OpenDialog od = new OpenDialog("Select image file", OpenDialog.getDefaultDirectory(), null);
String dir = od.getDirectory();
final String filename = od.getFileName();
// dialog was canceled
if (null == dir)
return;
if (IJ.isWindows())
dir = dir.replace('\\', '/');
if (!dir.endsWith("/"))
dir += "/";
// Compare filenames
if (!filename.equals(f.getName())) {
YesNoDialog yn = new YesNoDialog(projects.get(patch.getProject()).frame, "WARNING", "Different file names!\n old: " + f.getName() + "\n new: " + filename + "\nSet to new file name?");
if (!yn.yesPressed())
return;
// Remove mipmaps: would not be found with the new name and the old ones would remain behind unused
if (!f.getName().equals(new File(old_path).getName())) {
// remove mipmaps: the name wouldn't match otherwise
patch.getProject().getLoader().removeMipMaps(patch);
}
}
//
String wrong_parent_path = new File(data.vpath.get(row)).getParent();
wrong_parent_path = wrong_parent_path.replace('\\', '/');
// not File.separatorChar, TrakEM2 uses '/' as folder separator
if (!wrong_parent_path.endsWith("/"))
wrong_parent_path = new StringBuilder(wrong_parent_path).append('/').toString();
final String path = new StringBuilder(dir).append(filename).toString();
// keep track of fixed slices to avoid calling n_slices * n_slices times!
final HashSet<Patch> fixed = new HashSet<Patch>();
int n_fixed = 0;
if (-1 == patch.getFilePath().lastIndexOf("-----#slice=")) {
if (!fixPatchPath(patch, path, update_mipmaps)) {
return;
}
data.remove(patch);
fixed.add(patch);
n_fixed += 1;
} else {
int n = fixStack(data, fixed, patch.getStackPatches(), old_path, path, update_mipmaps);
if (0 == n) {
// some error ocurred, no paths fixed
return;
}
n_fixed += n;
// data already cleared of removed patches by fixStack
}
String good_parent_path = dir;
// not File.separatorChar, TrakEM2 uses '/' as folder separator
if (!dir.endsWith("/"))
good_parent_path = new StringBuilder(good_parent_path).append('/').toString();
// Check for similar parent paths and see if they can be fixed
if (fix_similar) {
for (int i = data.vp.size() - 1; i > -1; i--) {
final String wrong_path = data.vpath.get(i);
final Patch p = data.vp.get(i);
if (wrong_path.startsWith(wrong_parent_path)) {
// try to fix as well
final File file = new File(new StringBuilder(good_parent_path).append(wrong_path.substring(wrong_parent_path.length())).toString());
if (file.exists()) {
if (-1 == p.getFilePath().lastIndexOf("-----#slice=")) {
if (!fixed.contains(p) && fixPatchPath(p, file.getAbsolutePath(), update_mipmaps)) {
// not by 'i' but by Patch, since if some fail the order is not the same
data.remove(p);
n_fixed++;
fixed.add(p);
}
} else {
if (fixed.contains(p))
continue;
n_fixed += fixStack(data, fixed, p.getStackPatches(), wrong_path, file.getAbsolutePath(), update_mipmaps);
}
}
}
}
}
if (fix_all) {
// traverse all Patch from the entire project, minus those already fixed
for (final Displayable d : patch.getLayerSet().getDisplayables(Patch.class)) {
final Patch p = (Patch) d;
final String wrong_path = p.getImageFilePath();
if (wrong_path.startsWith(wrong_parent_path)) {
File file = new File(new StringBuilder(good_parent_path).append(wrong_path.substring(wrong_parent_path.length())).toString());
if (file.exists()) {
if (-1 == p.getFilePath().lastIndexOf("-----#slice=")) {
if (!fixed.contains(p) && fixPatchPath(p, file.getAbsolutePath(), update_mipmaps)) {
// not by 'i' but by Patch, since if some fail the order is not the same
data.remove(p);
n_fixed++;
fixed.add(p);
}
} else {
if (fixed.contains(p))
continue;
n_fixed += fixStack(data, fixed, p.getStackPatches(), wrong_path, file.getAbsolutePath(), update_mipmaps);
}
}
}
}
}
// if table is empty, close
if (0 == data.vp.size()) {
FilePathRepair fpr = projects.remove(patch.getProject());
fpr.frame.dispose();
}
Utils.logAll("Fixed " + n_fixed + " image file path" + (n_fixed > 1 ? "s" : ""));
}
}
use of ini.trakem2.display.YesNoDialog in project TrakEM2 by trakem2.
the class Project method adjustProperties.
public void adjustProperties() {
// should be more generic, but for now it'll do
GenericDialog gd = new GenericDialog("Properties");
gd.addMessage("Ignore image linking for:");
boolean link_labels = addBox(gd, DLabel.class);
boolean nolink_segmentations = "true".equals(ht_props.get("segmentations_nolinks"));
gd.addCheckbox("Segmentations", nolink_segmentations);
gd.addMessage("Currently linked objects will remain so\nunless explicitly unlinked.");
boolean dissector_zoom = "true".equals(ht_props.get("dissector_zoom"));
gd.addCheckbox("Zoom-invariant markers for Dissector", dissector_zoom);
gd.addChoice("Image_resizing_mode: ", Loader.MIPMAP_MODES.values().toArray(new String[Loader.MIPMAP_MODES.size()]), Loader.getMipMapModeName(mipmaps_mode));
gd.addChoice("mipmaps format:", FSLoader.MIPMAP_FORMATS, FSLoader.MIPMAP_FORMATS[loader.getMipMapFormat()]);
gd.addNumericField("Save mipmap images from level", this.first_mipmap_level_saved, 0);
boolean layer_mipmaps = "true".equals(ht_props.get("layer_mipmaps"));
gd.addCheckbox("Layer_mipmaps", layer_mipmaps);
boolean keep_mipmaps = "true".equals(ht_props.get("keep_mipmaps"));
// coping with the fact that thee is no Action context ... there should be one in the Worker thread.
gd.addCheckbox("Keep_mipmaps_when_deleting_images", keep_mipmaps);
int bucket_side = (int) getProperty("bucket_side", Bucket.MIN_BUCKET_SIZE);
gd.addNumericField("Bucket side length: ", bucket_side, 0, 6, "pixels");
boolean no_shutdown_hook = "true".equals(ht_props.get("no_shutdown_hook"));
gd.addCheckbox("No_shutdown_hook to save the project", no_shutdown_hook);
int n_undo_steps = getProperty("n_undo_steps", 32);
gd.addSlider("Undo steps", 32, 200, n_undo_steps);
boolean flood_fill_to_image_edge = "true".equals(ht_props.get("flood_fill_to_image_edge"));
gd.addCheckbox("AreaList_flood_fill_to_image_edges", flood_fill_to_image_edge);
int look_ahead_cache = (int) getProperty("look_ahead_cache", 0);
gd.addNumericField("Look_ahead_cache:", look_ahead_cache, 0, 6, "layers");
// default: every 10 minutes
int autosaving_interval = getProperty("autosaving_interval", 10);
gd.addNumericField("Autosave every:", autosaving_interval, 0, 6, "minutes");
int n_mipmap_threads = getProperty("n_mipmap_threads", 1);
gd.addSlider("Number of threads for mipmaps", 1, n_mipmap_threads, n_mipmap_threads);
int meshResolution = getProperty("mesh_resolution", 32);
gd.addSlider("Default mesh resolution for images", 1, 512, meshResolution);
//
gd.showDialog();
//
if (gd.wasCanceled())
return;
setLinkProp(link_labels, gd.getNextBoolean(), DLabel.class);
boolean nolink_segmentations2 = gd.getNextBoolean();
if (nolink_segmentations) {
if (!nolink_segmentations2)
ht_props.remove("segmentations_nolinks");
} else if (nolink_segmentations2)
ht_props.put("segmentations_nolinks", "true");
if (adjustProp("dissector_zoom", dissector_zoom, gd.getNextBoolean())) {
// TODO: should repaint nested LayerSets as well
Display.repaint(layer_set);
}
this.mipmaps_mode = Loader.getMipMapModeIndex(gd.getNextChoice());
final int new_mipmap_format = gd.getNextChoiceIndex();
final int old_mipmap_format = loader.getMipMapFormat();
if (new_mipmap_format != old_mipmap_format) {
YesNoDialog yn = new YesNoDialog("MipMaps format", "Changing mipmaps format to '" + FSLoader.MIPMAP_FORMATS[new_mipmap_format] + "'requires regenerating all mipmaps. Proceed?");
if (yn.yesPressed()) {
if (loader.setMipMapFormat(new_mipmap_format)) {
loader.updateMipMapsFormat(old_mipmap_format, new_mipmap_format);
}
}
}
setFirstMipMapLevelSaved(gd.getNextNumber());
boolean layer_mipmaps2 = gd.getNextBoolean();
if (adjustProp("layer_mipmaps", layer_mipmaps, layer_mipmaps2)) {
if (layer_mipmaps && !layer_mipmaps2) {
// TODO
// 1 - ask first
// 2 - remove all existing images from layer.mipmaps folder
} else if (!layer_mipmaps && layer_mipmaps2) {
// TODO
// 1 - ask first
// 2 - create de novo all layer mipmaps in a background task
}
}
adjustProp("keep_mipmaps", keep_mipmaps, gd.getNextBoolean());
Utils.log2("keep_mipmaps: " + getBooleanProperty("keep_mipmaps"));
//
bucket_side = (int) gd.getNextNumber();
if (bucket_side > Bucket.MIN_BUCKET_SIZE) {
setProperty("bucket_side", Integer.toString(bucket_side));
layer_set.recreateBuckets(true);
}
adjustProp("no_shutdown_hook", no_shutdown_hook, gd.getNextBoolean());
n_undo_steps = (int) gd.getNextNumber();
if (n_undo_steps < 0)
n_undo_steps = 0;
setProperty("n_undo_steps", Integer.toString(n_undo_steps));
adjustProp("flood_fill_to_image_edge", flood_fill_to_image_edge, gd.getNextBoolean());
double d_look_ahead_cache = gd.getNextNumber();
if (!Double.isNaN(d_look_ahead_cache) && d_look_ahead_cache >= 0) {
setProperty("look_ahead_cache", Integer.toString((int) d_look_ahead_cache));
if (0 == d_look_ahead_cache) {
Display.clearColumnScreenshots(this.layer_set);
} else {
Utils.logAll("WARNING: look-ahead cache is incomplete.\n Expect issues when editing objects, adding new ones, and the like.\n Use \"Project - Flush image cache\" to fix any lack of refreshing issues you encounter.");
}
} else {
Utils.log2("Ignoring invalid 'look ahead cache' value " + d_look_ahead_cache);
}
double autosaving_interval2 = gd.getNextNumber();
if (((int) (autosaving_interval2)) == autosaving_interval) {
// do nothing
} else if (autosaving_interval2 < 0 || Double.isNaN(autosaving_interval)) {
Utils.log("IGNORING invalid autosaving interval: " + autosaving_interval2);
} else {
setProperty("autosaving_interval", Integer.toString((int) autosaving_interval2));
restartAutosaving();
}
int n_mipmap_threads2 = (int) Math.max(1, gd.getNextNumber());
if (n_mipmap_threads != n_mipmap_threads2) {
setProperty("n_mipmap_threads", Integer.toString(n_mipmap_threads2));
// WARNING: this does it for a static service, affecting all projects!
FSLoader.restartMipMapThreads(n_mipmap_threads2);
}
int meshResolution2 = (int) gd.getNextNumber();
if (meshResolution != meshResolution2) {
if (meshResolution2 > 0) {
setProperty("mesh_resolution", Integer.toString(meshResolution2));
} else {
Utils.log("WARNING: ignoring invalid mesh resolution value " + meshResolution2);
}
}
}
Aggregations