diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties
index 46a969ff4..f836bf176 100644
--- a/core/resources/l10n/messages.properties
+++ b/core/resources/l10n/messages.properties
@@ -306,7 +306,7 @@ pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; dire
pref.dlg.RASPfiles = RASP motor files (*.eng)
pref.dlg.RockSimfiles = RockSim engine files (*.rse)
pref.dlg.ZIParchives = ZIP archives (*.zip)
-pref.dlg.checkbox.Checkupdates = Check for software updates at startup
+pref.dlg.checkbox.Checkupdates = Always check for software updates at startup
pref.dlg.checkbox.Checkupdates.ttip = Check for software updates every time you start up OpenRocket
pref.dlg.checkbox.CheckBetaupdates = Also check for beta releases
pref.dlg.checkbox.CheckBetaupdates.ttip = If checked, beta release updates are also notified. If unchecked, only official releases are considered.
@@ -363,11 +363,11 @@ update.dlg.latestVersion = You are running the latest version of OpenRocket, ver
update.dlg.newerVersion.title = Newer version detected
update.dlg.newerVersion = You are either running a test/unofficial release of OpenRocket, or you have a time machine and are running an official release from the future.\n\nYour version: %s\nLatest official release: %s
update.dlg.updateAvailable.title = Update available
-update.dlg.updateAvailable.txtPane.title = OpenRocket version %s available!
-update.dlg.updateAvailable.txtPane.yourVersion = Your current version: %s
-update.dlg.updateAvailable.txtPane.changelog = Changelog
+update.dlg.updateAvailable.lbl.title = A new version of OpenRocket is available!
+update.dlg.updateAvailable.lbl.yourVersion = OpenRocket %s is available! \u2015 you have %s. Would you like to download it now?
+update.dlg.updateAvailable.lbl.releaseNotes = Release notes:
update.dlg.updateAvailable.txtPane.readMore = Read more on GitHub
-update.dlg.updateAvailable.but.install = Install update
+update.dlg.updateAvailable.but.install = Install Update
update.dlg.updateAvailable.combo.noDownloads = No downloads available
update.fetcher.badResponse = Bad response code from server: %d
update.fetcher.badConnection = Could not connect to the GitHub server. Please check your internet connection.
diff --git a/core/resources/l10n/messages_ru.properties b/core/resources/l10n/messages_ru.properties
index 2903f7242..622206d70 100644
--- a/core/resources/l10n/messages_ru.properties
+++ b/core/resources/l10n/messages_ru.properties
@@ -64,6 +64,8 @@ RocketPanel.lbl.Stability = \u0421\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u04
RocketPanel.checkbox.ShowCGCP = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0426\u0422/\u0426\u0414
RocketPanel.checkbox.ShowCGCP.ttip = \u041E\u0442\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u044D\u0442\u043E\u0433\u043E \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 \u0441\u043A\u0440\u043E\u0435\u0442 \u043E\u0442\u043C\u0435\u0442\u043A\u0438 \u0426\u0422/\u0426\u0414.
RocketPanel.lbl.Stages = \u0421\u0442\u0443\u043F\u0435\u043D\u0438:
+RocketPanel.btn.Stages.Toggle.ttip = \u041D\u0430\u0436\u0430\u0442\u0438\u0435 \u044D\u0442\u043E\u0439 \u043A\u043D\u043E\u043F\u043A\u0438 \u0430\u043A\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u0442/\u0434\u0435\u0430\u043A\u0442\u0438\u0432\u0438\u0440\u0443\u0435\u0442 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0443\u044E \u0441\u0442\u0443\u043F\u0435\u043D\u044C \u0440\u0430\u043A\u0435\u0442\u044B.
+RocketPanel.btn.Stages.NoChildren.ttip = \u0412 \u044D\u0442\u043E\u0439 \u0441\u0442\u0443\u043F\u0435\u043D\u0438 \u043D\u0435\u0442 \u0434\u043E\u0447\u0435\u0440\u043D\u0438\u0445 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432, \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u043E\u043D\u0430 \u043F\u043E\u043C\u0435\u0447\u0435\u043D\u0430 \u043A\u0430\u043A \u043D\u0435\u0430\u043A\u0442\u0438\u0432\u043D\u0430\u044F.
\u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u044B \u0432 \u0441\u0442\u0443\u043F\u0435\u043D\u044C, \u0447\u0442\u043E\u0431\u044B \u0430\u043A\u0442\u0438\u0432\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0435\u0451.
RocketPanel.ttip.Rotation = \u0421\u043C\u0435\u043D\u0430 \u0432\u0440\u0430\u0449\u0435\u043D\u0438\u044F \u043A\u0440\u0435\u043D\u0430 \u0440\u0430\u043A\u0435\u0442\u044B (\u0442\u043E\u043B\u044C\u043A\u043E \u0432 \u043E\u043A\u043D\u0435 \u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0430)
! BasicFrame
@@ -305,7 +307,7 @@ pref.dlg.Allthrustcurvefiles = \u0424\u0430\u0439\u043B\u044B \u043F\u0440\u043E
pref.dlg.RASPfiles = \u0424\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RASP (*.eng)
pref.dlg.RockSimfiles = \u0424\u0430\u0439\u043B\u044B \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043B\u0435\u0439 RockSim (*.rse)
pref.dlg.ZIParchives = ZIP-\u0430\u0440\u0445\u0438\u0432\u044B (*.zip)
-pref.dlg.checkbox.Checkupdates = \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043D\u0430\u043B\u0438\u0447\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
+pref.dlg.checkbox.Checkupdates = \u0412\u0441\u0435\u0433\u0434\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043D\u0430\u043B\u0438\u0447\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043F\u0440\u0438 \u0437\u0430\u043F\u0443\u0441\u043A\u0435
pref.dlg.checkbox.Checkupdates.ttip = \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043D\u0430\u043B\u0438\u0447\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043F\u0440\u0438 \u043A\u0430\u0436\u0434\u043E\u043C \u0437\u0430\u043F\u0443\u0441\u043A\u0435 OpenRocket
pref.dlg.checkbox.CheckBetaupdates = \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u0431\u0435\u0442\u0430-\u0432\u0435\u0440\u0441\u0438\u0438
pref.dlg.checkbox.CheckBetaupdates.ttip = \u0415\u0441\u043B\u0438 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0431\u0435\u0442\u0430-\u0432\u0435\u0440\u0441\u0438\u0438 \u0442\u0430\u043A\u0436\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u044E\u0442\u0441\u044F. \u0415\u0441\u043B\u0438 \u0444\u043B\u0430\u0436\u043E\u043A \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0443\u0447\u0438\u0442\u044B\u0432\u0430\u044E\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u043E\u0444\u0438\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0435 \u0432\u044B\u043F\u0443\u0441\u043A\u0438.
@@ -362,9 +364,9 @@ update.dlg.latestVersion = \u0412\u044B \u0440\u0430\u0431\u043E\u0442\u0430\u04
update.dlg.newerVersion.title = \u041E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\u0430 \u0431\u043E\u043B\u0435\u0435 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F
update.dlg.newerVersion = \u0412\u044B \u043B\u0438\u0431\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435 \u0442\u0435\u0441\u0442\u043E\u0432\u0443\u044E/\u043D\u0435\u043E\u0444\u0438\u0446\u0438\u0430\u043B\u044C\u043D\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E OpenRocket, \u043B\u0438\u0431\u043E \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044C \u043C\u0430\u0448\u0438\u043D\u0430 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0438 \u0432\u044B \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435 \u043E\u0444\u0438\u0446\u0438\u0430\u043B\u044C\u043D\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E \u0438\u0437 \u0431\u0443\u0434\u0443\u0449\u0435\u0433\u043E.\n\n\u0412\u0430\u0448\u0430 \u0432\u0435\u0440\u0441\u0438\u044F: %s\n\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u043E\u0444\u0438\u0446\u0438\u0430\u043B\u044C\u043D\u044B\u0439 \u0432\u044B\u043F\u0443\u0441\u043A: %s
update.dlg.updateAvailable.title = \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F
-update.dlg.updateAvailable.txtPane.title = \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0432\u0435\u0440\u044F\u0438 OpenRocket %s!
-update.dlg.updateAvailable.txtPane.yourVersion = \u0412\u0430\u0448\u0430 \u0442\u0435\u043A\u0443\u0449\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F: %s
-update.dlg.updateAvailable.txtPane.changelog = \u0421\u043F\u0438\u0441\u043E\u043A \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439
+update.dlg.updateAvailable.lbl.title = \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F OpenRocket!
+update.dlg.updateAvailable.lbl.yourVersion = \u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 OpenRocket %s! \u0423 \u0432\u0430\u0441 %s. \u0425\u043E\u0442\u0438\u0442\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0435\u0451 \u0441\u0435\u0439\u0447\u0430\u0441?
+update.dlg.updateAvailable.lbl.releaseNotes = \u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u044F \u043A \u0432\u044B\u043F\u0443\u0441\u043A\u0443:
update.dlg.updateAvailable.txtPane.readMore = \u0423\u0437\u043D\u0430\u0439\u0442\u0435 \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0430 GitHub
update.dlg.updateAvailable.but.install = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435
update.dlg.updateAvailable.combo.noDownloads = \u041D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043E\u043A
diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
index 6e32873e4..3cc791d79 100644
--- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java
@@ -428,8 +428,15 @@ public class OpenRocketSaver extends RocketSaver {
private void savePhotoSettings(Map p) throws IOException {
log.debug("Saving Photo Settings");
+
+ writeln("");
+ indent++;
+
for (String s : PhotoStudioSaver.getElements(p))
writeln(s);
+
+ indent--;
+ writeln("");
}
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 e9bd33b29..60a20db09 100644
--- a/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
+++ b/core/src/net/sf/openrocket/file/openrocket/importt/DocumentConfig.java
@@ -374,7 +374,7 @@ class DocumentConfig {
// MassObject
setters.put("MassObject:packedlength", new DoubleSetter(
- Reflection.findMethod(MassObject.class, "setLength", double.class)));
+ Reflection.findMethod(MassObject.class, "setLengthNoAuto", double.class)));
setters.put("MassObject:packedradius", new DoubleSetter(
Reflection.findMethod(MassObject.class, "setRadius", double.class),
"auto", " ",
diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java
index 2d91e5f40..16a79c459 100644
--- a/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java
+++ b/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java
@@ -21,8 +21,6 @@ public class PhotoStudioSaver {
if (photoSettings == null || photoSettings.size() == 0) return elements;
- elements.add("");
-
elements.add("" + photoSettings.get("roll") + "");
elements.add("" + photoSettings.get("yaw") + "");
elements.add("" + photoSettings.get("pitch") + "");
@@ -45,7 +43,6 @@ public class PhotoStudioSaver {
emitColor("flameColor", elements, photoSettings.get("flameColor"));
elements.add("" + photoSettings.get("smoke") + "");
emitColor("smokeColor", elements, photoSettings.get("smokeColor"));
- elements.add("" + photoSettings.get("smokeOpacity") + "");
elements.add("" + photoSettings.get("sparks") + "");
elements.add("" + photoSettings.get("exhaustScale") + "");
elements.add("" + photoSettings.get("flameAspectRatio") + "");
@@ -55,8 +52,6 @@ public class PhotoStudioSaver {
elements.add("" + photoSettings.get("sky") + "");
- elements.add("");
-
return elements;
}
diff --git a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java
index 1522fde04..cfd69691f 100644
--- a/core/src/net/sf/openrocket/rocketcomponent/MassObject.java
+++ b/core/src/net/sf/openrocket/rocketcomponent/MassObject.java
@@ -53,10 +53,10 @@ public abstract class MassObject extends InternalComponent {
@Override
public double getLength() {
if (this.autoRadius) {
- // Calculate the parachute volume using the non auto radius and the non auto length, and transform that back
+ // Calculate the volume using the non auto radius and the non auto length, and transform that back
// to the auto radius situation to get the auto radius length (the volume in both situations is the same).
- double parachuteVolume = Math.pow(this.radius, 2) * this.length; // Math.PI left out, not needed
- return parachuteVolume / Math.pow(getRadius(), 2);
+ double volume = Math.pow(this.radius, 2) * this.length; // Math.PI left out, not needed
+ return volume / Math.pow(getRadius(), 2);
}
return length;
}
@@ -93,10 +93,10 @@ public abstract class MassObject extends InternalComponent {
length = Math.max(length, 0);
if (this.autoRadius) {
- // Calculate the parachute volume using the auto radius and the new "auto" length, and transform that back
+ // Calculate the volume using the auto radius and the new "auto" length, and transform that back
// to the non auto radius situation to set this.length (the volume in both situations is the same).
- double parachuteVolume = Math.pow(getRadius(), 2) * length; // Math.PI left out, not needed
- double newLength = parachuteVolume / Math.pow(this.radius, 2);
+ double volume = Math.pow(getRadius(), 2) * length; // Math.PI left out, not needed
+ double newLength = volume / Math.pow(this.radius, 2);
if (MathUtil.equals(this.length, newLength))
return;
this.length = newLength;
@@ -168,8 +168,8 @@ public abstract class MassObject extends InternalComponent {
autoRadius = auto;
// Set the length
- double parachuteVolume = (Math.PI * Math.pow(getRadius(), 2) * length);
- length = parachuteVolume / (Math.PI * Math.pow(getRadius(), 2));
+ double volume = (Math.PI * Math.pow(getRadius(), 2) * length);
+ length = volume / (Math.PI * Math.pow(getRadius(), 2));
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
}
@@ -248,8 +248,8 @@ public abstract class MassObject extends InternalComponent {
@Override
public final Collection getComponentBounds() {
Collection c = new ArrayList();
- addBound(c, 0, radius);
- addBound(c, length, radius);
+ addBound(c, 0, getRadius());
+ addBound(c, getLength(), getRadius());
return c;
}
diff --git a/core/src/net/sf/openrocket/startup/Preferences.java b/core/src/net/sf/openrocket/startup/Preferences.java
index 90da3c320..0b27c19f1 100644
--- a/core/src/net/sf/openrocket/startup/Preferences.java
+++ b/core/src/net/sf/openrocket/startup/Preferences.java
@@ -58,6 +58,7 @@ public abstract class Preferences implements ChangeSource {
private static final String CHECK_UPDATES = "CheckUpdates";
+ private static final String IGNORE_VERSIONS = "IgnoreVersions";
private static final String CHECK_BETA_UPDATES = "CheckBetaUpdates";
public static final String MOTOR_DIAMETER_FILTER = "MotorDiameterMatch";
@@ -150,6 +151,14 @@ public abstract class Preferences implements ChangeSource {
this.putBoolean(CHECK_UPDATES, check);
}
+ public final List getIgnoreVersions() {
+ return List.of(this.getString(IGNORE_VERSIONS, "").split("\n"));
+ }
+
+ public final void setIgnoreVersions(List versions) {
+ this.putString(IGNORE_VERSIONS, String.join("\n", versions));
+ }
+
public final boolean getCheckBetaUpdates() {
return this.getBoolean(CHECK_BETA_UPDATES, BuildProperties.getDefaultCheckBetaUpdates());
}
diff --git a/core/test/net/sf/openrocket/rocketcomponent/MassObjectTest.java b/core/test/net/sf/openrocket/rocketcomponent/MassObjectTest.java
new file mode 100644
index 000000000..a7e18ea75
--- /dev/null
+++ b/core/test/net/sf/openrocket/rocketcomponent/MassObjectTest.java
@@ -0,0 +1,86 @@
+package net.sf.openrocket.rocketcomponent;
+
+import net.sf.openrocket.util.BaseTestCase.BaseTestCase;
+import net.sf.openrocket.util.MathUtil;
+import org.junit.Test;
+import org.junit.Assert;
+
+public class MassObjectTest extends BaseTestCase {
+ @Test
+ public void testAutoRadius() {
+ MassObject sc = new ShockCord();
+ MassObject mc = new MassComponent();
+ MassObject pc = new Parachute();
+ MassObject st = new Streamer();
+ MassObject[] massObjects = {sc, mc, pc, st};
+
+ for (MassObject mo : massObjects) {
+ // Test no auto
+ mo.setRadiusAutomatic(false);
+ mo.setRadius(0.1);
+ mo.setLength(0.1);
+ Assert.assertEquals(String.format(" No auto %s incorrect radius", mo.getClass().getName()),
+ 0.1, mo.getRadius(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" No auto %s incorrect no auto radius", mo.getClass().getName()),
+ 0.1, mo.getRadiusNoAuto(),MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" No auto %s incorrect length", mo.getClass().getName()),
+ 0.1, mo.getLength(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" No auto %s incorrect no auto length", mo.getClass().getName()),
+ 0.1, mo.getLengthNoAuto(), MathUtil.EPSILON);
+
+ mo.setLengthNoAuto(0.1);
+ Assert.assertEquals(String.format(" No auto 2 %s incorrect length", mo.getClass().getName()),
+ 0.1, mo.getLength(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" No auto 2 %s incorrect no auto length", mo.getClass().getName()),
+ 0.1, mo.getLengthNoAuto(), MathUtil.EPSILON);
+
+ // Test auto
+ BodyTube parent = new BodyTube();
+ parent.setOuterRadius(0.05);
+ parent.setInnerRadius(0.05);
+ parent.addChild(mo);
+ mo.setRadiusAutomatic(true);
+ Assert.assertEquals(String.format(" Auto 1 %s incorrect radius", mo.getClass().getName()),
+ 0.05, mo.getRadius(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 1 %s incorrect no auto radius", mo.getClass().getName()),
+ 0.1, mo.getRadiusNoAuto(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 1 %s incorrect length", mo.getClass().getName()),
+ 0.4, mo.getLength(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 1 %s incorrect no auto length", mo.getClass().getName()),
+ 0.1, mo.getLengthNoAuto(), MathUtil.EPSILON);
+
+ parent.setOuterRadius(0.1);
+ parent.setInnerRadius(0.1);
+ Assert.assertEquals(String.format(" Auto 2 %s incorrect radius", mo.getClass().getName()),
+ 0.1, mo.getRadius(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 2 %s incorrect no auto radius", mo.getClass().getName()),
+ 0.1, mo.getRadiusNoAuto(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 2 %s incorrect length", mo.getClass().getName()),
+ 0.1, mo.getLength(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 2 %s incorrect no auto length", mo.getClass().getName()),
+ 0.1, mo.getLengthNoAuto(), MathUtil.EPSILON);
+
+ parent.setOuterRadius(0.075);
+ parent.setInnerRadius(0.075);
+ mo.setLength(0.075);
+ Assert.assertEquals(String.format(" Auto 3 %s incorrect radius", mo.getClass().getName()),
+ 0.075, mo.getRadius(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 3 %s incorrect no auto radius", mo.getClass().getName()),
+ 0.1, mo.getRadiusNoAuto(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 3 %s incorrect length", mo.getClass().getName()),
+ 0.075, mo.getLength(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 3 %s incorrect no auto length", mo.getClass().getName()),
+ 0.0422, mo.getLengthNoAuto(), 0.001);
+
+ mo.setLengthNoAuto(0.05);
+ Assert.assertEquals(String.format(" Auto 4 %s incorrect radius", mo.getClass().getName()),
+ 0.075, mo.getRadius(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 4 %s incorrect no auto radius", mo.getClass().getName()),
+ 0.1, mo.getRadiusNoAuto(), MathUtil.EPSILON);
+ Assert.assertEquals(String.format(" Auto 4 %s incorrect length", mo.getClass().getName()),
+ 0.0889, mo.getLength(), 0.001);
+ Assert.assertEquals(String.format(" Auto 4 %s incorrect no auto length", mo.getClass().getName()),
+ 0.05, mo.getLengthNoAuto(), MathUtil.EPSILON);
+ }
+ }
+}
diff --git a/swing/src/net/sf/openrocket/communication/AssetHandler.java b/swing/src/net/sf/openrocket/communication/AssetHandler.java
index e21b5e997..942dec758 100644
--- a/swing/src/net/sf/openrocket/communication/AssetHandler.java
+++ b/swing/src/net/sf/openrocket/communication/AssetHandler.java
@@ -32,7 +32,7 @@ public class AssetHandler {
mapExtensionToPlatform.put(".sh", new UpdatePlatform[] {UpdatePlatform.LINUX, UpdatePlatform.UNIX});
mapExtensionToPlatform.put(".jar", new UpdatePlatform[] {UpdatePlatform.JAR});
- mapPlatformToName.put(UpdatePlatform.MAC_OS, "Mac OS");
+ mapPlatformToName.put(UpdatePlatform.MAC_OS, "macOS");
mapPlatformToName.put(UpdatePlatform.WINDOWS, "Windows");
mapPlatformToName.put(UpdatePlatform.LINUX, "Linux");
mapPlatformToName.put(UpdatePlatform.UNIX, "Linux");
@@ -42,7 +42,7 @@ public class AssetHandler {
/**
* Maps a list of asset URLs to their respective operating platform name.
* E.g. "https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.dmg" is mapped a
- * map element with "Mac OS" as key and the url as value.
+ * map element with "macOS" as key and the url as value.
* @param urls list of asset URLs
* @return map with as key the operating platform name and as value the corresponding asset URL
*/
@@ -70,7 +70,7 @@ public class AssetHandler {
}
/**
- * Get the name of a platform (e.g. for Platform.MAC_OS, return "Mac OS")
+ * Get the name of a platform (e.g. for Platform.MAC_OS, return "macOS")
* @param platform platform to get the name from
* @return name of the platform
*/
diff --git a/swing/src/net/sf/openrocket/file/photo/PhotoStudioGetter.java b/swing/src/net/sf/openrocket/file/photo/PhotoStudioGetter.java
index 31bea899d..41f37e796 100644
--- a/swing/src/net/sf/openrocket/file/photo/PhotoStudioGetter.java
+++ b/swing/src/net/sf/openrocket/file/photo/PhotoStudioGetter.java
@@ -135,11 +135,6 @@ public class PhotoStudioGetter {
p.setSmokeColor(smokeColor);
return;
}
- if ("smokeOpacity".equals(element)) {
- double smokeOpacity = Double.parseDouble(content);
- p.setSmokeOpacity(smokeOpacity);
- return;
- }
if ("sparks".equals(element)) {
boolean sparks = Boolean.parseBoolean(content);
p.setSparks(sparks);
diff --git a/swing/src/net/sf/openrocket/file/photo/PhotoStudioSetter.java b/swing/src/net/sf/openrocket/file/photo/PhotoStudioSetter.java
index 3fd4bd48f..b5dfec0ca 100644
--- a/swing/src/net/sf/openrocket/file/photo/PhotoStudioSetter.java
+++ b/swing/src/net/sf/openrocket/file/photo/PhotoStudioSetter.java
@@ -41,7 +41,6 @@ public class PhotoStudioSetter {
photoSettings.put("flameColor", getColor(p.getFlameColor()));
photoSettings.put("smoke", String.valueOf(p.isSmoke()));
photoSettings.put("smokeColor", getColor(p.getSmokeColor()));
- photoSettings.put("smokeOpacity", String.valueOf(p.getSmokeOpacity()));
photoSettings.put("sparks", String.valueOf(p.isSparks()));
photoSettings.put("exhaustScale", String.valueOf(p.getExhaustScale()));
photoSettings.put("flameAspectRatio", String.valueOf(p.getFlameAspectRatio()));
diff --git a/swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java b/swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java
index e5587a812..3a8cc9bcf 100644
--- a/swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java
+++ b/swing/src/net/sf/openrocket/gui/dialogs/UpdateInfoDialog.java
@@ -7,6 +7,7 @@ import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -28,6 +29,8 @@ import net.sf.openrocket.communication.AssetHandler;
import net.sf.openrocket.communication.AssetHandler.UpdatePlatform;
import net.sf.openrocket.communication.ReleaseInfo;
import net.sf.openrocket.communication.UpdateInfo;
+import net.sf.openrocket.gui.components.StyledLabel;
+import net.sf.openrocket.gui.configdialog.CommonStrings;
import net.sf.openrocket.gui.util.GUIUtil;
import net.sf.openrocket.gui.util.Icons;
import net.sf.openrocket.gui.util.SwingPreferences;
@@ -55,8 +58,19 @@ public class UpdateInfoDialog extends JDialog {
JPanel panel = new JPanel(new MigLayout("insets n n 8px n, fill"));
- panel.add(new JLabel(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket")),
- "split, span, top");
+ panel.add(new JLabel(Icons.getScaledIcon(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket"), 0.6)),
+ "spany, top, gapright 20px, cell 0 0");
+
+ // OpenRocket version available!
+ panel.add(new StyledLabel(trans.get("update.dlg.updateAvailable.lbl.title"), 8, StyledLabel.Style.BOLD), "spanx, wrap");
+
+ // Your version
+ ReleaseInfo release = info.getLatestRelease();
+ panel.add(new StyledLabel(String.format(trans.get("update.dlg.updateAvailable.lbl.yourVersion"),
+ release.getReleaseName(), BuildProperties.getVersion()), -1, StyledLabel.Style.PLAIN), "skip 1, spanx, wrap para");
+
+ // Release notes
+ panel.add(new StyledLabel(trans.get("update.dlg.updateAvailable.lbl.releaseNotes"), 1, StyledLabel.Style.BOLD), "spanx, wrap");
// Release information box
final JTextPane textPane = new JTextPane();
@@ -65,18 +79,10 @@ public class UpdateInfoDialog extends JDialog {
textPane.setMargin(new Insets(10, 10, 40, 10));
textPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true);
- ReleaseInfo release = info.getLatestRelease();
StringBuilder sb = new StringBuilder();
-
- // OpenRocket version available!
sb.append("");
- sb.append(String.format("%s
", String.format(trans.get("update.dlg.updateAvailable.txtPane.title"), release.getReleaseName())));
- // Your version
- sb.append(String.format("%s
", String.format(trans.get("update.dlg.updateAvailable.txtPane.yourVersion"), BuildProperties.getVersion())));
-
- // Changelog
- sb.append(String.format("%s
", trans.get("update.dlg.updateAvailable.txtPane.changelog")));
+ // Release notes
String releaseNotes = release.getReleaseNotes();
releaseNotes = releaseNotes.replaceAll("^\"|\"$", ""); // Remove leading and trailing quotations
sb.append(MarkdownUtil.toHtml(releaseNotes)).append("
");
@@ -103,7 +109,7 @@ public class UpdateInfoDialog extends JDialog {
textPane.setText(sb.toString());
textPane.setCaretPosition(0); // Scroll to the top
- panel.add(new JScrollPane(textPane), "left, grow, span, push, gapleft 40px, gapbottom 6px, wrap");
+ panel.add(new JScrollPane(textPane), "skip 1, left, spanx, grow, push, gapbottom 6px, wrap");
//// Check for software updates at startup
JCheckBox checkAtStartup = new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates"));
@@ -116,9 +122,36 @@ public class UpdateInfoDialog extends JDialog {
preferences.setCheckUpdates(checkAtStartup.isSelected());
}
});
- panel.add(checkAtStartup);
+ panel.add(checkAtStartup, "skip 1, spanx, wrap");
- // Install operating system combo box
+ // Lower row buttons
+ //// Remind me later button
+ JButton btnLater = new SelectColorButton("Remind Me Later");
+ btnLater.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ UpdateInfoDialog.this.dispose();
+ }
+ });
+ panel.add(btnLater, "skip 1, split 2");
+
+ //// Skip this version button
+ JButton btnSkip = new SelectColorButton("Skip This Version");
+ btnSkip.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ List ignoreVersions = new ArrayList<>(preferences.getIgnoreVersions());
+ String ignore = release.getReleaseName();
+ if (!ignoreVersions.contains(ignore)) {
+ ignoreVersions.add(ignore);
+ preferences.setIgnoreVersions(ignoreVersions);
+ }
+ UpdateInfoDialog.this.dispose();
+ }
+ });
+ panel.add(btnSkip);
+
+ //// Install operating system combo box
List assetURLs = release.getAssetURLs();
Map mappedAssets = AssetHandler.mapURLToPlatform(assetURLs);
JComboBox