Merge branch 'unstable' into issue-1621

This commit is contained in:
SiboVG 2022-10-17 17:30:20 +02:00
commit 6c97dc8440
70 changed files with 510 additions and 204 deletions

1
.gitignore vendored
View File

@ -49,6 +49,7 @@
# User-specific stuff:
.idea/workspace.xml
.idea/tasks.xml
.idea/shelf
.idea/dictionaries
.idea/vcs.xml
.idea/jsLibraryMappings.xml

View File

@ -60,7 +60,7 @@
<javac debug="true" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" includeantruntime="false" source="1.8" target="1.8"/>
</target>
<!-- Executible Eclipse-Jar-In-Jar style JAR -->
<!-- Executable Eclipse-Jar-In-Jar style JAR -->
<target name="jar" depends="build" description="Create the OpenRocket Core">
<mkdir dir="${jar.dir}" />
<jar destfile="${jar.file}" basedir="${dist.dir}">

View File

@ -10,7 +10,7 @@ pyrotechnics. At its best, it works as an inspiration for youngsters
to study engineering and sciences.
This thesis work provides one of the computer-age tools for everybody
intrested in model rocket design. Providing everybody free access to
interested in model rocket design. Providing everybody free access to
a full-fledged rocket simulator allows many more hobbyists to
experiment with different kinds of rocket designs and become more
involved in the sport. The most enthusiastic rocketeers may dive
@ -44,7 +44,7 @@ insight into the effects of roll during flight.
The external listener classes that can be attached to the simulator
allow huge potential for custom extensions. For example testing the
active roll reduction controller that will be included in the
successor project of Haisunäätä would have been exceedingly difficult
successor project of Haisun<EFBFBD><EFBFBD>t<EFBFBD> would have been exceedingly difficult
without such support. By interfacing the actual controller with a
simulated flight environment it was possible to discover various bugs
in the controller software that would otherwise have gone undetected.

View File

@ -113,7 +113,7 @@ mass. The <em>packed length</em>, <em>diameter</em> and
<em>position</em> affect the packed size and location of the
parachute.
<p>The <em>Deploys at</em> propery can be used to affect when the
<p>The <em>Deploys at</em> property can be used to affect when the
parachute deploys. The <em>First ejection charge of this stage</em>
option will deploy the parachute when the ejection charge is fired, as
is typical in small model rockets.

View File

@ -276,6 +276,10 @@ pref.dlg.tab.Simulation = Simulation
pref.dlg.tab.Launch = Launch
pref.dlg.tab.Miscellaneousoptions = Miscellaneous options
pref.dlg.lbl.RockSimWarning = Show warning when saving in RockSim format
pref.dlg.but.clearCachedPreferences = Reset all preferences
pref.dlg.but.clearCachedPreferences.ttip = Reset all the preferences, including cached preferences (UI settings, recent files, etc.)
pref.dlg.clearCachedPreferences.title = Reset preferences?
pref.dlg.clearCachedPreferences.message = Are you sure you want to reset all your preferences?
pref.dlg.tab.Graphics = Graphics
pref.dlg.lbl.DecalEditor = Graphics Editor
@ -306,7 +310,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 +367,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.
@ -1303,6 +1307,10 @@ StorageOptChooser.lbl.Saveopt = Save options
TCMotorSelPan.lbl.Selrocketmotor = Select rocket motor:
TCMotorSelPan.checkbox.hideSimilar = Hide very similar thrust curves
TCMotorSelPan.checkbox.hideUsed = Hide motors already used in the mount
TCMotorSelPan.lbl.motorNameColumn = Motor name column:
TCMotorSelPan.lbl.motorNameColumn.ttip = Select which motor property to display in the motor name column.
TCMotorSelPan.btn.commonName = Use common name
TCMotorSelPan.btn.designation = Use manufacturer's designation
TCMotorSelPan.lbl.nrOfMotors = Number of motors:
TCMotorSelPan.lbl.ttip.nrOfMotors = Number of motors currently visible in the motor selection table
TCMotorSelPan.checkbox.limitlength = Limit motor length to mount length
@ -1695,7 +1703,7 @@ FlightEvent.Type.EXCEPTION = Exception
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Manufacturer
TCurveMotorCol.COMMON_NAME = Name
TCurveMotorCol.NAME = Name
TCurveMotorCol.CASEINFO = Case
TCurveMotorCol.DIAMETER = Diameter
TCurveMotorCol.LENGTH = Length
@ -1827,6 +1835,7 @@ Warning.ZERO_LENGTH_BODY = Zero length bodies may not result in accurate simulat
Warning.ZERO_RADIUS_BODY = Zero length bodies may not result in accurate simulations.
Warning.TUBE_SEPARATION = Space between tube fins may not result in accurate simulations.
Warning.TUBE_OVERLAP = Overlapping tube fins may not result in accurate simulations.
Warning.SEPARATION_ORDER = Stages separated in an unreasonable order
! Scale dialog
ScaleDialog.lbl.scaleRocket = Entire rocket

View File

@ -1213,7 +1213,7 @@ FlightEvent.Type.ALTITUDE = Zmena v
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Výrobce
TCurveMotorCol.COMMON_NAME = Jméno
TCurveMotorCol.NAME = Jméno
! TCurveMotorCol.DESIGNATION = Pojmenování
TCurveMotorCol.TYPE = Druh
TCurveMotorCol.DIAMETER = Prumer

View File

@ -1273,7 +1273,7 @@ FlightEvent.Type.ALTITUDE = H
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Hersteller
TCurveMotorCol.COMMON_NAME = Name
TCurveMotorCol.NAME = Name
! TCurveMotorCol.DESIGNATION = Bezeichnung
TCurveMotorCol.TYPE = Typ
TCurveMotorCol.DIAMETER = Durchmesser

View File

@ -1157,7 +1157,7 @@ TCurveMotor.ttip.maxThrust = Empuje m\u00e1ximo:
TCurveMotor.ttip.totalImpulse = Impulso total:
! ThrustCurveMotorColumns
TCurveMotorCol.COMMON_NAME = Nombre
TCurveMotorCol.NAME = Nombre
! TCurveMotorCol.DESIGNATION = Designaci\u00f3n
TCurveMotorCol.DIAMETER = Di\u00e1metro
TCurveMotorCol.LENGTH = Longitud

View File

@ -1151,7 +1151,7 @@ TCurveMotor.ttip.maxThrust = Pouss\u00E9e Maximum:
TCurveMotor.ttip.totalImpulse = Impulsion Totale:
! ThrustCurveMotorColumns
TCurveMotorCol.COMMON_NAME = Nom
TCurveMotorCol.NAME = Nom
! TCurveMotorCol.DESIGNATION = D\u00E9signation
TCurveMotorCol.DIAMETER = Diam\u00E8tre
TCurveMotorCol.LENGTH = Longueur

View File

@ -1276,7 +1276,7 @@ FlightEvent.Type.ALTITUDE = Cambio altitudine
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Produttore
TCurveMotorCol.COMMON_NAME = Nome
TCurveMotorCol.NAME = Nome
! TCurveMotorCol.DESIGNATION = Classe
TCurveMotorCol.TYPE = Tipo
TCurveMotorCol.DIAMETER = Diametro

View File

@ -1325,7 +1325,7 @@ FlightEvent.Type.ALTITUDE = \u59FF\u52E2\u5909\u66F4
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = \u30E1\u30FC\u30AB\u30FC
! TCurveMotorCol.DESIGNATION = \u8A18\u53F7
TCurveMotorCol.COMMON_NAME = \u8A18\u53F7
TCurveMotorCol.NAME = \u8A18\u53F7
TCurveMotorCol.TYPE = \u30BF\u30A4\u30D7
TCurveMotorCol.DIAMETER = \u76F4\u5F84
TCurveMotorCol.LENGTH = \u9577\u3055

