Skip to content

Commit

Permalink
Merge pull request #3121 from ControlSystemStudio/CSSTUDIO-2371
Browse files Browse the repository at this point in the history
CSSTUDIO-2371 Open links to logbook-entries in the Logbook application and add "Back"- and "Forward"-buttons
  • Loading branch information
shroffk authored Aug 28, 2024
2 parents 8b7da49 + 5bb341a commit 54a414c
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToolBar;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import org.phoebus.logbook.LogEntry;
import org.phoebus.logbook.olog.ui.write.LogEntryEditorStage;
import org.phoebus.olog.es.api.model.LogGroupProperty;
import org.phoebus.olog.es.api.model.OlogLog;
import org.phoebus.ui.javafx.ImageCache;


public class LogEntryDisplayController {
Expand All @@ -52,12 +58,23 @@ public class LogEntryDisplayController {
@FXML
private Button replyButton;
@FXML
private Region spring;
@FXML
private Button goBackButton;
@FXML
private Button goForwardButton;
@FXML
private BorderPane emptyPane;
@FXML
private Node singleLogEntryDisplay;
@FXML
private Node mergedLogEntryDisplay;

ImageView goBackButtonIcon = ImageCache.getImageView(LogEntryDisplayController.class, "/icons/backward_nav.png");
ImageView goBackButtonIconDisabled = ImageCache.getImageView(LogEntryDisplayController.class, "/icons/backward_disabled.png");
ImageView goForwardButtonIcon = ImageCache.getImageView(LogEntryDisplayController.class, "/icons/forward_nav.png");
ImageView goForwardButtonIconDisabled = ImageCache.getImageView(LogEntryDisplayController.class, "/icons/forward_disabled.png");

private final SimpleObjectProperty<LogEntry> logEntryProperty =
new SimpleObjectProperty<>();

Expand All @@ -82,6 +99,19 @@ public void initialize() {
.bind(Bindings.createBooleanBinding(() -> currentViewProperty.get() == SINGLE, currentViewProperty));
mergedLogEntryDisplay.visibleProperty()
.bind(Bindings.createBooleanBinding(() -> currentViewProperty.get() == MERGED, currentViewProperty));
HBox.setHgrow(spring, Priority.ALWAYS); // Spring to make subsequent elements right-aligned in the toolbar.

{
ChangeListener<Boolean> goBackButtonDisabledPropertyChangeListener = (property, oldValue, newValue) -> goBackButton.setGraphic(newValue ? goBackButtonIconDisabled : goBackButtonIcon);
goBackButton.disableProperty().addListener(goBackButtonDisabledPropertyChangeListener);
goBackButtonDisabledPropertyChangeListener.changed(goBackButton.disableProperty(), false, true);
}

{
ChangeListener<Boolean> goForwardButtonDisabledPropertyChangeListener = (property, oldValue, newValue) -> goForwardButton.setGraphic(newValue ? goForwardButtonIconDisabled : goForwardButtonIcon);
goForwardButton.disableProperty().addListener(goForwardButtonDisabledPropertyChangeListener);
goForwardButtonDisabledPropertyChangeListener.changed(goForwardButton.disableProperty(), false, true);
}
}

@FXML
Expand Down Expand Up @@ -116,6 +146,20 @@ public void newLogEntry(){
new LogEntryEditorStage(new OlogLog(), null, null).show();
}

@FXML
public void goBack() {
if (logEntryTableViewController.goBackAndGoForwardActions.isPresent()) {
logEntryTableViewController.goBackAndGoForwardActions.get().goBack();
}
}

@FXML
public void goForward() {
if (logEntryTableViewController.goBackAndGoForwardActions.isPresent()) {
logEntryTableViewController.goBackAndGoForwardActions.get().goForward();
}
}

public void setLogEntry(LogEntry logEntry) {
if(logEntry == null){
currentViewProperty.set(EMPTY);
Expand Down Expand Up @@ -147,5 +191,9 @@ public void updateLogEntry(LogEntry logEntry){

public void setLogEntryTableViewController(LogEntryTableViewController logEntryTableViewController){
this.logEntryTableViewController = logEntryTableViewController;
if (logEntryTableViewController.goBackAndGoForwardActions.isPresent()) {
goBackButton.disableProperty().bind(Bindings.isEmpty(logEntryTableViewController.goBackAndGoForwardActions.get().goBackActions));
goForwardButton.disableProperty().bind(Bindings.isEmpty(logEntryTableViewController.goBackAndGoForwardActions.get().goForwardActions));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.phoebus.logbook.olog.ui;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import org.phoebus.framework.nls.NLS;
Expand Down Expand Up @@ -29,8 +31,11 @@ public class LogEntryTable implements AppInstance {
private final LogEntryTableApp app;
private LogEntryTableViewController controller;

public GoBackAndGoForwardActions goBackAndGoForwardActions;

public LogEntryTable(final LogEntryTableApp app) {
this.app = app;
goBackAndGoForwardActions = new GoBackAndGoForwardActions();
try {
OlogQueryManager ologQueryManager = OlogQueryManager.getInstance();
SearchParameters searchParameters = new SearchParameters();
Expand All @@ -44,13 +49,16 @@ public LogEntryTable(final LogEntryTableApp app) {
try {
if (app.getClient() != null) {
if (clazz.isAssignableFrom(LogEntryTableViewController.class)) {
return clazz.getConstructor(LogClient.class, OlogQueryManager.class, SearchParameters.class)
.newInstance(app.getClient(), ologQueryManager, searchParameters);
LogEntryTableViewController logEntryTableViewController = (LogEntryTableViewController) clazz.getConstructor(LogClient.class, OlogQueryManager.class, SearchParameters.class).newInstance(app.getClient(), ologQueryManager, searchParameters);
logEntryTableViewController.setGoBackAndGoForwardActions(goBackAndGoForwardActions);
return logEntryTableViewController;
} else if (clazz.isAssignableFrom(AdvancedSearchViewController.class)) {
return clazz.getConstructor(LogClient.class, SearchParameters.class)
.newInstance(app.getClient(), searchParameters);
} else if (clazz.isAssignableFrom(SingleLogEntryDisplayController.class)) {
return clazz.getConstructor(LogClient.class).newInstance(app.getClient());
SingleLogEntryDisplayController singleLogEntryDisplayController = (SingleLogEntryDisplayController) clazz.getConstructor(LogClient.class).newInstance(app.getClient());
singleLogEntryDisplayController.setSelectLogEntryInUI(id -> goBackAndGoForwardActions.loadLogEntryWithID(id));
return singleLogEntryDisplayController;
} else if (clazz.isAssignableFrom(LogEntryDisplayController.class)) {
return clazz.getConstructor().newInstance();
} else if (clazz.isAssignableFrom(LogPropertiesController.class)) {
Expand Down Expand Up @@ -118,4 +126,76 @@ public void save(final Memento memento) {
public void logEntryChanged(LogEntry logEntry){
controller.logEntryChanged(logEntry);
}

protected class GoBackAndGoForwardActions {

private GoBackAndGoForwardActions() {
goBackActions = FXCollections.observableArrayList();
goForwardActions = FXCollections.observableArrayList();
}

protected ObservableList<Runnable> goBackActions;
protected ObservableList<Runnable> goForwardActions;

private boolean isRecordingHistoryDisabled = false; // Used to not add go-back actions when clicking "back".

protected boolean getIsRecordingHistoryDisabled() {
return isRecordingHistoryDisabled;
}
public void setIsRecordingHistoryDisabled(boolean isRecordingHistoryDisabled) {
this.isRecordingHistoryDisabled = isRecordingHistoryDisabled;
}

private void gotoLogEntry(LogEntry logEntry) {
isRecordingHistoryDisabled = true;
boolean selected = controller.selectLogEntry(logEntry);
if (!selected) {
// The log entry was not available in the TreeView. Set the log entry without selecting it in the treeview:
controller.setLogEntry(logEntry);
}
isRecordingHistoryDisabled = false;
}

protected void addGoBackAction() {
LogEntry currentLogEntry = controller.getLogEntry();

if (currentLogEntry != null) {
goBackActions.add(0, () -> gotoLogEntry(currentLogEntry));
}
}

private void addGoForwardAction() {
LogEntry currentLogEntry = controller.getLogEntry();

if (currentLogEntry != null) {
goForwardActions.add(0, () -> gotoLogEntry(currentLogEntry));
}
}

private void loadLogEntryWithID(Long id) {
goForwardActions.clear();
addGoBackAction();

LogEntry logEntry = controller.client.getLog(id);
gotoLogEntry(logEntry);
}

protected void goBack() {
if (goBackActions.size() > 0) {
addGoForwardAction();
Runnable goBackAction = goBackActions.get(0);
goBackActions.remove(0);
goBackAction.run();
}
}

protected void goForward() {
if (goForwardActions.size() > 0) {
addGoBackAction();
Runnable goForwardAction = goForwardActions.get(0);
goForwardActions.remove(0);
goForwardAction.run();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,18 @@ public class LogEntryTableViewController extends LogbookSearchController {
*
* @param logClient Log client implementation
*/
public LogEntryTableViewController(LogClient logClient, OlogQueryManager ologQueryManager, SearchParameters searchParameters) {
public LogEntryTableViewController(LogClient logClient,
OlogQueryManager ologQueryManager,
SearchParameters searchParameters) {
setClient(logClient);
this.ologQueryManager = ologQueryManager;
this.searchParameters = searchParameters;
}

protected void setGoBackAndGoForwardActions(LogEntryTable.GoBackAndGoForwardActions goBackAndGoForwardActions) {
this.goBackAndGoForwardActions = Optional.of(goBackAndGoForwardActions);
}

private final SimpleIntegerProperty hitCountProperty = new SimpleIntegerProperty(0);
private final SimpleIntegerProperty pageSizeProperty =
new SimpleIntegerProperty(LogbookUIPreferences.search_result_page_size);
Expand All @@ -121,6 +127,7 @@ public LogEntryTableViewController(LogClient logClient, OlogQueryManager ologQue

private final SearchParameters searchParameters;

protected Optional<LogEntryTable.GoBackAndGoForwardActions> goBackAndGoForwardActions = Optional.empty();

@FXML
public void initialize() {
Expand Down Expand Up @@ -182,6 +189,10 @@ public void initialize() {
tableView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
// Update detailed view, but only if selection contains a single item.
if (newValue != null && tableView.getSelectionModel().getSelectedItems().size() == 1) {
if (goBackAndGoForwardActions.isPresent() && !goBackAndGoForwardActions.get().getIsRecordingHistoryDisabled()) {
goBackAndGoForwardActions.get().addGoBackAction();
goBackAndGoForwardActions.get().goForwardActions.clear();
}
logEntryDisplayController.setLogEntry(newValue.getLogEntry());
}
List<LogEntry> logEntries = tableView.getSelectionModel().getSelectedItems()
Expand Down Expand Up @@ -392,7 +403,16 @@ private void refresh() {
for (TableViewListItem selectedItem : selectedLogEntries) {
for (TableViewListItem item : tableView.getItems()) {
if (item.getLogEntry().getId().equals(selectedItem.getLogEntry().getId())) {
Platform.runLater(() -> tableView.getSelectionModel().select(item));
Platform.runLater(() -> {
if (goBackAndGoForwardActions.isPresent()) {
goBackAndGoForwardActions.get().setIsRecordingHistoryDisabled(true); // Do not create a "Back" action for the automatic reload.
tableView.getSelectionModel().select(item);
goBackAndGoForwardActions.get().setIsRecordingHistoryDisabled(false);
}
else {
tableView.getSelectionModel().select(item);
}
});
}
}
}
Expand Down Expand Up @@ -530,6 +550,14 @@ public void logEntryChanged(LogEntry logEntry) {
logEntryDisplayController.updateLogEntry(logEntry);
}

protected LogEntry getLogEntry() {
return logEntryDisplayController.getLogEntry();
}

protected void setLogEntry(LogEntry logEntry) {
logEntryDisplayController.setLogEntry(logEntry);
}

/**
* Selects a log entry as a result of an action outside the {@link TreeView}, but selection happens on the
* {@link TreeView} item, if it exists (match on log entry id). If it does not exist, selection is cleared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class Messages
ArchivedLaunchExternalAppFailed,
ArchivedNoEntriesFound,
ArchivedSaveFailed,
Back,
CloseRequestHeader,
CloseRequestButtonContinue,
CloseRequestButtonDiscard,
Expand All @@ -29,6 +30,7 @@ public class Messages
FileSave,
FileSaveFailed,
FileTooLarge,
Forward,
GroupingFailed,
GroupSelectedEntries,
Level,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -87,11 +89,17 @@ public class SingleLogEntryDisplayController extends HtmlAwareController {

private final SimpleBooleanProperty logEntryUpdated = new SimpleBooleanProperty();

private Optional<Consumer<Long>> selectLogEntryInUI = Optional.empty();

public SingleLogEntryDisplayController(LogClient logClient) {
super(logClient.getServiceUrl());
this.logClient = logClient;
}

public void setSelectLogEntryInUI(Consumer<Long> selectLogEntryInUI) {
this.selectLogEntryInUI = Optional.of(id -> selectLogEntryInUI.accept(id));
};

@FXML
public void initialize() {

Expand All @@ -101,9 +109,12 @@ public void initialize() {
copyURLButton.visibleProperty().setValue(LogbookUIPreferences.web_client_root_URL != null
&& !LogbookUIPreferences.web_client_root_URL.isEmpty());

webEngine = webView.getEngine();
// This will make links clicked in the WebView to open in default browser.
webEngine.getLoadWorker().stateProperty().addListener(new HyperLinkRedirectListener(webView));
{
Optional<String> webClientRoot = LogbookUIPreferences.web_client_root_URL == null || LogbookUIPreferences.web_client_root_URL.equals("") ? Optional.empty() : Optional.of(LogbookUIPreferences.web_client_root_URL);
webEngine = webView.getEngine();
// This will make links clicked in the WebView to open in default browser.
webEngine.getLoadWorker().stateProperty().addListener(new HyperLinkRedirectListener(webView, webClientRoot, selectLogEntryInUI));
}

updatedIndicator.visibleProperty().bind(logEntryUpdated);
updatedIndicator.setOnMouseEntered(me -> updatedIndicator.setCursor(Cursor.HAND));
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<Button fx:id="replyButton" mnemonicParsing="false" onAction="#reply" text="%Reply" disable="true"/>
<ToggleButton fx:id="showHideLogEntryGroupButton" contentDisplay="RIGHT" mnemonicParsing="false"
text="%ShowHideLogEntryGroup" disable="true" onAction="#showHideLogEntryGroup"/>
<Region fx:id="spring" /> <!-- Spring to make the next elements right-aligned. -->
<Button fx:id="goBackButton" mnemonicParsing="false"
onAction="#goBack" text="%Back" disable="true" />
<Button fx:id="goForwardButton" mnemonicParsing="false"
onAction="#goForward" text="%Forward" disable="true" />
</items>
</ToolBar>
</top>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ArchivedLaunchExternalAppFailed=Unable to launch external application to view fi
Author=Author:
Attachments=Attachments
AttachmentsSearchProperty=Attachments:
Back=Back
BrowseButton=Browse
Cancel=Cancel
CancelTooltip=Cancel the current entry.
Expand Down Expand Up @@ -40,6 +41,7 @@ File=File
FileSave=Save Attachment
FileSaveFailed=Failed to save attachment.
FileTooLarge=File {0} too large, selected file(s) not added.
Forward=Forward
GoToFirstPage=Go to first page
GoToLastPage=Go to last page
GroupingFailed=Failed to create group, log entries already contained in different groups.
Expand Down
Loading

0 comments on commit 54a414c

Please sign in to comment.