Search in sources :

Example 16 with ZDisplayable

use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.

the class Project method removeAll.

/**
 * Remove any set of Displayable objects from the Layer, LayerSet and Project Tree as necessary.
 *  ASSUMES there aren't any nested LayerSet objects in @param col.
 */
public final boolean removeAll(final Set<Displayable> col, final DefaultMutableTreeNode top_node) {
    // 0. Sort into Displayable and ZDisplayable
    final Set<ZDisplayable> zds = new HashSet<ZDisplayable>();
    final List<Displayable> ds = new ArrayList<Displayable>();
    for (final Displayable d : col) {
        if (d instanceof ZDisplayable) {
            zds.add((ZDisplayable) d);
        } else {
            ds.add(d);
        }
    }
    // Displayable:
    // 1. First the Profile from the Project Tree, one by one,
    // while creating a map of Layer vs Displayable list to remove in that layer:
    final HashMap<Layer, Set<Displayable>> ml = new HashMap<Layer, Set<Displayable>>();
    for (final Iterator<Displayable> it = ds.iterator(); it.hasNext(); ) {
        final Displayable d = it.next();
        if (d.getClass() == Profile.class) {
            if (!project_tree.remove(false, findProjectThing(d), null)) {
                // like Profile.remove2
                Utils.log("Could NOT delete " + d);
                continue;
            }
            // remove the Profile
            it.remove();
            continue;
        }
        // The map of Layer vs Displayable list
        Set<Displayable> l = ml.get(d.getLayer());
        if (null == l) {
            l = new HashSet<Displayable>();
            ml.put(d.getLayer(), l);
        }
        l.add(d);
    }
    // 2. Then the rest, in bulk:
    if (ml.size() > 0) {
        for (final Map.Entry<Layer, Set<Displayable>> e : ml.entrySet()) {
            e.getKey().removeAll(e.getValue());
        }
    }
    // 3. Stacks
    if (zds.size() > 0) {
        final Set<ZDisplayable> stacks = new HashSet<ZDisplayable>();
        for (final Iterator<ZDisplayable> it = zds.iterator(); it.hasNext(); ) {
            final ZDisplayable zd = it.next();
            if (zd.getClass() == Stack.class) {
                it.remove();
                stacks.add(zd);
            }
        }
        layer_set.removeAll(stacks);
    }
    // 4. ZDisplayable: bulk removal
    if (zds.size() > 0) {
        // 1. From the Project Tree:
        Set<Displayable> not_removed = project_tree.remove(zds, top_node);
        // 2. Then only those successfully removed, from the LayerSet:
        zds.removeAll(not_removed);
        layer_set.removeAll(zds);
    }
    // TODO
    return true;
}
Also used : Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) Set(java.util.Set) HashSet(java.util.HashSet) LayerSet(ini.trakem2.display.LayerSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Layer(ini.trakem2.display.Layer) ZDisplayable(ini.trakem2.display.ZDisplayable) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 17 with ZDisplayable

use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.

the class Project method openDBProject.

/**
 * Open a TrakEM2 project from the database. Queries the database for existing projects and if more than one, asks which one to open.
 */
public static Project openDBProject() {
    if (Utils.wrongImageJVersion())
        return null;
    DBLoader loader = new DBLoader();
    if (!loader.isReady())
        return null;
    // check connection
    if (!loader.isConnected()) {
        Utils.showMessage("Can't talk to database.");
        loader.destroy();
        return null;
    }
    // query the database for existing projects
    Project[] projects = loader.getProjects();
    if (null == projects) {
        Utils.showMessage("Can't talk to database (null list of projects).");
        loader.destroy();
        return null;
    }
    Project project = null;
    if (0 == projects.length) {
        Utils.showMessage("No projects in this database.");
        loader.destroy();
        return null;
    } else if (1 == projects.length) {
        project = projects[0];
    } else {
        // ask to choose one
        String[] titles = new String[projects.length];
        for (int i = 0; i < projects.length; i++) {
            titles[i] = projects[i].title;
        }
        GenericDialog gd = new GenericDialog("Choose");
        gd.addMessage("Choose project to open:");
        gd.addChoice("project: ", titles, titles[titles.length - 1]);
        gd.showDialog();
        if (gd.wasCanceled()) {
            loader.destroy();
            return null;
        }
        project = projects[gd.getNextChoiceIndex()];
    }
    // check if the selected project is open already
    for (final Project p : al_open_projects) {
        if (loader.isIdenticalProjectSource(p.loader) && p.id == project.id && p.title.equals(project.title)) {
            Utils.showMessage("A project with title " + p.title + " and id " + p.id + " from the same database is already open.");
            loader.destroy();
            return null;
        }
    }
    // now, open the selected project
    // assign loader
    project.loader = loader;
    // grab the XML template
    TemplateThing template_root = loader.getTemplateRoot(project);
    if (null == template_root) {
        Utils.showMessage("Failed to retrieve the template tree.");
        project.destroy();
        return null;
    }
    project.template_tree = new TemplateTree(project, template_root);
    synchronized (project.ht_unique_tt) {
        project.ht_unique_tt.clear();
        project.ht_unique_tt.putAll(template_root.getUniqueTypes(new HashMap<String, TemplateThing>()));
    }
    // create the project Thing, to be root of the whole user Thing tree (and load all its objects)
    // to collect all created displayables, and  then reassign to the proper layers.
    HashMap<Long, Displayable> hs_d = new HashMap<Long, Displayable>();
    try {
        // create a template for the project Thing
        TemplateThing project_template = new TemplateThing("project");
        project.ht_unique_tt.put("project", project_template);
        project_template.addChild(template_root);
        project.root_pt = loader.getRootProjectThing(project, template_root, project_template, hs_d);
        // restore parent/child and attribute ownership and values (now that all Things exist)
        project.root_pt.setup();
    } catch (Exception e) {
        Utils.showMessage("Failed to retrieve the Thing tree for the project.");
        IJError.print(e);
        project.destroy();
        return null;
    }
    // create the user objects tree
    project.project_tree = new ProjectTree(project, project.root_pt);
    // restore the expanded state of each node
    loader.restoreNodesExpandedState(project);
    // create the layers templates
    project.createLayerTemplates();
    // fetch the root layer thing and the root layer set (will load all layers and layer sets, with minimal contents of patches; gets the basic objects -profile, pipe, etc.- from the project.root_pt). Will open all existing displays for each layer.
    LayerThing root_layer_thing = null;
    try {
        root_layer_thing = loader.getRootLayerThing(project, project.root_pt, Project.layer_set_template, Project.layer_template);
        if (null == root_layer_thing) {
            project.destroy();
            Utils.showMessage("Could not retrieve the root layer thing.");
            return null;
        }
        // set the child/parent relationships now that everything exists
        root_layer_thing.setup();
        project.layer_set = (LayerSet) root_layer_thing.getObject();
        if (null == project.layer_set) {
            project.destroy();
            Utils.showMessage("Could not retrieve the root layer set.");
            return null;
        }
        // set the active layer to each ZDisplayable
        project.layer_set.setup();
        // debug:
        // Utils.log2("$$$ root_lt: " + root_layer_thing + "   ob: " + root_layer_thing.getObject().getClass().getName() + "\n children: " + ((LayerSet)root_layer_thing.getObject()).getLayers().size());
        project.layer_tree = new LayerTree(project, root_layer_thing);
        project.root_lt = root_layer_thing;
    } catch (Exception e) {
        Utils.showMessage("Failed to retrieve the Layer tree for the project.");
        IJError.print(e);
        project.destroy();
        return null;
    }
    // if all when well, register as open:
    al_open_projects.add(project);
    // create the project control window, containing the trees in a double JSplitPane
    ControlWindow.add(project, project.template_tree, project.project_tree, project.layer_tree);
    // now open the displays that were stored for later, if any:
    Display.openLater();
    return project;
}
Also used : Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) HashMap(java.util.HashMap) LayerThing(ini.trakem2.tree.LayerThing) TemplateTree(ini.trakem2.tree.TemplateTree) ProjectTree(ini.trakem2.tree.ProjectTree) LayerTree(ini.trakem2.tree.LayerTree) DBLoader(ini.trakem2.persistence.DBLoader) GenericDialog(ij.gui.GenericDialog) TemplateThing(ini.trakem2.tree.TemplateThing)

