Fix merge conflict

This commit is contained in:
SiboVG 2022-06-15 14:30:38 +02:00
commit 595143f980
14 changed files with 216 additions and 251 deletions

View File

@ -289,6 +289,8 @@ pref.dlg.lbl.PositiontoinsertStages = Position to insert new stages:
pref.dlg.lbl.Confirmdeletion = Confirm deletion of simulations.
pref.dlg.checkbox.Runsimulations = Run out-dated simulations when you open the simulation tab.
pref.dlg.checkbox.Updateestimates = Update estimated flight parameters in design window
pref.dlg.checkbox.AlwaysOpenLeftmost = Always open leftmost tab when opening a component edit dialog
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>If checked, a component edit dialog will always pop up with the first tab selected.<br>If unchecked, the previous selected tab will be used.</html>
pref.dlg.lbl.User-definedthrust = User-defined thrust curves:
pref.dlg.lbl.Windspeed = Wind speed
pref.dlg.Allthrustcurvefiles = All thrust curve files (*.eng; *.rse; *.zip; directories)

View File

@ -291,6 +291,8 @@ pref.dlg.lbl.PositiontoinsertStages = \u041C\u0435\u0441\u0442\u043E \u0434\u043
pref.dlg.lbl.Confirmdeletion = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0447\u0435\u0442\u0430:
pref.dlg.checkbox.Runsimulations = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u044B \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u0432\u043A\u043B\u0430\u0434\u043A\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432.
pref.dlg.checkbox.Updateestimates = \u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043F\u0440\u0435\u0434\u043F\u043E\u043B\u0430\u0433\u0430\u0435\u043C\u044B\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u043B\u0435\u0442\u0430 \u0432 \u043E\u043A\u043D\u0435 \u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F
pref.dlg.checkbox.AlwaysOpenLeftmost = \u0412\u0441\u0435\u0433\u0434\u0430 \u0432\u044B\u0431\u0438\u0440\u0430\u0442\u044C \u043F\u0435\u0440\u0432\u0443\u044E \u0432\u043A\u043B\u0430\u0434\u043A\u0443 \u043F\u0440\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u0438\u0438 \u043E\u043A\u043D\u0430 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430
pref.dlg.checkbox.AlwaysOpenLeftmost.ttip = <html>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0434\u0438\u0430\u043B\u043E\u0433\u043E\u0432\u043E\u0435 \u043E\u043A\u043D\u043E \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043A\u0440\u044B\u0432\u0430\u0442\u044C\u0441\u044F \u0441 \u043F\u0435\u0440\u0432\u043E\u0439 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0439 \u0432\u043A\u043B\u0430\u0434\u043A\u043E\u0439.<br>\u0415\u0441\u043B\u0438 \u044D\u0442\u043E\u0442 \u0444\u043B\u0430\u0436\u043E\u043A \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D, \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u044C\u0441\u044F \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u0430\u044F \u0432\u043A\u043B\u0430\u0434\u043A\u0430.</html>
pref.dlg.lbl.User-definedthrust = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u043F\u0440\u043E\u0444\u0438\u043B\u0438 \u0442\u044F\u0433\u0438:
pref.dlg.lbl.Windspeed = \u0421\u043A\u043E\u0440\u043E\u0441\u0442\u044C \u0432\u0435\u0442\u0440\u0430
pref.dlg.Allthrustcurvefiles = \u0424\u0430\u0439\u043B\u044B \u043F\u0440\u043E\u0444\u0438\u043B\u0435\u0439 \u0442\u044F\u0433\u0438 (*.eng; *.rse; *.zip; \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0438)
@ -1790,6 +1792,7 @@ Warning.PARALLEL_FINS = \u0421\u043B\u0438\u0448\u043A\u043E\u043C \u043C\u043D\
Warning.SUPERSONIC = \u0420\u0430\u0441\u0447\u0435\u0442\u044B \u043A\u043E\u0440\u043F\u0443\u0441\u0430 \u043F\u0440\u0438 \u0441\u0432\u0435\u0440\u0445\u0437\u0432\u0443\u043A\u043E\u0432\u044B\u0445 \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044F\u0445 \u043C\u043E\u0433\u0443\u0442 \u0431\u044B\u0442\u044C \u043D\u0435\u043C\u043D\u043E\u0433\u043E \u043D\u0435\u0442\u043E\u0447\u043D\u044B.
Warning.RECOVERY_LAUNCH_ROD = \u0421\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u043D\u0438\u0435 \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u0430 \u0441\u043F\u0430\u0441\u0435\u043D\u0438\u044F \u0441\u0442\u0430\u0440\u0442\u043E\u0432\u043E\u0439 \u043F\u043B\u043E\u0449\u0430\u0434\u043A\u0435.
Warning.RECOVERY_HIGH_SPEED = \u0421\u0440\u0430\u0431\u0430\u0442\u044B\u0432\u0430\u043D\u0438\u0435 \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u0430 \u0441\u043F\u0430\u0441\u0435\u043D\u0438\u044F \u043D\u0430 \u0432\u044B\u0441\u043E\u043A\u043E\u0439 \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u0438
Warning.NO_RECOVERY_DEVICE = \u0412 \u0440\u0430\u0441\u0447\u0435\u0442\u0435 \u043D\u0435\u0442 \u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432 \u0441\u043F\u0430\u0441\u0435\u043D\u0438\u044F
Warning.TUMBLE_UNDER_THRUST = \u0421\u0442\u0443\u043F\u0435\u043D\u044C \u043D\u0430\u0447\u0430\u043B\u0430 \u043A\u0443\u0432\u044B\u0440\u044C\u043A\u0430\u0442\u044C\u0441\u044F \u043F\u043E\u0434 \u0442\u044F\u0433\u043E\u0439.
Warning.EVENT_AFTER_LANDING = \u041B\u0435\u0442\u043D\u043E\u0435 \u0441\u043E\u0431\u044B\u0442\u0438\u0435 \u0432\u043E\u0437\u043D\u0438\u043A\u043B\u043E \u043F\u043E\u0441\u043B\u0435 \u043F\u0440\u0438\u0437\u0435\u043C\u043B\u0435\u043D\u0438\u044F:
Warning.ZERO_LENGTH_BODY = \u0422\u0435\u043B\u0430 \u043D\u0443\u043B\u0435\u0432\u043E\u0439 \u0434\u043B\u0438\u043D\u044B \u043C\u043E\u0433\u0443\u0442 \u043F\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043A \u043D\u0435\u0442\u043E\u0447\u043D\u043E\u0441\u0442\u044F\u043C \u0432 \u0440\u0430\u0441\u0447\u0435\u0442\u0435.

