Search in sources :

Example 16 with Macros

use of org.csstudio.display.builder.model.macros.Macros in project org.csstudio.display.builder by kasemir.

the class DisplayNavigationTest method testNavigation.

@Test
public void testNavigation() {
    final DisplayNavigation navigation = new DisplayNavigation();
    final Listener listener = nav -> changes.incrementAndGet();
    navigation.addListener(listener);
    // No history
    assertThat(navigation.getBackwardDisplays().size(), equalTo(0));
    assertThat(navigation.getForwardDisplays().size(), equalTo(0));
    assertThat(changes.get(), equalTo(0));
    // Current display, still no history
    DisplayInfo display = new DisplayInfo("/path/a.opi", "A", new Macros());
    navigation.setCurrentDisplay(display);
    System.out.println(navigation);
    assertThat(navigation.getBackwardDisplays().size(), equalTo(0));
    assertThat(navigation.getForwardDisplays().size(), equalTo(0));
    assertThat(changes.get(), equalTo(0));
    // Open new displays: Now 5 items available to go back
    for (int i = 1; i <= 5; ++i) navigation.setCurrentDisplay(new DisplayInfo("/path/N" + i + ".opi", "N" + i, new Macros()));
    System.out.println(navigation);
    assertThat(navigation.getBackwardDisplays().size(), equalTo(5));
    assertThat(navigation.getForwardDisplays().size(), equalTo(0));
    assertThat(changes.get(), equalTo(5));
    display = navigation.goBackward(2);
    System.out.println(navigation);
    assertThat(display.getName(), equalTo("N3"));
    assertThat(navigation.getBackwardDisplays().size(), equalTo(3));
    assertThat(navigation.getForwardDisplays().size(), equalTo(2));
    assertThat(changes.get(), equalTo(6));
    // Informing navigation about the display that's already current
    // (equal, not necessarily identical) has no impact on history
    navigation.setCurrentDisplay(new DisplayInfo(display.getPath(), display.getName(), new Macros()));
    assertThat(navigation.getBackwardDisplays().size(), equalTo(3));
    assertThat(navigation.getForwardDisplays().size(), equalTo(2));
    assertThat(changes.get(), equalTo(6));
    // Navigate back to the first display
    display = navigation.goBackward(3);
    System.out.println(navigation);
    assertThat(display.getName(), equalTo("A"));
    assertThat(navigation.getBackwardDisplays().size(), equalTo(0));
    assertThat(navigation.getForwardDisplays().size(), equalTo(5));
    assertThat(changes.get(), equalTo(7));
    // Navigate forward to "N1"
    display = navigation.goForward(1);
    System.out.println(navigation);
    assertThat(display.getName(), equalTo("N1"));
    assertThat(navigation.getBackwardDisplays().size(), equalTo(1));
    assertThat(navigation.getForwardDisplays().size(), equalTo(4));
    assertThat(changes.get(), equalTo(8));
    // Clear forward chain by opening different display
    display = new DisplayInfo("/path/x.opi", "X", new Macros());
    navigation.setCurrentDisplay(display);
    System.out.println(navigation);
    assertThat(navigation.getBackwardDisplays().size(), equalTo(2));
    assertThat(navigation.getForwardDisplays().size(), equalTo(0));
    assertThat(changes.get(), equalTo(9));
    navigation.removeListener(listener);
}
Also used : Assert.assertThat(org.junit.Assert.assertThat) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CoreMatchers.equalTo(org.hamcrest.CoreMatchers.equalTo) Macros(org.csstudio.display.builder.model.macros.Macros) Listener(org.csstudio.display.builder.rcp.run.DisplayNavigation.Listener) DisplayNavigation(org.csstudio.display.builder.rcp.run.DisplayNavigation) Test(org.junit.Test) Listener(org.csstudio.display.builder.rcp.run.DisplayNavigation.Listener) DisplayNavigation(org.csstudio.display.builder.rcp.run.DisplayNavigation) Macros(org.csstudio.display.builder.model.macros.Macros) Test(org.junit.Test)

Example 17 with Macros

use of org.csstudio.display.builder.model.macros.Macros in project org.csstudio.display.builder by kasemir.

the class ArrayWidget method getEffectiveMacros.

/**
 * Array widget extends parent macros
 *
 * @return {@link Macros}
 */
@Override
public Macros getEffectiveMacros() {
    final Macros base = super.getEffectiveMacros();
    final Macros my_macros = propMacros().getValue();
    return Macros.merge(base, my_macros);
}
Also used : CommonWidgetProperties.propMacros(org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMacros) Macros(org.csstudio.display.builder.model.macros.Macros)

Example 18 with Macros