View File

@ -1573,7 +1573,7 @@ FlightEvent.Type.EXCEPTION = Uitzondering
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Fabrikant
TCurveMotorCol.COMMON_NAME = Naam
TCurveMotorCol.NAME = Naam
! TCurveMotorCol.DESIGNATION = Benaming
TCurveMotorCol.CASEINFO = Behuizing
TCurveMotorCol.DIAMETER = Diameter

View File

@ -1217,7 +1217,7 @@ update.dlg.latestVersion = Korzystasz z najnowszej wersji OpenRocket: %s.
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Producent
TCurveMotorCol.COMMON_NAME = Nazwa
TCurveMotorCol.NAME = Nazwa
! TCurveMotorCol.DESIGNATION = Oznaczenie
TCurveMotorCol.TYPE = Typ
TCurveMotorCol.DIAMETER = \u015Arednica

View File

@ -1117,7 +1117,7 @@ TCurveMotor.ttip.maxThrust = M\u00e1ximo de impulso:
TCurveMotor.ttip.totalImpulse = Impulso total:
# ThrustCurveMotorColumns
TCurveMotorCol.COMMON_NAME = Nome
TCurveMotorCol.NAME = Nome
! TCurveMotorCol.DESIGNATION = Designa\u00e7\u00e3o
TCurveMotorCol.DIAMETER = Di\u00e2metro
TCurveMotorCol.LENGTH = Comprimento

View File

@ -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 = <html>\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.<br>\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.</html>
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
@ -1694,7 +1696,7 @@ FlightEvent.Type.EXCEPTION = \u041E\u0448\u0438\u0431\u043A\u0430
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = \u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C
TCurveMotorCol.COMMON_NAME = \u041E\u0431\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
TCurveMotorCol.NAME = \u041E\u0431\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435
TCurveMotorCol.CASEINFO = \u041A\u043E\u0440\u043F\u0443\u0441
TCurveMotorCol.TYPE = \u0422\u0438\u043F
TCurveMotorCol.DIAMETER = \u0414\u0438\u0430\u043C\u0435\u0442\u0440

View File

@ -1421,7 +1421,7 @@ FlightEvent.Type.EXCEPTION = Exception
! ThrustCurveMotorColumns
TCurveMotorCol.MANUFACTURER = Manufacturer
TCurveMotorCol.COMMON_NAME = Name
TCurveMotorCol.NAME = Name
! TCurveMotorCol.DESIGNATION = Designation
TCurveMotorCol.TYPE = Type
TCurveMotorCol.DIAMETER = Diameter

View File

@ -1221,7 +1221,7 @@ TCurveMotor.ttip.maxThrust = \u6700\u5927\u63A8\u529B:
TCurveMotor.ttip.totalImpulse = \u603B\u51B2\u529B:
! ThrustCurveMotorColumns
TCurveMotorCol.COMMON_NAME = \u540D\u79F0
TCurveMotorCol.NAME = \u540D\u79F0
! TCurveMotorCol.DESIGNATION = \u540D\u79F0
TCurveMotorCol.DIAMETER = \u76F4\u5F84
TCurveMotorCol.LENGTH = \u957F\u5EA6

View File

@ -396,4 +396,6 @@ public abstract class Warning {
public static final Warning TUBE_SEPARATION = new Other(trans.get("Warning.TUBE_SEPARATION"));
public static final Warning TUBE_OVERLAP = new Other(trans.get("Warning.TUBE_OVERLAP"));
public static final Warning SEPARATION_ORDER = new Other(trans.get("Warning.SEPARATION_ORDER"));
}

View File

