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))