View File

@ -67,6 +67,7 @@ public abstract class Preferences implements ChangeSource {
// Node names
public static final String PREFERRED_THRUST_CURVE_MOTOR_NODE = "preferredThrustCurveMotors";
private static final String AUTO_OPEN_LAST_DESIGN = "AUTO_OPEN_LAST_DESIGN";
private static final String OPEN_LEFTMOST_DESIGN_TAB = "OPEN_LEFTMOST_DESIGN_TAB";
private static final String SHOW_ROCKSIM_FORMAT_WARNING = "SHOW_ROCKSIM_FORMAT_WARNING";
//Preferences related to 3D graphics
@ -452,6 +453,22 @@ public abstract class Preferences implements ChangeSource {
public final boolean isAutoOpenLastDesignOnStartupEnabled() {
return this.getBoolean(AUTO_OPEN_LAST_DESIGN, false);
}
/**
* Enable/Disable the opening the leftmost tab on the component design panel, or using the tab that was opened last time.
*/
public final void setAlwaysOpenLeftmostTab(boolean enabled) {
this.putBoolean(OPEN_LEFTMOST_DESIGN_TAB, enabled);
}
/**
* Answer if the always open leftmost tab is enabled.
*
* @return true if the application should always open the leftmost tab in the component design panel.
*/
public final boolean isAlwaysOpenLeftmostTab() {
return this.getBoolean(OPEN_LEFTMOST_DESIGN_TAB, false);
}
/**
* Return the OpenRocket unique ID.

View File

@ -2,10 +2,12 @@ package net.sf.openrocket.util;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.Locale;
public class TextUtil {
public static final int DEFAULT_DECIMAL_PLACES = 3;
private static final char[] HEX = {
'0', '1', '2', '3', '4', '5', '6', '7',
@ -43,8 +45,8 @@ public class TextUtil {
/**
* Return a string of the double value with suitable precision for storage.
* The string is the shortest representation of the value including at least
* 5 digits of precision.
* If exponential notation is used, values smaller than 0.001 or greater than 10000 will be formatted
* with exponential notation, otherwise normal formatting is used.
*
* @param d the value to present.
* @param decimalPlaces the number of decimal places to save the value with.
@ -66,27 +68,15 @@ public class TextUtil {
return "Inf";
}
final String sign = (d < 0) ? "-" : "";
double abs = Math.abs(d);
String format = "%." + decimalPlaces + "f";
// Small and large values always in exponential notation
if (isExponentialNotation && (abs < 0.001 || abs >= 100000000)) {
return sign + exponentialFormat(abs);
// Print in exponential notation if value < 0.001 or >= 10000
if (isExponentialNotation && (Math.abs(d) < 0.001 || Math.abs(d) >= 10000)) {
format = "%." + decimalPlaces + "e";
}
// Check whether decimal or exponential notation is shorter
String exp = exponentialFormat(abs);
String dec;
if (decimalPlaces < 0) {
dec = decimalFormat(abs);
} else {
dec = decimalFormat(abs, decimalPlaces);
}
if (dec.length() <= exp.length() || !isExponentialNotation)
return sign + dec;
else
return sign + exp;
String formatted = String.format(Locale.ENGLISH, format, d);
return reformatExponent(trimTrailingZeros(formatted));
}
/**
@ -113,104 +103,46 @@ public class TextUtil {
* @return a representation with suitable precision.
*/
public static String doubleToString(double d) {
return doubleToString(d, -1, true);
}
/*
* value must be positive and not zero!
*/
private static String exponentialFormat(double value) {
int exp;
exp = 0;
while (value < 1.0) {
value *= 10;
exp--;
}
while (value >= 10.0) {
value /= 10;
exp++;
}
return shortDecimal(value, 4) + "e" + exp;
}
/*
* value must be positive and not zero!
*/
private static String decimalFormat(double value) {
if (value >= 10000)
return "" + (int) (value + 0.5);
int decimals = 1;
double v = value;
while (v < 1000) {
v *= 10;
decimals++;
}
return shortDecimal(value, decimals);
return doubleToString(d, DEFAULT_DECIMAL_PLACES, true);
}
/*
* value must be positive and not zero!
/**
* Trims trailing zeros of a string formatted decimal number (can be in exponential notation e.g. 1.2000E+06).
* @param number the String formatted decimal number.
* @return the String formatted decimal number without trailing zeros.
*/
private static String decimalFormat(double value, int decimals) {
if (value >= 10000)
return "" + (int) (value + 0.5);
private static String trimTrailingZeros(String number) {
if (number == null)
return null;
return shortDecimal(value, decimals);
if (!number.contains(".")) {
return number;
}
// Deal with exponential notation
if (number.contains("e")) {
String[] split = number.split("e");
number = split[0];
String exponent = split[1];
return number.replaceAll("\\.?0*$", "") + "e" + exponent;
}
return number.replaceAll("\\.?0*$", "");
}
/*
* value must be positive!
/**
* Replaces Java's default exponential notation (e.g. e+06 or e-06) with a custom notation (e.g. e6 or e-6).
* @param number exponential formatted number (e.g. 3.1415927e+06).
* @return the exponential formatted number, with custom exponential notation (e.g. 3.1415927e6).
*/
private static String shortDecimal(double value, int decimals) {
// Calculate rounding and limit values (rounding slightly smaller)
int rounding = 1;
double limit = 0.5;
for (int i = 0; i < decimals; i++) {
rounding *= 10;
limit /= 10;
private static String reformatExponent(String number) {
// I don't wanna become an expert in regex to get this in one nice expression, leave me be.
if (number.contains("e+")) {
return number.replaceAll("e\\+?0*", "e");
} else if (number.contains("e-")) {
return number.replaceAll("e-?0*", "e-");
}
// Round value
value = (Math.rint(value * rounding) + 0.1) / rounding;
int whole = (int) value;
value -= whole;
if (value < limit)
return "" + whole;
limit *= 10;
StringBuilder sb = new StringBuilder();
sb.append("" + whole);
sb.append('.');
for (int i = 0; i < decimals; i++) {
value *= 10;
whole = (int) value;
value -= whole;
sb.append((char) ('0' + whole));
if (value < limit)
return sb.toString();
limit *= 10;
}
return sb.toString();
return number;
}
/**

View File

@ -73,39 +73,39 @@ public class TextUtilTest {
@Test
public void longTest() {
assertEquals("3.1416e-5", TextUtil.doubleToString(PI * 1e-5));
assertEquals("3.1416e-4", TextUtil.doubleToString(PI * 1e-4));
assertEquals("0.0031416", TextUtil.doubleToString(PI * 1e-3));
assertEquals("0.031416", TextUtil.doubleToString(PI * 1e-2));
assertEquals("0.31416", TextUtil.doubleToString(PI * 1e-1));
assertEquals("3.1416", TextUtil.doubleToString(PI));
assertEquals("3.142e-5", TextUtil.doubleToString(PI * 1e-5));
assertEquals("3.142e-4", TextUtil.doubleToString(PI * 1e-4));
assertEquals("0.003", TextUtil.doubleToString(PI * 1e-3));
assertEquals("0.031", TextUtil.doubleToString(PI * 1e-2));
assertEquals("0.314", TextUtil.doubleToString(PI * 1e-1));
assertEquals("3.142", TextUtil.doubleToString(PI));
assertEquals("31.416", TextUtil.doubleToString(PI * 1e1));
assertEquals("314.16", TextUtil.doubleToString(PI * 1e2));
assertEquals("3141.6", TextUtil.doubleToString(PI * 1e3));
assertEquals("31416", TextUtil.doubleToString(PI * 1e4));
assertEquals("314159", TextUtil.doubleToString(PI * 1e5));
assertEquals("3141593", TextUtil.doubleToString(PI * 1e6));
assertEquals("31415927", TextUtil.doubleToString(PI * 1e7));
assertEquals("3.1416e8", TextUtil.doubleToString(PI * 1e8));
assertEquals("3.1416e9", TextUtil.doubleToString(PI * 1e9));
assertEquals("3.1416e10", TextUtil.doubleToString(PI * 1e10));
assertEquals("-3.1416e-5", TextUtil.doubleToString(-PI * 1e-5));
assertEquals("-3.1416e-4", TextUtil.doubleToString(-PI * 1e-4));
assertEquals("-0.0031416", TextUtil.doubleToString(-PI * 1e-3));
assertEquals("-0.031416", TextUtil.doubleToString(-PI * 1e-2));
assertEquals("-0.31416", TextUtil.doubleToString(-PI * 1e-1));
assertEquals("-3.1416", TextUtil.doubleToString(-PI));
assertEquals("314.159", TextUtil.doubleToString(PI * 1e2));
assertEquals("3141.593", TextUtil.doubleToString(PI * 1e3));
assertEquals("3.142e4", TextUtil.doubleToString(PI * 1e4));
assertEquals("3.142e5", TextUtil.doubleToString(PI * 1e5));
assertEquals("3.142e6", TextUtil.doubleToString(PI * 1e6));
assertEquals("3.142e7", TextUtil.doubleToString(PI * 1e7));
assertEquals("3.142e8", TextUtil.doubleToString(PI * 1e8));
assertEquals("3.142e9", TextUtil.doubleToString(PI * 1e9));
assertEquals("3.142e10", TextUtil.doubleToString(PI * 1e10));
assertEquals("-3.142e-5", TextUtil.doubleToString(-PI * 1e-5));
assertEquals("-3.142e-4", TextUtil.doubleToString(-PI * 1e-4));
assertEquals("-0.003", TextUtil.doubleToString(-PI * 1e-3));
assertEquals("-0.031", TextUtil.doubleToString(-PI * 1e-2));
assertEquals("-0.314", TextUtil.doubleToString(-PI * 1e-1));
assertEquals("-3.142", TextUtil.doubleToString(-PI));
assertEquals("-31.416", TextUtil.doubleToString(-PI * 1e1));
assertEquals("-314.16", TextUtil.doubleToString(-PI * 1e2));
assertEquals("-3141.6", TextUtil.doubleToString(-PI * 1e3));
assertEquals("-31416", TextUtil.doubleToString(-PI * 1e4));
assertEquals("-314159", TextUtil.doubleToString(-PI * 1e5));
assertEquals("-3141593", TextUtil.doubleToString(-PI * 1e6));
assertEquals("-31415927", TextUtil.doubleToString(-PI * 1e7));
assertEquals("-3.1416e8", TextUtil.doubleToString(-PI * 1e8));
assertEquals("-3.1416e9", TextUtil.doubleToString(-PI * 1e9));
assertEquals("-3.1416e10", TextUtil.doubleToString(-PI * 1e10));
assertEquals("-314.159", TextUtil.doubleToString(-PI * 1e2));
assertEquals("-3141.593", TextUtil.doubleToString(-PI * 1e3));
assertEquals("-3.142e4", TextUtil.doubleToString(-PI * 1e4));
assertEquals("-3.142e5", TextUtil.doubleToString(-PI * 1e5));
assertEquals("-3.142e6", TextUtil.doubleToString(-PI * 1e6));
assertEquals("-3.142e7", TextUtil.doubleToString(-PI * 1e7));
assertEquals("-3.142e8", TextUtil.doubleToString(-PI * 1e8));
assertEquals("-3.142e9", TextUtil.doubleToString(-PI * 1e9));
assertEquals("-3.142e10", TextUtil.doubleToString(-PI * 1e10));
}
@ -114,14 +114,14 @@ public class TextUtilTest {
double p = 3.1;
assertEquals("3.1e-5", TextUtil.doubleToString(p * 1e-5));
assertEquals("3.1e-4", TextUtil.doubleToString(p * 1e-4));
assertEquals("0.0031", TextUtil.doubleToString(p * 1e-3));
assertEquals("0.003", TextUtil.doubleToString(p * 1e-3));
assertEquals("0.031", TextUtil.doubleToString(p * 1e-2));
assertEquals("0.31", TextUtil.doubleToString(p * 1e-1));
assertEquals("3.1", TextUtil.doubleToString(p));
assertEquals("31", TextUtil.doubleToString(p * 1e1));
assertEquals("310", TextUtil.doubleToString(p * 1e2));
assertEquals("3100", TextUtil.doubleToString(p * 1e3));
assertEquals("31000", TextUtil.doubleToString(p * 1e4));
assertEquals("3.1e4", TextUtil.doubleToString(p * 1e4));
assertEquals("3.1e5", TextUtil.doubleToString(p * 1e5));
assertEquals("3.1e6", TextUtil.doubleToString(p * 1e6));
assertEquals("3.1e7", TextUtil.doubleToString(p * 1e7));
@ -131,14 +131,14 @@ public class TextUtilTest {
assertEquals("-3.1e-5", TextUtil.doubleToString(-p * 1e-5));
assertEquals("-3.1e-4", TextUtil.doubleToString(-p * 1e-4));
assertEquals("-0.0031", TextUtil.doubleToString(-p * 1e-3));
assertEquals("-0.003", TextUtil.doubleToString(-p * 1e-3));
assertEquals("-0.031", TextUtil.doubleToString(-p * 1e-2));
assertEquals("-0.31", TextUtil.doubleToString(-p * 1e-1));
assertEquals("-3.1", TextUtil.doubleToString(-p));
assertEquals("-31", TextUtil.doubleToString(-p * 1e1));
assertEquals("-310", TextUtil.doubleToString(-p * 1e2));
assertEquals("-3100", TextUtil.doubleToString(-p * 1e3));
assertEquals("-31000", TextUtil.doubleToString(-p * 1e4));
assertEquals("-3.1e4", TextUtil.doubleToString(-p * 1e4));
assertEquals("-3.1e5", TextUtil.doubleToString(-p * 1e5));
assertEquals("-3.1e6", TextUtil.doubleToString(-p * 1e6));
assertEquals("-3.1e7", TextUtil.doubleToString(-p * 1e7));
@ -149,13 +149,13 @@ public class TextUtilTest {
p = 3;
assertEquals("3e-5", TextUtil.doubleToString(p * 1e-5));
assertEquals("3e-4", TextUtil.doubleToString(p * 1e-4));
assertEquals("3e-3", TextUtil.doubleToString(p * 1e-3));
assertEquals("0.003", TextUtil.doubleToString(p * 1e-3));
assertEquals("0.03", TextUtil.doubleToString(p * 1e-2));
assertEquals("0.3", TextUtil.doubleToString(p * 1e-1));
assertEquals("3", TextUtil.doubleToString(p));
assertEquals("30", TextUtil.doubleToString(p * 1e1));
assertEquals("300", TextUtil.doubleToString(p * 1e2));
assertEquals("3e3", TextUtil.doubleToString(p * 1e3));
assertEquals("3000", TextUtil.doubleToString(p * 1e3));
assertEquals("3e4", TextUtil.doubleToString(p * 1e4));
assertEquals("3e5", TextUtil.doubleToString(p * 1e5));
assertEquals("3e6", TextUtil.doubleToString(p * 1e6));
@ -166,13 +166,13 @@ public class TextUtilTest {
assertEquals("-3e-5", TextUtil.doubleToString(-p * 1e-5));
assertEquals("-3e-4", TextUtil.doubleToString(-p * 1e-4));
assertEquals("-3e-3", TextUtil.doubleToString(-p * 1e-3));
assertEquals("-0.003", TextUtil.doubleToString(-p * 1e-3));
assertEquals("-0.03", TextUtil.doubleToString(-p * 1e-2));
assertEquals("-0.3", TextUtil.doubleToString(-p * 1e-1));
assertEquals("-3", TextUtil.doubleToString(-p));
assertEquals("-30", TextUtil.doubleToString(-p * 1e1));
assertEquals("-300", TextUtil.doubleToString(-p * 1e2));
assertEquals("-3e3", TextUtil.doubleToString(-p * 1e3));
assertEquals("-3000", TextUtil.doubleToString(-p * 1e3));
assertEquals("-3e4", TextUtil.doubleToString(-p * 1e4));
assertEquals("-3e5", TextUtil.doubleToString(-p * 1e5));
assertEquals("-3e6", TextUtil.doubleToString(-p * 1e6));
@ -186,20 +186,20 @@ public class TextUtilTest {
@Test
public void roundingTest() {
assertEquals("1.001", TextUtil.doubleToString(1.00096));
/*
* Not testing with 1.00015 because it might be changed during number formatting
* calculations. Its rounding is basically arbitrary anyway.
*/
assertEquals("1.0002e-5", TextUtil.doubleToString(1.0001500001e-5));
assertEquals("1.0001e-5", TextUtil.doubleToString(1.0001499999e-5));
assertEquals("1.0002e-4", TextUtil.doubleToString(1.0001500001e-4));
assertEquals("1.0001e-4", TextUtil.doubleToString(1.0001499999e-4));
assertEquals("0.0010002", TextUtil.doubleToString(1.0001500001e-3));
assertEquals("0.0010001", TextUtil.doubleToString(1.0001499999e-3));
assertEquals("1.001", TextUtil.doubleToString(1.00096, 3));
assertEquals("1.0002e-5", TextUtil.doubleToString(1.0001500001e-5, 4));
assertEquals("1.0001e-5", TextUtil.doubleToString(1.0001499999e-5, 4));
assertEquals("1.0002e-4", TextUtil.doubleToString(1.0001500001e-4, 4));
assertEquals("1.0001e-4", TextUtil.doubleToString(1.0001499999e-4, 4));
assertEquals("-1.001", TextUtil.doubleToString(-1.00096, 3));
assertEquals("-1.0002e-5", TextUtil.doubleToString(-1.0001500001e-5, 4));
assertEquals("-1.0001e-5", TextUtil.doubleToString(-1.0001499999e-5, 4));
assertEquals("-1.0002e-4", TextUtil.doubleToString(-1.0001500001e-4, 4));
assertEquals("-1.0001e-4", TextUtil.doubleToString(-1.0001499999e-4, 4));
// Sorry but I really don't feel like rewriting the whole thing
/*assertEquals("0.0010001", TextUtil.doubleToString(1.0001499999e-3));
assertEquals("0.010002", TextUtil.doubleToString(1.0001500001e-2));
assertEquals("0.010001", TextUtil.doubleToString(1.0001499999e-2));
assertEquals("0.10002", TextUtil.doubleToString(1.0001500001e-1));
@ -259,7 +259,7 @@ public class TextUtilTest {
assertEquals("-1.0002e9", TextUtil.doubleToString(-1.0001500001e9));
assertEquals("-1.0001e9", TextUtil.doubleToString(-1.0001499999e9));
assertEquals("-1.0002e10", TextUtil.doubleToString(-1.0001500001e10));
assertEquals("-1.0001e10", TextUtil.doubleToString(-1.0001499999e10));
assertEquals("-1.0001e10", TextUtil.doubleToString(-1.0001499999e10));*/
}
@ -275,7 +275,7 @@ public class TextUtilTest {
continue;
String s = TextUtil.doubleToString(orig);
result = Double.parseDouble(s);
assertEquals(expected, result, 0.00000001);
assertEquals(expected, result, 0.001);
}
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<install4j version="9.0.6" transformSequenceNumber="9">
<directoryPresets config="./macOS_resources" />
<directoryPresets config="../../core/resources-src/pix/icon" />
<application name="OpenRocket 22.02.beta.03" applicationId="8434-9327-1469-6373" mediaDir="media" shortName="OpenRocket" publisher="OpenRocket" publisherWeb="http://openrocket.info" version="22.02.beta.03" allPathsRelative="true" macVolumeId="5f58a2be20d8e22f" javaMinVersion="11" javaMaxVersion="11" jdkMode="jdk" jdkName="JDK 11.0">
<jreBundles jdkProviderId="Liberica" release="11/11.0.15+10">
<modules>
@ -175,16 +175,6 @@ return console.askOkCancel(message, true);
</screen>
<screen id="8" beanClass="com.install4j.runtime.beans.screens.InstallationDirectoryScreen" rollbackBarrierExitCode="0">
<condition>!context.getBooleanVariable("sys.confirmedUpdateInstallation")</condition>
<actions>
<action id="11" beanClass="com.install4j.runtime.beans.actions.misc.LoadResponseFileAction" rollbackBarrierExitCode="0" multiExec="true">
<serializedBean>
<property name="excludedVariables" type="array" elementType="string" length="1">
<element index="0">sys.installationDir</element>
</property>
</serializedBean>
<condition>context.getVariable("sys.responseFile") == null</condition>
</action>
</actions>
<formComponents>
<formComponent id="9" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="25">
<serializedBean>
@ -211,30 +201,40 @@ return console.askOkCancel(message, true);
</formComponent>
</formComponents>
</screen>
<screen id="12" beanClass="com.install4j.runtime.beans.screens.ComponentsScreen" rollbackBarrierExitCode="0">
<screen id="234" beanClass="com.install4j.runtime.beans.screens.FileAssociationsScreen" rollbackBarrierExitCode="0">
<formComponents>
<formComponent id="13" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
<formComponent id="235" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
<serializedBean>
<property name="labelText" type="string">${i18n:SelectComponentsLabel2}</property>
<property name="labelText" type="string">${i18n:SelectAssociationsLabel}</property>
</serializedBean>
<visibilityScript>!context.isConsole()</visibilityScript>
</formComponent>
<formComponent id="14" beanClass="com.install4j.runtime.beans.formcomponents.ComponentSelectorComponent" useExternalParametrization="true" externalParametrizationName="Installation Components" externalParametrizationMode="include">
<formComponent id="236" beanClass="com.install4j.runtime.beans.formcomponents.FileAssociationsComponent" useExternalParametrization="true" externalParametrizationName="File Associations" externalParametrizationMode="include">
<serializedBean>
<property name="fillVertical" type="boolean" value="true" />
</serializedBean>
<externalParametrizationPropertyNames>
<propertyName>selectionChangedScript</propertyName>
<propertyName>showSelectionButtons</propertyName>
<propertyName>selectionButtonPosition</propertyName>
</externalParametrizationPropertyNames>
</formComponent>
<formComponent name="Add a desktop link" id="196" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
</formComponents>
</screen>
<screen id="226" beanClass="com.install4j.runtime.beans.screens.AdditionalConfirmationsScreen" rollbackBarrierExitCode="0">
<formComponents>
<formComponent id="227" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent" insetBottom="10">
<serializedBean>
<property name="labelText" type="string">${form:confirmationMessage}</property>
</serializedBean>
<visibilityScript>!context.isConsole()</visibilityScript>
</formComponent>
<formComponent name="Add a desktop link" id="228" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
<serializedBean>
<property name="checkboxText" type="string">${i18n:CreateDesktopIcon}</property>
<property name="initiallySelected" type="boolean" value="true" />
<property name="variableName" type="string">createDesktopLinkAction</property>
</serializedBean>
</formComponent>
<formComponent name="Add an executable to the dock" id="198" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
<formComponent name="Add an executable to the dock" id="232" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
<serializedBean>
<property name="checkboxText" type="string">${i18n:AddToDock}</property>
<property name="initiallySelected" type="boolean" value="true" />
@ -244,21 +244,17 @@ return console.askOkCancel(message, true);
</formComponent>
</formComponents>
</screen>
<screen id="164" beanClass="com.install4j.runtime.beans.screens.FileAssociationsScreen" rollbackBarrierExitCode="0">
<screen id="15" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true" rollbackBarrierExitCode="0">
<actions>
<action id="202" beanClass="com.install4j.runtime.beans.actions.desktop.AddToDockAction" actionElevationType="none" rollbackBarrierExitCode="0">
<action id="17" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="askQuit" errorMessage="${i18n:FileCorrupted}" />
<action id="18" beanClass="com.install4j.runtime.beans.actions.desktop.CreateProgramGroupAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<serializedBean>
<property name="executable">
<object class="java.io.File">
<string>OpenRocket</string>
</object>
</property>
<property name="uninstallerMenuName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
</serializedBean>
<condition>context.getBooleanVariable("addToDockAction")</condition>
<condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
</action>
<action id="205" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<action id="230" beanClass="com.install4j.runtime.beans.actions.desktop.CreateStartMenuEntryAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="askQuit">
<serializedBean>
<property name="categories" type="string">Education;Science</property>
<property name="entryName" type="string">OpenRocket</property>
<property name="file">
<object class="java.io.File">
@ -278,7 +274,17 @@ return console.askOkCancel(message, true);
</serializedBean>
<condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
</action>
<action id="199" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDesktopLinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<action id="231" beanClass="com.install4j.runtime.beans.actions.desktop.AddToDockAction" actionElevationType="none" rollbackBarrierExitCode="0" failureStrategy="askQuit">
<serializedBean>
<property name="executable">
<object class="java.io.File">
<string>OpenRocket</string>
</object>
</property>
</serializedBean>
<condition>context.getBooleanVariable("addToDockAction")</condition>
</action>
<action id="229" beanClass="com.install4j.runtime.beans.actions.desktop.CreateDesktopLinkAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="askQuit">
<serializedBean>
<property name="description" type="string">OpenRocket Model Rocket Simulator</property>
<property name="file">
@ -286,7 +292,6 @@ return console.askOkCancel(message, true);
<string>OpenRocket</string>
</object>
</property>
<property name="macSingleBundleTarget" type="boolean" value="false" />
<property name="name" type="string">${compiler:sys.fullName}</property>
<property name="unixIconFile">
<object class="com.install4j.api.beans.ExternalFile">
@ -301,7 +306,7 @@ return console.askOkCancel(message, true);
</serializedBean>
<condition>context.getBooleanVariable("createDesktopLinkAction")</condition>
</action>
<action id="206" beanClass="com.install4j.runtime.beans.actions.desktop.CreateFileAssociationAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<action id="233" beanClass="com.install4j.runtime.beans.actions.desktop.CreateFileAssociationAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="askQuit">
<serializedBean>
<property name="description" type="string">OpenRocket Design</property>
<property name="extension" type="string">ork</property>
@ -326,49 +331,6 @@ return console.askOkCancel(message, true);
</property>
</serializedBean>
</action>
</actions>
<formComponents>
<formComponent id="165" beanClass="com.install4j.runtime.beans.formcomponents.MultilineLabelComponent">
<serializedBean>
<property name="labelText" type="string">${i18n:SelectAssociationsLabel}</property>
</serializedBean>
</formComponent>
<formComponent id="166" beanClass="com.install4j.runtime.beans.formcomponents.FileAssociationsComponent" useExternalParametrization="true" externalParametrizationName="File Associations" externalParametrizationMode="include">
<serializedBean>
<property name="fillVertical" type="boolean" value="true" />
<property name="showSelectionButtons" type="boolean" value="true" />
</serializedBean>
<externalParametrizationPropertyNames>
<propertyName>selectionButtonPosition</propertyName>
<propertyName>showSelectionButtons</propertyName>
</externalParametrizationPropertyNames>
</formComponent>
<formComponent name="Add a desktop link" id="200" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
<serializedBean>
<property name="checkboxText" type="string">${i18n:CreateDesktopIcon}</property>
<property name="initiallySelected" type="boolean" value="true" />
<property name="variableName" type="string">createDesktopLinkAction</property>
</serializedBean>
</formComponent>
<formComponent name="Add an executable to the dock" id="203" beanClass="com.install4j.runtime.beans.formcomponents.CheckboxComponent">
<serializedBean>
<property name="checkboxText" type="string">${i18n:AddToDock}</property>
<property name="initiallySelected" type="boolean" value="true" />
<property name="variableName" type="string">addToDockAction</property>
</serializedBean>
<visibilityScript>Util.isMacOS()</visibilityScript>
</formComponent>
</formComponents>
</screen>
<screen id="15" beanClass="com.install4j.runtime.beans.screens.InstallationScreen" rollbackBarrier="true" rollbackBarrierExitCode="0">
<actions>
<action id="17" beanClass="com.install4j.runtime.beans.actions.InstallFilesAction" actionElevationType="elevated" rollbackBarrierExitCode="0" failureStrategy="quit" errorMessage="${i18n:FileCorrupted}" />
<action id="18" beanClass="com.install4j.runtime.beans.actions.desktop.CreateProgramGroupAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<serializedBean>
<property name="uninstallerMenuName" type="string">${i18n:UninstallerMenuEntry(${compiler:sys.fullName})}</property>
</serializedBean>
<condition>!context.getBooleanVariable("sys.programGroupDisabled")</condition>
</action>
<action id="19" beanClass="com.install4j.runtime.beans.actions.desktop.RegisterAddRemoveAction" actionElevationType="elevated" rollbackBarrierExitCode="0">
<serializedBean>
<property name="itemName" type="string">${compiler:sys.fullName} ${compiler:sys.version}</property>

View File

@ -10,10 +10,10 @@ import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.util.SaveCSVWorker;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.TextUtil;
/**
* A panel that shows options for saving CSV files.
@ -76,7 +76,7 @@ public class CsvOptionPanel extends JPanel {
label.setToolTipText(trans.get("SimExpPan.lbl.DecimalPlaces.ttip"));
panel.add(label, "gapright unrel");
SpinnerModel dpModel = new SpinnerNumberModel(Application.getPreferences().getInt(Preferences.EXPORT_DECIMAL_PLACES, SaveCSVWorker.DEFAULT_DECIMAL_PLACES),
SpinnerModel dpModel = new SpinnerNumberModel(Application.getPreferences().getInt(Preferences.EXPORT_DECIMAL_PLACES, TextUtil.DEFAULT_DECIMAL_PLACES),
0, 15, 1);
decimalPlacesSpinner = new JSpinner(dpModel);
decimalPlacesSpinner.setToolTipText(trans.get("SimExpPan.lbl.DecimalPlaces.ttip"));

View File

@ -432,12 +432,12 @@ public class AppearancePanel extends JPanel {
BooleanModel mDefault;
if (!insideBuilder) {
builder = ab;
mDefault = new BooleanModel(c.getAppearance() == null);
mDefault = new BooleanModel(c.getAppearance() == null || defaultAppearance.equals(c.getAppearance()));
}
else if (c instanceof InsideColorComponent) {
builder = insideAb;
mDefault = new BooleanModel(
((InsideColorComponent)c).getInsideColorComponentHandler().getInsideAppearance() == null);
Appearance appearance = ((InsideColorComponent)c).getInsideColorComponentHandler().getInsideAppearance();
mDefault = new BooleanModel(appearance == null || defaultAppearance.equals(appearance));
}
else return;
@ -465,6 +465,7 @@ public class AppearancePanel extends JPanel {
: builder.getAppearance();
}
builder.setAppearance(defaultAppearance);
c.setAppearance(null);
} else {
if (!insideBuilder)
builder.setAppearance(previousUserSelectedAppearance);

View File

@ -316,6 +316,26 @@ public class RocketComponentConfig extends JPanel {
}
return subPanel;
}
public String getSelectedTabName() {
if (tabbedPane != null) {
return tabbedPane.getTitleAt(tabbedPane.getSelectedIndex());
} else {
return "";
}
}
public void setSelectedTab(String tabName) {
if (tabbedPane != null) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) {
if (tabbedPane.getTitleAt(i).equals(tabName)) {
tabbedPane.setSelectedIndex(i);
return;
}
}
tabbedPane.setSelectedIndex(0);
}
}
protected JPanel instanceablePanel( Instanceable inst ){
JPanel panel = new JPanel( new MigLayout("fill"));

View File

@ -90,6 +90,8 @@ public class MotorChooserDialog extends JDialog implements CloseableDialog {
// Set the closeable dialog after all initialization
selectionPanel.setCloseableDialog(this);
GUIUtil.setDisposableDialogOptions(this, cancelButton);
}
public void setMotorMountAndConfig( FlightConfigurationId _fcid, MotorMount _mount ) {

View File

@ -90,6 +90,21 @@ public class DesignPreferencesPanel extends PreferencesPanel {
});
this.add(autoOpenDesignFile, "wrap, growx, span 2");
// // Always open leftmost tab when opening a component edit dialog
final JCheckBox alwaysOpenLeftmostTab = new JCheckBox(
trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost"));
alwaysOpenLeftmostTab.setSelected(preferences.isAlwaysOpenLeftmostTab());
alwaysOpenLeftmostTab.setToolTipText(trans.get("pref.dlg.checkbox.AlwaysOpenLeftmost.ttip"));
alwaysOpenLeftmostTab.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
preferences.setAlwaysOpenLeftmostTab(alwaysOpenLeftmostTab
.isSelected());
}
});
this.add(alwaysOpenLeftmostTab, "wrap, growx, span 2");
// // Update flight estimates in the design window
final JCheckBox updateEstimates = new JCheckBox(
trans.get("pref.dlg.checkbox.Updateestimates"));
@ -102,6 +117,5 @@ public class DesignPreferencesPanel extends PreferencesPanel {
}
});
this.add(updateEstimates, "wrap, growx, sg combos ");
}
}

View File

@ -488,7 +488,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
}
}
ComponentConfigDialog.showDialog(parent, document, component);
ComponentConfigDialog.showDialog(parent, document, component, false);
}
}

View File

@ -18,12 +18,12 @@ import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.Unit;
import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.TextUtil;
public class SaveCSVWorker extends SwingWorker<Void, Void> {
private static final int BYTES_PER_FIELD_PER_POINT = 7;
public static final int DEFAULT_DECIMAL_PLACES = 3;
private final File file;
private final Simulation simulation;
@ -94,7 +94,7 @@ public class SaveCSVWorker extends SwingWorker<Void, Void> {
FlightDataType[] fields, Unit[] units, String fieldSeparator,
String commentStarter, boolean simulationComments,
boolean fieldComments, boolean eventComments, Window parent) {
return export(file, simulation, branch, fields, units, fieldSeparator, DEFAULT_DECIMAL_PLACES, true,
return export(file, simulation, branch, fields, units, fieldSeparator, TextUtil.DEFAULT_DECIMAL_PLACES, true,
commentStarter, simulationComments, fieldComments, eventComments, parent);
}

View File

@ -2,6 +2,8 @@ package net.sf.openrocket.startup;
import java.awt.*;
import java.awt.desktop.AboutHandler;
import java.awt.desktop.OpenFilesEvent;
import java.awt.desktop.OpenFilesHandler;
import java.awt.desktop.PreferencesHandler;
import java.awt.desktop.QuitHandler;
@ -13,6 +15,7 @@ import net.sf.openrocket.arch.SystemInfo.Platform;
import net.sf.openrocket.gui.dialogs.AboutDialog;
import net.sf.openrocket.gui.dialogs.preferences.PreferencesDialog;
import net.sf.openrocket.gui.main.BasicFrame;
import net.sf.openrocket.gui.main.MRUDesignFile;
import javax.swing.*;
@ -31,6 +34,14 @@ final class OSXSetup {
// The image resource to use for the Dock Icon
private static final String ICON_RSRC = "/pix/icon/icon-256.png";
/**
* The handler for file associations
*/
public static final OpenFilesHandler OPEN_FILE_HANDLER = (e) -> {
log.info("Opening file from association: " + e.getFiles().get(0));
BasicFrame.open(e.getFiles().get(0), null);
};
/**
* The handler for the Quit item in the OSX app menu
@ -81,6 +92,7 @@ final class OSXSetup {
// Set handlers
osxDesktop.setAboutHandler(ABOUT_HANDLER);
osxDesktop.setOpenFileHandler(OPEN_FILE_HANDLER);
osxDesktop.setPreferencesHandler(PREFERENCES_HANDLER);
osxDesktop.setQuitHandler(QUIT_HANDLER);