Search in sources :

Example 36 with PathObject

use of qupath.lib.objects.PathObject in project qupath by qupath.

the class PointIO method writePoints.

/**
 * Write a list of point annotations to a stream.
 * @param stream
 * @param pathObjects
 * @throws IOException
 */
public static void writePoints(OutputStream stream, Collection<? extends PathObject> pathObjects) throws IOException {
    // Check that all PathObjects contain only point annotations
    int unfilteredSize = pathObjects.size();
    pathObjects = pathObjects.stream().filter(p -> p.getROI() instanceof PointsROI).collect(Collectors.toList());
    int filteredSize = pathObjects.size();
    if (unfilteredSize != filteredSize)
        logger.warn(unfilteredSize - filteredSize + " of the " + filteredSize + " elements in list is/are not point annotations. These will be skipped.");
    try (Writer writer = new BufferedWriter(new OutputStreamWriter(stream, StandardCharsets.UTF_8))) {
        List<String> cols = new ArrayList<>();
        cols.addAll(Arrays.asList("x", "y"));
        String sep = "\t";
        ImagePlane defaultPlane = ImagePlane.getDefaultPlane();
        boolean hasClass = pathObjects.stream().anyMatch(p -> p.getPathClass() != null);
        boolean hasName = pathObjects.stream().anyMatch(p -> p.getName() != null);
        boolean hasColor = pathObjects.stream().anyMatch(p -> p.getColorRGB() != null);
        boolean hasC = pathObjects.stream().anyMatch(p -> p.getROI().getC() > defaultPlane.getC());
        boolean hasZ = pathObjects.stream().anyMatch(p -> p.getROI().getZ() > defaultPlane.getZ());
        boolean hasT = pathObjects.stream().anyMatch(p -> p.getROI().getT() > defaultPlane.getT());
        if (hasC)
            cols.add("c");
        if (hasZ)
            cols.add("z");
        if (hasT)
            cols.add("t");
        if (hasClass)
            cols.add("class");
        if (hasName)
            cols.add("name");
        if (hasColor)
            cols.add("color");
        for (String col : cols) writer.write(col + sep);
        writer.write(System.lineSeparator());
        for (PathObject pathObject : pathObjects) {
            if (!PathObjectTools.hasPointROI(pathObject))
                continue;
            PointsROI points = (PointsROI) pathObject.getROI();
            for (Point2 point : points.getAllPoints()) {
                String[] row = new String[cols.size()];
                row[cols.indexOf("x")] = point.getX() + "";
                row[cols.indexOf("y")] = sep + point.getY();
                if (hasC)
                    row[cols.indexOf("c")] = sep + points.getC();
                if (hasZ)
                    row[cols.indexOf("z")] = sep + points.getZ();
                if (hasT)
                    row[cols.indexOf("t")] = sep + points.getT();
                if (hasClass)
                    row[cols.indexOf("class")] = pathObject.getPathClass() != null ? sep + pathObject.getPathClass() : sep;
                if (hasName)
                    row[cols.indexOf("name")] = pathObject.getName() != null ? sep + pathObject.getName() : sep;
                if (hasColor)
                    row[cols.indexOf("color")] = pathObject.getColorRGB() != null ? sep + pathObject.getColorRGB() : sep;
                for (String val : row) writer.write(val);
                writer.write(System.lineSeparator());
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) PointsROI(qupath.lib.roi.PointsROI) BufferedWriter(java.io.BufferedWriter) PathObject(qupath.lib.objects.PathObject) Point2(qupath.lib.geom.Point2) OutputStreamWriter(java.io.OutputStreamWriter) ImagePlane(qupath.lib.regions.ImagePlane) OutputStreamWriter(java.io.OutputStreamWriter) BufferedWriter(java.io.BufferedWriter) Writer(java.io.Writer)

Example 37 with PathObject

use of qupath.lib.objects.PathObject in project qupath by qupath.

the class TMAScoreImporter method importFromCSV.

private static int importFromCSV(final Map<String, List<String>> map, final PathObjectHierarchy hierarchy) {
    TMAGrid tmaGrid = hierarchy.getTMAGrid();
    if (tmaGrid == null || tmaGrid.nCores() == 0) {
        logger.error("No TMA grid found!");
        return 0;
    }
    // Try to get a 'core' column
    String coreKey = null;
    for (String key : map.keySet()) {
        if (key.trim().toLowerCase().equals("core")) {
            coreKey = key;
            break;
        }
    }
    List<String> coreNames = coreKey == null ? null : map.remove(coreKey);
    // Try to get a unique ID column
    List<String> coreIDs = map.remove(TMACoreObject.KEY_UNIQUE_ID);
    // If we don't have a core column OR a unique ID column, we can't do anything
    if (coreNames == null && coreIDs == null) {
        logger.error("No column with header 'core' or '" + TMACoreObject.KEY_UNIQUE_ID + "' found");
        return 0;
    }
    // int n = coreNames == null ? coreIDs.size() : coreNames.size();
    // Get a list of cores ordered by whatever info we have
    Map<Integer, List<TMACoreObject>> cores = new HashMap<>();
    boolean coresFound = false;
    // If we have any unique IDs, use these and change names accordingly - if possible, and necessary
    if (coreIDs != null) {
        int i = 0;
        for (String id : coreIDs) {
            List<TMACoreObject> coresByID = new ArrayList<>();
            for (TMACoreObject coreTemp : tmaGrid.getTMACoreList()) if (id != null && id.equals(coreTemp.getUniqueID()))
                coresByID.add(coreTemp);
            if (!coresByID.isEmpty()) {
                cores.put(i, coresByID);
                coresFound = true;
                if (coreNames != null && coresByID.size() == 1) {
                    String currentName = coresByID.get(0).getName();
                    String newName = coreNames.get(i);
                    if (!newName.equals(currentName)) {
                        coresByID.get(0).setName(newName);
                        if (currentName != null)
                            logger.warn("Core name changed from {} to {}", currentName, newName);
                    }
                }
            }
            i++;
        }
    }
    // If we didn't have any unique IDs, we need to work with core names instead
    if (!coresFound && coreNames != null) {
        int i = 0;
        for (String name : coreNames) {
            TMACoreObject core = tmaGrid.getTMACore(name);
            if (core != null) {
                cores.put(i, Collections.singletonList(core));
                coresFound = true;
                if (coreIDs != null) {
                    String currentID = core.getUniqueID();
                    String newID = coreIDs.get(i);
                    if (newID != null && !newID.equals(currentID)) {
                        core.setUniqueID(newID);
                        // It shouldn't occur that an existing ID is changed... although it's possible if there are duplicates
                        if (currentID != null)
                            logger.warn("Core unique ID changed from {} to {}", currentID, newID);
                    }
                }
            }
            i++;
        }
    }
    // Add extra columns from the map, either as metadata or measurements
    for (Entry<String, List<String>> entry : map.entrySet()) {
        // Skip columns without headers
        if (entry.getKey() == null || entry.getKey().trim().length() == 0)
            continue;
        // If we have survival data, or else can't parse numeric values, add as metadata
        boolean isOverallSurvival = entry.getKey().equalsIgnoreCase(TMACoreObject.KEY_OVERALL_SURVIVAL);
        boolean isRecurrenceFreeSurvival = entry.getKey().equalsIgnoreCase(TMACoreObject.KEY_RECURRENCE_FREE_SURVIVAL);
        boolean isOSCensored = entry.getKey().equalsIgnoreCase(TMACoreObject.KEY_OS_CENSORED);
        boolean isRFSCensored = entry.getKey().equalsIgnoreCase(TMACoreObject.KEY_RFS_CENSORED);
        // Try to parse numeric data, if we can
        boolean isSurvivalRelated = isOverallSurvival || isRecurrenceFreeSurvival || isOSCensored || isRFSCensored;
        double[] vals = parseNumeric(entry.getValue(), !isSurvivalRelated);
        if (isSurvivalRelated || vals == null || vals.length == GeneralTools.numNaNs(vals)) {
            for (int i : cores.keySet()) {
                for (TMACoreObject core : cores.get(i)) {
                    if (core == null)
                        continue;
                    if (isOverallSurvival)
                        core.getMeasurementList().putMeasurement(TMACoreObject.KEY_OVERALL_SURVIVAL, vals[i]);
                    else if (isRecurrenceFreeSurvival)
                        core.getMeasurementList().putMeasurement(TMACoreObject.KEY_RECURRENCE_FREE_SURVIVAL, vals[i]);
                    else if (isOSCensored)
                        core.getMeasurementList().putMeasurement(TMACoreObject.KEY_OS_CENSORED, vals[i] > 0 ? 1 : 0);
                    else if (isRFSCensored)
                        core.getMeasurementList().putMeasurement(TMACoreObject.KEY_RFS_CENSORED, vals[i] > 0 ? 1 : 0);
                    else
                        core.putMetadataValue(entry.getKey(), entry.getValue().get(i));
                }
            }
        } else {
            // If we have a numeric column, add to measurement list
            for (int i : cores.keySet()) {
                for (TMACoreObject core : cores.get(i)) {
                    core.getMeasurementList().addMeasurement(entry.getKey(), vals[i]);
                }
            }
        }
    }
    // Loop through and close any measurement lists, recording anywhere changes were made
    Set<PathObject> changed = new HashSet<>();
    for (List<TMACoreObject> coreList : cores.values()) {
        for (TMACoreObject core : coreList) {
            if (core == null)
                continue;
            core.getMeasurementList().close();
            changed.add(core);
        }
    }
    hierarchy.fireObjectsChangedEvent(null, changed);
    return changed.size();
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TMACoreObject(qupath.lib.objects.TMACoreObject) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) ArrayList(java.util.ArrayList) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet)

Example 38 with PathObject

use of qupath.lib.objects.PathObject in project qupath by qupath.

the class GuiTools method promptToClearAllSelectedObjects.

/**
 * Prompt user to select all currently-selected objects (except TMA core objects).
 *
 * @param imageData
 * @return
 */
public static boolean promptToClearAllSelectedObjects(final ImageData<?> imageData) {
    // Get all non-TMA core objects
    PathObjectHierarchy hierarchy = imageData.getHierarchy();
    Collection<PathObject> selectedRaw = hierarchy.getSelectionModel().getSelectedObjects();
    List<PathObject> selected = selectedRaw.stream().filter(p -> !(p instanceof TMACoreObject)).collect(Collectors.toList());
    if (selected.isEmpty()) {
        if (selectedRaw.size() > selected.size())
            Dialogs.showErrorMessage("Delete selected objects", "No valid objects selected! \n\nNote: Individual TMA cores cannot be deleted with this method.");
        else
            Dialogs.showErrorMessage("Delete selected objects", "No objects selected!");
        return false;
    }
    int n = selected.size();
    String message;
    if (n == 1)
        message = "Delete selected object?";
    else
        message = "Delete " + n + " selected objects?";
    if (Dialogs.showYesNoDialog("Delete objects", message)) {
        // Check for descendants
        List<PathObject> children = new ArrayList<>();
        for (PathObject temp : selected) {
            children.addAll(temp.getChildObjects());
        }
        children.removeAll(selected);
        boolean keepChildren = true;
        if (!children.isEmpty()) {
            Dialogs.DialogButton response = Dialogs.showYesNoCancelDialog("Delete objects", "Keep descendant objects?");
            if (response == Dialogs.DialogButton.CANCEL)
                return false;
            keepChildren = response == Dialogs.DialogButton.YES;
        }
        hierarchy.removeObjects(selected, keepChildren);
        hierarchy.getSelectionModel().clearSelection();
        imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Delete selected objects", "clearSelectedObjects(" + keepChildren + ");"));
        if (keepChildren)
            logger.info(selected.size() + " object(s) deleted");
        else
            logger.info(selected.size() + " object(s) deleted with descendants");
        imageData.getHistoryWorkflow().addStep(new DefaultScriptableWorkflowStep("Delete selected objects", "clearSelectedObjects();"));
        logger.info(selected.size() + " object(s) deleted");
        return true;
    } else
        return false;
}
Also used : CheckComboBox(org.controlsfx.control.CheckComboBox) UnaryOperator(java.util.function.UnaryOperator) TextFormatter(javafx.scene.control.TextFormatter) PathRootObject(qupath.lib.objects.PathRootObject) ParameterList(qupath.lib.plugins.parameters.ParameterList) PointsROI(qupath.lib.roi.PointsROI) Matcher(java.util.regex.Matcher) Action(java.awt.Desktop.Action) ColorTools(qupath.lib.common.ColorTools) GraphicsContext(javafx.scene.canvas.GraphicsContext) Canvas(javafx.scene.canvas.Canvas) Screen(javafx.stage.Screen) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Platform(javafx.application.Platform) CountDownLatch(java.util.concurrent.CountDownLatch) Transparency(java.awt.Transparency) Clipboard(javafx.scene.input.Clipboard) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) StringProperty(javafx.beans.property.StringProperty) Callable(java.util.concurrent.Callable) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) DefaultColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains.DefaultColorDeconvolutionStains) Bindings(javafx.beans.binding.Bindings) NumberFormat(java.text.NumberFormat) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Slider(javafx.scene.control.Slider) SplitAnnotationsPlugin(qupath.lib.plugins.objects.SplitAnnotationsPlugin) GridPane(javafx.scene.layout.GridPane) Color(javafx.scene.paint.Color) GeneralTools(qupath.lib.common.GeneralTools) Commands(qupath.lib.gui.commands.Commands) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) IOException(java.io.IOException) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Menu(javafx.scene.control.Menu) ROI(qupath.lib.roi.interfaces.ROI) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) Image(javafx.scene.image.Image) Button(javafx.scene.control.Button) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) DoubleBinding(javafx.beans.binding.DoubleBinding) ListCell(javafx.scene.control.ListCell) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) RenderingHints(java.awt.RenderingHints) Side(javafx.geometry.Side) ContextMenu(javafx.scene.control.ContextMenu) URI(java.net.URI) QuPathGUI(qupath.lib.gui.QuPathGUI) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Spinner(javafx.scene.control.Spinner) Collectors(java.util.stream.Collectors) StainVector(qupath.lib.color.StainVector) PathObject(qupath.lib.objects.PathObject) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) List(java.util.List) Robot(javafx.scene.robot.Robot) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Pattern(java.util.regex.Pattern) ClipboardContent(javafx.scene.input.ClipboardContent) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) TextArea(javafx.scene.control.TextArea) ParsePosition(java.text.ParsePosition) DoubleProperty(javafx.beans.property.DoubleProperty) ColorDeconvolutionHelper(qupath.lib.color.ColorDeconvolutionHelper) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) SwingUtilities(javax.swing.SwingUtilities) Graphics2D(java.awt.Graphics2D) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) ColorPicker(javafx.scene.control.ColorPicker) ImageData(qupath.lib.images.ImageData) Desktop(java.awt.Desktop) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) WritableImage(javafx.scene.image.WritableImage) TMACoreObject(qupath.lib.objects.TMACoreObject) DoubleSpinnerValueFactory(javafx.scene.control.SpinnerValueFactory.DoubleSpinnerValueFactory) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) SpinnerValueFactory(javafx.scene.control.SpinnerValueFactory) SwingFXUtils(javafx.embed.swing.SwingFXUtils) Window(javafx.stage.Window) Collections(java.util.Collections) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) TMACoreObject(qupath.lib.objects.TMACoreObject) ArrayList(java.util.ArrayList) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) PathObject(qupath.lib.objects.PathObject) Dialogs(qupath.lib.gui.dialogs.Dialogs)

