Skip to content

Commit 59ee623

Browse files
committed
Adding context menu support for creating log based on save&restore selection
1 parent 423f287 commit 59ee623

File tree

8 files changed

+140
-72
lines changed

8 files changed

+140
-72
lines changed

app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/write/ContextMenuLogging.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,4 @@ public void call(Node parent, Selection selection) {
5151
public Class<?> getSupportedType() {
5252
return supportedType;
5353
}
54-
5554
}

app/save-and-restore/app/src/main/java/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreController.java

Lines changed: 69 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,14 @@
101101
import org.phoebus.applications.saveandrestore.ui.snapshot.tag.TagWidget;
102102
import org.phoebus.framework.jobs.JobManager;
103103
import org.phoebus.framework.preferences.PhoebusPreferenceService;
104+
import org.phoebus.framework.selection.SelectionService;
104105
import org.phoebus.framework.workbench.ApplicationService;
105106
import org.phoebus.security.tokens.ScopedAuthenticationToken;
107+
import org.phoebus.ui.application.ContextMenuService;
106108
import org.phoebus.ui.dialog.DialogHelper;
107109
import org.phoebus.ui.dialog.ExceptionDetailsErrorDialog;
108110
import org.phoebus.ui.javafx.ImageCache;
111+
import org.phoebus.ui.spi.ContextMenuEntry;
109112

110113
import javax.ws.rs.core.MultivaluedHashMap;
111114
import javax.ws.rs.core.MultivaluedMap;
@@ -304,10 +307,13 @@ public Filter fromString(String s) {
304307
treeView.getRoot().setValue(Node.builder().uniqueId(Node.ROOT_FOLDER_UNIQUE_ID).name(name).build());
305308
});
306309

307-
JobManager.schedule("Configure context menu", monitor -> {
308-
configureContextMenuItems();
309-
treeView.setContextMenu(contextMenu);
310-
});
310+
//JobManager.schedule("Configure context menu", monitor -> {
311+
MenuItem addTagMenuItem = TagWidget.AddTagMenuItem();
312+
addTagMenuItem.setOnAction(action -> addTagToSnapshots());
313+
tagWithComment.getItems().addAll(addTagMenuItem);
314+
//configureContextMenuItems();
315+
treeView.setContextMenu(contextMenu);
316+
//});
311317

