Search in sources :

Example 6 with Tree

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

the class TMLHandler method getProjectData.

/**
 * returns 4 objects packed in an array:
 *	 <pre>
 *	 [0] = root TemplateThing
 *	 [1] = root ProjectThing (contains Project instance)
 *	 [2] = root LayerThing (contains the top-level LayerSet)
 *	 [3] = expanded states of all ProjectThing objects
 *	 </pre>
 * <p>
 * Also, triggers the reconstruction of links and assignment of Displayable objects to their layer.
 * </p>
 */
public Object[] getProjectData(final boolean open_displays) {
    if (null == project)
        return null;
    this.open_displays = open_displays;
    // Links exist between Displayable objects.
    for (final Displayable d : ht_displayables.values()) {
        String olinks = ht_links.get(d);
        // not linked
        if (null == olinks)
            continue;
        String[] links = olinks.split(",");
        Long lid = null;
        for (int i = 0; i < links.length; i++) {
            try {
                lid = new Long(links[i]);
            } catch (NumberFormatException nfe) {
                Utils.log2("Ignoring incorrectly formated link '" + links[i] + "' for ob " + d);
                continue;
            }
            Displayable partner = ht_displayables.get(lid);
            if (null != partner)
                d.link(partner, false);
            else
                Utils.log("TMLHandler: can't find partner with id=" + links[i] + " for Displayable with id=" + d.getId());
        }
    }
    // 1.2 - Reconstruct linked properties
    for (final Map.Entry<Displayable, Map<Long, Map<String, String>>> lpe : all_linked_props.entrySet()) {
        final Displayable origin = lpe.getKey();
        for (final Map.Entry<Long, Map<String, String>> e : lpe.getValue().entrySet()) {
            final Displayable target = ht_displayables.get(e.getKey());
            if (null == target) {
                Utils.log("Setting linked properties for origin " + origin.getId() + ":\n\t* Could not find target displayable #" + e.getKey());
                continue;
            }
            origin.setLinkedProperties(target, e.getValue());
        }
    }
    // 2 - Add Displayable objects to ProjectThing that can contain them
    for (final Map.Entry<Long, ProjectThing> entry : ht_oid_pt.entrySet()) {
        ProjectThing pt = entry.getValue();
        Object od = ht_displayables.remove(entry.getKey());
        // Utils.log("==== processing: Displayable [" + od + "]  vs. ProjectThing [" + pt + "]");
        if (null != od) {
            pt.setObject(od);
        } else {
            Utils.log("#### Failed to find a Displayable for ProjectThing " + pt + " #####");
        }
    }
    // 3 - Assign a layer pointer to ZDisplayable objects
    for (final ZDisplayable zd : ht_zdispl.values()) {
        // zd.setLayer((Layer)zd.getLayerSet().getLayers().get(0));
        zd.setLayer(zd.getLayerSet().getLayer(0));
    }
    // 4 - Assign layers to Treeline nodes
    for (final Layer la : al_layers) {
        final List<Node<?>> list = node_layer_table.remove(la.getId());
        if (null == list)
            continue;
        for (final Node<?> nd : list) nd.setLayer(la);
    }
    if (!node_layer_table.isEmpty()) {
        Utils.log("ERROR: node_layer_table is not empty!");
    }
    // 5 - Assign root nodes to Treelines, now that all nodes have a layer
    for (final Map.Entry<Tree<?>, Node<?>> e : tree_root_nodes.entrySet()) {
        if (null == e.getValue()) {
            // Utils.log2("Ignoring, applies to new Treeline format only.");
            continue;
        }
        // Can't compile with <?>
        // will generate node caches of each Treeline
        e.getKey().setRoot((Node) e.getValue());
    }
    tree_root_nodes.clear();
    // Assign colors to nodes
    for (final Map.Entry<Color, Collection<Node<?>>> e : node_colors.entrySet()) {
        for (final Node<?> nd : e.getValue()) {
            nd.setColor(e.getKey());
        }
    }
    node_colors.clear();
    // 6 - Run legacy operations
    for (final Runnable r : legacy) {
        r.run();
    }
    try {
        // Create a table with all layer ids vs layer instances:
        final HashMap<Long, Layer> ht_lids = new HashMap<Long, Layer>();
        for (final Layer layer : al_layers) {
            ht_lids.put(new Long(layer.getId()), layer);
        }
        // Spawn threads to recreate buckets, starting from the subset of displays to open
        int n = Runtime.getRuntime().availableProcessors();
        switch(n) {
            case 1:
                break;
            case 2:
            case 3:
            case 4:
                n--;
                break;
            default:
                n -= 2;
                break;
        }
        final ExecutorService exec = Utils.newFixedThreadPool(n, "TMLHandler-recreateBuckets");
        final Set<Long> dlids = new HashSet<Long>();
        final LayerSet layer_set = (LayerSet) root_lt.getObject();
        final List<Future<?>> fus = new ArrayList<Future<?>>();
        final List<Future<?>> fus2 = new ArrayList<Future<?>>();
        for (final HashMap<String, String> ht_attributes : al_displays) {
            String ob = ht_attributes.get("layer_id");
            if (null == ob)
                continue;
            final Long lid = new Long(ob);
            dlids.add(lid);
            final Layer la = ht_lids.get(lid);
            if (null == la) {
                ht_lids.remove(lid);
                continue;
            }
            // to open later:
            new Display(project, Long.parseLong(ht_attributes.get("id")), la, ht_attributes);
            fus.add(exec.submit(new Runnable() {

                public void run() {
                    la.recreateBuckets();
                }
            }));
        }
        fus.add(exec.submit(new Runnable() {

            public void run() {
                // only for ZDisplayable
                layer_set.recreateBuckets(false);
            }
        }));
        // Ensure launching:
        if (dlids.isEmpty() && layer_set.size() > 0) {
            dlids.add(layer_set.getLayer(0).getId());
        }
        final List<Layer> layers = layer_set.getLayers();
        for (final Long lid : new HashSet<Long>(dlids)) {
            fus.add(exec.submit(new Runnable() {

                public void run() {
                    int start = layer_set.indexOf(layer_set.getLayer(lid.longValue()));
                    int next = start + 1;
                    int prev = start - 1;
                    while (next < layer_set.size() || prev > -1) {
                        if (prev > -1) {
                            final Layer lprev = layers.get(prev);
                            synchronized (dlids) {
                                if (dlids.add(lprev.getId())) {
                                    // returns true if not there already
                                    fus2.add(exec.submit(new Runnable() {

                                        public void run() {
                                            lprev.recreateBuckets();
                                        }
                                    }));
                                }
                            }
                            prev--;
                        }
                        if (next < layers.size()) {
                            final Layer lnext = layers.get(next);
                            synchronized (dlids) {
                                if (dlids.add(lnext.getId())) {
                                    // returns true if not there already
                                    fus2.add(exec.submit(new Runnable() {

                                        public void run() {
                                            lnext.recreateBuckets();
                                        }
                                    }));
                                }
                            }
                            next++;
                        }
                    }
                    Utils.log2("done recreateBuckets chunk");
                }
            }));
        }
        Utils.wait(fus);
        exec.submit(new Runnable() {

            public void run() {
                Utils.log2("waiting for TMLHandler fus...");
                Utils.wait(fus2);
                Utils.log2("done waiting TMLHandler fus.");
                exec.shutdown();
            }
        });
    } catch (Throwable t) {
        IJError.print(t);
    }
    return new Object[] { root_tt, root_pt, root_lt, ht_pt_expanded };
}
Also used : HashMap(java.util.HashMap) Node(ini.trakem2.display.Node) ArrayList(java.util.ArrayList) AreaTree(ini.trakem2.display.AreaTree) Tree(ini.trakem2.display.Tree) ProjectThing(ini.trakem2.tree.ProjectThing) HashSet(java.util.HashSet) Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) LayerSet(ini.trakem2.display.LayerSet) Color(java.awt.Color) Layer(ini.trakem2.display.Layer) ZDisplayable(ini.trakem2.display.ZDisplayable) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) Future(java.util.concurrent.Future) Map(java.util.Map) HashMap(java.util.HashMap) Display(ini.trakem2.display.Display)

