Search in sources :

Example 6 with WorkflowStep

use of qupath.lib.plugins.workflow.WorkflowStep in project qupath by qupath.

the class ParameterDialogWrapper method createDialog.

private Stage createDialog(final PathInteractivePlugin<T> plugin, final ParameterList params, final PluginRunner<T> pluginRunner) {
    panel = new ParameterPanelFX(params);
    panel.getPane().setPadding(new Insets(5, 5, 5, 5));
    // panel.addParameterChangeListener(new ParameterChangeListener() {
    // 
    // @Override
    // public void parameterChanged(ParameterList parameterList, String key, boolean isAdjusting) {
    // 
    // if (!plugin.requestLiveUpdate())
    // return;
    // 
    // PathObjectHierarchy hierarchy = pluginRunner.getHierarchy();
    // if (hierarchy == null)
    // return;
    // 
    // Collection<Class<? extends PathObject>> supportedParents = plugin.getSupportedParentObjectClasses();
    // 
    // PathObject selectedObject = pluginRunner.getSelectedObject();
    // if (selectedObject == null) {
    // if (supportedParents.contains(PathRootObject.class))
    // Collections.singleton(hierarchy.getRootObject());
    // } else if (supportedParents.contains(selectedObject.getClass()))
    // Collections.singleton(selectedObject);
    // }
    // 
    // });
    // final Button btnRun = new Button("Run " + plugin.getName());
    final Button btnRun = new Button("Run");
    btnRun.textProperty().bind(Bindings.createStringBinding(() -> {
        if (btnRun.isDisabled())
            return "Please wait...";
        else
            return "Run";
    }, btnRun.disabledProperty()));
    final Stage dialog = new Stage();
    QuPathGUI qupath = QuPathGUI.getInstance();
    if (qupath != null)
        dialog.initOwner(qupath.getStage());
    dialog.setTitle(plugin.getName());
    final String emptyLabel = " \n";
    final Label label = new Label(emptyLabel);
    label.setStyle("-fx-font-weight: bold;");
    label.setPadding(new Insets(5, 5, 5, 5));
    label.setAlignment(Pos.CENTER);
    label.setTextAlignment(TextAlignment.CENTER);
    btnRun.setOnAction(e -> {
        // Check if we have the parent objects available to make this worthwhile
        if (plugin instanceof PathInteractivePlugin) {
            // // Strip off any of our extra parameters
            // params.removeParameter(KEY_REGIONS);
            boolean alwaysPrompt = plugin.alwaysPromptForObjects();
            ImageData<?> imageData = pluginRunner.getImageData();
            Collection<PathObject> selected = imageData == null ? Collections.emptyList() : imageData.getHierarchy().getSelectionModel().getSelectedObjects();
            Collection<? extends PathObject> parents = PathObjectTools.getSupportedObjects(selected, plugin.getSupportedParentObjectClasses());
            if (alwaysPrompt || parents == null || parents.isEmpty()) {
                if (!ParameterDialogWrapper.promptForParentObjects(pluginRunner, plugin, alwaysPrompt && !parents.isEmpty()))
                    return;
            }
        // promptForParentObjects
        }
        dialog.getScene().setCursor(Cursor.WAIT);
        btnRun.setDisable(true);
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                try {
                    WorkflowStep lastStep = pluginRunner.getImageData().getHistoryWorkflow().getLastStep();
                    boolean success = plugin.runPlugin(pluginRunner, ParameterList.getParameterListJSON(params, "  "));
                    WorkflowStep lastStepNew = pluginRunner.getImageData().getHistoryWorkflow().getLastStep();
                    if (success && lastStep != lastStepNew)
                        lastWorkflowStep = lastStepNew;
                    else
                        lastWorkflowStep = null;
                } catch (Exception e) {
                    Dialogs.showErrorMessage("Plugin error", e);
                } catch (OutOfMemoryError e) {
                    // This doesn't actually work...
                    Dialogs.showErrorMessage("Out of memory error", "Out of memory - try to close other applications, or decrease the number of parallel processors in the QuPath preferences");
                } finally {
                    Platform.runLater(() -> {
                        QuPathGUI.getInstance().pluginRunningProperty().set(false);
                        dialog.getScene().setCursor(Cursor.DEFAULT);
                        label.setText(plugin.getLastResultsDescription());
                        btnRun.setDisable(false);
                    });
                }
            }
        };
        Thread t = new Thread(runnable, "Plugin thread");
        QuPathGUI.getInstance().pluginRunningProperty().set(true);
        t.start();
    });
    BorderPane pane = new BorderPane();
    ScrollPane scrollPane = new ScrollPane();
    label.setMaxWidth(Double.MAX_VALUE);
    scrollPane.setContent(panel.getPane());
    scrollPane.setFitToWidth(true);
    pane.setCenter(scrollPane);
    btnRun.setMaxWidth(Double.MAX_VALUE);
    btnRun.setPadding(new Insets(5, 5, 5, 5));
    pane.setBottom(btnRun);
    Scene scene = new Scene(pane);
    dialog.setScene(scene);
    // Request focus, to make it easier to run from the keyboard
    btnRun.requestFocus();
    dialog.sizeToScene();
    return dialog;
}
Also used : BorderPane(javafx.scene.layout.BorderPane) Insets(javafx.geometry.Insets) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) Label(javafx.scene.control.Label) Scene(javafx.scene.Scene) ParameterPanelFX(qupath.lib.gui.dialogs.ParameterPanelFX) PathInteractivePlugin(qupath.lib.plugins.PathInteractivePlugin) PathObject(qupath.lib.objects.PathObject) Button(javafx.scene.control.Button) ScrollPane(javafx.scene.control.ScrollPane) Stage(javafx.stage.Stage)

