diff --git a/corefx/src/main/java/com/core/Controller.java b/corefx/src/main/java/com/core/Controller.java index 3c8e4c82..5418fef6 100644 --- a/corefx/src/main/java/com/core/Controller.java +++ b/corefx/src/main/java/com/core/Controller.java @@ -52,6 +52,7 @@ public class Controller implements Initializable { private Application application; private Stage window; + private Properties properties; // core client utilities private ICoreClient coreClient; @@ -80,6 +81,7 @@ public class Controller implements Initializable { private LocationDialog locationDialog = new LocationDialog(this); private GeoDialog geoDialog = new GeoDialog(this); private ConnectDialog connectDialog = new ConnectDialog(this); + private GuiPreferencesDialog guiPreferencesDialog = new GuiPreferencesDialog(this); public Controller() { } @@ -141,6 +143,7 @@ public class Controller implements Initializable { backgroundDialog.setOwner(window); locationDialog.setOwner(window); connectDialog.setOwner(window); + guiPreferencesDialog.setOwner(window); } @FXML @@ -164,6 +167,11 @@ public class Controller implements Initializable { locationDialog.showDialog(); } + @FXML + private void onOptionsMenuPreferences(ActionEvent event) { + guiPreferencesDialog.showDialog(); + } + @FXML private void onHelpMenuWebsite(ActionEvent event) { application.getHostServices().showDocument("https://github.com/coreemu/core"); @@ -183,7 +191,8 @@ public class Controller implements Initializable { private void onOpenXmlAction() { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Open Session"); - fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + String xmlPath = properties.getProperty(ConfigUtils.CORE_XML_PATH); + fileChooser.setInitialDirectory(new File(xmlPath)); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml")); File file = fileChooser.showOpenDialog(window); if (file != null) { @@ -201,7 +210,8 @@ public class Controller implements Initializable { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Save Session"); fileChooser.setInitialFileName("session.xml"); - fileChooser.setInitialDirectory(new File(System.getProperty("user.home"))); + String xmlPath = properties.getProperty(ConfigUtils.CORE_XML_PATH); + fileChooser.setInitialDirectory(new File(xmlPath)); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("XML", "*.xml")); File file = fileChooser.showSaveDialog(window); if (file != null) { @@ -266,8 +276,8 @@ public class Controller implements Initializable { public void initialize(URL location, ResourceBundle resources) { coreClient = new CoreRestClient(this); coreWebSocket = new CoreWebSocket(this); - Properties properties = ConfigUtils.load(); - String coreUrl = properties.getProperty("core-rest"); + properties = ConfigUtils.load(); + String coreUrl = properties.getProperty(ConfigUtils.CORE_REST); logger.info("core rest: {}", coreUrl); connectDialog.setCoreUrl(coreUrl); connectToCore(coreUrl); diff --git a/corefx/src/main/java/com/core/graph/NetworkGraph.java b/corefx/src/main/java/com/core/graph/NetworkGraph.java index a01edc3b..3a47937f 100644 --- a/corefx/src/main/java/com/core/graph/NetworkGraph.java +++ b/corefx/src/main/java/com/core/graph/NetworkGraph.java @@ -3,6 +3,7 @@ package com.core.graph; import com.core.Controller; import com.core.data.*; import com.core.ui.Toast; +import com.core.utils.ConfigUtils; import com.core.utils.IconUtils; import com.google.common.base.Supplier; import edu.uci.ics.jung.algorithms.layout.StaticLayout; @@ -117,8 +118,9 @@ public class NetworkGraph { if (mouseEvent.getClickCount() == 2 && controller.getCoreClient().isRunning()) { try { + String shellCommand = controller.getProperties().getProperty(ConfigUtils.SHELL_COMMAND); String terminalCommand = controller.getCoreClient().getTerminalCommand(node); - terminalCommand = String.format("gnome-terminal -x %s", terminalCommand); + terminalCommand = String.format("%s %s", shellCommand, terminalCommand); logger.info("launching node terminal: {}", terminalCommand); String[] commands = terminalCommand.split("\\s+"); logger.info("launching node terminal: {}", Arrays.toString(commands)); diff --git a/corefx/src/main/java/com/core/ui/dialogs/GuiPreferencesDialog.java b/corefx/src/main/java/com/core/ui/dialogs/GuiPreferencesDialog.java new file mode 100644 index 00000000..0d75a2f7 --- /dev/null +++ b/corefx/src/main/java/com/core/ui/dialogs/GuiPreferencesDialog.java @@ -0,0 +1,50 @@ +package com.core.ui.dialogs; + +import com.core.Controller; +import com.core.ui.Toast; +import com.core.utils.ConfigUtils; +import com.jfoenix.controls.JFXButton; +import com.jfoenix.controls.JFXTextField; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.util.Properties; + +public class GuiPreferencesDialog extends StageDialog { + private static final Logger logger = LogManager.getLogger(); + private @FXML JFXTextField xmlFilePathTextField; + private @FXML JFXTextField shellCommandTextField; + private @FXML JFXButton saveButton; + + public GuiPreferencesDialog(Controller controller) { + super(controller, "/fxml/gui_preferences.fxml"); + setTitle("GUI Preferences"); + saveButton = createButton("Save"); + saveButton.setOnAction(onSave); + addCancelButton(); + } + + private EventHandler onSave = event -> { + Properties properties = getController().getProperties(); + properties.setProperty(ConfigUtils.CORE_XML_PATH, xmlFilePathTextField.getText()); + properties.setProperty(ConfigUtils.SHELL_COMMAND, shellCommandTextField.getText()); + try { + ConfigUtils.save(properties); + Toast.success("Updated preferences"); + } catch (IOException ex) { + Toast.error("Failure to update preferences", ex); + } + close(); + }; + + public void showDialog() { + Properties properties = getController().getProperties(); + xmlFilePathTextField.setText(properties.getProperty(ConfigUtils.CORE_XML_PATH)); + shellCommandTextField.setText(properties.getProperty(ConfigUtils.SHELL_COMMAND)); + show(); + } +} diff --git a/corefx/src/main/java/com/core/utils/ConfigUtils.java b/corefx/src/main/java/com/core/utils/ConfigUtils.java index 93a76c23..e357d3c2 100644 --- a/corefx/src/main/java/com/core/utils/ConfigUtils.java +++ b/corefx/src/main/java/com/core/utils/ConfigUtils.java @@ -3,24 +3,52 @@ package com.core.utils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Properties; public final class ConfigUtils { private static final Logger logger = LogManager.getLogger(); private static final String DEFAULT_CONFIG = "/config.properties"; + private static final Path CORE_HOME = Paths.get(System.getProperty("user.home"), ".core"); + private static final Path CORE_PROPERTIES = Paths.get(CORE_HOME.toString(), "config.properties"); + private static final Path CORE_XML_DIR = Paths.get(CORE_HOME.toString(), "xml"); + // config fields + public static final String CORE_REST = "core-rest"; + public static final String CORE_XML_PATH = "xml-path"; + public static final String SHELL_COMMAND = "shell-command"; + private ConfigUtils() { } - public static Properties load() { - String filePath = System.getProperty("config.file", DEFAULT_CONFIG); - logger.info("loading config file: {}", filePath); + public static void save(Properties properties) throws IOException { + properties.store(new FileOutputStream(CORE_PROPERTIES.toFile()), null); + } + public static Properties load() { try { + if (!CORE_HOME.toFile().exists()) { + logger.info("creating core home directory"); + Files.createDirectory(CORE_HOME); + Files.createDirectory(CORE_XML_DIR); + } + Properties properties = new Properties(); - properties.load(ConfigUtils.class.getResourceAsStream(filePath)); + if (!CORE_PROPERTIES.toFile().exists()) { + logger.info("creating default configuration"); + Files.copy(ConfigUtils.class.getResourceAsStream(DEFAULT_CONFIG), CORE_PROPERTIES); + properties.load(new FileInputStream(CORE_PROPERTIES.toFile())); + properties.setProperty(CORE_XML_PATH, CORE_XML_DIR.toString()); + save(properties); + } else { + properties.load(new FileInputStream(CORE_PROPERTIES.toFile())); + } // override values if provided for (String key : properties.stringPropertyNames()) { diff --git a/corefx/src/main/resources/config.properties b/corefx/src/main/resources/config.properties index 15e1d886..e3ab482a 100644 --- a/corefx/src/main/resources/config.properties +++ b/corefx/src/main/resources/config.properties @@ -1 +1,2 @@ -core-rest=http://127.0.0.1:5000 \ No newline at end of file +core-rest=http://127.0.0.1:5000 +shell-command=gnome-terminal --window -- diff --git a/corefx/src/main/resources/fxml/gui_preferences.fxml b/corefx/src/main/resources/fxml/gui_preferences.fxml new file mode 100644 index 00000000..ce006bf5 --- /dev/null +++ b/corefx/src/main/resources/fxml/gui_preferences.fxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/corefx/src/main/resources/fxml/main.fxml b/corefx/src/main/resources/fxml/main.fxml index 27eed7e9..650d8a02 100644 --- a/corefx/src/main/resources/fxml/main.fxml +++ b/corefx/src/main/resources/fxml/main.fxml @@ -33,14 +33,15 @@ + - +