312318
loadTreeData();
313319
}
@@ -983,7 +989,7 @@ protected void addTagToSnapshots() {
983989
*
984990
* @param tagMenu The {@link Menu} subject to configuration.
985991
*/
986-
public void tag(final Menu tagMenu) {
992+
public void configureTagContextMenu(final Menu tagMenu) {
987993

988994
List<Node> selectedNodes =
989995
browserSelectionModel.getSelectedItems().stream().map(TreeItem::getValue).collect(Collectors.toList());
@@ -1414,53 +1420,35 @@ private void openNode(String nodeId) {
14141420
});
14151421
}
14161422

1417-
/**
1418-
* Creates context menu items.
1419-
*/
1420-
private void configureContextMenuItems() {
1421-
contextMenu.getItems().add(new LoginMenuItem(this, selectedItemsProperty,
1422-
unused -> ApplicationService.createInstance("credentials_management")));
1423-
contextMenu.getItems().add(new NewFolderMenuItem(this, selectedItemsProperty,
1424-
unused -> createNewFolder()));
1425-
contextMenu.getItems().add(new NewConfigurationMenuItem(this, selectedItemsProperty,
1426-
unused -> createNewConfiguration()));
1427-
contextMenu.getItems().add(new CreateSnapshotMenuItem(this, selectedItemsProperty,
1428-
unused -> openConfigurationForSnapshot()));
1429-
contextMenu.getItems().add(new NewCompositeSnapshotMenuItem(this, selectedItemsProperty,
1430-
unused -> createNewCompositeSnapshot()));
1431-
contextMenu.getItems().add(new SeparatorMenuItem());
1432-
contextMenu.getItems().add(new EditCompositeMenuItem(this, selectedItemsProperty,
1433-
unused -> editCompositeSnapshot()));
1434-
1435-
contextMenu.getItems().add(new RenameFolderMenuItem(this, selectedItemsProperty,
1436-
unused -> renameNode()));
1437-
contextMenu.getItems().add(new CopyMenuItem(this, selectedItemsProperty, unused -> copySelectionToClipboard()));
1438-
contextMenu.getItems().add(new PasteMenuItem(this, selectedItemsProperty,
1439-
unused -> pasteFromClipboard()));
1440-
contextMenu.getItems().add(new DeleteNodeMenuItem(this, selectedItemsProperty,
1441-
unused -> deleteNodes()));
1442-
contextMenu.getItems().add(new SeparatorMenuItem());
1443-
1444-
contextMenu.getItems().add(new CompareSnapshotsMenuItem(this, selectedItemsProperty,
1445-
unused -> compareSnapshot()));
1446-
contextMenu.getItems().add(new TagGoldenMenuItem(this, selectedItemsProperty, null));
1447-
1448-
MenuItem addTagMenuItem = TagWidget.AddTagMenuItem();
1449-
addTagMenuItem.setOnAction(action -> addTagToSnapshots());
1450-
tagWithComment.getItems().addAll(addTagMenuItem);
1451-
contextMenu.getItems().add(tagWithComment);
1452-
1453-
1454-
contextMenu.getItems().add(new SeparatorMenuItem());
1455-
contextMenu.getItems().add(new CopyUniqueIdToClipboardMenuItem(this, selectedItemsProperty,
1456-
unused -> copyUniqueNodeIdToClipboard()));
1457-
contextMenu.getItems().add(new SeparatorMenuItem());
1458-
contextMenu.getItems().add(new ImportFromCSVMenuItem(this, selectedItemsProperty,
1459-
unused -> importFromCSV()));
1460-
contextMenu.getItems().add(new ExportToCSVMenuItem(this, selectedItemsProperty,
1461-
unused -> exportToCSV()));
1462-
}
1463-
1423+
List<MenuItem> menuItems = Arrays.asList(
1424+
new LoginMenuItem(this, selectedItemsProperty,
1425+
unused -> ApplicationService.createInstance("credentials_management")),
1426+
new NewFolderMenuItem(this, selectedItemsProperty,
1427+
unused -> createNewFolder()),
1428+
new NewConfigurationMenuItem(this, selectedItemsProperty,
1429+
unused -> createNewConfiguration()),
1430+
new CreateSnapshotMenuItem(this, selectedItemsProperty,
1431+
unused -> openConfigurationForSnapshot()),
1432+
new NewCompositeSnapshotMenuItem(this, selectedItemsProperty,
1433+
unused -> createNewCompositeSnapshot()),
1434+
new SeparatorMenuItem(),
1435+
new EditCompositeMenuItem(this, selectedItemsProperty, unused -> editCompositeSnapshot()),
1436+
new RenameFolderMenuItem(this, selectedItemsProperty, unused -> renameNode()),
1437+
new CopyMenuItem(this, selectedItemsProperty, unused -> copySelectionToClipboard()),
1438+
new PasteMenuItem(this, selectedItemsProperty, unused -> pasteFromClipboard()),
1439+
new DeleteNodeMenuItem(this, selectedItemsProperty, unused -> deleteNodes()),
1440+
new SeparatorMenuItem(),
1441+
new CompareSnapshotsMenuItem(this, selectedItemsProperty, unused -> compareSnapshot()),
1442+
new TagGoldenMenuItem(this, selectedItemsProperty, null),
1443+
tagWithComment,
1444+
new SeparatorMenuItem(),
1445+
new CopyUniqueIdToClipboardMenuItem(this, selectedItemsProperty,
1446+
unused -> copyUniqueNodeIdToClipboard()),
1447+
new SeparatorMenuItem(),
1448+
new ImportFromCSVMenuItem(this, selectedItemsProperty, unused -> importFromCSV()),
1449+
new ExportToCSVMenuItem(this, selectedItemsProperty, unused -> exportToCSV()),
1450+
new SeparatorMenuItem()
1451+
);
14641452

14651453
/**
14661454
* Called when user requests context menu. Updates the {@link #selectedItemsProperty}, and since
@@ -1471,17 +1459,44 @@ private void configureContextMenuItems() {
14711459
*/
14721460
@SuppressWarnings("unused")
14731461
@FXML
1474-
public void createContextMenu(ContextMenuEvent e) {
1462+
public void configureContextMenu(ContextMenuEvent e) {
14751463
ObservableList<? extends TreeItem<Node>> selectedItems = browserSelectionModel.getSelectedItems();
14761464
selectedItemsProperty.setAll(selectedItems.stream().map(TreeItem::getValue).toList());
1465+
1466+
// Need to construct the selection carefully in order to be able to match an AdapterFactory to it.
1467+
List<List<Node>> selection = new ArrayList<>();
1468+
List<Node> nodes = new ArrayList<>();
1469+
nodes.addAll(selectedItemsProperty);
1470+
selection.add(nodes);
1471+
SelectionService.getInstance().setSelection(SaveAndRestoreApplication.NAME, selection);
1472+
1473+
contextMenu.getItems().clear();
1474+
contextMenu.getItems().addAll(menuItems);
1475+
List<ContextMenuEntry> supported = ContextMenuService.getInstance().listSupportedContextMenuEntries();
1476+
1477+
supported.stream().forEach(action -> {
1478+
MenuItem menuItem = new MenuItem(action.getName(), new ImageView(action.getIcon()));
1479+
menuItem.setOnAction((ee) -> {
1480+
try {
1481+
action.call(null, SelectionService.getInstance().getSelection());
1482+
} catch (Exception ex) {
1483+
logger.log(Level.WARNING, "Failed to execute " + action.getName() + " from display builder.", ex);
1484+
}
1485+
});
1486+
menuItem.disableProperty().set(selectedItemsProperty.isEmpty());
1487+
contextMenu.getItems().add(menuItem);
1488+
});
1489+
14771490
snapshotOrCompositeSnapshotOnlySelection.set(selectedItems.stream().filter(t ->
14781491
!t.getValue().getNodeType().equals(NodeType.SNAPSHOT) &&
14791492
!t.getValue().getNodeType().equals(NodeType.COMPOSITE_SNAPSHOT)).findFirst().isEmpty());
14801493
tagWithComment.disableProperty().set(userIdentity.isNull().get() ||
14811494
selectedItemsProperty.size() != 1 ||
14821495
(!selectedItemsProperty.get(0).getNodeType().equals(NodeType.SNAPSHOT) &&
14831496
!selectedItemsProperty.get(0).getNodeType().equals(NodeType.COMPOSITE_SNAPSHOT)));
1484-
tag(tagWithComment);
1497+
configureTagContextMenu(tagWithComment);
1498+
1499+
14851500
}
14861501

14871502
/**

app/save-and-restore/app/src/main/resources/org/phoebus/applications/saveandrestore/ui/SaveAndRestoreUI.fxml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
</HBox>
4747

48-
<TreeView fx:id="treeView" onContextMenuRequested="#createContextMenu" prefHeight="347.0" prefWidth="195.0" BorderPane.alignment="CENTER" VBox.vgrow="ALWAYS" />
48+
<TreeView fx:id="treeView" onContextMenuRequested="#configureContextMenu" prefHeight="347.0" prefWidth="195.0" BorderPane.alignment="CENTER" VBox.vgrow="ALWAYS" />
4949

5050
</VBox>
5151
<VBox fx:id="errorPane" alignment="CENTER" visible="false">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (C) 2024 European Spallation Source ERIC.
3+
*/
4+
5+
package org.phoebus.applications.saveandrestore.logging;
6+
7+
import org.phoebus.applications.saveandrestore.model.Node;
8+
import org.phoebus.framework.adapter.AdapterFactory;
9+
import org.phoebus.logbook.LogEntry;
10+
import org.phoebus.logbook.LogEntryImpl;
11+
import org.phoebus.logbook.PropertyImpl;
12+
13+
import java.util.ArrayList;
14+
import java.util.Arrays;
15+
import java.util.HashMap;
16+
import java.util.List;
17+
import java.util.Map;
18+
import java.util.Optional;
19+
20+
import static org.phoebus.logbook.LogEntryImpl.LogEntryBuilder.log;
21+
22+
/**
23+
* Adapts a selection of save&restore {@link Node}s to a log entry. Each selected {@link Node}
24+
* is added as a separate property with a name constructed from the {@link Node}'s name.
25+
*/
26+
public class NodeSelectionAdapterFactory implements AdapterFactory {
27+
28+
@Override
29+
public Class getAdaptableObject() {
30+
return ArrayList.class;
31+
}
32+
33+
@Override
34+
public List<? extends Class> getAdapterList() {
35+
return Arrays.asList(LogEntry.class);
36+
}
37+
38+
@Override
39+
public <T> Optional<T> adapt(Object adaptableObject, Class<T> adapterType) {
40+
List<Node> selectedNodes = (List<Node>) adaptableObject;
41+
List<Map> properties = new ArrayList<>();
42+
selectedNodes.forEach(n -> {
43+
Map<String, String> map = new HashMap<>();
44+
map.put("file", "file:/" + n.getUniqueId() + "?app=saveandrestore");
45+
map.put("name", n.getName());
46+
properties.add(map);
47+
});
48+
49+
LogEntryImpl.LogEntryBuilder log = log().description("");
50+
properties.forEach(m -> log.appendProperty(PropertyImpl.of("Save&restore resource " + m.get("name"), m)));
51+
return Optional.of(adapterType.cast(log.build()));
52+
}
53+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
org.phoebus.applications.saveandrestore.logging.SaveSnapshotActionAdapterFactory
2-
org.phoebus.applications.saveandrestore.logging.RestoreSnapshotActionAdapterFactory
2+
org.phoebus.applications.saveandrestore.logging.RestoreSnapshotActionAdapterFactory
3+
org.phoebus.applications.saveandrestore.logging.NodeSelectionAdapterFactory

app/save-and-restore/model/pom.xml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
<dependencies>
1414

15+
<dependency>
16+
<groupId>org.phoebus</groupId>
17+
<artifactId>core-framework</artifactId>
18+
<version>4.7.4-SNAPSHOT</version>
19+
</dependency>
20+
1521
<dependency>
1622
<groupId>javax.json</groupId>
1723
<artifactId>javax.json-api</artifactId>
@@ -57,13 +63,6 @@
5763
<artifactId>javax.json</artifactId>
5864
<version>1.1.4</version>
5965
</dependency>
60-
61-
<!-- https://mvnrepository.com/artifact/org.glassfish/jakarta.json -->
62-
<!--<dependency>
63-
<groupId>org.glassfish</groupId>
64-
<artifactId>jakarta.json</artifactId>
65-
<version>2.0.1</version>
66-
</dependency>-->
6766

6867
<!-- https://mvnrepository.com/artifact/junit/junit -->
6968
<dependency>

core/framework/src/main/java/org/phoebus/framework/adapter/AdapterService.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,27 +88,27 @@ public static List<AdapterFactory> getAdaptersforAdaptable(Class cls)
8888
}
8989

9090
/**
91-
* Adapts the adaptableObject to type adapterType using registered adaptor factories.
91+
* Adapts the adaptableObject to type targetType using registered adaptor factories.
9292
* @param <T> , the type to convert
9393
* @param adaptableObject , the object to adapt
94-
* @param adapterType , the target type
95-
* @return an {@link Optional} with the the adapted object or empty
94+
* @param targetType , the target type of <code>adaptableObject</code>
95+
* @return an {@link Optional} with the adapted object or empty
9696
*/
97-
public static <T> Optional<T> adapt(Object adaptableObject, Class<T> adapterType)
97+
public static <T> Optional<T> adapt(Object adaptableObject, Class<T> targetType)
9898
{
99-
if(adapterType.isInstance(adaptableObject))
99+
if(targetType.isInstance(adaptableObject))
100100
{
101-
return Optional.of(adapterType.cast(adaptableObject));
101+
return Optional.of(targetType.cast(adaptableObject));
102102
}
103103
List<AdapterFactory> factories = AdapterService.getAdaptersforAdaptable(adaptableObject.getClass()).stream().filter(factory -> {
104-
return factory.getAdapterList().contains(adapterType);
104+
return factory.getAdapterList().contains(targetType);
105105
}).collect(Collectors.toList());
106106
if(factories.isEmpty())
107107
{
108108
logger.warning("failed to adapt the object " + adaptableObject + " due to no avaiable adaptor factories.");
109109
} else if(factories.size() == 1)
110110
{
111-
return factories.get(0).adapt(adaptableObject, adapterType);
111+
return factories.get(0).adapt(adaptableObject, targetType);
112112
} else if(factories.size() >= 1)
113113
{
114114
logger.warning("failed to adapt the object " + adaptableObject + " due to multiple factories " + factories.size());

core/ui/src/main/java/org/phoebus/ui/application/ContextMenuService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public List<ContextMenuEntry> listContextMenuEntries() {
5757
*/
5858
public List<ContextMenuEntry> listSupportedContextMenuEntries() {
5959
// List of types of the current selection
60+
List list = SelectionService.getInstance().getSelection().getSelections();
6061
List<Class> selectionTypes = SelectionService.getInstance().getSelection().getSelections().stream().map(s -> {
6162
return s.getClass();
6263
}).collect(Collectors.toList());

0 commit comments

Comments
 (0)