From 500c75aeab99d8a911339cb6c8bff35dcd60e5c0 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Mon, 22 Jul 2024 00:02:08 +0200 Subject: [PATCH] Save document preferences in design file --- .../core/document/OpenRocketDocument.java | 13 +++ .../events/DocumentChangeListener.java | 6 +- .../core/file/openrocket/OpenRocketSaver.java | 19 ++++ .../importt/DocumentPreferencesHandler.java | 66 +++++++++++++ .../importt/OpenRocketContentHandler.java | 6 +- .../core/preferences/DocumentPreferences.java | 97 +++++++++++++++++++ fileformat.txt | 1 + .../openrocket/swing/gui/main/BasicFrame.java | 1 + 8 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/info/openrocket/core/file/openrocket/importt/DocumentPreferencesHandler.java create mode 100644 core/src/main/java/info/openrocket/core/preferences/DocumentPreferences.java diff --git a/core/src/main/java/info/openrocket/core/document/OpenRocketDocument.java b/core/src/main/java/info/openrocket/core/document/OpenRocketDocument.java index 8b04e51aa..556ce9c33 100644 --- a/core/src/main/java/info/openrocket/core/document/OpenRocketDocument.java +++ b/core/src/main/java/info/openrocket/core/document/OpenRocketDocument.java @@ -5,6 +5,7 @@ import java.util.*; import info.openrocket.core.file.wavefrontobj.export.OBJExportOptions; import info.openrocket.core.preferences.ApplicationPreferences; +import info.openrocket.core.preferences.DocumentPreferences; import info.openrocket.core.rocketcomponent.*; import info.openrocket.core.util.StateChangeListener; import org.slf4j.Logger; @@ -38,6 +39,7 @@ import info.openrocket.core.util.ArrayList; public class OpenRocketDocument implements ComponentChangeListener, StateChangeListener { private static final Logger log = LoggerFactory.getLogger(OpenRocketDocument.class); private static final ApplicationPreferences prefs = Application.getPreferences(); + private final DocumentPreferences docPrefs = new DocumentPreferences(); private final List file_extensions = Arrays.asList("ork", "ork.gz", "rkt", "rkt.gz"); // Possible extensions of an OpenRocket document /** * The minimum number of undo levels that are stored. @@ -848,6 +850,13 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL l.documentChanged(event); } } + + public void fireDocumentSavingEvent(DocumentChangeEvent event) { + DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]); + for (DocumentChangeListener l : array) { + l.documentSaving(event); + } + } public String toSimulationDetail(){ StringBuilder str = new StringBuilder(); @@ -868,4 +877,8 @@ public class OpenRocketDocument implements ComponentChangeListener, StateChangeL public void setPhotoSettings(Map photoSettings) { this.photoSettings = photoSettings; } + + public DocumentPreferences getDocumentPreferences() { + return docPrefs; + } } diff --git a/core/src/main/java/info/openrocket/core/document/events/DocumentChangeListener.java b/core/src/main/java/info/openrocket/core/document/events/DocumentChangeListener.java index d105dcee9..54dfb8fff 100644 --- a/core/src/main/java/info/openrocket/core/document/events/DocumentChangeListener.java +++ b/core/src/main/java/info/openrocket/core/document/events/DocumentChangeListener.java @@ -2,6 +2,10 @@ package info.openrocket.core.document.events; public interface DocumentChangeListener { - public void documentChanged(DocumentChangeEvent event); + void documentChanged(DocumentChangeEvent event); + + default void documentSaving(DocumentChangeEvent event) { + // Do nothing + } } diff --git a/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java b/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java index 8a5ef3e27..47b0110f4 100644 --- a/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java +++ b/core/src/main/java/info/openrocket/core/file/openrocket/OpenRocketSaver.java @@ -11,6 +11,7 @@ import info.openrocket.core.file.openrocket.savers.PhotoStudioSaver; import info.openrocket.core.logging.ErrorSet; import info.openrocket.core.logging.SimulationAbort; import info.openrocket.core.logging.WarningSet; +import info.openrocket.core.preferences.DocumentPreferences; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,6 +108,9 @@ public class OpenRocketSaver extends RocketSaver { // Save PhotoSettings savePhotoSettings(document.getPhotoSettings()); + + // Save document preferences + saveDocumentPreferences(document.getDocumentPreferences()); indent--; writeln(""); @@ -428,6 +432,21 @@ public class OpenRocketSaver extends RocketSaver { writeln(""); } + private void saveDocumentPreferences(DocumentPreferences docPrefs) throws IOException { + log.debug("Saving Document Preferences"); + + writeln(""); + indent++; + + Map prefs = docPrefs.getPreferencesMap(); + for (Map.Entry entry : prefs.entrySet()) { + DocumentPreferences.DocumentPreference pref = entry.getValue(); + writeEntry("pref", entry.getKey(), pref.getValue(), true); + } + + indent--; + writeln(""); + } /** * Write an entry element, which has a key and type attribute, and a value, to the output. diff --git a/core/src/main/java/info/openrocket/core/file/openrocket/importt/DocumentPreferencesHandler.java b/core/src/main/java/info/openrocket/core/file/openrocket/importt/DocumentPreferencesHandler.java new file mode 100644 index 000000000..57e1bbcd0 --- /dev/null +++ b/core/src/main/java/info/openrocket/core/file/openrocket/importt/DocumentPreferencesHandler.java @@ -0,0 +1,66 @@ +package info.openrocket.core.file.openrocket.importt; + +import info.openrocket.core.preferences.DocumentPreferences; +import info.openrocket.core.document.OpenRocketDocument; +import info.openrocket.core.file.simplesax.ElementHandler; +import info.openrocket.core.file.simplesax.PlainTextHandler; +import info.openrocket.core.logging.WarningSet; +import org.xml.sax.SAXException; + +import java.util.HashMap; + +public class DocumentPreferencesHandler extends EntryHandler { + private final OpenRocketDocument document; + + public DocumentPreferencesHandler(OpenRocketDocument document) { + this.document = document; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) throws SAXException { + if (element.equals("pref") && "list".equals(attributes.get("type"))) { + listHandler = new ConfigHandler(); + return listHandler; + } else { + return PlainTextHandler.INSTANCE; + } + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { + if (element.equals("pref")) { + String key = attributes.get("key"); + String type = attributes.get("type"); + Object value = EntryHelper.getValueFromEntry(DocumentPreferencesHandler.this, attributes, content); + if (value == null) { + return; + } + if (key != null) { + addValueToDocumentPreferences(key, value, type); + } else { + list.add(value); + } + } else { + super.closeElement(element, attributes, content, warnings); + } + } + + private void addValueToDocumentPreferences(String key, Object value, String type) { + DocumentPreferences docPrefs = document.getDocumentPreferences(); + + if ("boolean".equals(type)) { + docPrefs.putBoolean(key, (Boolean) value); + } else if ("string".equals(type)) { + docPrefs.putString(key, (String) value); + } else if ("integer".equals(type)) { + docPrefs.putInt(key, (Integer) value); + } else if ("double".equals(type)) { + docPrefs.putDouble(key, (Double) value); + } else if ("number".equals(type)) { + throw new RuntimeException("Number preferences are not supported"); + } else if ("list".equals(type)) { + // We don't support nested preferences + throw new RuntimeException("Nested preferences are not supported"); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/info/openrocket/core/file/openrocket/importt/OpenRocketContentHandler.java b/core/src/main/java/info/openrocket/core/file/openrocket/importt/OpenRocketContentHandler.java index 40619c893..6bf13d91d 100644 --- a/core/src/main/java/info/openrocket/core/file/openrocket/importt/OpenRocketContentHandler.java +++ b/core/src/main/java/info/openrocket/core/file/openrocket/importt/OpenRocketContentHandler.java @@ -65,7 +65,11 @@ class OpenRocketContentHandler extends AbstractElementHandler { } if (element.equals("photostudio")) { - return new PhotoStudioHandler(context.getOpenRocketDocument().getPhotoSettings()); + return new PhotoStudioHandler(getDocument().getPhotoSettings()); + } + + if (element.equals("docprefs")) { + return new DocumentPreferencesHandler(getDocument()); } warnings.add(Warning.fromString("Unknown element " + element + ", ignoring.")); diff --git a/core/src/main/java/info/openrocket/core/preferences/DocumentPreferences.java b/core/src/main/java/info/openrocket/core/preferences/DocumentPreferences.java new file mode 100644 index 000000000..4b794a47f --- /dev/null +++ b/core/src/main/java/info/openrocket/core/preferences/DocumentPreferences.java @@ -0,0 +1,97 @@ +package info.openrocket.core.preferences; + +import info.openrocket.core.util.ChangeSource; +import info.openrocket.core.util.StateChangeListener; +import java.util.HashMap; +import java.util.Map; + +/** + * ORPreferences specific to an OpenRocket document (= preferences that are saved in the document file, not + * implemented application-wise). + * + * @author Sibo Van Gool + */ +public class DocumentPreferences implements ChangeSource, ORPreferences { + // Map that stores all the document preferences + private final Map preferencesMap = new HashMap<>(); + + @Override + public void addChangeListener(StateChangeListener listener) { + + } + + @Override + public void removeChangeListener(StateChangeListener listener) { + + } + + @Override + public boolean getBoolean(String key, boolean defaultValue) { + DocumentPreference pref = preferencesMap.get(key); + return preferencesMap.containsKey(key) ? (Boolean) pref.getValue() : defaultValue; + } + + @Override + public void putBoolean(String key, boolean value) { + preferencesMap.put(key, new DocumentPreference(value)); + } + + @Override + public int getInt(String key, int defaultValue) { + DocumentPreference pref = preferencesMap.get(key); + return preferencesMap.containsKey(key) ? (Integer) pref.getValue() : defaultValue; + } + + @Override + public void putInt(String key, int value) { + preferencesMap.put(key, new DocumentPreference(value)); + } + + @Override + public double getDouble(String key, double defaultValue) { + DocumentPreference pref = preferencesMap.get(key); + return preferencesMap.containsKey(key) ? (Double) pref.getValue() : defaultValue; + } + + @Override + public void putDouble(String key, double value) { + preferencesMap.put(key, new DocumentPreference(value)); + } + + @Override + public String getString(String key, String defaultValue) { + DocumentPreference pref = preferencesMap.get(key); + return preferencesMap.containsKey(key) ? (String) pref.getValue() : defaultValue; + } + + @Override + public void putString(String key, String value) { + preferencesMap.put(key, new DocumentPreference(value)); + } + + /** + * Returns the map that stores all the document preferences key-value pairs. + * @return The document preferences map + */ + public Map getPreferencesMap() { + return preferencesMap; + } + + public static class DocumentPreference { + private final Object value; + private final Class type; + + public DocumentPreference(Object value) { + this.value = value; + this.type = value.getClass(); + } + + public Object getValue() { + return value; + } + + public Class getType() { + return type; + } + } +} diff --git a/fileformat.txt b/fileformat.txt index ae33ec0b5..03b3e25f6 100644 --- a/fileformat.txt +++ b/fileformat.txt @@ -69,3 +69,4 @@ The following file format versions exist: 1.10: Introduced with OpenRocket 24.XX. Added a priority attribute to simulation warnings. + Added document preferences (). diff --git a/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java b/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java index 349c3aaf9..67e27f3c4 100644 --- a/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java +++ b/swing/src/main/java/info/openrocket/swing/gui/main/BasicFrame.java @@ -1388,6 +1388,7 @@ public class BasicFrame extends JFrame { * @return true if the file was saved, false otherwise */ private boolean saveAction() { + document.fireDocumentSavingEvent(new DocumentChangeEvent(this)); File file = document.getFile(); if (file == null || document.getDefaultStorageOptions().getFileType().equals(FileType.ROCKSIM) || document.getDefaultStorageOptions().getFileType().equals(FileType.RASAERO)) {