diff --git a/app/save-and-restore/app/doc/index.rst b/app/save-and-restore/app/doc/index.rst index 5753aeaef7..8ca16a478e 100644 --- a/app/save-and-restore/app/doc/index.rst +++ b/app/save-and-restore/app/doc/index.rst @@ -51,12 +51,6 @@ tags is indicated with a symbol to the right of the node name: .. image:: images/snapshot-with-tag.png -Similarly, snapshots and composite snapshots referenced in other composite snapshots are annotated with a symbol to the -right of the node name: - -.. image:: images/snapshot-with-references.png - - Node names and ordering ----------------------- @@ -279,7 +273,7 @@ The composite snapshot can be saved when a case sensitive name and a description * The combined list of PV names in the referenced snapshots must not contain duplicates. This is checked for each item dropped into the list when editing a composite snapshot. If duplicates are detected, an error dialog is shown. -* Snapshots and composite snapshots cannot be deleted if referenced in a composite snapshot. +* Snapshots and composite snapshots cannot be deleted if referenced in any composite snapshot. This is indicated by disabling the Delete context menu item. Edit Composite Snapshot using drag-n-drop ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java index 0c43aa11b8..71a8a1a5b0 100644 --- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java +++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/BrowserTreeCell.java @@ -18,7 +18,6 @@ package org.phoebus.applications.saveandrestore.ui; -import javafx.application.Platform; import javafx.scene.control.Label; import javafx.scene.control.Tooltip; import javafx.scene.control.TreeCell; @@ -39,13 +38,9 @@ import org.phoebus.applications.saveandrestore.model.Node; import org.phoebus.applications.saveandrestore.model.NodeType; import org.phoebus.applications.saveandrestore.model.Tag; -import org.phoebus.applications.saveandrestore.model.search.SearchResult; -import org.phoebus.framework.jobs.JobManager; import org.phoebus.ui.javafx.ImageCache; import org.phoebus.util.time.TimestampFormats; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.MultivaluedMap; import java.util.ArrayList; import java.util.List; @@ -188,7 +183,6 @@ public void updateItem(Node node, boolean empty) { tagImage.setPreserveRatio(true); hBox.getChildren().add(tagImage); } - annotateContainedInCompositeSnapshot(node, hBox); break; case COMPOSITE_SNAPSHOT: hBox.getChildren().add(new ImageView(ImageRepository.COMPOSITE_SNAPSHOT)); @@ -199,7 +193,6 @@ public void updateItem(Node node, boolean empty) { tagImage.setPreserveRatio(true); getChildren().add(tagImage); } - annotateContainedInCompositeSnapshot(node, hBox); break; case CONFIGURATION: hBox.getChildren().add(new ImageView(ImageRepository.CONFIGURATION)); @@ -216,17 +209,4 @@ public void updateItem(Node node, boolean empty) { setGraphic(hBox); } - - private void annotateContainedInCompositeSnapshot(Node node, HBox hbox) { - JobManager.schedule("Annotate contained in snapshot", monitor -> { - MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); - multivaluedMap.put("referenced", List.of(node.getUniqueId())); - SearchResult searchResult = saveAndRestoreController.saveAndRestoreService.search(multivaluedMap); - if (searchResult.getHitCount() > 0) { - Platform.runLater(() -> { - hbox.getChildren().add(new ImageView(ImageRepository.LINK)); - }); - } - }); - } } diff --git a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java index 7274e4da5a..1bdefc4f94 100644 --- a/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java +++ b/app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java @@ -134,6 +134,8 @@ import java.util.ServiceLoader; import java.util.Stack; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -1405,10 +1407,41 @@ public void configureContextMenu(ContextMenuEvent e) { compareSnapshotsMenuItem.disableProperty().set(!compareSnapshotsPossible()); deleteNodeMenuItem.disableProperty().set(getUserIdentity().isNull().get() || selectedItemsProperty.stream().anyMatch(n -> n.getUniqueId().equals(Node.ROOT_FOLDER_UNIQUE_ID)) || - !hasSameParent()); + !hasSameParent() || + hasReferences(selectedItemsProperty.get(0))); pasteMenuItem.disableProperty().set(!mayPaste()); } + /** + * Queries service if the specified {@link Node} is referenced in any composite snapshot. + * + * @param node The node to check. + * @return true if the {@link Node} is referenced. + */ + private boolean hasReferences(Node node) { + if (node.getNodeType().equals(NodeType.FOLDER) || node.getNodeType().equals(NodeType.CONFIGURATION)) { + return false; + } + AtomicBoolean hasReferences = new AtomicBoolean(false); + CountDownLatch countDownLatch = new CountDownLatch(1); + JobManager.schedule("Find references", monitor -> { + MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); + multivaluedMap.put("referenced", List.of(node.getUniqueId())); + try { + hasReferences.set(saveAndRestoreService.search(multivaluedMap).getHitCount() > 0); + } catch (Exception e) { + logger.log(Level.WARNING, "Failed to check for references for node " + node.getUniqueId(), e); + } + countDownLatch.countDown(); + }); + try { + countDownLatch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.log(Level.WARNING, "Timeout when checking references for node " + node.getUniqueId(), e); + } + return hasReferences.get(); + } + /** * Adds a create log menu item based on current selection and logbook client availability */