@ -523,7 +523,7 @@ public class AppearanceBuilder extends AbstractChangeSource {
}
/**
* only applies change if there is no more changes comming
* only applies change if there is no more changes coming
*/
@Override
protected void fireChangeEvent() {

View File

@ -155,7 +155,7 @@ public class Databases {
* @param type The type of material
* @param baseName the name of material
* @param density density
* @return a new onejct withe the material data
* @return a new object with the material data
*/
private static Material newMaterial(Type type, String baseName, double density) {
String name = trans.get("material", baseName);

View File

@ -104,7 +104,7 @@ public class GeneralRocketLoader {
}
/**
* This method determines the type file contained in the stream then calls the appropriate loading mecahnism.
* This method determines the type file contained in the stream then calls the appropriate loading mechanism.
*
* If the stream is a gzip file, the argument is wrapped in a GzipInputStream and the rocket loaded.
*

View File

@ -428,8 +428,15 @@ public class OpenRocketSaver extends RocketSaver {
private void savePhotoSettings(Map<String, String> p) throws IOException {
log.debug("Saving Photo Settings");
writeln("<photostudio>");
indent++;
for (String s : PhotoStudioSaver.getElements(p))
writeln(s);
indent--;
writeln("</photostudio>");
}

View File

@ -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", " ",

View File

@ -20,7 +20,7 @@ public class AxialStageSaver extends ComponentAssemblySaver {
if (c.isAfter()) {
// yes, this test is redundant. I'm merely paranoid, and attempting to future-proof it
if (c.getClass().equals(AxialStage.class)) {
// kept as simply 'stage' for backward compatability
// kept as simply 'stage' for backward compatibility
list.add("<stage>");
instance.addParams(c, list);
list.add("</stage>");

View File

@ -21,8 +21,6 @@ public class PhotoStudioSaver {
if (photoSettings == null || photoSettings.size() == 0) return elements;
elements.add("<photostudio>");
elements.add("<roll>" + photoSettings.get("roll") + "</roll>");
elements.add("<yaw>" + photoSettings.get("yaw") + "</yaw>");
elements.add("<pitch>" + photoSettings.get("pitch") + "</pitch>");
@ -45,7 +43,6 @@ public class PhotoStudioSaver {
emitColor("flameColor", elements, photoSettings.get("flameColor"));
elements.add("<smoke>" + photoSettings.get("smoke") + "</smoke>");
emitColor("smokeColor", elements, photoSettings.get("smokeColor"));
elements.add("<smokeOpacity>" + photoSettings.get("smokeOpacity") + "</smokeOpacity>");
elements.add("<sparks>" + photoSettings.get("sparks") + "</sparks>");
elements.add("<exhaustScale>" + photoSettings.get("exhaustScale") + "</exhaustScale>");
elements.add("<flameAspectRatio>" + photoSettings.get("flameAspectRatio") + "</flameAspectRatio>");
@ -55,8 +52,6 @@ public class PhotoStudioSaver {
elements.add("<sky>" + photoSettings.get("sky") + "</sky>");
elements.add("</photostudio>");
return elements;
}

View File

@ -16,7 +16,7 @@ public class AtmosphericConditions implements Cloneable, Monitorable {
/** The standard air pressure (1.01325 bar). */
public static final double STANDARD_PRESSURE = 101325.0;
/** The standard air temperature (20 degrees Celcius). */
/** The standard air temperature (20 degrees Celsius). */
public static final double STANDARD_TEMPERATURE = 293.15;
@ -83,7 +83,7 @@ public class AtmosphericConditions implements Cloneable, Monitorable {
* Return the current speed of sound for dry air.
* <p>
* The speed of sound is calculated using the expansion around the temperature 0 C
* <code> c = 331.3 + 0.606*T </code> where T is in Celcius. The result is accurate
* <code> c = 331.3 + 0.606*T </code> where T is in Celsius. The result is accurate
* to about 0.5 m/s for temperatures between -30 and 30 C, and within 2 m/s
* for temperatures between -55 and 30 C.
*
@ -98,7 +98,7 @@ public class AtmosphericConditions implements Cloneable, Monitorable {
* Return the current kinematic viscosity of the air.
* <p>
* The effect of temperature on the viscosity of a gas can be computed using
* Sutherland's formula. In the region of -40 ... 40 degrees Celcius the effect
* Sutherland's formula. In the region of -40 ... 40 degrees Celsius the effect
* is highly linear, and thus a linear approximation is used in its stead.
* This is divided by the result of {@link #getDensity()} to achieve the
* kinematic viscosity.

View File

@ -222,7 +222,7 @@ public abstract class BaseComponentDTO {
} else if ("LINE".equals(type)) {
return Material.Type.LINE;
}
throw new IllegalArgumentException("Inavlid material type " + type + " specified for Component");
throw new IllegalArgumentException("Invalid material type " + type + " specified for Component");
}
}

View File

@ -146,6 +146,34 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
updateMotors();
updateActiveInstances();
}
/**
* This method clears a stage and all stages below (higher stage number)
*
* @param stageNumber first stage number to turn off
*/
public void clearStagesBelow(int stageNumber) {
// I can't just use _setStageActive(stageNumber, false, true)
// because that won't clear side boosters' active flags (should it?)
for (int i = stageNumber; i < rocket.getStageCount(); i++) {
_setStageActive(i, false, false);
}
updateMotors();
updateActiveInstances();
}
/**
* This method clears all stages above (but not including) a stage
*
* @param stageNumber first stage number to stay active
*/
public void clearStagesAbove(int stageNumber) {
for (int i = 0; i < stageNumber; i++) {
_setStageActive(i, false, false);
}
updateMotors();
updateActiveInstances();
}
/**
* Activates all stages as active starting from the specified component
@ -187,7 +215,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
}
/**
* This method flags the specified stage as requested. Other stages are unaffected.
* This method flags the specified stage as requested. Substages may be affected, depending on third parameter
*
* @param stageNumber stage number to flag
* @param _active inactive (<code>false</code>) or active (<code>true</code>)

View File

@ -28,7 +28,7 @@ public final class FlightConfigurationId implements Comparable<FlightConfigurati
/**
* builds the id with the given String
* @param _str te string to be made into the id
* @param _str the string to be made into the id
*/
public FlightConfigurationId(final String _str) {
UUID candidate;

View File

@ -215,7 +215,7 @@ public class FreeformFinSet extends FinSet {
* - non-self-intersecting fin shape (aborts set on invalid fin point)
* </p><p>
* NOTE: the fin-point axes differ from rocket axes:
* +x within the fin points foreward; +x for the rocket points aft
* +x within the fin points forward; +x for the rocket points aft
* </p><p>
* Moving of the first point in the X-axis is allowed, but this actually moves
* all of the other points the corresponding distance back, relative to the first.

View File

@ -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<Coordinate> getComponentBounds() {
Collection<Coordinate> c = new ArrayList<Coordinate>();
addBound(c, 0, radius);
addBound(c, length, radius);
addBound(c, 0, getRadius());
addBound(c, getLength(), getRadius());
return c;
}

View File

@ -13,6 +13,8 @@ import net.sf.openrocket.util.Quaternion;
public abstract class AbstractSimulationStepper implements SimulationStepper {
protected static final double MIN_TIME_STEP = 0.001;
/**
* Compute the atmospheric conditions, allowing listeners to override.
*

View File

@ -213,7 +213,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
// }
// Check for Tumbling
// Conditions for transision are:
// Conditions for transition are:
// apogee reached (if sustainer stage)
// and is not already tumbling
// and not stable (cg > cp)
@ -305,6 +305,9 @@ public class BasicEventSimulationEngine implements SimulationEngine {
if (event.getSource() != null && event.getSource().getParent() != null &&
!currentStatus.getConfiguration().isComponentActive(event.getSource())) {
log.trace("Ignoring event from unattached component");
log.debug(" source " + event.getSource());
log.debug(" parent " + event.getSource().getParent());
log.debug(" active " + currentStatus.getConfiguration().isComponentActive(event.getSource()));
continue;
}
@ -381,7 +384,6 @@ public class BasicEventSimulationEngine implements SimulationEngine {
}
// and queue up the burnout for this motor, as well.
// double duration = motorState.getMotor().getBurnTimeEstimate();
double duration = motorState.getBurnTime();
double burnout = currentStatus.getSimulationTime() + duration;
addEvent(new FlightEvent(FlightEvent.Type.BURNOUT, burnout,
@ -436,19 +438,36 @@ public class BasicEventSimulationEngine implements SimulationEngine {
case STAGE_SEPARATION: {
RocketComponent boosterStage = event.getSource();
final int stageNumber = boosterStage.getStageNumber();
log.debug("separating at stage " + stageNumber);
if (currentStatus.getConfiguration().isStageActive(stageNumber-1)) {
// Record the event.
currentStatus.getFlightData().addEvent(event);
// Mark the status as having dropped the booster
currentStatus.getConfiguration().clearStage( stageNumber);
// Prepare the simulation branch
// If I've got something other than one active stage below the separation point,
// flag a warning
int numActiveBelow = 0;
for (int i = stageNumber; i < currentStatus.getConfiguration().getStageCount(); i++) {
if (currentStatus.getConfiguration().isStageActive(i)) {
numActiveBelow++;
}
}
if (numActiveBelow != 1) {
currentStatus.getWarnings().add(Warning.SEPARATION_ORDER);
}
// Create a new simulation branch for the booster
SimulationStatus boosterStatus = new SimulationStatus(currentStatus);
// Prepare the new simulation branch
boosterStatus.setFlightData(new FlightDataBranch(boosterStage.getName(), FlightDataType.TYPE_TIME));
// Mark the booster status as only having the booster.
boosterStatus.getConfiguration().setOnlyStage(stageNumber);
// Mark the current status as having dropped the current stage and all stages below it
currentStatus.getConfiguration().clearStagesBelow( stageNumber);
// Mark the booster status as having no active stages above
boosterStatus.getConfiguration().clearStagesAbove(stageNumber);
toSimulate.push(boosterStatus);
log.info(String.format("==>> @ %g; from Branch: %s ---- Branching: %s ---- \n",
currentStatus.getSimulationTime(),

View File

@ -73,10 +73,12 @@ public class BasicLandingStepper extends AbstractSimulationStepper {
double timeStep = RECOVERY_TIME_STEP;
// adjust based on change in acceleration (ie jerk)
final double jerk = linearAcceleration.sub(status.getRocketAcceleration()).multiply(1.0/status.getPreviousTimeStep()).length();
final double jerk = Math.abs(linearAcceleration.sub(status.getRocketAcceleration()).multiply(1.0/status.getPreviousTimeStep()).length());
if (jerk > MathUtil.EPSILON) {
timeStep = Math.min(timeStep, 1.0/jerk);
}
// but don't let it get *too* small
timeStep = Math.max(timeStep, MIN_TIME_STEP);
// Perform Euler integration
Coordinate newPosition = status.getRocketPosition().add(status.getRocketVelocity().multiply(timeStep)).

View File

@ -13,8 +13,11 @@ public class BasicTumbleStepper extends AbstractSimulationStepper {
private static final double RECOVERY_TIME_STEP = 0.5;
@Override
public SimulationStatus initialize(SimulationStatus status) {
return new BasicTumbleStatus(status);
public SimulationStatus initialize(SimulationStatus original) {
BasicTumbleStatus status = new BasicTumbleStatus(original);
status.setWarnings(original.getWarnings());
return status;
}
@Override

View File

@ -251,7 +251,7 @@ public class FlightDataType implements Comparable<FlightDataType> {
* This returns an existing data type if the symbol matches that of an existing type.
*
* If the symbol matches but the unit and description information differ, then the old stored datatype
* is erased and the updated version based on the given parametes is returned.
* is erased and the updated version based on the given parameters is returned.
* The only exception is if the description or unitgroup are undefined (null or empty string). In this case
* we just get these parameters from the existing type when making the new one.
*

View File

@ -58,9 +58,6 @@ public class RK4SimulationStepper extends AbstractSimulationStepper {
private static final double MAX_ROLL_RATE_CHANGE = 2 * Math.PI / 180;
private static final double MAX_PITCH_CHANGE = 4 * Math.PI / 180;
private static final double MIN_TIME_STEP = 0.001;
private Random random;

View File

@ -6,6 +6,7 @@ import java.util.Map;
import net.sf.openrocket.aerodynamics.AerodynamicCalculator;
import net.sf.openrocket.aerodynamics.AerodynamicForces;
import net.sf.openrocket.aerodynamics.FlightConditions;
import net.sf.openrocket.aerodynamics.WarningSet;
import net.sf.openrocket.motor.MotorConfiguration;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.RocketComponent;
@ -85,7 +86,7 @@ public class DampingMoment extends AbstractSimulationListener {
AerodynamicCalculator aerocalc = status.getSimulationConditions().getAerodynamicCalculator();
// Must go through each component ...
Map<RocketComponent, AerodynamicForces> forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, null);
Map<RocketComponent, AerodynamicForces> forces = aerocalc.getForceAnalysis(status.getConfiguration(), flightConditions, status.getWarnings());
for (Map.Entry<RocketComponent, AerodynamicForces> entry : forces.entrySet()) {
RocketComponent comp = entry.getKey();

View File

@ -58,12 +58,15 @@ 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";
public static final String MOTOR_HIDE_SIMILAR = "MotorHideSimilar";
public static final String MOTOR_HIDE_UNAVAILABLE = "MotorHideUnavailable";
public static final String MOTOR_NAME_COLUMN = "MotorNameColumn";
public static final String MATCH_FORE_DIAMETER = "MatchForeDiameter";
public static final String MATCH_AFT_DIAMETER = "MatchAftDiameter";
@ -150,6 +153,14 @@ public abstract class Preferences implements ChangeSource {
this.putBoolean(CHECK_UPDATES, check);
}
public final List<String> getIgnoreVersions() {
return List.of(this.getString(IGNORE_VERSIONS, "").split("\n"));
}
public final void setIgnoreVersions(List<String> versions) {
this.putString(IGNORE_VERSIONS, String.join("\n", versions));
}
public final boolean getCheckBetaUpdates() {
return this.getBoolean(CHECK_BETA_UPDATES, BuildProperties.getDefaultCheckBetaUpdates());
}

View File

@ -92,7 +92,6 @@ public class UnitGroup {
static {
UNITS_NONE = new UnitGroup();
UNITS_NONE.addUnit(Unit.NOUNIT);
UNITS_NONE.setDefaultUnit(0);
UNITS_ENERGY = new UnitGroup();
UNITS_ENERGY.addUnit(new GeneralUnit(1, "J"));
@ -100,7 +99,6 @@ public class UnitGroup {
UNITS_ENERGY.addUnit(new GeneralUnit(1.055, "BTU"));
UNITS_ENERGY.addUnit(new GeneralUnit(4.184, "cal"));
UNITS_ENERGY.addUnit(new GeneralUnit(1.3558179483314, "ft" + DOT + "lbf"));
UNITS_ENERGY.setDefaultUnit(0);
UNITS_POWER = new UnitGroup();
UNITS_POWER.addUnit(new GeneralUnit(1e-3, "mW"));
@ -108,21 +106,17 @@ public class UnitGroup {
UNITS_POWER.addUnit(new GeneralUnit(1e3, "kW"));
UNITS_POWER.addUnit(new GeneralUnit(1e-7, "ergs"));
UNITS_POWER.addUnit(new GeneralUnit(745.699872, "hp"));
UNITS_POWER.setDefaultUnit(1);
UNITS_MOMENTUM = new UnitGroup();
UNITS_MOMENTUM.addUnit(new GeneralUnit(1, "kg" + DOT + "m/s"));
UNITS_MOMENTUM.setDefaultUnit(0);
UNITS_VOLTAGE = new UnitGroup();
UNITS_VOLTAGE.addUnit(new GeneralUnit(1e-3, "mV"));
UNITS_VOLTAGE.addUnit(new GeneralUnit(1, "V"));
UNITS_VOLTAGE.setDefaultUnit(1);
UNITS_CURRENT = new UnitGroup();
UNITS_CURRENT.addUnit(new GeneralUnit(1e-3, "mA"));
UNITS_CURRENT.addUnit(new GeneralUnit(1, "A"));
UNITS_CURRENT.setDefaultUnit(1);
UNITS_LENGTH = new UnitGroup();
UNITS_LENGTH.addUnit(new GeneralUnit(0.001, "mm"));
@ -131,14 +125,12 @@ public class UnitGroup {
UNITS_LENGTH.addUnit(new InchUnit(0.0254, "in"));
UNITS_LENGTH.addUnit(new FractionalUnit(0.0254, "in/64", "in", 64, 1d / 16d, 0.5d / 64d));
UNITS_LENGTH.addUnit(new GeneralUnit(0.3048, "ft"));
UNITS_LENGTH.setDefaultUnit(1);
UNITS_MOTOR_DIMENSIONS = new UnitGroup();
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.001, "mm"));
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.01, "cm"));
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(1, "m"));
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.0254, "in"));
UNITS_MOTOR_DIMENSIONS.setDefaultUnit(0);
UNITS_DISTANCE = new UnitGroup();
UNITS_DISTANCE.addUnit(new GeneralUnit(1, "m"));
@ -147,7 +139,6 @@ public class UnitGroup {
UNITS_DISTANCE.addUnit(new GeneralUnit(0.9144, "yd"));
UNITS_DISTANCE.addUnit(new GeneralUnit(1609.344, "mi"));
UNITS_DISTANCE.addUnit(new GeneralUnit(1852, "nmi"));
UNITS_DISTANCE.setDefaultUnit(0);
UNITS_ALL_LENGTHS = new UnitGroup();
UNITS_ALL_LENGTHS.addUnit(new GeneralUnit(0.001, "mm"));
@ -160,7 +151,6 @@ public class UnitGroup {
UNITS_ALL_LENGTHS.addUnit(new GeneralUnit(0.9144, "yd"));
UNITS_ALL_LENGTHS.addUnit(new GeneralUnit(1609.344, "mi"));
UNITS_ALL_LENGTHS.addUnit(new GeneralUnit(1852, "nmi"));
UNITS_ALL_LENGTHS.setDefaultUnit(2);
UNITS_AREA = new UnitGroup();
UNITS_AREA.addUnit(new GeneralUnit(pow2(0.001), "mm" + SQUARED));
@ -168,7 +158,6 @@ public class UnitGroup {
UNITS_AREA.addUnit(new GeneralUnit(1, "m" + SQUARED));
UNITS_AREA.addUnit(new GeneralUnit(pow2(0.0254), "in" + SQUARED));
UNITS_AREA.addUnit(new GeneralUnit(pow2(0.3048), "ft" + SQUARED));
UNITS_AREA.setDefaultUnit(1);
UNITS_STABILITY = new UnitGroup();
@ -178,11 +167,9 @@ public class UnitGroup {
UNITS_STABILITY.addUnit(new GeneralUnit(0.0254, "in"));
UNITS_STABILITY.addUnit(new CaliberUnit((Rocket) null));
UNITS_STABILITY.addUnit(new PercentageOfLengthUnit((Rocket) null));
UNITS_STABILITY.setDefaultUnit(4);
UNITS_STABILITY_CALIBERS = new UnitGroup();
UNITS_STABILITY_CALIBERS.addUnit(new GeneralUnit(1, "cal"));
UNITS_STABILITY_CALIBERS.setDefaultUnit(0);
UNITS_VELOCITY = new UnitGroup();
UNITS_VELOCITY.addUnit(new GeneralUnit(1, "m/s"));
@ -190,7 +177,6 @@ public class UnitGroup {
UNITS_VELOCITY.addUnit(new GeneralUnit(0.3048, "ft/s"));
UNITS_VELOCITY.addUnit(new GeneralUnit(0.44704, "mph"));
UNITS_VELOCITY.addUnit(new GeneralUnit(0.51444445, "kt"));
UNITS_VELOCITY.setDefaultUnit(0);
UNITS_WINDSPEED = new UnitGroup();
UNITS_WINDSPEED.addUnit(new GeneralUnit(1, "m/s"));
@ -198,20 +184,17 @@ public class UnitGroup {
UNITS_WINDSPEED.addUnit(new GeneralUnit(0.3048, "ft/s"));
UNITS_WINDSPEED.addUnit(new GeneralUnit(0.44704, "mph"));
UNITS_WINDSPEED.addUnit(new GeneralUnit(0.51444445, "kt"));
UNITS_WINDSPEED.setDefaultUnit(0);
UNITS_ACCELERATION = new UnitGroup();
UNITS_ACCELERATION.addUnit(new GeneralUnit(1, "m/s" + SQUARED));
UNITS_ACCELERATION.addUnit(new GeneralUnit(0.3048, "ft/s" + SQUARED));
UNITS_ACCELERATION.addUnit(new GeneralUnit(9.80665, "G"));
UNITS_ACCELERATION.setDefaultUnit(0);
UNITS_MASS = new UnitGroup();
UNITS_MASS.addUnit(new GeneralUnit(0.001, "g"));
UNITS_MASS.addUnit(new GeneralUnit(1, "kg"));
UNITS_MASS.addUnit(new GeneralUnit(0.0283495231, "oz"));
UNITS_MASS.addUnit(new GeneralUnit(0.45359237, "lb"));
UNITS_MASS.setDefaultUnit(0);
UNITS_INERTIA = new UnitGroup();
UNITS_INERTIA.addUnit(new GeneralUnit(0.0001, "kg" + DOT + "cm" + SQUARED));
@ -220,13 +203,11 @@ public class UnitGroup {
UNITS_INERTIA.addUnit(new GeneralUnit(0.000292639653, "lb" + DOT + "in" + SQUARED));
UNITS_INERTIA.addUnit(new GeneralUnit(0.0421401101, "lb" + DOT + "ft" + SQUARED));
UNITS_INERTIA.addUnit(new GeneralUnit(1.35581795, "lbf" + DOT + "ft" + DOT + "s" + SQUARED));
UNITS_INERTIA.setDefaultUnit(1);
UNITS_ANGLE = new UnitGroup();
UNITS_ANGLE.addUnit(new DegreeUnit());
UNITS_ANGLE.addUnit(new FixedPrecisionUnit("rad", 0.01));
UNITS_ANGLE.addUnit(new GeneralUnit(1.0 / 3437.74677078, "arcmin"));
UNITS_ANGLE.setDefaultUnit(0);
UNITS_DENSITY_BULK = new UnitGroup();
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1000, "g/cm" + CUBED));
@ -234,7 +215,6 @@ public class UnitGroup {
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1, "kg/m" + CUBED));
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1729.99404, "oz/in" + CUBED));
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(16.0184634, "lb/ft" + CUBED));
UNITS_DENSITY_BULK.setDefaultUnit(0);
UNITS_DENSITY_SURFACE = new UnitGroup();
UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(10, "g/cm" + SQUARED));
@ -243,51 +223,42 @@ public class UnitGroup {
UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(43.9418487, "oz/in" + SQUARED));
UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(0.305151727, "oz/ft" + SQUARED));
UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(4.88242764, "lb/ft" + SQUARED));
UNITS_DENSITY_SURFACE.setDefaultUnit(1);
UNITS_DENSITY_LINE = new UnitGroup();
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.001, "g/m"));
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(1, "kg/m"));
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.0930102465, "oz/ft"));
UNITS_DENSITY_LINE.setDefaultUnit(0);
UNITS_FORCE = new UnitGroup();
UNITS_FORCE.addUnit(new GeneralUnit(1, "N"));
UNITS_FORCE.addUnit(new GeneralUnit(4.44822162, "lbf"));
UNITS_FORCE.addUnit(new GeneralUnit(9.80665, "kgf"));
UNITS_FORCE.setDefaultUnit(0);
UNITS_IMPULSE = new UnitGroup();
UNITS_IMPULSE.addUnit(new GeneralUnit(1, "Ns"));
UNITS_IMPULSE.addUnit(new GeneralUnit(4.44822162, "lbf" + DOT + "s"));
UNITS_IMPULSE.setDefaultUnit(0);
UNITS_TIME_STEP = new UnitGroup();
UNITS_TIME_STEP.addUnit(new FixedPrecisionUnit("ms", 1, 0.001));
UNITS_TIME_STEP.addUnit(new FixedPrecisionUnit("s", 0.01));
UNITS_TIME_STEP.setDefaultUnit(1);
UNITS_SHORT_TIME = new UnitGroup();
UNITS_SHORT_TIME.addUnit(new GeneralUnit(1, "s"));
UNITS_SHORT_TIME.setDefaultUnit(0);
UNITS_FLIGHT_TIME = new UnitGroup();
UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(1, "s"));
UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(60, "min"));
UNITS_FLIGHT_TIME.setDefaultUnit(0);
UNITS_ROLL = new UnitGroup();
UNITS_ROLL.addUnit(new GeneralUnit(1, "rad/s"));
UNITS_ROLL.addUnit(new GeneralUnit(Math.PI / 180, DEGREE + "/s"));
UNITS_ROLL.addUnit(new GeneralUnit(2 * Math.PI, "r/s"));
UNITS_ROLL.addUnit(new GeneralUnit(2 * Math.PI / 60, "rpm"));
UNITS_ROLL.setDefaultUnit(1);
UNITS_TEMPERATURE = new UnitGroup();
UNITS_TEMPERATURE.addUnit(new FixedPrecisionUnit("K", 1));
UNITS_TEMPERATURE.addUnit(new TemperatureUnit(1, 273.15, DEGREE + "C"));
UNITS_TEMPERATURE.addUnit(new TemperatureUnit(5.0 / 9.0, 459.67, DEGREE + "F"));
UNITS_TEMPERATURE.setDefaultUnit(1);
UNITS_PRESSURE = new UnitGroup();
UNITS_PRESSURE.addUnit(new FixedPrecisionUnit("mbar", 1, 1.0e2));
@ -297,25 +268,21 @@ public class UnitGroup {
UNITS_PRESSURE.addUnit(new GeneralUnit(3386.389, "inHg"));
UNITS_PRESSURE.addUnit(new GeneralUnit(6894.75729, "psi"));
UNITS_PRESSURE.addUnit(new GeneralUnit(1, "Pa"));
UNITS_PRESSURE.setDefaultUnit(0);
UNITS_RELATIVE = new UnitGroup();
UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01, 1.0));
UNITS_RELATIVE.addUnit(new GeneralUnit(0.01, "%"));
UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + PERMILLE, 1, 0.001));
UNITS_RELATIVE.setDefaultUnit(1);
UNITS_ROUGHNESS = new UnitGroup();
UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.000001, MICRO + "m"));
UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.0000254, "mil"));
UNITS_ROUGHNESS.addUnit(new GeneralUnit(1, "m"));
UNITS_ROUGHNESS.setDefaultUnit(0);
UNITS_COEFFICIENT = new UnitGroup();
UNITS_COEFFICIENT.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01)); // zero-width space
UNITS_COEFFICIENT.setDefaultUnit(0);
// This is not used by OpenRocket, and not extensively tested:
@ -323,8 +290,8 @@ public class UnitGroup {
UNITS_FREQUENCY.addUnit(new FrequencyUnit(.001, "mHz"));
UNITS_FREQUENCY.addUnit(new FrequencyUnit(1, "Hz"));
UNITS_FREQUENCY.addUnit(new FrequencyUnit(1000, "kHz"));
UNITS_FREQUENCY.setDefaultUnit(1);
resetDefaultUnits();
HashMap<String, UnitGroup> map = new HashMap<String, UnitGroup>();
map.put("NONE", UNITS_NONE);
@ -437,6 +404,43 @@ public class UnitGroup {
UNITS_RELATIVE.setDefaultUnit("%");
UNITS_ROUGHNESS.setDefaultUnit("mil");
}
public static void resetDefaultUnits() {
UNITS_NONE.setDefaultUnit(0);
UNITS_ENERGY.setDefaultUnit(0);
UNITS_POWER.setDefaultUnit(1);
UNITS_MOMENTUM.setDefaultUnit(0);
UNITS_VOLTAGE.setDefaultUnit(1);
UNITS_CURRENT.setDefaultUnit(1);
UNITS_LENGTH.setDefaultUnit(1);
UNITS_MOTOR_DIMENSIONS.setDefaultUnit(0);
UNITS_DISTANCE.setDefaultUnit(0);
UNITS_ALL_LENGTHS.setDefaultUnit(2);
UNITS_AREA.setDefaultUnit(1);
UNITS_STABILITY.setDefaultUnit(4);
UNITS_STABILITY_CALIBERS.setDefaultUnit(0);
UNITS_VELOCITY.setDefaultUnit(0);
UNITS_WINDSPEED.setDefaultUnit(0);
UNITS_ACCELERATION.setDefaultUnit(0);
UNITS_MASS.setDefaultUnit(0);
UNITS_INERTIA.setDefaultUnit(1);
UNITS_ANGLE.setDefaultUnit(0);
UNITS_DENSITY_BULK.setDefaultUnit(0);
UNITS_DENSITY_SURFACE.setDefaultUnit(1);
UNITS_DENSITY_LINE.setDefaultUnit(0);
UNITS_FORCE.setDefaultUnit(0);
UNITS_IMPULSE.setDefaultUnit(0);
UNITS_TIME_STEP.setDefaultUnit(1);
UNITS_SHORT_TIME.setDefaultUnit(0);
UNITS_FLIGHT_TIME.setDefaultUnit(0);
UNITS_ROLL.setDefaultUnit(1);
UNITS_TEMPERATURE.setDefaultUnit(1);
UNITS_PRESSURE.setDefaultUnit(0);
UNITS_RELATIVE.setDefaultUnit(1);
UNITS_ROUGHNESS.setDefaultUnit(0);
UNITS_COEFFICIENT.setDefaultUnit(0);
UNITS_FREQUENCY.setDefaultUnit(1);
}
/**

View File

@ -1594,7 +1594,7 @@ public class TestRockets {
stage2.setName("Stage2");
rocket.addChild(stage2);
// make 2st stage body tube
// make 2nd stage body tube
BodyTube bodyTube2 = new BodyTube(12, 1, 0.05);
stage2.addChild(bodyTube2);

View File

@ -289,7 +289,7 @@ public class BarrowmanCalculatorTest {
AerodynamicCalculator calc = new BarrowmanCalculator();
FlightConfiguration configuration = rocket.getSelectedConfiguration();
assertTrue("Estes Alpha III should be continous: ", calc.isContinuous(configuration, rocket));
assertTrue("Estes Alpha III should be continuous: ", calc.isContinuous(configuration, rocket));
}
@Test

View File

@ -27,7 +27,7 @@
<FinishMedium>0</FinishMedium>
<FinishCoatCount>1</FinishCoatCount>
<GlueType>0</GlueType>
<Comments>This is a neat design that shows off the ability of RockSim to compute the stability of Assymetrical fin arrangements.</Comments>
<Comments>This is a neat design that shows off the ability of RockSim to compute the stability of Asymmetrical fin arrangements.</Comments>
<Designer>Tim Van Milligan. Visit my web site at: www.ApogeeRockets.com</Designer>
<CPSimFlags>4</CPSimFlags>
<LastSerialNumber>29</LastSerialNumber>

View File

@ -27,7 +27,7 @@
<FinishMedium>0</FinishMedium>
<FinishCoatCount>1</FinishCoatCount>
<GlueType>0</GlueType>
<Comments>This is a neat design that shows off the ability of RockSim to compute the stability of Assymetrical fin arrangements.</Comments>
<Comments>This is a neat design that shows off the ability of RockSim to compute the stability of Asymmetrical fin arrangements.</Comments>
<Designer>Tim Van Milligan. Visit my web site at: www.ApogeeRockets.com</Designer>
<CPSimFlags>4</CPSimFlags>
<LastSerialNumber>29</LastSerialNumber>

View File

@ -1030,7 +1030,7 @@ public class MassCalculatorTest extends BaseTestCase {
mmt.setOverrideMass(0.213);
// cm= 0.21300000g @[1.28900000,0.07700000,0.00000000]
// Fin mass is not overriden
// Fin mass is not overridden
// cm= 0.15995232g @[1.23793939,0.07700000,0.00000000]
RigidBody boosterData = MassCalculator.calculateStructure(config);

View File

@ -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);
}
}
}

View File

@ -74,7 +74,7 @@ header("Content-type: text/plain");
* Currently all old versions are handled manually.
* Update checking was introduced in OpenRocket 0.9.4
*
* We ignore "pre" versions, they are handled exacly like
* We ignore "pre" versions, they are handled exactly like
* their non-pre counterparts.
*/
$version = $_GET["version"];

View File

@ -10,7 +10,7 @@
<h2>Mailing lists</h2>
<p>OpenRocket currently has two mailing lists for
intrested users:</p>
interested users:</p>
<dl>
<dt>

View File

@ -45,14 +45,14 @@
<p><span class="date">15.11.2013:</span> Version 13.11.1 is
<a href="download.html">released</a>! This release contains bug fixes
including fixing Tube Coupler configuration, various exceptions in
the flight configuration tab, updated 3d libraris (which didn't really make
the flight configuration tab, updated 3d libraries (which didn't really make
it into previous versions).</p>
<p><span class="date">8.11.2013:</span> Version 13.11 is
<a href="download.html">released</a>! This release simplifies
flight configurations by replacing the dialog with the configuration
tab. Motor filtering in the motor chooser dialog has been enhanced.
Chineese translations have been added and Russian translations updated.
Chinese translations have been added and Russian translations updated.
Updated the 3D libraries, and squashed some bugs introduced by Java 1.7.0_45-b18.</p>
<p><span class="date">6.10.2013:</span> Version 13.09.1 is
@ -104,7 +104,7 @@
<li>Support for fractional inches (1/64) for unit length</li>
<li>Added preference for windspeed units separately</li>
<li>Added "most recently used files" in File Menu</li>
<li>Improved printed accurracy in fin marking guide</li>
<li>Improved printed accuracy in fin marking guide</li>
<li>Calibration rulers added to printed templates</li>
<li>Translations in Czech and Polish, numerous updates</li>
</ul>

@ -1 +1 @@
Subproject commit 525b7898f9e92f40be9688a5a89a3d1de3bc12cd
Subproject commit 49a453dd1cb62f68dfbbbd56e69d7fbcdf4bd4a1

Binary file not shown.

View File

@ -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
*/

View File

@ -153,7 +153,8 @@ public class MotorDatabaseLoader extends AsynchronousDatabaseLoader {
"<br>" + trans.get("MotorDbLoaderDlg.message2") + "</p></body></html>";
JOptionPane pane = new JOptionPane(message, JOptionPane.WARNING_MESSAGE);
JDialog dialog = pane.createDialog(null, trans.get("MotorDbLoaderDlg.title"));
dialog.setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
dialog.setModalityType(Dialog.ModalityType.MODELESS);
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
}
f.getV().close();

View File

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

View File

@ -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()));

View File

@ -171,8 +171,10 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
// Stage and motor selection:
//// Active stages:
StageSelector stageSelector = new StageSelector(rkt);
rkt.addChangeListener(stageSelector);
panel.add(new JLabel(trans.get("componentanalysisdlg.lbl.activestages")), "spanx, split, gapafter rel");
panel.add(new StageSelector( rkt), "gapafter paragraph");
panel.add(stageSelector, "gapafter paragraph");
//// Motor configuration:
JLabel label = new JLabel(trans.get("componentanalysisdlg.lbl.motorconf"));

View File

@ -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("<html>");
sb.append(String.format("<h1>%s</h1>", String.format(trans.get("update.dlg.updateAvailable.txtPane.title"), release.getReleaseName())));
// Your version
sb.append(String.format("<i>%s</i> <br><br>", String.format(trans.get("update.dlg.updateAvailable.txtPane.yourVersion"), BuildProperties.getVersion())));
// Changelog
sb.append(String.format("<h2>%s</h2>", 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("<br><br>");
@ -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<String> 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<String> assetURLs = release.getAssetURLs();
Map<UpdatePlatform, String> mappedAssets = AssetHandler.mapURLToPlatform(assetURLs);
JComboBox<Object> comboBox;
@ -141,7 +174,7 @@ public class UpdateInfoDialog extends JDialog {
}
panel.add(comboBox, "pushx, right");
// Install update button
//// Install update button
JButton btnInstall = new SelectColorButton(trans.get("update.dlg.updateAvailable.but.install"));
btnInstall.addActionListener(new ActionListener() {
@Override
@ -159,25 +192,15 @@ public class UpdateInfoDialog extends JDialog {
if (mappedAssets == null || mappedAssets.size() == 0) {
btnInstall.setEnabled(false);
}
panel.add(btnInstall, "gapright 20");
// Cancel button
JButton btnCancel = new SelectColorButton(trans.get("button.cancel"));
btnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
UpdateInfoDialog.this.dispose();
}
});
panel.add(btnCancel);
panel.add(btnInstall, "wrap");
panel.setPreferredSize(new Dimension(900, 600));
panel.setPreferredSize(new Dimension(850, 700));
this.add(panel);
this.pack();
this.setLocationRelativeTo(null);
GUIUtil.setDisposableDialogOptions(this, btnCancel);
GUIUtil.setDisposableDialogOptions(this, btnLater);
}
/**

View File

@ -219,8 +219,18 @@ public class MotorRowFilter extends RowFilter<TableModel, Integer> implements Ch
main: for (String s : searchTerms) {
for (ThrustCurveMotorColumns col : ThrustCurveMotorColumns.values()) {
String str = col.getValue(m).toString().toLowerCase(Locale.getDefault());
if (str.indexOf(s) >= 0)
if (str.contains(s)) {
continue main;
}
}
// Make sure that you can search on both the common name, and designation
// Yes, there is some duplication here because the common name or designation is already checked in the previous loop
// but it's not worth checking that...
String common = m.getCommonName().toLowerCase(Locale.getDefault());
String designation = m.getDesignation().toLowerCase(Locale.getDefault());
if (common.contains(s) || designation.contains(s)) {
continue main;
}
return false;
}

View File

@ -4,6 +4,7 @@ import java.text.Collator;
import java.util.Comparator;
import net.sf.openrocket.database.motor.ThrustCurveMotorSet;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.motor.DesignationComparator;
import net.sf.openrocket.motor.ThrustCurveMotor;
@ -31,10 +32,17 @@ enum ThrustCurveMotorColumns {
}
},
//// Common name
COMMON_NAME("TCurveMotorCol.COMMON_NAME") {
NAME("TCurveMotorCol.NAME") {
@Override
public String getValue(ThrustCurveMotorSet m) {
return m.getCommonName();
if (!(Application.getPreferences() instanceof SwingPreferences)) {
return m.getCommonName();
}
if (((SwingPreferences) Application.getPreferences()).getMotorNameColumn()) {
return m.getDesignation();
} else {
return m.getCommonName();
}
}
@Override

View File

@ -18,6 +18,7 @@ import java.util.List;
import java.util.Set;
import java.util.prefs.Preferences;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
@ -25,6 +26,7 @@ import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
@ -228,6 +230,47 @@ public class ThrustCurveMotorSelectionPanel extends JPanel implements MotorSelec
}
//// Motor name column
{
JLabel motorNameColumn = new JLabel(trans.get("TCMotorSelPan.lbl.motorNameColumn"));
motorNameColumn.setToolTipText(trans.get("TCMotorSelPan.lbl.motorNameColumn.ttip"));
JRadioButton commonName = new JRadioButton(trans.get("TCMotorSelPan.btn.commonName"));
JRadioButton designation = new JRadioButton(trans.get("TCMotorSelPan.btn.designation"));
ButtonGroup bg = new ButtonGroup();
bg.add(commonName);
bg.add(designation);
commonName.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((SwingPreferences) Application.getPreferences()).setMotorNameColumn(false);
int selectedRow = table.getSelectedRow();
model.fireTableDataChanged();
if (selectedRow >= 0) {
table.setRowSelectionInterval(selectedRow, selectedRow);
}
}
});
designation.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((SwingPreferences) Application.getPreferences()).setMotorNameColumn(true);
int selectedRow = table.getSelectedRow();
model.fireTableDataChanged();
if (selectedRow >= 0) {
table.setRowSelectionInterval(selectedRow, selectedRow);
}
}
});
boolean initValue = ((SwingPreferences) Application.getPreferences()).getMotorNameColumn();
commonName.setSelected(!initValue);
designation.setSelected(initValue);
panel.add(motorNameColumn, "gapleft para");
panel.add(commonName);
panel.add(designation, "spanx, growx, wrap");
}
//// Motor selection table
{
table = new JTable(model);

View File

@ -246,7 +246,21 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
}
});
this.add(rocksimWarningDialogBox,"spanx, wrap");
//// Clear cached preferences
final JButton clearCachedPreferences = new SelectColorButton(trans.get("pref.dlg.but.clearCachedPreferences"));
clearCachedPreferences.setToolTipText(trans.get("pref.dlg.but.clearCachedPreferences.ttip"));
clearCachedPreferences.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int resultYesNo = JOptionPane.showConfirmDialog(parent, trans.get("pref.dlg.clearCachedPreferences.message"),
trans.get("pref.dlg.clearCachedPreferences.title"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (resultYesNo == JOptionPane.YES_OPTION) {
preferences.clearPreferences();
}
}
});
this.add(clearCachedPreferences, "spanx, pushy, bottom, wrap");
}
@ -326,6 +340,13 @@ public class GeneralPreferencesPanel extends PreferencesPanel {
// Nothing went wrong (yay!)
ReleaseStatus status = info.getReleaseStatus();
ReleaseInfo release = info.getLatestRelease();
// Do nothing if the release is part of the ignore versions
if (preferences.getIgnoreVersions().contains(release.getReleaseName())) {
return;
}
// Display software updater dialog, based on the current build version status
switch (status) {
case LATEST:
JOptionPane.showMessageDialog(this,

View File

@ -31,7 +31,6 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
private Color flameColor = new Color(255, 100, 50);
private boolean smoke = false;
private Color smokeColor = new Color(230, 230, 230, 102);
private double smokeOpacity = 0.4;
private boolean sparks = false;
private double exhaustScale = 1.0;
private double flameAspectRatio = 1.0;
@ -204,19 +203,23 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
}
public void setSmokeColor(Color smokeColor) {
smokeColor.setAlpha(this.smokeColor.getAlpha());
this.smokeColor = smokeColor;
fireChangeEvent();
}
public double getSmokeAlpha() {
return smokeColor.getAlpha() / 255f;
}
public void setSmokeAlpha(double alpha) {
smokeColor.setAlpha((int) (alpha * 255));
fireChangeEvent();
}
public double getSmokeOpacity() {
return smokeColor.getAlpha() / 255f;
}
public void setSmokeOpacity(double smokeOpacity) {
setSmokeAlpha(smokeOpacity);
}
public boolean isSparks() {
return sparks;
@ -271,13 +274,4 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings
this.sparkWeight = sparkWeight;
fireChangeEvent();
}
public double getSmokeOpacity() {
return smokeOpacity;
}
public void setSmokeOpacity(double smokeOpacity) {
this.smokeOpacity = smokeOpacity;
setSmokeAlpha(smokeOpacity);
}
}

View File

@ -152,8 +152,6 @@ public final class FlameRenderer {
public Color getSmokeColor();
public double getSmokeAlpha();
public double getFlameAspectRatio();
public boolean isSparks();

View File

@ -331,7 +331,7 @@ public class ComponentAddButtons extends JPanel implements Scrollable {
// Add labels
String[] l = text.split("\n");
for (int i = 0; i < l.length; i++) {
add(new StyledLabel(l[i], SwingConstants.CENTER, -3.0f), "growx");
add(new StyledLabel(l[i], SwingConstants.CENTER, -2.0f), "growx");
}
add(new JLabel(), "push, sizegroup spacing");

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.gui.main;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@ -90,7 +91,7 @@ public class DocumentSelectionModel {
* @return the currently selected rocket components, or <code>null</code>.
*/
public List<RocketComponent> getSelectedComponents() {
if (componentSelection.size() == 0) return null;
if (componentSelection.size() == 0) return Collections.emptyList();
return componentSelection;
}

View File

@ -183,22 +183,19 @@ public class SimulationPanel extends JPanel {
@Override
public void mouseClicked(MouseEvent e) {
int selectedRow = simulationTable.getSelectedRow();
int row = simulationTable.rowAtPoint(e.getPoint());
int column = simulationTable.columnAtPoint(e.getPoint());
// Clear the table selection when clicked outside the table rows.
if (row == -1 || column == -1 || selectedRow == -1) {
simulationTable.clearSelection();
return;
}
if (e.getButton() == MouseEvent.BUTTON1) {
// Clear the table selection when clicked outside the table rows.
if (e.getClickCount() == 1) {
int row = simulationTable.rowAtPoint(e.getPoint());
int column = simulationTable.columnAtPoint(e.getPoint());
if (row == -1 || column == -1) {
simulationTable.clearSelection();
}
}
// Edit the simulation or plot/export
else if (e.getClickCount() == 2) {
if (e.getClickCount() == 2) {
int selected = simulationTable.convertRowIndexToModel(selectedRow);
int column = simulationTable.columnAtPoint(e.getPoint());
if (column == 0) {
SimulationWarningDialog.showWarningDialog(SimulationPanel.this, document.getSimulations().get(selected));
} else {

View File

@ -427,6 +427,7 @@ public class SimulationPlot {
// Plot the markers
if (config.getDomainAxisType() == FlightDataType.TYPE_TIME) {
double markerWidth = 0.01 * plot.getDomainAxis().getUpperBound();
// Domain time is plotted as vertical markers
for (int i = 0; i < eventTimes.size(); i++) {
@ -441,6 +442,10 @@ public class SimulationPlot {
m.setAlpha(0.7f);
m.setLabelFont(new Font("Dialog", Font.PLAIN, 13));
plot.addDomainMarker(m);
if (t > plot.getDomainAxis().getUpperBound() - markerWidth) {
plot.setDomainAxis(new PresetNumberAxis(plot.getDomainAxis().getLowerBound(), t + markerWidth));
}
}
} else {

View File

@ -71,7 +71,7 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
*/
private static final String NODENAME = (DEBUG ? "OpenRocket-debug" : "OpenRocket");
private final Preferences PREFNODE;
private Preferences PREFNODE;
public SwingPreferences() {
@ -93,7 +93,20 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
//////////////////////
public void clearPreferences() {
try {
Preferences root = Preferences.userRoot();
if (root.nodeExists(NODENAME)) {
root.node(NODENAME).removeNode();
}
PREFNODE = root.node(NODENAME);
UnitGroup.resetDefaultUnits();
storeDefaultUnits();
log.info("Cleared preferences");
} catch (BackingStoreException e) {
throw new BugException("Unable to clear preference node", e);
}
}
/**
* Store the current OpenRocket version into the preferences to allow for preferences migration.
@ -331,7 +344,23 @@ public class SwingPreferences extends net.sf.openrocket.startup.Preferences {
// TODO: MEDIUM: Motor fill color (settable?)
return new Color(0, 0, 0, 100);
}
/**
* Check whether to display the common name (false), or designation (true) in the motor selection table "Name" column
* @return true to display designation, false to display common name
*/
public boolean getMotorNameColumn() {
return getBoolean(net.sf.openrocket.startup.Preferences.MOTOR_NAME_COLUMN, true);
}
/**
* Set whether to display the common name, or designation in the motor selection table "Name" column
* @param value if true, display designation, if false, display common name
*/
public void setMotorNameColumn(boolean value) {
putBoolean(net.sf.openrocket.startup.Preferences.MOTOR_NAME_COLUMN, value);
}
public static int getMaxThreadCount() {

View File

@ -7,6 +7,7 @@ import java.awt.desktop.PreferencesHandler;
import java.awt.desktop.QuitHandler;
import java.awt.desktop.AppReopenedListener;
import net.sf.openrocket.communication.UpdateInfoRetriever;
import net.sf.openrocket.gui.util.DummyFrameMenuOSX;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -56,6 +57,10 @@ final class OSXSetup {
if (BasicFrame.isFramesEmpty()) {
log.info("App re-opened");
BasicFrame.reopen();
// Also check for software updates
final UpdateInfoRetriever updateRetriever = SwingStartup.startUpdateChecker();
SwingStartup.checkUpdateStatus(updateRetriever);
}
};

View File

@ -193,15 +193,7 @@ public class SwingStartup {
guiModule.startLoader();
// Start update info fetching
final UpdateInfoRetriever updateRetriever;
if (Application.getPreferences().getCheckUpdates()) {
log.info("Starting update check");
updateRetriever = new UpdateInfoRetriever();
updateRetriever.startFetchUpdateInfo();
} else {
log.info("Update check disabled");
updateRetriever = null;
}
final UpdateInfoRetriever updateRetriever = startUpdateChecker();
// Set the best available look-and-feel
log.info("Setting best LAF");
@ -248,9 +240,21 @@ public class SwingStartup {
}
}
public static UpdateInfoRetriever startUpdateChecker() {
final UpdateInfoRetriever updateRetriever;
if (Application.getPreferences().getCheckUpdates()) {
log.info("Starting update check");
updateRetriever = new UpdateInfoRetriever();
updateRetriever.startFetchUpdateInfo();
} else {
log.info("Update check disabled");
updateRetriever = null;
}
return updateRetriever;
}
private void checkUpdateStatus(final UpdateInfoRetriever updateRetriever) {
public static void checkUpdateStatus(final UpdateInfoRetriever updateRetriever) {
if (updateRetriever == null)
return;
@ -268,10 +272,12 @@ public class SwingStartup {
if (!updateRetriever.isRunning()) {
timer.stop();
final SwingPreferences preferences = (SwingPreferences) Application.getPreferences();
UpdateInfo info = updateRetriever.getUpdateInfo();
// Only display something when an update is found
if (info != null && info.getException() == null && info.getReleaseStatus() == ReleaseStatus.OLDER) {
if (info != null && info.getException() == null && info.getReleaseStatus() == ReleaseStatus.OLDER &&
!preferences.getIgnoreVersions().contains(info.getLatestRelease().getReleaseName())) {
UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
infoDialog.setVisible(true);
}