Example 39 with PathObject

use of qupath.lib.objects.PathObject in project qupath by qupath.

the class GuiTools method promptToSetActiveAnnotationProperties.

/**
 * Prompt the user to set properties for the currently-selected annotation(s).
 *
 * @param hierarchy current hierarchy
 * @return true if changes to annotation properties were made, false otherwise.
 */
public static boolean promptToSetActiveAnnotationProperties(final PathObjectHierarchy hierarchy) {
    PathObject currentObject = hierarchy.getSelectionModel().getSelectedObject();
    if (currentObject == null || !currentObject.isAnnotation())
        return false;
    ROI roi = currentObject.getROI();
    if (roi == null)
        return false;
    Collection<PathAnnotationObject> otherAnnotations = hierarchy.getSelectionModel().getSelectedObjects().stream().filter(p -> p.isAnnotation() && p != currentObject).map(p -> (PathAnnotationObject) p).collect(Collectors.toList());
    if (promptToSetAnnotationProperties((PathAnnotationObject) currentObject, otherAnnotations)) {
        hierarchy.fireObjectsChangedEvent(null, Collections.singleton(currentObject));
        // Ensure the object is still selected
        hierarchy.getSelectionModel().setSelectedObject(currentObject);
        return true;
    }
    return false;
}
Also used : CheckComboBox(org.controlsfx.control.CheckComboBox) UnaryOperator(java.util.function.UnaryOperator) TextFormatter(javafx.scene.control.TextFormatter) PathRootObject(qupath.lib.objects.PathRootObject) ParameterList(qupath.lib.plugins.parameters.ParameterList) PointsROI(qupath.lib.roi.PointsROI) Matcher(java.util.regex.Matcher) Action(java.awt.Desktop.Action) ColorTools(qupath.lib.common.ColorTools) GraphicsContext(javafx.scene.canvas.GraphicsContext) Canvas(javafx.scene.canvas.Canvas) Screen(javafx.stage.Screen) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) Platform(javafx.application.Platform) CountDownLatch(java.util.concurrent.CountDownLatch) Transparency(java.awt.Transparency) Clipboard(javafx.scene.input.Clipboard) SimpleDoubleProperty(javafx.beans.property.SimpleDoubleProperty) StringProperty(javafx.beans.property.StringProperty) Callable(java.util.concurrent.Callable) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) DefaultColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains.DefaultColorDeconvolutionStains) Bindings(javafx.beans.binding.Bindings) NumberFormat(java.text.NumberFormat) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Slider(javafx.scene.control.Slider) SplitAnnotationsPlugin(qupath.lib.plugins.objects.SplitAnnotationsPlugin) GridPane(javafx.scene.layout.GridPane) Color(javafx.scene.paint.Color) GeneralTools(qupath.lib.common.GeneralTools) Commands(qupath.lib.gui.commands.Commands) Node(javafx.scene.Node) CheckBox(javafx.scene.control.CheckBox) IOException(java.io.IOException) File(java.io.File) PathObjectTools(qupath.lib.objects.PathObjectTools) Menu(javafx.scene.control.Menu) ROI(qupath.lib.roi.interfaces.ROI) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) Image(javafx.scene.image.Image) Button(javafx.scene.control.Button) ImageServer(qupath.lib.images.servers.ImageServer) CombineOp(qupath.lib.roi.RoiTools.CombineOp) DoubleBinding(javafx.beans.binding.DoubleBinding) ListCell(javafx.scene.control.ListCell) CheckMenuItem(javafx.scene.control.CheckMenuItem) LoggerFactory(org.slf4j.LoggerFactory) RenderingHints(java.awt.RenderingHints) Side(javafx.geometry.Side) ContextMenu(javafx.scene.control.ContextMenu) URI(java.net.URI) QuPathGUI(qupath.lib.gui.QuPathGUI) TextField(javafx.scene.control.TextField) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) Collection(java.util.Collection) Spinner(javafx.scene.control.Spinner) Collectors(java.util.stream.Collectors) StainVector(qupath.lib.color.StainVector) PathObject(qupath.lib.objects.PathObject) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) QuPathViewer(qupath.lib.gui.viewer.QuPathViewer) List(java.util.List) Robot(javafx.scene.robot.Robot) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Pattern(java.util.regex.Pattern) ClipboardContent(javafx.scene.input.ClipboardContent) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) TextArea(javafx.scene.control.TextArea) ParsePosition(java.text.ParsePosition) DoubleProperty(javafx.beans.property.DoubleProperty) ColorDeconvolutionHelper(qupath.lib.color.ColorDeconvolutionHelper) Function(java.util.function.Function) Dialogs(qupath.lib.gui.dialogs.Dialogs) ColorDeconvolutionStains(qupath.lib.color.ColorDeconvolutionStains) SwingUtilities(javax.swing.SwingUtilities) Graphics2D(java.awt.Graphics2D) ActionTools(qupath.lib.gui.ActionTools) Tooltip(javafx.scene.control.Tooltip) ColorPicker(javafx.scene.control.ColorPicker) ImageData(qupath.lib.images.ImageData) Desktop(java.awt.Desktop) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Label(javafx.scene.control.Label) WritableImage(javafx.scene.image.WritableImage) TMACoreObject(qupath.lib.objects.TMACoreObject) DoubleSpinnerValueFactory(javafx.scene.control.SpinnerValueFactory.DoubleSpinnerValueFactory) SimpleBooleanProperty(javafx.beans.property.SimpleBooleanProperty) Stage(javafx.stage.Stage) SpinnerValueFactory(javafx.scene.control.SpinnerValueFactory) SwingFXUtils(javafx.embed.swing.SwingFXUtils) Window(javafx.stage.Window) Collections(java.util.Collections) PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) PointsROI(qupath.lib.roi.PointsROI) ROI(qupath.lib.roi.interfaces.ROI)