use of org.csstudio.display.builder.model.macros.Macros in project org.csstudio.display.builder by kasemir.

the class ActionUtil method executeCommand.

/**
 * Execute external command
 *  @param source_widget Widget from which the action is invoked
 *  @param action        Command action to execute
 */
private static void executeCommand(final Widget source_widget, final ExecuteCommandActionInfo action) {
    try {
        // Path to resolve, after expanding macros
        final Macros macros = source_widget.getEffectiveMacros();
        final String command = MacroHandler.replace(macros, action.getCommand());
        logger.log(Level.FINER, "{0}, effective macros {1} ({2})", new Object[] { action, macros, command });
        // Resolve command relative to the source widget model (not 'top'!)
        final DisplayModel widget_model = source_widget.getDisplayModel();
        final String parent_file = widget_model.getUserData(DisplayModel.USER_DATA_INPUT_FILE);
        final String parent_dir = ModelResourceUtil.getDirectory(ModelResourceUtil.getLocalPath(parent_file));
        // Execute (this is already running on background thread)
        logger.log(Level.FINE, "Executing command {0} in {1}", new Object[] { command, parent_dir });
        final CommandExecutor executor = new CommandExecutor(command, new File(parent_dir));
        executor.call();
    } catch (final Throwable ex) {
        logger.log(Level.WARNING, action + " failed", ex);
        ScriptUtil.showErrorDialog(source_widget, "Cannot execute " + action + ".\n\nSee log for details.");
    }
}
Also used : DisplayModel(org.csstudio.display.builder.model.DisplayModel) Macros(org.csstudio.display.builder.model.macros.Macros) File(java.io.File)

Example 19 with Macros

use of org.csstudio.display.builder.model.macros.Macros in project org.csstudio.display.builder by kasemir.

the class WidgetPropertySubscriptionUnitTest method testMacroizedValueChanges.