Example 7 with WorkflowStep

use of qupath.lib.plugins.workflow.WorkflowStep in project qupath by qupath.

the class DragDropImportListener method handleFileDropImpl.

private void handleFileDropImpl(final QuPathViewer viewer, final List<File> list) throws IOException {
    // Shouldn't occur... but keeps FindBugs happy to check
    if (list == null) {
        logger.warn("No files given!");
        return;
    }
    // Check if we have only jar files
    int nJars = 0;
    for (File file : list) {
        if (file.getName().toLowerCase().endsWith(".jar"))
            nJars++;
    }
    if (nJars == list.size()) {
        if (qupath.canInstallExtensions())
            qupath.installExtensions(list);
        else
            Dialogs.showErrorMessage("Install extensions", "Sorry, extensions can only be installed when QuPath is run as a standalone application.");
        return;
    }
    // Try to get a hierarchy for importing ROIs
    ImageData<BufferedImage> imageData = viewer == null ? null : viewer.getImageData();
    PathObjectHierarchy hierarchy = imageData == null ? null : imageData.getHierarchy();
    // Some consumers can only handle one file
    boolean singleFile = list.size() == 1;
    // Gather together the extensions - if this has length one, we know all the files have the same extension
    Set<String> allExtensions = list.stream().map(f -> GeneralTools.getExtension(f).orElse("")).collect(Collectors.toSet());
    // If we have a zipped file, create a set that includes the files within the zip image
    // This helps us determine whether or not a zip file contains an image or objects, for example
    Set<String> allUnzippedExtensions = allExtensions;
    if (allExtensions.contains(".zip")) {
        allUnzippedExtensions = list.stream().flatMap(f -> {
            try {
                return PathIO.unzippedExtensions(f.toPath()).stream();
            } catch (IOException e) {
                logger.debug(e.getLocalizedMessage(), e);
                return Arrays.stream(new String[0]);
            }
        }).collect(Collectors.toSet());
    }
    // Extract the first (and possibly only) file
    File file = list.get(0);
    String fileName = file.getName().toLowerCase();
    // Check if this is a hierarchy file
    if (singleFile && (fileName.endsWith(PathPrefs.getSerializationExtension()))) {
        // If we have a different path, open as a new image
        if (viewer == null) {
            Dialogs.showErrorMessage("Load data", "Please drag the file onto a specific viewer to open!");
            return;
        }
        try {
            // Check if we should be importing objects or opening the file
            if (imageData != null) {
                var dialog = new Dialog<ButtonType>();
                var btOpen = new ButtonType("Open image");
                var btImport = new ButtonType("Import objects");
                dialog.getDialogPane().getButtonTypes().setAll(btOpen, btImport, ButtonType.CANCEL);
                dialog.setTitle("Open data");
                dialog.setHeaderText("What do you want to do with the data file?");
                dialog.setContentText("You can\n" + " 1. Open the image in the current viewer\n" + " 2. Import objects and add them to the current image");
                // dialog.setHeaderText("What do you want to do?");
                var choice = dialog.showAndWait().orElse(ButtonType.CANCEL);
                if (choice == ButtonType.CANCEL)
                    return;
                if (choice == btImport) {
                    var pathObjects = PathIO.readObjects(file);
                    hierarchy.addPathObjects(pathObjects);
                    return;
                }
            }
            qupath.openSavedData(viewer, file, false, true);
        } catch (Exception e) {
            Dialogs.showErrorMessage("Load data", e);
        }
        return;
    }
    // Check if this is a directory - if so, look for a single project file
    if (singleFile && file.isDirectory()) {
        // Identify all files in the directory, and also all potential project files
        File[] filesInDirectory = file.listFiles(f -> !f.isHidden());
        List<File> projectFiles = Arrays.stream(filesInDirectory).filter(f -> f.isFile() && f.getAbsolutePath().toLowerCase().endsWith(ProjectIO.getProjectExtension())).collect(Collectors.toList());
        if (projectFiles.size() == 1) {
            file = projectFiles.get(0);
            logger.warn("Selecting project file {}", file);
        } else if (projectFiles.size() > 1) {
            // Prompt to select which project file to open
            logger.debug("Multiple project files found in directory {}", file);
            String[] fileNames = projectFiles.stream().map(f -> f.getName()).toArray(n -> new String[n]);
            String selectedName = Dialogs.showChoiceDialog("Select project", "Select project to open", fileNames, fileNames[0]);
            if (selectedName == null)
                return;
            file = new File(file, selectedName);
        } else if (filesInDirectory.length == 0) {
            // If we have an empty directory, offer to set it as a project
            if (Dialogs.showYesNoDialog("Create project", "Create project for empty directory?")) {
                Project<BufferedImage> project = Projects.createProject(file, BufferedImage.class);
                qupath.setProject(project);
                if (!project.isEmpty())
                    project.syncChanges();
                return;
            } else
                // Can't do anything else with an empty folder
                return;
        }
    }
    // Check if this is a project
    if (singleFile && (fileName.endsWith(ProjectIO.getProjectExtension()))) {
        try {
            Project<BufferedImage> project = ProjectIO.loadProject(file, BufferedImage.class);
            qupath.setProject(project);
        } catch (Exception e) {
            // Dialogs.showErrorMessage("Project error", e);
            logger.error("Could not open as project file: {}, opening in the Script Editor instead", e);
            qupath.getScriptEditor().showScript(file);
        }
        return;
    }
    // Check if it is an object file in GeoJSON format (.geojson)
    if (PathIO.getObjectFileExtensions(false).containsAll(allUnzippedExtensions)) {
        if (imageData == null || hierarchy == null) {
            qupath.getScriptEditor().showScript(file);
            logger.info("Opening the dragged file in the Script Editor as there is no currently opened image in the viewer");
            // Dialogs.showErrorMessage("Open object file", "Please open an image first to import objects!");
            return;
        }
        List<PathObject> pathObjects = new ArrayList<>();
        List<WorkflowStep> steps = new ArrayList<>();
        for (var tempFile : list) {
            try {
                var tempObjects = PathIO.readObjects(tempFile);
                if (tempObjects.isEmpty()) {
                    logger.warn("No objects found in {}, opening the dragged file in the Script Editor instead", tempFile.getAbsolutePath());
                    qupath.getScriptEditor().showScript(file);
                    return;
                }
                pathObjects.addAll(tempObjects);
                // Add step to workflow
                Map<String, String> map = new HashMap<>();
                map.put("path", file.getPath());
                String method = "Import objects";
                String methodString = String.format("%s(%s%s%s)", "importObjectsFromFile", "\"", GeneralTools.escapeFilePath(tempFile.getPath()), "\"");
                steps.add(new DefaultScriptableWorkflowStep(method, map, methodString));
            } catch (IOException | IllegalArgumentException e) {
                Dialogs.showErrorNotification("Object import", e.getLocalizedMessage());
                return;
            }
        }
        // Ask confirmation to user
        int nObjects = pathObjects.size();
        String message = nObjects == 1 ? "Add object to the hierarchy?" : String.format("Add %d objects to the hierarchy?", nObjects);
        var confirm = Dialogs.showConfirmDialog("Add to hierarchy", message);
        if (!confirm)
            return;
        // Add objects to hierarchy
        hierarchy.addPathObjects(pathObjects);
        imageData.getHistoryWorkflow().addSteps(steps);
        return;
    }
    // Check if this is TMA dearraying data file
    if (singleFile && (fileName.endsWith(TMADataIO.TMA_DEARRAYING_DATA_EXTENSION))) {
        if (hierarchy == null)
            Dialogs.showErrorMessage("TMA grid import", "Please open an image first before importing a dearrayed TMA grid!");
        else {
            TMAGrid tmaGrid = TMADataIO.importDearrayedTMAData(file);
            if (tmaGrid != null) {
                if (hierarchy.isEmpty() || Dialogs.showYesNoDialog("TMA grid import", "Set TMA grid for existing hierarchy?"))
                    hierarchy.setTMAGrid(tmaGrid);
            } else
                Dialogs.showErrorMessage("TMA grid import", "Could not parse TMA grid from " + file.getName());
        }
        return;
    }
    // Open file with an extension supported by the Script Editor
    ScriptEditor scriptEditor = qupath.getScriptEditor();
    if (scriptEditor instanceof DefaultScriptEditor && ((DefaultScriptEditor) scriptEditor).supportsFile(file)) {
        scriptEditor.showScript(file);
        return;
    }
    // Check handlers
    for (DropHandler<File> handler : dropHandlers) {
        if (handler.handleDrop(viewer, list))
            return;
    }
    // Assume we have images
    if (singleFile && file.isFile()) {
        // Try to open as an image, if the extension is known
        if (viewer == null) {
            Dialogs.showErrorMessage("Open image", "Please drag the file only a specific viewer to open!");
            return;
        }
        qupath.openImage(viewer, file.getAbsolutePath(), true, true);
        return;
    } else if (qupath.getProject() != null) {
        // Try importing multiple images to a project
        String[] potentialFiles = list.stream().filter(f -> f.isFile()).map(f -> f.getAbsolutePath()).toArray(String[]::new);
        if (potentialFiles.length > 0) {
            ProjectCommands.promptToImportImages(qupath, potentialFiles);
            return;
        }
    }
    if (qupath.getProject() == null) {
        if (list.size() > 1) {
            Dialogs.showErrorMessage("Drag & drop", "Could not handle multiple file drop - if you want to handle multiple images, you need to create a project first");
            return;
        }
    }
    if (list.size() > 1)
        Dialogs.showErrorMessage("Drag & drop", "Sorry, I couldn't figure out what to do with these files - try opening one at a time");
    else
        Dialogs.showErrorMessage("Drag & drop", "Sorry, I couldn't figure out what to do with " + list.get(0).getName());
}
Also used : EventHandler(javafx.event.EventHandler) Scene(javafx.scene.Scene) Arrays(java.util.Arrays) ButtonType(javafx.scene.control.ButtonType) LoggerFactory(org.slf4j.LoggerFactory) HashMap(java.util.HashMap) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) ScriptEditor(qupath.lib.gui.scripting.ScriptEditor) DragEvent(javafx.scene.input.DragEvent) TransferMode(javafx.scene.input.TransferMode) Projects(qupath.lib.projects.Projects) ArrayList(java.util.ArrayList) Dialogs(qupath.lib.gui.dialogs.Dialogs) TMADataIO(qupath.lib.gui.tma.TMADataIO) Dragboard(javafx.scene.input.Dragboard) Map(java.util.Map) QuPathGUI(qupath.lib.gui.QuPathGUI) ImageData(qupath.lib.images.ImageData) Logger(org.slf4j.Logger) Dialog(javafx.scene.control.Dialog) BufferedImage(java.awt.image.BufferedImage) GeneralTools(qupath.lib.common.GeneralTools) Node(javafx.scene.Node) Set(java.util.Set) IOException(java.io.IOException) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) ProjectCommands(qupath.lib.gui.commands.ProjectCommands) Collectors(java.util.stream.Collectors) File(java.io.File) PathObject(qupath.lib.objects.PathObject) List(java.util.List) Project(qupath.lib.projects.Project) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) ProjectIO(qupath.lib.projects.ProjectIO) DefaultScriptEditor(qupath.lib.gui.scripting.DefaultScriptEditor) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) PathPrefs(qupath.lib.gui.prefs.PathPrefs) PathIO(qupath.lib.io.PathIO) PathObjectHierarchy(qupath.lib.objects.hierarchy.PathObjectHierarchy) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DefaultScriptEditor(qupath.lib.gui.scripting.DefaultScriptEditor) BufferedImage(java.awt.image.BufferedImage) DefaultScriptableWorkflowStep(qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep) Dialog(javafx.scene.control.Dialog) ButtonType(javafx.scene.control.ButtonType) TMAGrid(qupath.lib.objects.hierarchy.TMAGrid) IOException(java.io.IOException) IOException(java.io.IOException) ScriptEditor(qupath.lib.gui.scripting.ScriptEditor) DefaultScriptEditor(qupath.lib.gui.scripting.DefaultScriptEditor) PathObject(qupath.lib.objects.PathObject) File(java.io.File)