Example 40 with PathObject

use of qupath.lib.objects.PathObject in project qupath by qupath.

the class GuiTools method setSelectedAnnotationLock.

/**
 * Set selected TMA cores to have the specified 'locked' status.
 *
 * @param hierarchy
 * @param setToLocked
 */
private static void setSelectedAnnotationLock(final PathObjectHierarchy hierarchy, final boolean setToLocked) {
    if (hierarchy == null)
        return;
    PathObject pathObject = hierarchy.getSelectionModel().getSelectedObject();
    List<PathObject> changed = new ArrayList<>();
    if (pathObject instanceof PathAnnotationObject) {
        PathAnnotationObject annotation = (PathAnnotationObject) pathObject;
        annotation.setLocked(setToLocked);
        changed.add(annotation);
        // Update any other selected cores to have the same status
        for (PathObject pathObject2 : hierarchy.getSelectionModel().getSelectedObjects()) {
            if (pathObject2 instanceof PathAnnotationObject) {
                annotation = (PathAnnotationObject) pathObject2;
                if (annotation.isLocked() != setToLocked) {
                    annotation.setLocked(setToLocked);
                    changed.add(annotation);
                }
            }
        }
    }
    if (!changed.isEmpty())
        hierarchy.fireObjectsChangedEvent(GuiTools.class, changed);
}
Also used : PathAnnotationObject(qupath.lib.objects.PathAnnotationObject) PathObject(qupath.lib.objects.PathObject) ArrayList(java.util.ArrayList)

Aggregations

PathObject (qupath.lib.objects.PathObject)182 ArrayList (java.util.ArrayList)84 ROI (qupath.lib.roi.interfaces.ROI)74 PathObjectHierarchy (qupath.lib.objects.hierarchy.PathObjectHierarchy)61 List (java.util.List)48 BufferedImage (java.awt.image.BufferedImage)37 IOException (java.io.IOException)37 PathClass (qupath.lib.objects.classes.PathClass)37 Collectors (java.util.stream.Collectors)35 PathAnnotationObject (qupath.lib.objects.PathAnnotationObject)34 Map (java.util.Map)33 Logger (org.slf4j.Logger)33 LoggerFactory (org.slf4j.LoggerFactory)33 ImageData (qupath.lib.images.ImageData)31 TMACoreObject (qupath.lib.objects.TMACoreObject)31 Collection (java.util.Collection)29 Collections (java.util.Collections)29 HashMap (java.util.HashMap)28 PathObjectTools (qupath.lib.objects.PathObjectTools)26 Arrays (java.util.Arrays)25