Example 7 with Tree

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

the class DefaultTreeTransferHandler method canPerformAction.

public boolean canPerformAction(DNDTree target, DefaultMutableTreeNode dragged_node, int action, Point location) {
    // prevent drags from non-tree components
    if (null == dragged_node)
        return false;
    // Can't drop onto a TemplateTree
    if (target instanceof TemplateTree) {
        return false;
    }
    // Can't drag a node that contains a Project!
    if (dragged_node.getUserObject() instanceof ProjectThing && ((ProjectThing) dragged_node.getUserObject()).getObject() instanceof Project) {
        return false;
    }
    // Can't drag basic object nodes from a template tree RECONSIDERED, I like it even if it looks inconsistent (but types are types!)
    /*
		if (dragged_node.getUserObject() instanceof TemplateThing && project.isBasicType(((Thing)dragged_node.getUserObject()).getType())) {
			return false;
		}
		*/
    // else, the target has to be not null
    TreePath pathTarget = target.getPathForLocation(location.x, location.y);
    if (pathTarget == null) {
        target.setSelectionPath(null);
        return false;
    }
    /* // debug
		if (action == DnDConstants.ACTION_COPY) {
			Utils.log("can drop: Action copy");
		} else if (action == DnDConstants.ACTION_MOVE) {
			Utils.log("can drop: Action move");
		} else {
			Utils.log("can drop: Unexpected action: " + action);
		}
		*/
    target.setSelectionPath(pathTarget);
    DefaultMutableTreeNode parent_node = (DefaultMutableTreeNode) pathTarget.getLastPathComponent();
    // can be a Thing or an Attribute
    Object parent_ob = parent_node.getUserObject();
    Thing child_thing = (Thing) dragged_node.getUserObject();
    if (DnDConstants.ACTION_MOVE == action || DnDConstants.ACTION_COPY == action) {
        if (parent_ob instanceof ProjectThing) {
            ProjectThing parent_thing = (ProjectThing) parent_ob;
            // check if it's allowed to give to this parent such a child:
            if (!parent_thing.uniquePathExists(child_thing.getType()) && !parent_thing.canHaveAsChild(child_thing)) {
                // Utils.log("Not possible.");
                return false;
            }
            // - the leaf that is going to be dropped into itself or any of its descendants.
            if (parent_node == dragged_node.getParent() || dragged_node.isNodeDescendant(parent_node)) {
                // Utils.log("preventing dragging onto itself or any of the self children.");
                return false;
            } else {
                return true;
            }
        }
    }
    // default:
    return false;
}
Also used : Project(ini.trakem2.Project) TreePath(javax.swing.tree.TreePath) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode)

