use of org.csstudio.display.builder.model.properties.OpenDisplayActionInfo.Target in project org.csstudio.display.builder by kasemir.
the class ActionsDialog method getOpenDisplayAction.
/**
* @return {@link OpenDisplayActionInfo} from sub pane
*/
private OpenDisplayActionInfo getOpenDisplayAction() {
Target target = Target.REPLACE;
List<Toggle> modes = open_display_targets.getToggles();
for (int i = 0; i < modes.size(); ++i) if (modes.get(i).isSelected()) {
target = Target.values()[i];
break;
}
return new OpenDisplayActionInfo(open_display_description.getText(), open_display_path.getText().trim(), open_display_macros.getMacros(), target);
}
use of org.csstudio.display.builder.model.properties.OpenDisplayActionInfo.Target in project org.csstudio.display.builder by kasemir.
the class ActionsDialog method createOpenDisplayDetails.
/**
* @return Sub-pane for OpenDisplay action
*/
private GridPane createOpenDisplayDetails() {
final InvalidationListener update = whatever -> {
if (updating || selected_action_index < 0)
return;
actions.set(selected_action_index, getOpenDisplayAction());
};
final GridPane open_display_details = new GridPane();
// open_display_details.setGridLinesVisible(true);
open_display_details.setHgap(10);
open_display_details.setVgap(10);
open_display_details.add(new Label(Messages.ActionsDialog_Description), 0, 0);
open_display_description = new TextField();
open_display_description.textProperty().addListener(update);
open_display_details.add(open_display_description, 1, 0);
GridPane.setHgrow(open_display_description, Priority.ALWAYS);
open_display_details.add(new Label(Messages.ActionsDialog_DisplayPath), 0, 1);
open_display_path = new TextField();
open_display_path.textProperty().addListener(update);
final Button select = new Button("...");
select.setOnAction(event -> {
try {
final String path = FilenameSupport.promptForRelativePath(widget, open_display_path.getText());
if (path != null)
open_display_path.setText(path);
FilenameSupport.performMostAwfulTerribleNoGoodHack(action_list);
} catch (Exception ex) {
logger.log(Level.WARNING, "Cannot prompt for filename", ex);
}
});
final HBox path_box = new HBox(open_display_path, select);
HBox.setHgrow(open_display_path, Priority.ALWAYS);
open_display_details.add(path_box, 1, 1);
final HBox modes_box = new HBox(10);
open_display_targets = new ToggleGroup();
final Target[] modes = Target.values();
for (int i = 0; i < modes.length; ++i) {
final RadioButton target = new RadioButton(modes[i].toString());
target.setToggleGroup(open_display_targets);
target.selectedProperty().addListener(update);
if (modes[i] == Target.STANDALONE && !Preferences.isStandaloneWindowSupported())
target.setDisable(true);
modes_box.getChildren().add(target);
}
open_display_details.add(modes_box, 0, 2, 2, 1);
open_display_macros = new MacrosTable(new Macros());
open_display_macros.addListener(update);
open_display_details.add(open_display_macros.getNode(), 0, 3, 2, 1);
GridPane.setHgrow(open_display_macros.getNode(), Priority.ALWAYS);
GridPane.setVgrow(open_display_macros.getNode(), Priority.ALWAYS);
return open_display_details;
}
use of org.csstudio.display.builder.model.properties.OpenDisplayActionInfo.Target in project org.csstudio.display.builder by kasemir.
the class ContextMenuSupport method fillContextMenu.
private void fillContextMenu(final IMenuManager manager) {
final Widget context_menu_widget = view.getActiveWidget();
if (context_menu_widget == null) {
logger.log(Level.WARNING, "Missing context_menu_widget");
manager.add(new Action("No widget") {
});
} else {
// Widget info
manager.add(new WidgetInfoAction(context_menu_widget));
// Actions of the widget
for (ActionInfo info : context_menu_widget.propActions().getValue().getActions()) {
if (info.getType() == ActionType.OPEN_DISPLAY) {
// Add variant for all the available Target types: Replace, new Tab, ...
final OpenDisplayActionInfo open_info = (OpenDisplayActionInfo) info;
for (Target target : Target.values()) {
// STANDALONE can be achieved via StandaloneAction on new display
if (target == Target.STANDALONE)
continue;
final String desc = target == Target.REPLACE ? open_info.getDescription() : open_info.getDescription() + " (" + target + ")";
manager.add(new ActionInfoWrapper(context_menu_widget, new OpenDisplayActionInfo(desc, open_info.getFile(), open_info.getMacros(), target)));
}
} else
manager.add(new ActionInfoWrapper(context_menu_widget, info));
}
// Actions of the widget runtime
final WidgetRuntime<Widget> runtime = RuntimeUtil.getRuntime(context_menu_widget);
if (runtime == null)
throw new NullPointerException("Missing runtime for " + context_menu_widget);
for (RuntimeAction info : runtime.getRuntimeActions()) manager.add(new RuntimeActionWrapper(context_menu_widget, info));
}
// Placeholder for ProcessVariable object contributions
manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(new Separator());
if (context_menu_widget != null) {
final Node node = JFXBaseRepresentation.getJFXNode(context_menu_widget);
final Scene scene = node.getScene();
manager.add(new SaveSnapshotAction(shell, scene));
manager.add(new PrintAction(shell, scene));
manager.add(new SendEMailAction(shell, scene));
manager.add(new SendLogbookAction(shell, scene));
manager.add(new FullScreenAction(view.getSite().getPage()));
if (support_standalone)
manager.add(new StandaloneAction(view));
}
// Placeholder for the display editor.
// If editor.rcp plugin is included, it adds "Open in editor"
manager.add(new Separator("display_editor"));
manager.add(new ReloadDisplayAction());
}
use of org.csstudio.display.builder.model.properties.OpenDisplayActionInfo.Target in project org.csstudio.display.builder by kasemir.
the class ActionsWidgetProperty method readFromXML.
@Override
public void readFromXML(final ModelReader model_reader, final Element property_xml) throws Exception {
final boolean execute_as_one = Boolean.parseBoolean(property_xml.getAttribute(XMLTags.EXECUTE_AS_ONE)) || // Legacy files
Boolean.parseBoolean(property_xml.getAttribute("hook_all"));
final List<ActionInfo> actions = new ArrayList<>();
for (final Element action_xml : XMLUtil.getChildElements(property_xml, XMLTags.ACTION)) {
String type = action_xml.getAttribute(XMLTags.TYPE);
if ("OPEN_OPI_IN_VIEW".equals(type)) {
// No longer supporting open-in-view with <Position>
// to select left, right, ... part stack.
// Change into 'open display' for new tab
type = OPEN_DISPLAY;
final Document doc = action_xml.getOwnerDocument();
final Element target = doc.createElement(XMLTags.TARGET);
target.appendChild(doc.createTextNode(OpenDisplayActionInfo.Target.TAB.name()));
action_xml.appendChild(target);
}
final String description = XMLUtil.getChildString(action_xml, XMLTags.DESCRIPTION).orElse("");
if (// legacy used uppercase type name
OPEN_DISPLAY.equalsIgnoreCase(type)) {
// Use <file>, falling back to legacy <path>
final String file = XMLUtil.getChildString(action_xml, XMLTags.FILE).orElse(XMLUtil.getChildString(action_xml, XMLTags.PATH).orElse(""));
OpenDisplayActionInfo.Target target = OpenDisplayActionInfo.Target.REPLACE;
// Legacy used <replace> with value 0/1/2 for TAB/REPLACE/WINDOW
final Optional<String> replace = XMLUtil.getChildString(action_xml, "replace");
// later it switched to <mode> with many more options
final Optional<String> mode = XMLUtil.getChildString(action_xml, "mode");
if (replace.isPresent()) {
if ("0".equals(replace.get()))
target = OpenDisplayActionInfo.Target.TAB;
else if ("2".equals(replace.get()))
target = OpenDisplayActionInfo.Target.WINDOW;
} else if (mode.isPresent())
target = modeToTargetConvert(Integer.valueOf(mode.get()));
else
target = OpenDisplayActionInfo.Target.valueOf(XMLUtil.getChildString(action_xml, XMLTags.TARGET).orElse(OpenDisplayActionInfo.Target.REPLACE.name()).toUpperCase());
final Macros macros;
final Element macro_xml = XMLUtil.getChildElement(action_xml, XMLTags.MACROS);
if (macro_xml != null)
macros = MacroXMLUtil.readMacros(macro_xml);
else
macros = new Macros();
actions.add(new OpenDisplayActionInfo(description, file, macros, target));
} else if (// legacy used uppercase type name
WRITE_PV.equalsIgnoreCase(type)) {
// Compare legacy XML:
// <action type="WRITE_PV">
// <pv_name>$(M).TWR</pv_name>
// <value>1</value>
// <timeout>10</timeout>
// <confirm_message/>
// <description>-</description>
// </action>
// PV Name should be set.
final String pv_name = XMLUtil.getChildString(action_xml, XMLTags.PV_NAME).orElse("");
if (pv_name.isEmpty())
logger.log(Level.WARNING, "Ignoring <action type='" + WRITE_PV + "'> with empty <pv_name> on " + getWidget());
// PV may be empty to write "".
// In contrast to legacy opibuilder the value is _not_ trimmed,
// so it's possible to write " " (which opibuilder wrote as "")
final String value = XMLUtil.getChildString(action_xml, XMLTags.VALUE).orElse("");
actions.add(new WritePVActionInfo(description, pv_name, value));
} else if (EXECUTE_SCRIPT.equals(type)) {
// <script file="EmbeddedPy">
// <text> the embedded text </text>
// </script>
final Element el = XMLUtil.getChildElement(action_xml, XMLTags.SCRIPT);
if (el == null)
throw new Exception("Missing <script..>");
else {
final String path = el.getAttribute(XMLTags.FILE);
final String text = XMLUtil.getChildString(el, XMLTags.TEXT).orElse(null);
final ScriptInfo info = new ScriptInfo(path, text, false, Collections.emptyList());
actions.add(new ExecuteScriptActionInfo(description, info));
}
} else if ("EXECUTE_PYTHONSCRIPT".equalsIgnoreCase(type) || "EXECUTE_JAVASCRIPT".equalsIgnoreCase(type)) {
// Legacy XML:
// <action type="EXECUTE_PYTHONSCRIPT"> .. or "EXECUTE_JAVASCRIPT"
// <path>script.py</path>
// <scriptText><![CDATA[ /* The script */ ]]></scriptText>
// <embedded>false</embedded>
// <description>A script</description>
// </action>
final boolean embed = Boolean.parseBoolean(XMLUtil.getChildString(action_xml, "embedded").orElse("false"));
final String path = XMLUtil.getChildString(action_xml, XMLTags.PATH).orElse("");
final String text = XMLUtil.getChildString(action_xml, "scriptText").orElse("");
final ScriptInfo info;
if (embed) {
final String dialect = type.contains("PYTHON") ? ScriptInfo.EMBEDDED_PYTHON : ScriptInfo.EMBEDDED_JAVASCRIPT;
info = new ScriptInfo(dialect, text, false, Collections.emptyList());
} else
info = new ScriptInfo(path, null, false, Collections.emptyList());
actions.add(new ExecuteScriptActionInfo(description, info));
} else if (// legacy used uppercase type name
OPEN_FILE.equalsIgnoreCase(type)) {
// Use <file>, falling back to legacy <path>
final String file = XMLUtil.getChildString(action_xml, XMLTags.FILE).orElse(XMLUtil.getChildString(action_xml, XMLTags.PATH).orElse(""));
actions.add(new OpenFileActionInfo(description, file));
} else if (// legacy used uppercase type name
OPEN_WEBPAGE.equalsIgnoreCase(type)) {
// Use <url>, falling back to legacy <hyperlink>
final String url = XMLUtil.getChildString(action_xml, XMLTags.URL).orElse(XMLUtil.getChildString(action_xml, "hyperlink").orElse(""));
actions.add(new OpenWebpageActionInfo(description, url));
} else if (EXECUTE_COMMAND.equalsIgnoreCase(type) || "EXECUTE_CMD".equalsIgnoreCase(type)) {
// 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>
String command = XMLUtil.getChildString(action_xml, XMLTags.COMMAND).orElse("");
String directory = XMLUtil.getChildString(action_xml, "command_directory").orElse(null);
// Commands are now by default resolved relative to the display file.
if ("$(opi.dir)".equals(directory))
directory = null;
// 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;
actions.add(new ExecuteCommandActionInfo(description, command));
} else
logger.log(Level.WARNING, "Ignoring action of unknown type '" + type + "'");
}
setValue(new ActionInfos(actions, execute_as_one));
}
Aggregations