Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/CSSTUDIO-1704-action-button-widget'
Browse files Browse the repository at this point in the history
into clean_master
  • Loading branch information
shroffk committed Jul 26, 2024
2 parents e44953c + 1a50552 commit 032002c
Show file tree
Hide file tree
Showing 99 changed files with 5,575 additions and 4,842 deletions.
22 changes: 22 additions & 0 deletions app/display/actions/build.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<project default="app-display-actions">
<import file="../../../dependencies/ant_settings.xml"/>

<target name="app-display-actions">
<mkdir dir="${classes}"/>
<javac destdir="${classes}" debug="${debug}">
<src path="${src}"/>
<classpath>
<path refid="app-classpath"/>
<pathelement path="../representation-javafx/${build}/app-display-representation-javafx-${version}.jar"/>
<pathelement path="../model/${build}/app-display-model-${version}.jar"/>
<pathelement path="../../core/framework/${build}/core-framework-${version}.jar"/>
</classpath>
</javac>

<jar destfile="${build}/app-display-actions-${version}.jar">
<fileset dir="${classes}"/>
<fileset dir="${resources}"/>
</jar>
</target>

</project>
35 changes: 35 additions & 0 deletions app/display/actions/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (C) 2024 European Spallation Source ERIC.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.phoebus</groupId>
<artifactId>app-display</artifactId>
<version>4.7.4-SNAPSHOT</version>
</parent>

<artifactId>app-display-actions</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.phoebus</groupId>
<artifactId>app-display-representation-javafx</artifactId>
<version>4.7.4-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.phoebus</groupId>
<artifactId>app-display-model</artifactId>
<version>4.7.4-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*/

package org.csstudio.display.actions;

import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.image.Image;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.persist.ModelReader;
import org.csstudio.display.builder.model.persist.ModelWriter;
import org.csstudio.display.builder.model.persist.XMLTags;
import org.csstudio.display.builder.model.properties.ActionInfoBase;
import org.csstudio.display.builder.model.spi.ActionInfo;
import org.csstudio.display.builder.representation.javafx.actionsdialog.ActionsDialog;
import org.phoebus.framework.nls.NLS;
import org.phoebus.framework.persistence.XMLUtil;
import org.phoebus.ui.javafx.ImageCache;
import org.w3c.dom.Element;

import javax.xml.stream.XMLStreamWriter;
import java.io.IOException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ExecuteCommandAction extends ActionInfoBase {

public static final String EXECUTE_COMMAND = "command";
private String command;
private ExecuteCommandActionController executeCommandActionController;

@SuppressWarnings("unused")
/**
* Do not remove, needed by SPI framework.
*/
public ExecuteCommandAction() {
this.description = Messages.ActionExecuteCommand;
this.type = EXECUTE_COMMAND;
}

public ExecuteCommandAction(String description, String command) {
this.description = description;
this.command = command;
this.type = EXECUTE_COMMAND;
}

@Override
public Image getImage() {
return ImageCache.getImage(ActionsDialog.class, "/icons/execute_script.png");
}


@Override
public void readFromXML(ModelReader modelReader, Element actionXml) {
// Legacy:
// <action type="EXECUTE_CMD">
// <command>echo Hello</command>
// <command_directory>$(user.home)</command_directory>
// <wait_time>10</wait_time>
// <description>Hello</description>
// </action>
//
// New:
// <action type="command">
// <command>echo Hello</command>
// <description>Hello</description>
// </action>
command = XMLUtil.getChildString(actionXml, XMLTags.COMMAND).orElse("");
String directory = XMLUtil.getChildString(actionXml, "command_directory")
.orElse(null);
// Legacy allowed "opi.dir" as magic macro.
// Commands are now by default resolved relative to the display file.
if ("$(opi.dir)".equals(directory))
directory = null;
// Legacy allowed user.home as a 'current working directory'.
// Commands are now executed with their location as cwd.
if ("$(user.home)".equals(directory))
directory = null;
// If a legacy directory was provided, locate command there
if (directory != null && !directory.isEmpty())
command = directory + "/" + command;
if (description.isEmpty())
description = Messages.ActionExecuteCommand;
}

@Override
public void writeToXML(ModelWriter modelWriter, XMLStreamWriter writer) throws Exception {

writer.writeAttribute(XMLTags.TYPE, EXECUTE_COMMAND);
writeDescriptionToXML(writer, description);
writer.writeStartElement(XMLTags.COMMAND);
writer.writeCharacters(command);
writer.writeEndElement();
}

@Override
public boolean matchesAction(String actionId) {
return actionId.equalsIgnoreCase(EXECUTE_COMMAND) ||
"EXECUTE_CMD".equalsIgnoreCase(type);
}

public String getCommand() {
return command;
}

@Override
public Node getEditor(Widget widget) {
if (editorUi != null) {
return editorUi;
}
ResourceBundle resourceBundle = NLS.getMessages(Messages.class);

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setResources(resourceBundle);
fxmlLoader.setLocation(this.getClass().getResource("ExecuteCommandAction.fxml"));
fxmlLoader.setControllerFactory(clazz -> {
try {
return clazz.getConstructor(Widget.class, ActionInfo.class).newInstance(widget, this);
} catch (Exception e) {
Logger.getLogger(ExecuteCommandAction.class.getName()).log(Level.SEVERE, "Failed to construct ExecuteCommandActionDetailsController", e);
}
return null;
});

try {
editorUi = fxmlLoader.load();
executeCommandActionController = fxmlLoader.getController();
return editorUi;
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
public void revert() {
executeCommandActionController.setDescription(this.description);
executeCommandActionController.setCommand(command);
}

@Override
public ActionInfo commit() {
description = executeCommandActionController.getDescription();
command = executeCommandActionController.getCommand();
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2024 European Spallation Source ERIC.
*/

package org.csstudio.display.actions;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
import org.csstudio.display.builder.model.ActionControllerBase;
import org.csstudio.display.builder.model.Widget;
import org.csstudio.display.builder.model.spi.ActionInfo;
import org.csstudio.display.builder.representation.javafx.FilenameSupport;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
* FXML Controller for the execute command action editor
*/
public class ExecuteCommandActionController extends ActionControllerBase {

private final ExecuteCommandAction executeCommandActionInfo;

private final Widget widget;

@FXML
private TextField command;

private final StringProperty commandProperty = new SimpleStringProperty();

private static final Logger logger =
Logger.getLogger(ExecuteCommandActionController.class.getName());

/**
* @param widget Widget
* @param actionInfo {@link ActionInfo}
*/
public ExecuteCommandActionController(Widget widget, ActionInfo actionInfo) {
this.widget = widget;
this.executeCommandActionInfo = (ExecuteCommandAction) actionInfo;
this.descriptionProperty.set(actionInfo.getDescription());
}

/**
* Init
*/
@FXML
public void initialize() {
super.initialize();
commandProperty.set(executeCommandActionInfo.getCommand());
command.textProperty().bindBidirectional(commandProperty);
}

/**
* Prompt for command to execute
*/
@FXML
public void selectCommand() {
try {
final String path = FilenameSupport.promptForRelativePath(widget, commandProperty.get());
if (path != null) {
commandProperty.set(path);
}
} catch (Exception ex) {
logger.log(Level.WARNING, "Cannot prompt for command/filename", ex);
}
}

public String getCommand(){
return commandProperty.get();
}

public void setCommand(String command){
commandProperty.set(command);
}
}
Loading

0 comments on commit 032002c

Please sign in to comment.