Example 8 with Tree

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

the class ProjectTree method keyPressed.

@Override
public void keyPressed(final KeyEvent ke) {
    super.keyPressed(ke);
    if (ke.isConsumed())
        return;
    if (!ke.getSource().equals(ProjectTree.this) || !project.isInputEnabled()) {
        return;
    }
    // get the first selected node only
    TreePath path = getSelectionPath();
    if (null == path)
        return;
    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
    if (null == node)
        return;
    final ProjectThing pt = (ProjectThing) node.getUserObject();
    if (null == pt)
        return;
    // 
    final int flags = ke.getModifiers();
    switch(ke.getKeyCode()) {
        case KeyEvent.VK_PAGE_UP:
            move(node, -1);
            // in any case
            ke.consume();
            break;
        case KeyEvent.VK_PAGE_DOWN:
            move(node, 1);
            // in any case
            ke.consume();
            break;
        case KeyEvent.VK_F2:
            rename(pt);
            ke.consume();
            break;
        case KeyEvent.VK_H:
            if (0 == (flags ^ Event.ALT_MASK)) {
                pt.setVisible(true);
                ke.consume();
            } else if (0 == flags) {
                pt.setVisible(false);
                ke.consume();
            }
            break;
        case KeyEvent.VK_A:
            if (0 == flags || (0 == (flags ^ Event.SHIFT_MASK))) {
                selectInDisplay(pt, 0 == (flags ^ Event.SHIFT_MASK));
                ke.consume();
            }
            break;
        case KeyEvent.VK_3:
            if (0 == flags) {
                ini.trakem2.display.Display3D.showAndResetView(pt);
                ke.consume();
                break;
            }
        // else, flow:
        case KeyEvent.VK_1:
        case KeyEvent.VK_2:
        case KeyEvent.VK_4:
        case KeyEvent.VK_5:
        case KeyEvent.VK_6:
        case KeyEvent.VK_7:
        case KeyEvent.VK_8:
        case KeyEvent.VK_9:
            // run a plugin, if any
            if (pt.getObject() instanceof Displayable && null != Utils.launchTPlugIn(ke, "Project Tree", project, (Displayable) pt.getObject())) {
                ke.consume();
            }
            break;
    }
    ke.consume();
}
Also used : Displayable(ini.trakem2.display.Displayable) ZDisplayable(ini.trakem2.display.ZDisplayable) TreePath(javax.swing.tree.TreePath) DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode)