Example 18 with ZDisplayable

use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.

the class Project method createSubproject.

/**
 * Create a new subproject for the given layer range and ROI.
 *   Create a new Project using the given project as template. This means the DTD of the given project is copied, as well as the storage and mipmaps folders; everything else is empty in the new project.
 */
public Project createSubproject(final Rectangle roi, final Layer first, final Layer last, final boolean ignore_hidden_patches) {
    try {
        // The order matters.
        final Project pr = new Project(new FSLoader(this.getLoader().getStorageFolder()));
        pr.id = this.id;
        // copy properties
        pr.title = this.title;
        pr.ht_props.putAll(this.ht_props);
        // copy template
        pr.root_tt = this.root_tt.clone(pr, true);
        pr.template_tree = new TemplateTree(pr, pr.root_tt);
        synchronized (pr.ht_unique_tt) {
            pr.ht_unique_tt.clear();
            pr.ht_unique_tt.putAll(root_tt.getUniqueTypes(new HashMap<String, TemplateThing>()));
        }
        TemplateThing project_template = new TemplateThing("project");
        project_template.addChild(pr.root_tt);
        pr.ht_unique_tt.put("project", project_template);
        // create the layers templates
        pr.createLayerTemplates();
        // copy LayerSet and all involved Displayable objects
        // (A two-step process to provide the layer_set pointer and all Layer pointers to the ZDisplayable to copy and crop.)
        pr.layer_set = (LayerSet) this.layer_set.clone(pr, first, last, roi, false, true, ignore_hidden_patches);
        LayerSet.cloneInto(this.layer_set, first, last, pr, pr.layer_set, roi, true);
        // create layer tree
        pr.root_lt = new LayerThing(Project.layer_set_template, pr, pr.layer_set);
        pr.layer_tree = new LayerTree(pr, pr.root_lt);
        // add layer nodes to the layer tree (solving chicken-and-egg problem)
        pr.layer_set.updateLayerTree();
        // copy project tree
        pr.root_pt = this.root_pt.subclone(pr);
        pr.project_tree = new ProjectTree(pr, pr.root_pt);
        // not copying node expanded state.
        // register
        al_open_projects.add(pr);
        // add to gui:
        ControlWindow.add(pr, pr.template_tree, pr.project_tree, pr.layer_tree);
        // Above, the id of each object is preserved from this project into the subproject.
        // The abstract structure should be copied in full regardless, without the basic objects
        // included if they intersect the roi.
        // Regenerate mipmaps (blocks GUI from interaction other than navigation)
        pr.loader.regenerateMipMaps(pr.layer_set.getDisplayables(Patch.class));
        pr.restartAutosaving();
        return pr;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
Also used : FSLoader(ini.trakem2.persistence.FSLoader) LayerTree(ini.trakem2.tree.LayerTree) ProjectTree(ini.trakem2.tree.ProjectTree) HashMap(java.util.HashMap) LayerThing(ini.trakem2.tree.LayerThing) TemplateTree(ini.trakem2.tree.TemplateTree) TemplateThing(ini.trakem2.tree.TemplateThing) Patch(ini.trakem2.display.Patch)

Example 19 with ZDisplayable

use of ini.trakem2.display.ZDisplayable in project TrakEM2 by trakem2.

the class Loader method getFlatAWTImage.

/**
 * @param layer The layer from which to collect visible Displayable instances that intersect the srcRect.
 * @param srcRect_ Rectangle in World coordinates representing the field of view to paint into the image, and defines the width and height of the image together with the scale.
 * @param scale Value between 0 and 1.
 * @param c_alphas Which color channels to include when painting Patch instances that hold an RGB image.
 * @param type Either ImagePlus.GRAY8 or ImagePlus.COLOR_RGB
 * @param clazz Include only Displayable instances of this class; use Displayable.class for all.
 * @param al_displ List of Displayable instances to include. Use null to include all visible intersected by srcRect.
 * @param quality Whether to attempt to create a larger image and then scale it down with area averaging for best quality.
 * @param background The color of the areas of the image where no Displayable paints.
 * @param active Whether to paint a particular Displayable instance in an active state (as if it was selected in the UI).
 * @return
 */
public Image getFlatAWTImage(final Layer layer, final Rectangle srcRect_, final double scale, final int c_alphas, final int type, final Class<?> clazz, List<? extends Displayable> al_displ, boolean quality, final Color background, final Displayable active) {
    try {
        // dimensions
        int w = 0;
        int h = 0;
        Rectangle srcRect = (null == srcRect_) ? null : (Rectangle) srcRect_.clone();
        if (null != srcRect) {
            w = srcRect.width;
            h = srcRect.height;
        } else {
            w = (int) Math.ceil(layer.getLayerWidth());
            h = (int) Math.ceil(layer.getLayerHeight());
            srcRect = new Rectangle(0, 0, w, h);
        }
        Utils.log2("Loader.getFlatImage: using rectangle " + srcRect);
        /*
			 * output size including excess space for not entirely covered
			 * pixels
			 */
        final int ww = (int) Math.ceil(w * scale);
        final int hh = (int) Math.ceil(h * scale);
        /* The size of the buffered image to be generated */
        final int biw, bih;
        final double scaleP, scalePX, scalePY;
        // on scaling down to output resolution.
        if (quality) {
            if (ww * hh >= Math.pow(2, 30)) {
                // 1 GB
                // While perhaps scale could be increased to an image size of up to 2 GB, it is not advisable
                scaleP = scalePX = scalePY = scale;
                quality = false;
                biw = ww;
                bih = hh;
                Utils.log("Can't use 'quality' flag for getFlatAWTImage: would be too large");
            // If the image is larger than 2 GB, it will thrown a NegativeArraySizeException below and stop.
            } else {
                // Max area: the smallest of the srcRect at 100x magnification and 1 GB
                final double max_area = Math.min(srcRect.width * srcRect.height, Math.pow(2, 30));
                final double ratio = ww / (double) hh;
                // area = w * h
                // ratio = w / h
                // w = ratio * h
                // area = ratio * h * h
                // h = sqrt(area / ratio)
                // scaleP is then the ratio between the real-world height and the target height
                // (And clamp to a maximum of 1.0: above makes no sense)
                scaleP = Math.min(1.0, srcRect.height / Math.sqrt(max_area / ratio));
                biw = (int) Math.ceil(ww / scale);
                bih = (int) Math.ceil(hh / scale);
                /* compensate for excess space due to ceiling */
                scalePX = (double) biw / (double) ww * scale;
                scalePY = (double) bih / (double) hh * scale;
                Utils.log("getFlatAWTImage -- scale: " + scale + "; quality scale: " + scaleP);
            }
        } else {
            scaleP = scalePX = scalePY = scale;
            biw = ww;
            bih = hh;
        }
        // estimate image size
        final long n_bytes = (long) ((biw * bih * (ImagePlus.GRAY8 == type ? 1.0 : /*byte*/
        4.0)));
        Utils.log2("Flat image estimated size in bytes: " + Long.toString(n_bytes) + "  w,h : " + (int) Math.ceil(biw) + "," + (int) Math.ceil(bih) + (quality ? " (using 'quality' flag: scaling to " + scale + " is done later with area averaging)" : ""));
        releaseToFit(n_bytes);
        // go
        BufferedImage bi = null;
        switch(type) {
            case ImagePlus.GRAY8:
                bi = new BufferedImage(biw, bih, BufferedImage.TYPE_BYTE_INDEXED, GRAY_LUT);
                break;
            case ImagePlus.COLOR_RGB:
                bi = new BufferedImage(biw, bih, BufferedImage.TYPE_INT_ARGB);
                break;
            default:
                Utils.log2("Left bi,icm as null");
                break;
        }
        final Graphics2D g2d = bi.createGraphics();
        g2d.setColor(background);
        g2d.fillRect(0, 0, bi.getWidth(), bi.getHeight());
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        // TODO Stephan, test if that introduces offset vs nearest neighbor
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        // to smooth edges of the images
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        ArrayList<ZDisplayable> al_zdispl = null;
        if (null == al_displ) {
            al_displ = new ArrayList<Displayable>(layer.find(clazz, srcRect, true, true));
            al_zdispl = new ArrayList<ZDisplayable>((Collection) layer.getParent().findZDisplayables(clazz, layer, srcRect, true, true));
        } else {
            // separate ZDisplayables into their own array
            al_displ = new ArrayList<Displayable>(al_displ);
            final HashSet<ZDisplayable> az = new HashSet<ZDisplayable>();
            for (final Iterator<?> it = al_displ.iterator(); it.hasNext(); ) {
                final Object ob = it.next();
                if (ob instanceof ZDisplayable) {
                    it.remove();
                    az.add((ZDisplayable) ob);
                }
            }
            // order ZDisplayables by their stack order
            final ArrayList<ZDisplayable> al_zdispl2 = layer.getParent().getZDisplayables();
            for (final Iterator<ZDisplayable> it = al_zdispl2.iterator(); it.hasNext(); ) {
                if (!az.contains(it.next()))
                    it.remove();
            }
            al_zdispl = al_zdispl2;
        }
        // prepare the canvas for the srcRect and magnification
        final AffineTransform at_original = g2d.getTransform();
        final AffineTransform atc = new AffineTransform();
        atc.scale(scalePX, scalePY);
        atc.translate(-srcRect.x, -srcRect.y);
        at_original.preConcatenate(atc);
        g2d.setTransform(at_original);
        // Utils.log2("will paint: " + al_displ.size() + " displ and " + al_zdispl.size() + " zdispl");
        // int total = al_displ.size() + al_zdispl.size();
        int count = 0;
        boolean zd_done = false;
        final List<Layer> layers = layer.getParent().getColorCueLayerRange(layer);
        for (final Displayable d : al_displ) {
            // paint the ZDisplayables before the first label, if any
            if (!zd_done && d instanceof DLabel) {
                zd_done = true;
                for (final ZDisplayable zd : al_zdispl) {
                    if (!zd.isOutOfRepaintingClip(scaleP, srcRect, null)) {
                        zd.paint(g2d, srcRect, scaleP, active == zd, c_alphas, layer, layers);
                    }
                    count++;
                // Utils.log2("Painted " + count + " of " + total);
                }
            }
            if (!d.isOutOfRepaintingClip(scaleP, srcRect, null)) {
                d.paintOffscreen(g2d, srcRect, scaleP, active == d, c_alphas, layer, layers);
            // Utils.log("painted: " + d + "\n with: " + scaleP + ", " + c_alphas + ", " + layer);
            } else {
            // Utils.log2("out: " + d);
            }
            count++;
        // Utils.log2("Painted " + count + " of " + total);
        }
        if (!zd_done) {
            zd_done = true;
            for (final ZDisplayable zd : al_zdispl) {
                if (!zd.isOutOfRepaintingClip(scaleP, srcRect, null)) {
                    zd.paint(g2d, srcRect, scaleP, active == zd, c_alphas, layer, layers);
                }
                count++;
            // Utils.log2("Painted " + count + " of " + total);
            }
        }
        // ensure enough memory is available for the processor and a new awt from it
        // locks on its own
        releaseToFit((long) (n_bytes * 2.3));
        try {
            if (quality) {
                // need to scale back down
                Image scaled = null;
                if (!isMipMapsRegenerationEnabled() || scale >= 0.499) {
                    // there are no proper mipmaps above 50%, so there's need for SCALE_AREA_AVERAGING.
                    // very slow, but best by far
                    scaled = bi.getScaledInstance(ww, hh, Image.SCALE_AREA_AVERAGING);
                    if (ImagePlus.GRAY8 == type) {
                        // getScaledInstance generates RGB images for some reason.
                        final BufferedImage bi8 = new BufferedImage(ww, hh, BufferedImage.TYPE_BYTE_GRAY);
                        bi8.createGraphics().drawImage(scaled, 0, 0, null);
                        scaled.flush();
                        scaled = bi8;
                    }
                } else {
                    // faster, but requires gaussian blurred images (such as the mipmaps)
                    if (bi.getType() == BufferedImage.TYPE_BYTE_INDEXED) {
                        scaled = new BufferedImage(ww, hh, bi.getType(), GRAY_LUT);
                    } else {
                        scaled = new BufferedImage(ww, hh, bi.getType());
                    }
                    final Graphics2D gs = (Graphics2D) scaled.getGraphics();
                    // gs.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                    gs.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    gs.drawImage(bi, 0, 0, ww, hh, null);
                }
                bi.flush();
                return scaled;
            } else {
                // else the image was made scaled down already, and of the proper type
                return bi;
            }
        } catch (final OutOfMemoryError oome) {
            Utils.log("Not enough memory to create the ImagePlus. Try scaling it down or not using the 'quality' flag.");
        }
    } catch (final Exception e) {
        IJError.print(e);
    }
    return null;
}
Also used : ZDisplayable(ini.trakem2.display.ZDisplayable) Displayable(ini.trakem2.display.Displayable) Rectangle(java.awt.Rectangle) Image(java.awt.Image) BufferedImage(java.awt.image.BufferedImage) MipMapImage(ini.trakem2.display.MipMapImage) Layer(ini.trakem2.display.Layer) BufferedImage(java.awt.image.BufferedImage) IOException(java.io.IOException) FormatException(loci.formats.FormatException) Graphics2D(java.awt.Graphics2D) ZDisplayable(ini.trakem2.display.ZDisplayable) DLabel(ini.trakem2.display.DLabel) Collection(java.util.Collection) AffineTransform(java.awt.geom.AffineTransform) HashSet(java.util.HashSet)

Example 20 with ZDisplayable

use of ini.trakem2.display.ZDisplayable 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;
}
Also used : Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) ArrayList(java.util.ArrayList) Layer(ini.trakem2.display.Layer) VectorData(ini.trakem2.display.VectorData) Profile(ini.trakem2.display.Profile) ZDisplayable(ini.trakem2.display.ZDisplayable) TreePath(javax.swing.tree.TreePath) HashSet(java.util.HashSet)

Aggregations

ZDisplayable (ini.trakem2.display.ZDisplayable)13 ArrayList (java.util.ArrayList)10 HashMap (java.util.HashMap)10 HashSet (java.util.HashSet)10 Displayable (ini.trakem2.display.Displayable)9 Layer (ini.trakem2.display.Layer)7 Worker (ini.trakem2.utils.Worker)6 Map (java.util.Map)6 GenericDialog (ij.gui.GenericDialog)5 LayerSet (ini.trakem2.display.LayerSet)5 Project (ini.trakem2.Project)4 DBObject (ini.trakem2.persistence.DBObject)4 ProjectThing (ini.trakem2.tree.ProjectThing)4 Point (java.awt.Point)4 Collection (java.util.Collection)4 List (java.util.List)4 TreeMap (java.util.TreeMap)4 ImagePlus (ij.ImagePlus)3 Roi (ij.gui.Roi)3 Display (ini.trakem2.display.Display)3