diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java index d29068f6c..97d0e4925 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java @@ -152,7 +152,7 @@ class DocumentConfig { // BodyTube setters.put("BodyTube:radius", new DoubleSetter( Reflection.findMethod(BodyTube.class, "setOuterRadius", double.class), - "auto", + "auto", " ", Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class))); // Parallel Stage @@ -204,11 +204,11 @@ class DocumentConfig { setters.put("Transition:foreradius", new DoubleSetter( Reflection.findMethod(Transition.class, "setForeRadius", double.class), - "auto", + "auto", " ", Reflection.findMethod(Transition.class, "setForeRadiusAutomatic", boolean.class))); setters.put("Transition:aftradius", new DoubleSetter( Reflection.findMethod(Transition.class, "setAftRadius", double.class), - "auto", + "auto", " ", Reflection.findMethod(Transition.class, "setAftRadiusAutomatic", boolean.class))); setters.put("Transition:foreshoulderradius", new DoubleSetter( diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java b/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java index 5d553b57b..5525f8086 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/DoubleSetter.java @@ -1,6 +1,8 @@ package net.sf.openrocket.file.openrocket.importt; +import java.util.Arrays; import java.util.HashMap; +import java.util.Objects; import net.sf.openrocket.aerodynamics.Warning; import net.sf.openrocket.aerodynamics.WarningSet; @@ -17,6 +19,7 @@ class DoubleSetter implements Setter { private final String specialString; private final Reflection.Method specialMethod; private final double multiplier; + private String separator; /** * Set only the double value. @@ -59,6 +62,23 @@ class DoubleSetter implements Setter { this.specialMethod = specialMethod; this.multiplier = 1.0; } + + /** + * Set the double value, or if the value equals the special string, use the + * special setter and set it to true. If the input string contains more information + * besides the special string, you can specify which separator should be used for + * this extra information. The part before the separator is then the special string + * and the part after the separator is the set value. + * + * @param set double setter. + * @param special special string + * @param specialMethod boolean setter. + */ + public DoubleSetter(Reflection.Method set, String special, String separator, + Reflection.Method specialMethod) { + this(set, special, specialMethod); + this.separator = separator; + } /** @@ -80,26 +100,39 @@ class DoubleSetter implements Setter { WarningSet warnings) { s = s.trim(); - - // Check for special case - if (specialMethod != null && s.equalsIgnoreCase(specialString)) { - specialMethod.invoke(c, true); - return; + String special = s; + String data = s; + String[] args = null; + + // Extract special string and data if s contains multiple data elements, separated by separator + if (separator != null) { + args = s.split(this.separator); + if (args.length > 1) { + special = args[0]; + data = String.join(separator, Arrays.copyOfRange(args, 1, args.length)); + } } // Normal case - try { - double d = Double.parseDouble(s); - - if (configGetter == null) { - setMethod.invoke(c, d * multiplier); - } else { - FlightConfigurableParameterSet config = (FlightConfigurableParameterSet) configGetter.invoke(c); - Object obj = config.getDefault(); - setMethod.invoke(obj, d * multiplier); + if (!special.equalsIgnoreCase(specialString) || (args != null && args.length > 1)) { + try { + double d = Double.parseDouble(data); + + if (configGetter == null) { + setMethod.invoke(c, d * multiplier); + } else { + FlightConfigurableParameterSet config = (FlightConfigurableParameterSet) configGetter.invoke(c); + Object obj = config.getDefault(); + setMethod.invoke(obj, d * multiplier); + } + } catch (NumberFormatException e) { + warnings.add(Warning.FILE_INVALID_PARAMETER + " data: '" + data + "' - " + c.getName()); } - } catch (NumberFormatException e) { - warnings.add(Warning.FILE_INVALID_PARAMETER); + } + + // Check for special case + if (specialMethod != null && special.equalsIgnoreCase(specialString)) { + specialMethod.invoke(c, true); } } } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/BodyTubeSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/BodyTubeSaver.java index 8b1ef6a58..d6aa0c85c 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/BodyTubeSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/BodyTubeSaver.java @@ -22,8 +22,9 @@ public class BodyTubeSaver extends SymmetricComponentSaver { super.addParams(c, elements); net.sf.openrocket.rocketcomponent.BodyTube tube = (net.sf.openrocket.rocketcomponent.BodyTube) c; - if (tube.isOuterRadiusAutomatic()) - elements.add("auto"); + if (tube.isOuterRadiusAutomatic()) { + elements.add("auto " + tube.getOuterRadiusNoAutomatic() + ""); + } else elements.add("" + tube.getOuterRadius() + ""); diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java index 0a4169f9e..054506eae 100644 --- a/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/savers/TransitionSaver.java @@ -45,13 +45,13 @@ public class TransitionSaver extends SymmetricComponentSaver { if (!nosecone) { if (trans.isForeRadiusAutomatic()) - elements.add("auto"); + elements.add("auto " + trans.getForeRadiusNoAutomatic() + ""); else elements.add("" + trans.getForeRadius() + ""); } if (trans.isAftRadiusAutomatic()) - elements.add("auto"); + elements.add("auto " + trans.getAftRadiusNoAutomatic() + ""); else elements.add("" + trans.getAftRadius() + ""); diff --git a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java index 684279ca5..eb3b6d3d6 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java +++ b/core/src/net/sf/openrocket/rocketcomponent/BodyTube.java @@ -97,6 +97,14 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou } return outerRadius; } + + /** + * Return the outer radius that was manually entered, so not the value that the component received from automatic + * outer radius. + */ + public double getOuterRadiusNoAutomatic() { + return outerRadius; + } /** * Set the outer radius of the body tube. If the radius is less than the wall thickness, diff --git a/core/src/net/sf/openrocket/rocketcomponent/Transition.java b/core/src/net/sf/openrocket/rocketcomponent/Transition.java index 188a01f40..422561119 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/Transition.java +++ b/core/src/net/sf/openrocket/rocketcomponent/Transition.java @@ -94,6 +94,14 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return foreRadius; } + /** + * Return the fore radius that was manually entered, so not the value that the component received from automatic + * fore radius. + */ + public double getForeRadiusNoAutomatic() { + return foreRadius; + } + public void setForeRadius(double radius) { if ((this.foreRadius == radius) && (autoForeRadius == false)) return; @@ -142,7 +150,13 @@ public class Transition extends SymmetricComponent implements InsideColorCompone return aftRadius; } - + /** + * Return the aft radius that was manually entered, so not the value that the component received from automatic + * zft radius. + */ + public double getAftRadiusNoAutomatic() { + return aftRadius; + } public void setAftRadius(double radius) { if ((this.aftRadius == radius) && (autoAftRadius2 == false))