Example 9 with Tree

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

the class Merger method compare.

/**
 * Take two projects and find out what is different among them,
 *  independent of id.
 */
public static final void compare(final Project p1, final Project p2) {
    Utils.log("Be warned: only Treeline, AreaTree and Connector are considered at the moment.");
    final LayerSet ls1 = p1.getRootLayerSet(), ls2 = p2.getRootLayerSet();
    final Collection<ZDisplayable> zds1 = ls1.getZDisplayables(), zds2 = ls2.getZDisplayables();
    final HashSet<Class<?>> accepted = new HashSet<Class<?>>();
    accepted.add(Treeline.class);
    accepted.add(AreaTree.class);
    accepted.add(Connector.class);
    final HashMap<Displayable, List<Change>> matched = new HashMap<Displayable, List<Change>>();
    final HashSet<ZDisplayable> empty1 = new HashSet<ZDisplayable>(), empty2 = new HashSet<ZDisplayable>();
    final HashSet<ZDisplayable> unmatched1 = new HashSet<ZDisplayable>(), unmatched2 = new HashSet<ZDisplayable>(zds2);
    // Remove instances of classes not accepted
    for (final Iterator<ZDisplayable> it = unmatched2.iterator(); it.hasNext(); ) {
        ZDisplayable zd = it.next();
        if (!accepted.contains(zd.getClass())) {
            it.remove();
            continue;
        }
        if (zd.isDeletable()) {
            it.remove();
            empty2.add(zd);
        }
    }
    zds2.removeAll(empty2);
    final AtomicInteger counter = new AtomicInteger(0);
    // or at least one or more that are similar in that they have some nodes in common.
    try {
        ini.trakem2.parallel.Process.unbound(zds1, new TaskFactory<ZDisplayable, Object>() {

            @Override
            public Object process(final ZDisplayable zd1) {
                Utils.showProgress(counter.getAndIncrement() / (float) zds1.size());
                if (!accepted.contains(zd1.getClass())) {
                    Utils.log("Ignoring: [A] " + zd1);
                    return null;
                }
                if (zd1.isDeletable()) {
                    synchronized (empty1) {
                        empty1.add(zd1);
                    }
                    return null;
                }
                final List<Change> cs = new ArrayList<Change>();
                for (final ZDisplayable zd2 : zds2) {
                    // Same class?
                    if (zd1.getClass() != zd2.getClass())
                        continue;
                    if (zd1 instanceof Tree<?> && zd2 instanceof Tree<?>) {
                        Change c = compareTrees(zd1, zd2);
                        if (c.hasSimilarNodes()) {
                            cs.add(c);
                            if (1 == cs.size()) {
                                synchronized (matched) {
                                    matched.put(zd1, cs);
                                }
                            }
                            synchronized (unmatched2) {
                                unmatched2.remove(zd2);
                            }
                        }
                        // debug
                        if (zd1.getId() == zd2.getId()) {
                            Utils.log("zd1 #" + zd1.getId() + " is similar to #" + zd2.getId() + ": " + c.hasSimilarNodes());
                        }
                    }
                }
                if (cs.isEmpty()) {
                    synchronized (unmatched1) {
                        unmatched1.add(zd1);
                    }
                }
                return null;
            }
        });
    } catch (Exception e) {
        IJError.print(e);
    }
    // reset
    Utils.showProgress(1);
    Utils.log("matched.size(): " + matched.size());
    makeGUI(p1, p2, empty1, empty2, matched, unmatched1, unmatched2);
}
Also used : ZDisplayable(ini.trakem2.display.ZDisplayable) Displayable(ini.trakem2.display.Displayable) LayerSet(ini.trakem2.display.LayerSet) HashMap(java.util.HashMap) ZDisplayable(ini.trakem2.display.ZDisplayable) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Tree(ini.trakem2.display.Tree) AreaTree(ini.trakem2.display.AreaTree) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 10 with Tree

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