@Test
public void testMacroizedValueChanges() {
    // Group widget supports macros
    final GroupWidget widget = new GroupWidget();
    final Macros macros = new Macros();
    macros.add("NAME", "Fred");
    widget.propMacros().setValue(macros);
    final MacroizedWidgetProperty<String> name_prop = (MacroizedWidgetProperty<String>) widget.propName();
    final AtomicInteger updates = new AtomicInteger();
    final AtomicReference<String> received_value = new AtomicReference<String>(null);
    name_prop.addPropertyListener((prop, old_value, new_value) -> {
        System.out.println(prop.getName() + " changes from " + old_value + " to " + new_value);
        updates.incrementAndGet();
        received_value.set(new_value);
    });
    assertThat(updates.get(), equalTo(0));
    // Setting the specification triggers a notification
    name_prop.setSpecification("$(NAME)");
    assertThat(updates.get(), equalTo(1));
    // The listener received null, because only the specification
    // was set, and the value has not been resolved
    assertThat(received_value.get(), nullValue());
    // Fetching the value will resolve macros,
    // but that does _not_ trigger another update
    assertThat(name_prop.getValue(), equalTo("Fred"));
    assertThat(updates.get(), equalTo(1));
    // Setting the value (not the description) to something
    // that doesn't contain macros will just set the value.
    name_prop.setValue("New Name");
    assertThat(updates.get(), equalTo(2));
    assertThat(received_value.get(), equalTo("New Name"));
    // Fetching that value does not trigger macro resolution
    // and another value update
    assertThat(name_prop.getValue(), equalTo("New Name"));
    assertThat(updates.get(), equalTo(2));
    // Setting the specification to something that does
    // not contain macros will set the value right away
    name_prop.setSpecification("Plain Text");
    assertThat(updates.get(), equalTo(3));
    assertThat(name_prop.getSpecification(), equalTo("Plain Text"));
    // Fetching the value does _not_ trigger another update
    assertThat(name_prop.getValue(), equalTo("Plain Text"));
    assertThat(updates.get(), equalTo(3));
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicReference(java.util.concurrent.atomic.AtomicReference) Macros(org.csstudio.display.builder.model.macros.Macros) GroupWidget(org.csstudio.display.builder.model.widgets.GroupWidget) Test(org.junit.Test)

Example 20 with Macros

use of org.csstudio.display.builder.model.macros.Macros in project org.csstudio.display.builder by kasemir.

the class ActionUtil method openDisplay.

/**
 * Open a display
 *
 *  <p>Depending on the target of the action,
 *  this will open a new display or replace
 *  an existing display
 *
 *  @param source_widget Widget from which the action is invoked
 *                       Used to resolve the potentially relative path of the
 *                       display specified in the action
 *  @param action        Information on which display to open and how
 */
private static void openDisplay(final Widget source_widget, final OpenDisplayActionInfo action) {
    if (action.getFile().isEmpty()) {
        logger.log(Level.WARNING, "Action without file: {0}", action);
        return;
    }
    try {
        // Path to resolve, after expanding macros of source widget and action
        final Macros macros = Macros.merge(source_widget.getEffectiveMacros(), action.getMacros());
        final String expanded_path = MacroHandler.replace(macros, action.getFile());
        logger.log(Level.FINER, "{0}, effective macros {1} ({2})", new Object[] { action, macros, expanded_path });
        // Resolve new display file relative to the source widget model (not 'top'!)
        final DisplayModel widget_model = source_widget.getDisplayModel();
        final String parent_file = widget_model.getUserData(DisplayModel.USER_DATA_INPUT_FILE);
        // Load new model. If that fails, no reason to continue.
        final DisplayModel new_model = ModelLoader.resolveAndLoadModel(parent_file, expanded_path);
        // Model is standalone; source_widget (Action button, ..) is _not_ the parent,
        // but it does add macros to those already defined in the display file.
        final Macros combined_macros = Macros.merge(macros, new_model.propMacros().getValue());
        new_model.propMacros().setValue(combined_macros);
        // Schedule representation on UI thread...
        final DisplayModel top_model = source_widget.getTopDisplayModel();
        final ToolkitRepresentation<Object, Object> toolkit = ToolkitRepresentation.getToolkit(top_model);
        final Future<Object> wait_for_ui;
        if (action.getTarget() == OpenDisplayActionInfo.Target.TAB) {
            wait_for_ui = toolkit.submit(() -> {
                // Create new panel
                final ToolkitRepresentation<Object, Object> new_toolkit = toolkit.openPanel(new_model, ActionUtil::handleClose);
                RuntimeUtil.hookRepresentationListener(new_toolkit);
                return null;
            });
        } else if (action.getTarget() == OpenDisplayActionInfo.Target.WINDOW) {
            wait_for_ui = toolkit.submit(() -> {
                // Create new top-level window
                final ToolkitRepresentation<Object, Object> new_toolkit = toolkit.openNewWindow(new_model, ActionUtil::handleClose);
                RuntimeUtil.hookRepresentationListener(new_toolkit);
                return null;
            });
        } else if (action.getTarget() == OpenDisplayActionInfo.Target.STANDALONE) {
            wait_for_ui = toolkit.submit(() -> {
                final ToolkitRepresentation<Object, Object> new_toolkit = toolkit.openStandaloneWindow(new_model, ActionUtil::handleClose);
                RuntimeUtil.hookRepresentationListener(new_toolkit);
                return null;
            });
        } else {
            // Default to OpenDisplayActionInfo.Target.REPLACE
            // Stop old runtime.
            RuntimeUtil.stopRuntime(top_model);
            wait_for_ui = toolkit.submit(() -> {
                // Close old representation
                final Object parent = toolkit.disposeRepresentation(top_model);
                // Tell toolkit about new model to represent
                toolkit.representModel(parent, new_model);
                return null;
            });
        }
        wait_for_ui.get();
        // Back in background thread, create new runtime
        RuntimeUtil.startRuntime(new_model);
    } catch (final Exception ex) {
        logger.log(Level.WARNING, "Error handling " + action, ex);
        ScriptUtil.showErrorDialog(source_widget, "Cannot open " + action.getFile() + ".\n\nSee log for details.");
    }
}
Also used : ToolkitRepresentation(org.csstudio.display.builder.representation.ToolkitRepresentation) DisplayModel(org.csstudio.display.builder.model.DisplayModel) Macros(org.csstudio.display.builder.model.macros.Macros)

Aggregations

Macros (org.csstudio.display.builder.model.macros.Macros)33 CommonWidgetProperties.propMacros (org.csstudio.display.builder.model.properties.CommonWidgetProperties.propMacros)12 OpenDisplayActionInfo (org.csstudio.display.builder.model.properties.OpenDisplayActionInfo)4 Test (org.junit.Test)4 DisplayModel (org.csstudio.display.builder.model.DisplayModel)3 ActionInfos (org.csstudio.display.builder.model.properties.ActionInfos)3 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 Widget (org.csstudio.display.builder.model.Widget)2 ActionInfo (org.csstudio.display.builder.model.properties.ActionInfo)2 ExecuteScriptActionInfo (org.csstudio.display.builder.model.properties.ExecuteScriptActionInfo)2 ScriptInfo (org.csstudio.display.builder.model.properties.ScriptInfo)2 WritePVActionInfo (org.csstudio.display.builder.model.properties.WritePVActionInfo)2 Element (org.w3c.dom.Element)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 URI (java.net.URI)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 List (java.util.List)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1