Skip to content

Commit

Permalink
Merge pull request #2995 from ControlSystemStudio/CSSTUDIO-2231
Browse files Browse the repository at this point in the history
CSSTUDIO-2231 Add flag `-select_settings` for selecting a Phoebus configuration file on startup
  • Loading branch information
abrahamwolk authored Apr 15, 2024
2 parents 5a69830 + f915435 commit d7f5e36
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ public class Messages
public static String DockSplitH;
public static String DockSplitV;
public static String Enjoy;
public static String ErrorDuringEvalutationOfTheFlagSelectSettings;
public static String ErrorLoadingPhoebusConfiguration;
public static String Exit;
public static String ExitContent;
public static String ExitHdr;
public static String ExitTitle;
public static String File;
public static String FileDoesNotExist;
public static String FileExists;
public static String FixedTitle;
public static String Help;
Expand Down Expand Up @@ -91,10 +94,12 @@ public class Messages
public static String MonitorTaskUi;
public static String NamePane;
public static String NamePaneHdr;
public static String OK;
public static String Open;
public static String OpenHdr;
public static String OpenTitle;
public static String OpenWith;
public static String PhoebusWillQuit;
public static String ProgressTitle;
public static String PVListAppName;
public static String PVListJobName;
Expand Down Expand Up @@ -130,10 +135,13 @@ public class Messages
public static String SavingHdr;
public static String ScreenshotErrHdr;
public static String ScreenshotErrMsg;
public static String SelectPhoebusConfiguration;
public static String SelectTab;
public static String ShowInFileBrowserApp;
public static String ShowStatusbar;
public static String ShowToolbar;
public static String TheArgumentIsNotADirectory;
public static String TheDirectoryDoesNotContainConfigurationFiles;
public static String Time12h;
public static String Time1d;
public static String Time3d;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.io.FileNotFoundException;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -28,6 +29,8 @@
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
Expand All @@ -36,6 +39,7 @@
import javafx.scene.control.CheckBox;
import javafx.scene.control.CheckMenuItem;
import javafx.scene.control.Dialog;
import javafx.scene.control.ListView;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuButton;
Expand All @@ -44,14 +48,27 @@
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.ToolBar;
import javafx.scene.control.Tooltip;
import javafx.scene.layout.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.util.Pair;
import org.phoebus.framework.jobs.JobManager;
import org.phoebus.framework.jobs.JobMonitor;
import org.phoebus.framework.jobs.SubJobMonitor;
import org.phoebus.framework.persistence.MementoTree;
import org.phoebus.framework.persistence.XMLMementoTree;
import org.phoebus.framework.preferences.PropertyPreferenceLoader;
import org.phoebus.framework.spi.AppDescriptor;
import org.phoebus.framework.spi.AppResourceDescriptor;
import org.phoebus.framework.util.ResourceParser;
Expand Down Expand Up @@ -85,12 +102,6 @@
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
import javafx.stage.Window;