Example 8 with WorkflowStep

use of qupath.lib.plugins.workflow.WorkflowStep in project qupath by qupath.

the class TMADearrayerPluginIJ method addWorkflowStep.

@Override
protected void addWorkflowStep(final ImageData<BufferedImage> imageData, final String arg) {
    WorkflowStep step = new SimplePluginWorkflowStep(getName(), (Class<? extends PathPlugin<?>>) getClass(), arg, "if (!isTMADearrayed()) {\n\t", "\n\treturn;\n}");
    imageData.getHistoryWorkflow().addStep(step);
    logger.info("{}", step);
}
Also used : WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep) SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep)

Example 9 with WorkflowStep

use of qupath.lib.plugins.workflow.WorkflowStep in project qupath by qupath.

the class WorkflowCommandLogView method createPane.

protected BorderPane createPane() {
    BorderPane pane = new BorderPane();
    TableColumn<KeyValue<Object>, String> col1 = new TableColumn<>("Parameter");
    col1.setCellValueFactory(c -> c.getValue().keyProperty());
    TableColumn<KeyValue<Object>, Object> col2 = new TableColumn<>("Value");
    col2.setCellValueFactory(c -> c.getValue().valueProperty());
    col2.setCellFactory(t -> new ParameterTableCell<>());
    table.getColumns().add(col1);
    table.getColumns().add(col2);
    table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
    SplitPane splitPane = new SplitPane();
    splitPane.setOrientation(Orientation.VERTICAL);
    splitPane.getItems().addAll(list, table);
    // Allow multiple selections for static model
    list.getSelectionModel().setSelectionMode(isStaticWorkflow ? SelectionMode.MULTIPLE : SelectionMode.SINGLE);
    list.getSelectionModel().selectedItemProperty().addListener((e, f, g) -> {
        WorkflowStep step = list.getSelectionModel().getSelectedItem();
        populateList(table.getItems(), step);
    });
    final ContextMenu contextMenu = new ContextMenu();
    MenuItem miCopyCommand = new MenuItem("Copy command" + (isStaticWorkflow ? "s" : ""));
    miCopyCommand.setOnAction(e -> {
        List<Integer> indices = list.getSelectionModel().getSelectedIndices();
        if (indices == null || indices.isEmpty())
            return;
        copyScriptToClipboard(indices);
    });
    miCopyCommand.disableProperty().bind(workflowProperty.isNull());
    contextMenu.getItems().setAll(miCopyCommand);
    if (isStaticWorkflow) {
        MenuItem miRemoveSelected = new MenuItem("Remove selected items");
        miRemoveSelected.setOnAction(e -> {
            var steps = getSelectedIndices();
            if (steps == null || steps.isEmpty())
                return;
            String message = steps.size() == 1 ? "Remove workflow step?" : "Remove " + steps.size() + " workflow steps?";
            if (!Dialogs.showYesNoDialog("Remove workflow steps", message))
                return;
            Collections.sort(steps);
            for (int i = steps.size() - 1; i >= 0; i--) getWorkflow().removeStep(steps.get(i));
        // workflow.removeSteps(steps);
        });
        miRemoveSelected.disableProperty().bind(workflowProperty.isNull());
        MenuItem miMoveUp = new MenuItem("Move up");
        miMoveUp.setOnAction(e -> {
            var indices = getSelectedIndices();
            if (indices == null || indices.isEmpty() || indices.get(0) <= 0)
                return;
            var workflow = getWorkflow();
            List<WorkflowStep> steps = new ArrayList<>(workflow.getSteps());
            WorkflowStep[] stepsRemoved = new WorkflowStep[indices.size()];
            workflow.removeSteps(steps);
            int[] newIndices = new int[indices.size()];
            for (int i = indices.size() - 1; i >= 0; i--) {
                int ind = indices.get(i);
                int indNew = ind - 1;
                newIndices[i] = indNew;
                stepsRemoved[i] = steps.remove(ind);
            }
            for (int i = 0; i < indices.size(); i++) {
                steps.add(newIndices[i], stepsRemoved[i]);
            }
            workflow.addSteps(steps);
            list.getSelectionModel().clearSelection();
            list.getSelectionModel().selectIndices(newIndices[0], newIndices);
        });
        miMoveUp.disableProperty().bind(workflowProperty.isNull());
        MenuItem miMoveDown = new MenuItem("Move down");
        miMoveDown.setOnAction(e -> {
            var indices = getSelectedIndices();
            var workflow = getWorkflow();
            if (indices == null || indices.isEmpty() || indices.get(indices.size() - 1) >= workflow.size() - 1)
                return;
            list.getSelectionModel().clearSelection();
            Collections.sort(indices);
            List<WorkflowStep> steps = new ArrayList<>(workflow.getSteps());
            WorkflowStep[] stepsRemoved = new WorkflowStep[indices.size()];
            workflow.removeSteps(steps);
            int[] newIndices = new int[indices.size()];
            for (int i = indices.size() - 1; i >= 0; i--) {
                int ind = indices.get(i);
                int indNew = ind + 1;
                newIndices[i] = indNew;
                stepsRemoved[i] = steps.remove(ind);
            }
            for (int i = 0; i < indices.size(); i++) {
                steps.add(newIndices[i], stepsRemoved[i]);
            }
            workflow.addSteps(steps);
            list.getSelectionModel().select(newIndices[0]);
            list.getSelectionModel().selectIndices(newIndices[0], newIndices);
        // int ind = list.getSelectionModel().getSelectedIndex();
        // if (ind < 0 || ind >= workflow.size()-1)
        // return;
        // List<WorkflowStep> steps = new ArrayList<>(workflow.getSteps());
        // WorkflowStep step = steps.remove(ind);
        // steps.add(ind+1, step);
        // workflow.removeSteps(steps);
        // workflow.addSteps(steps);
        // list.getSelectionModel().select(step);
        });
        miMoveDown.disableProperty().bind(workflowProperty.isNull());
        contextMenu.getItems().addAll(new SeparatorMenuItem(), miMoveUp, miMoveDown, new SeparatorMenuItem(), miRemoveSelected);
    }
    list.setCellFactory(new Callback<ListView<WorkflowStep>, ListCell<WorkflowStep>>() {

        @Override
        public ListCell<WorkflowStep> call(ListView<WorkflowStep> p) {
            ListCell<WorkflowStep> cell = new ListCell<>() {

                @Override
                protected void updateItem(WorkflowStep value, boolean bln) {
                    super.updateItem(value, bln);
                    if (value instanceof WorkflowStep)
                        setText(value.getName());
                    else if (value == null)
                        setText(null);
                    else
                        setText(value.toString());
                    setContextMenu(contextMenu);
                    setOnMouseClicked(e -> {
                        // Only handle double clicks
                        if (!e.isPopupTrigger() && e.getClickCount() == 2)
                            runWorkflowStepInteractively(qupath, value);
                    });
                    setOnKeyPressed(e -> {
                        if (copyCombination.match(e)) {
                            copyScriptToClipboard(getSelectedIndices());
                            e.consume();
                        }
                    });
                }
            };
            return cell;
        }
    });
    pane.setCenter(splitPane);
    Button btnCreateScript = new Button("Create script");
    btnCreateScript.setMaxWidth(Double.MAX_VALUE);
    btnCreateScript.setOnAction(e -> showScript());
    btnCreateScript.disableProperty().bind(workflowProperty.isNull());
    Button btnCreateWorkflow = null;
    if (!isStaticWorkflow) {
        btnCreateWorkflow = new Button("Create workflow");
        btnCreateWorkflow.setMaxWidth(Double.MAX_VALUE);
        btnCreateWorkflow.setOnAction(e -> {
            var workflow = getWorkflow();
            if (workflow == null)
                return;
            Stage stage = new Stage();
            stage.initOwner(qupath.getStage());
            stage.setTitle("Workflow");
            Workflow workflowNew = new Workflow();
            workflowNew.addSteps(workflow.getSteps());
            stage.setScene(new Scene(new WorkflowCommandLogView(qupath, workflowNew).getPane(), 400, 600));
            stage.show();
        });
        btnCreateWorkflow.disableProperty().bind(workflowProperty.isNull());
        pane.setBottom(PaneTools.createColumnGridControls(btnCreateWorkflow, btnCreateScript));
    } else
        pane.setBottom(btnCreateScript);
    // pane.setBottom(btnGenerateScript);
    return pane;
}
Also used : Button(javafx.scene.control.Button) ListCell(javafx.scene.control.ListCell) LoggerFactory(org.slf4j.LoggerFactory) KeyCombination(javafx.scene.input.KeyCombination) ParameterList(qupath.lib.plugins.parameters.ParameterList) ContextMenu(javafx.scene.control.ContextMenu) Map(java.util.Map) TableView(javafx.scene.control.TableView) QuPathGUI(qupath.lib.gui.QuPathGUI) Pane(javafx.scene.layout.Pane) Orientation(javafx.geometry.Orientation) SplitPane(javafx.scene.control.SplitPane) MenuItem(javafx.scene.control.MenuItem) BufferedImage(java.awt.image.BufferedImage) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) Platform(javafx.application.Platform) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) List(java.util.List) Clipboard(javafx.scene.input.Clipboard) SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep) Entry(java.util.Map.Entry) ObservableList(javafx.collections.ObservableList) ClipboardContent(javafx.scene.input.ClipboardContent) BorderPane(javafx.scene.layout.BorderPane) StringProperty(javafx.beans.property.StringProperty) Scene(javafx.scene.Scene) ListView(javafx.scene.control.ListView) WorkflowListener(qupath.lib.plugins.workflow.WorkflowListener) SimpleStringProperty(javafx.beans.property.SimpleStringProperty) ScriptEditor(qupath.lib.gui.scripting.ScriptEditor) PathPlugin(qupath.lib.plugins.PathPlugin) ArrayList(java.util.ArrayList) TableColumn(javafx.scene.control.TableColumn) Dialogs(qupath.lib.gui.dialogs.Dialogs) TableCell(javafx.scene.control.TableCell) Callback(javafx.util.Callback) Tooltip(javafx.scene.control.Tooltip) ImageData(qupath.lib.images.ImageData) KeyCode(javafx.scene.input.KeyCode) ObjectProperty(javafx.beans.property.ObjectProperty) Logger(org.slf4j.Logger) Workflow(qupath.lib.plugins.workflow.Workflow) KeyCodeCombination(javafx.scene.input.KeyCodeCombination) ScriptableWorkflowStep(qupath.lib.plugins.workflow.ScriptableWorkflowStep) SelectionMode(javafx.scene.control.SelectionMode) Stage(javafx.stage.Stage) SimpleObjectProperty(javafx.beans.property.SimpleObjectProperty) ObservableValue(javafx.beans.value.ObservableValue) ChangeListener(javafx.beans.value.ChangeListener) Collections(java.util.Collections) PaneTools(qupath.lib.gui.tools.PaneTools) BorderPane(javafx.scene.layout.BorderPane) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep) ScriptableWorkflowStep(qupath.lib.plugins.workflow.ScriptableWorkflowStep) ListCell(javafx.scene.control.ListCell) ArrayList(java.util.ArrayList) ContextMenu(javafx.scene.control.ContextMenu) SplitPane(javafx.scene.control.SplitPane) ListView(javafx.scene.control.ListView) Button(javafx.scene.control.Button) Stage(javafx.stage.Stage) Workflow(qupath.lib.plugins.workflow.Workflow) MenuItem(javafx.scene.control.MenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) SeparatorMenuItem(javafx.scene.control.SeparatorMenuItem) Scene(javafx.scene.Scene) TableColumn(javafx.scene.control.TableColumn)