the class TemplateTree method renameType.

/**
 * Rename a TemplateThing type from @param old_name to @param new_name.
 *  If such a new_name already exists, the renaming will not occur and returns false.
 */
public boolean renameType(final String old_name, String new_name) {
    // to lower case!
    new_name = new_name.toLowerCase();
    Project project = root.getProject();
    if (new_name.equals(old_name)) {
        return true;
    } else if (project.typeExists(new_name)) {
        Utils.logAll("Type '" + new_name + "' exists already!");
        return false;
    }
    // process name change in all TemplateThing instances that have it
    ArrayList<TemplateThing> al = root.collectAllChildren(new ArrayList<TemplateThing>());
    al.add(root);
    for (final TemplateThing tet : al) {
        // Utils.log("\tchecking " + tet.getType() + " " + tet.getId());
        if (tet.getType().equals(old_name))
            tet.rename(new_name);
    }
    // and update the ProjectThing objects in the tree and its dependant Displayable objects in the open Displays
    project.getRootProjectThing().updateType(new_name, old_name);
    // tell the project about it
    project.updateTypeName(old_name, new_name);
    // repaint both trees (will update the type names)
    updateUILater();
    project.getProjectTree().updateUILater();
    return true;
}
Also used : Project(ini.trakem2.Project)

Aggregations

ArrayList (java.util.ArrayList)14 HashMap (java.util.HashMap)13 HashSet (java.util.HashSet)10 Displayable (ini.trakem2.display.Displayable)9 ZDisplayable (ini.trakem2.display.ZDisplayable)9 ProjectThing (ini.trakem2.tree.ProjectThing)9 Project (ini.trakem2.Project)8 DBObject (ini.trakem2.persistence.DBObject)8 LayerSet (ini.trakem2.display.LayerSet)7 TemplateThing (ini.trakem2.tree.TemplateThing)7 TreePath (javax.swing.tree.TreePath)7 GenericDialog (ij.gui.GenericDialog)6 Layer (ini.trakem2.display.Layer)6 LayerThing (ini.trakem2.tree.LayerThing)6 List (java.util.List)6 Map (java.util.Map)6 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)6 ProjectTree (ini.trakem2.tree.ProjectTree)5 Worker (ini.trakem2.utils.Worker)5 ImagePlus (ij.ImagePlus)4