/**
* Primary UI for a phoebus application
Expand Down Expand Up @@ -286,6 +297,9 @@ public void start(final Stage initial_stage) throws Exception {
// Save original application parameters
application_parameters.addAll(getParameters().getRaw());

Platform.setImplicitExit(false); // Avoids shutdown of Phoebus when the '-select_settings' option is used after the dialog to select configuration file has been closed. Platform.setImplicitExit(true) is called below to restore the option again.
possiblySelectIniFile(application_parameters); // possiblySelectIniFile() must be called before preferences are initialized, to ensure that the selected configuration options are applied before old configuration options are loaded.

// Show splash screen as soon as possible..
final Splash splash = Preferences.splash ? new Splash(initial_stage) : null;

Expand All @@ -294,9 +308,131 @@ public void start(final Stage initial_stage) throws Exception {
{
final JobMonitor splash_monitor = new SplashJobMonitor(monitor, splash);
backgroundStartup(splash_monitor, splash);
Platform.setImplicitExit(true);
});
}

private void possiblySelectIniFile(CopyOnWriteArrayList<String> application_parameters) {

Consumer<Pair<String, String>> displayErrorMessageAndQuit = errorTitleAndErrorMessage -> {

String errorTitle = errorTitleAndErrorMessage.getKey();
String errorMessage = errorTitleAndErrorMessage.getValue();

logger.log(Level.SEVERE, errorMessage);

Dialog errorDialog = new Alert(AlertType.ERROR);
errorDialog.setTitle(errorTitle);
errorDialog.setHeaderText(errorTitle);
errorDialog.setContentText(errorMessage + "\n\n" + Messages.PhoebusWillQuit);
errorDialog.showAndWait();

stop();
};

if (application_parameters.contains("-select_settings")) {
int indexOfFlag = application_parameters.indexOf("-select_settings", 0);
if (indexOfFlag < 0) {
throw new RuntimeException("Error, this should never happen!");
}
if (application_parameters.size() > indexOfFlag) {
String iniFilesLocation_String = application_parameters.get(indexOfFlag + 1);
File iniFilesLocation_File = new File(iniFilesLocation_String);
if (iniFilesLocation_File.isDirectory()) {
List<File> iniFilesInDirectory_List = Arrays.stream(iniFilesLocation_File.listFiles()).filter(file -> file.getAbsolutePath().endsWith(".ini") || file.getAbsolutePath().endsWith(".xml")).collect(Collectors.toList());
ObservableList<File> iniFilesInDirectory_ObservableList = FXCollections.observableArrayList(iniFilesInDirectory_List);

if (iniFilesInDirectory_List.size() > 0) {
Dialog<File> iniFileSelectionDialog = new Dialog();
iniFileSelectionDialog.setTitle(Messages.SelectPhoebusConfiguration);
iniFileSelectionDialog.setHeaderText(Messages.SelectPhoebusConfiguration);
iniFileSelectionDialog.setGraphic(null);

iniFileSelectionDialog.setWidth(500);
iniFileSelectionDialog.setHeight(400);
iniFileSelectionDialog.setResizable(false);

ListView listView = new ListView(iniFilesInDirectory_ObservableList);
listView.getSelectionModel().select(0);

Runnable setReturnValueAndCloseDialog = () -> {
File selectedFile = (File) listView.getSelectionModel().getSelectedItem();
if (selectedFile == null) {
selectedFile = (File) listView.getItems().get(0);
}
iniFileSelectionDialog.setResult(selectedFile);
iniFileSelectionDialog.close();
};
listView.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getClickCount() == 2) {
setReturnValueAndCloseDialog.run();
}
});
listView.setOnKeyPressed(keyEvent -> {
if (keyEvent.getCode() == KeyCode.ENTER) {
setReturnValueAndCloseDialog.run();
}
});

iniFileSelectionDialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
Button closeButton = (Button) iniFileSelectionDialog.getDialogPane().lookupButton(ButtonType.CLOSE);
closeButton.setVisible(false); // In JavaFX, a button of type ButtonType.CLOSE must exist so that the "X"-button closes the window.

Button okButton = new Button(Messages.OK);
okButton.setOnAction(actionEvent -> setReturnValueAndCloseDialog.run());
okButton.setPrefWidth(500);

VBox vBox = new VBox(listView, okButton);
iniFileSelectionDialog.getDialogPane().setContent(vBox);
listView.requestFocus();

iniFileSelectionDialog.getDialogPane().addEventFilter(KeyEvent.KEY_PRESSED, keyEvent -> {
if (keyEvent.getCode() == KeyCode.ESCAPE) {
iniFileSelectionDialog.close();
keyEvent.consume();
}
});

iniFileSelectionDialog.setOnCloseRequest(dialogEvent -> {
Object currentResult = iniFileSelectionDialog.getResult();
if (currentResult == null || !(currentResult instanceof File)) {
// Return null when closing the dialog by clicking the "X"-button or the ESC-key.
iniFileSelectionDialog.setResult(null);
}
});

Optional<File> maybeSelectedFile = iniFileSelectionDialog.showAndWait();
if (maybeSelectedFile.isPresent()) {
File selectedFile = maybeSelectedFile.get();
try {
FileInputStream selectedFile_FileInputStream = new FileInputStream(selectedFile);
try {
if (selectedFile.getAbsolutePath().endsWith(".xml")) {
java.util.prefs.Preferences.importPreferences(selectedFile_FileInputStream);
}
else {
PropertyPreferenceLoader.load(selectedFile_FileInputStream);
}
} catch (Exception exception) {
displayErrorMessageAndQuit.accept(new Pair(Messages.ErrorLoadingPhoebusConfiguration, Messages.ErrorLoadingPhoebusConfiguration + " '" + selectedFile.getAbsolutePath() + "': " + exception.getMessage()));
}
} catch (FileNotFoundException e) {
displayErrorMessageAndQuit.accept(new Pair(Messages.ErrorLoadingPhoebusConfiguration, Messages.ErrorLoadingPhoebusConfiguration + " '" + selectedFile.getAbsolutePath() + "': " + Messages.FileDoesNotExist));
}
} else {
// Selecting a configuration was cancelled either by pressing the "X"-button or by pressing the ESC-key.
stop();
}
} else {
displayErrorMessageAndQuit.accept(new Pair(Messages.ErrorDuringEvalutationOfTheFlagSelectSettings, Messages.ErrorDuringEvalutationOfTheFlagSelectSettings + ": " + MessageFormat.format(Messages.TheDirectoryDoesNotContainConfigurationFiles, iniFilesLocation_String)));
}
} else {
displayErrorMessageAndQuit.accept(new Pair(Messages.ErrorDuringEvalutationOfTheFlagSelectSettings, Messages.ErrorDuringEvalutationOfTheFlagSelectSettings + ": " + MessageFormat.format(Messages.TheArgumentIsNotADirectory, iniFilesLocation_String)));
}
}
}
}

/**
* Perform potentially slow startup task off the UI thread
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ DockNotSaved=<Not saved to file>
DockSplitH=Split Left/Right
DockSplitV=Split Top/Bottom
Enjoy=Enjoy CS-Studio!
ErrorDuringEvalutationOfTheFlagSelectSettings=Error during evaluation of the flag '-select_settings'
ErrorLoadingPhoebusConfiguration=Error loading Phoebus configuration
Exit=Exit
ExitContent=Closing this window exits the application,\nclosing all other windows.\n
ExitHdr=Close main window
ExitTitle=Exit
File=File
FileDoesNotExist=File does not exist!
FileExists=File \"{0}\" already exists. Do you want to overwrite it?
FixedTitle=CS-Studio
Help=Help
Expand Down Expand Up @@ -77,10 +80,12 @@ MonitorTaskTabs=Restore tabs
MonitorTaskUi=Start UI
NamePane=Name Pane
NamePaneHdr=Assign a name to this pane.\nSome displays can be configured\nto appear in a named pane.
OK=OK
Open=Open...
OpenHdr=Select application for opening\n
OpenTitle=Open
OpenWith=Open With...
PhoebusWillQuit=Phoebus will quit.
ProgressTitle=CS-Studio
PVListAppName=PV List
PVListJobName=List PVs
Expand Down Expand Up @@ -116,10 +121,13 @@ SavingErr=Error saving
SavingHdr=Save error
ScreenshotErrHdr=Screenshot error
ScreenshotErrMsg=Cannot write screenshot
SelectPhoebusConfiguration=Select Phoebus configuration
SelectTab=Select Tab
ShowInFileBrowserApp=Show in File Browser app
ShowStatusbar=Show Status bar
ShowToolbar=Show Toolbar
TheArgumentIsNotADirectory=the argument ''{0}'' is not a directory!
TheDirectoryDoesNotContainConfigurationFiles=the directory ''{0}'' does not contain any .ini or .xml file(s)!
Time12h=12 h
Time1d=1 day
Time3d=3 days
Expand Down

0 comments on commit d7f5e36

Please sign in to comment.