Example 10 with WorkflowStep

use of qupath.lib.plugins.workflow.WorkflowStep in project qupath by qupath.

the class AbstractPlugin method addWorkflowStep.

/**
 * Add a workflow step to the ImageData indicating the argument that this plugin was run with.
 *
 * Subclasses may override this if a better workflow step should be logged.
 *
 * A subclass may also override this to avoid adding a workflow step at all.
 *
 * @param imageData
 * @param arg
 */
protected void addWorkflowStep(final ImageData<T> imageData, final String arg) {
    @SuppressWarnings("unchecked") WorkflowStep step = new SimplePluginWorkflowStep(getName(), (Class<? extends PathPlugin<T>>) getClass(), arg);
    imageData.getHistoryWorkflow().addStep(step);
    logger.debug("Adding workflow step: {}", step);
}
Also used : SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep) WorkflowStep(qupath.lib.plugins.workflow.WorkflowStep) SimplePluginWorkflowStep(qupath.lib.plugins.workflow.SimplePluginWorkflowStep)

Aggregations

WorkflowStep (qupath.lib.plugins.workflow.WorkflowStep)15 DefaultScriptableWorkflowStep (qupath.lib.plugins.workflow.DefaultScriptableWorkflowStep)11 ArrayList (java.util.ArrayList)6 List (java.util.List)5 Map (java.util.Map)5 Collectors (java.util.stream.Collectors)5 QuPathGUI (qupath.lib.gui.QuPathGUI)5 Dialogs (qupath.lib.gui.dialogs.Dialogs)5 ImageData (qupath.lib.images.ImageData)5 PathObject (qupath.lib.objects.PathObject)5 BufferedImage (java.awt.image.BufferedImage)4 Arrays (java.util.Arrays)4 StringProperty (javafx.beans.property.StringProperty)4 Scene (javafx.scene.Scene)4 Button (javafx.scene.control.Button)4 BorderPane (javafx.scene.layout.BorderPane)4 File (java.io.File)3 Collections (java.util.Collections)3 HashMap (java.util.HashMap)3 Set (java.util.Set)3