Merge branch 'unstable' into issue-1001
This commit is contained in:
commit
2c9877b68b
Binary file not shown.
@ -90,12 +90,13 @@ dlg.but.cancel = Cancel
|
||||
dlg.but.close = Close
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = Image files
|
||||
FileHelper.CSV_FILTER = Comma Separated Files (*.csv)
|
||||
FileHelper.PDF_FILTER = PDF files (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = All rocket designs (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket designs (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim designs (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = Image files
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -515,7 +516,6 @@ RK4SimulationStepper.error.valuesTooLarge = Simulation values exceeded limits.
|
||||
SimulationModifierTree.OptimizationParameters = Optimization Parameters
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Comma Separated Files (*.csv)
|
||||
SimExpPan.border.Vartoexport = Variables to export
|
||||
SimExpPan.border.Stage = Stage to export
|
||||
SimExpPan.but.Selectall = Select all
|
||||
@ -769,6 +769,9 @@ BodyTubecfg.tab.Generalproperties = General properties
|
||||
BodyTubecfg.tab.Motor = Motor
|
||||
BodyTubecfg.tab.Motormountconf = Motor mount configuration
|
||||
BodyTubecfg.checkbox.Automatic = Automatic
|
||||
BodyTubecfg.checkbox.ttip.Automatic = Use the diameter of the previous/next component
|
||||
BodyTubecfg.checkbox.ttip.Automatic_noReferenceComponent = There is no previous/next component to take the diameter of
|
||||
BodyTubecfg.checkbox.ttip.Automatic_alreadyAuto = The previous/next component already has its auto setting turned on
|
||||
BodyTubecfg.checkbox.Filled = Filled
|
||||
|
||||
! FinSetConfig
|
||||
@ -948,6 +951,7 @@ FreeformFinSetConfig.lbl.doubleClick2 = to edit
|
||||
FreeformFinSetConfig.lbl.clickDrag = Click+drag: Add and move points
|
||||
FreeformFinSetConfig.lbl.ctrlClick = Ctrl+click: Remove point
|
||||
FreeformFinSetConfig.lbl.scaleFin = Scale Fin
|
||||
FreeformFinSetConfig.lbl.exportCSV = Export CSV
|
||||
|
||||
!TubeFinSetConfig
|
||||
TubeFinSetCfg.lbl.Nbroffins = Number of fins:
|
||||
@ -1038,6 +1042,9 @@ NoseConeCfg.lbl.Shapeparam = Shape parameter:
|
||||
NoseConeCfg.lbl.Noseconelength = Nose cone length:
|
||||
NoseConeCfg.lbl.Basediam = Base diameter:
|
||||
NoseConeCfg.checkbox.Automatic = Automatic
|
||||
NoseConeCfg.checkbox.ttip.Automatic = Use the diameter of the next component
|
||||
NoseConeCfg.checkbox.ttip.Automatic_noReferenceComponent = There is no next component to take the diameter of
|
||||
NoseConeCfg.checkbox.ttip.Automatic_alreadyAuto = The next component already has its auto setting turned on
|
||||
NoseConeCfg.lbl.Wallthickness = Wall thickness:
|
||||
NoseConeCfg.checkbox.Filled = Filled
|
||||
NoseConeCfg.tab.General = General
|
||||
@ -1139,6 +1146,9 @@ TransitionCfg.lbl.Shapeparam = Shape parameter:
|
||||
TransitionCfg.lbl.Transitionlength = Transition length:
|
||||
TransitionCfg.lbl.Forediam = Fore diameter:
|
||||
TransitionCfg.checkbox.Automatic = Automatic
|
||||
TransitionCfg.checkbox.ttip.Automatic = Use the diameter of the previous/next component
|
||||
TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent = There is no previous/next component to take the diameter of
|
||||
TransitionCfg.checkbox.ttip.Automatic_alreadyAuto = The previous/next component already has its auto setting turned on
|
||||
TransitionCfg.lbl.Aftdiam = Aft diameter:
|
||||
TransitionCfg.lbl.Wallthickness = Wall thickness:
|
||||
TransitionCfg.checkbox.Filled = Filled
|
||||
@ -1215,6 +1225,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Select thrust curve:
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Ejection charge delay:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = None
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Number of seconds or \"None\")
|
||||
TCMotorSelPan.lbl.Designation = Designation:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Total impulse:
|
||||
TCMotorSelPan.lbl.Avgthrust = Avg. thrust:
|
||||
TCMotorSelPan.lbl.Maxthrust = Max. thrust:
|
||||
@ -1591,7 +1602,7 @@ FlightEvent.Type.EXCEPTION = Exception
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Manufacturer
|
||||
TCurveMotorCol.DESIGNATION = Designation
|
||||
TCurveMotorCol.COMMON_NAME = Name
|
||||
TCurveMotorCol.CASEINFO = Case
|
||||
TCurveMotorCol.DIAMETER = Diameter
|
||||
TCurveMotorCol.LENGTH = Length
|
||||
|
@ -57,9 +57,10 @@ RocketPanel.lbl.infoMessage = <html>Stiskni k oznacen
|
||||
|
||||
|
||||
! BasicFrame
|
||||
BasicFrame.SimpleFileFilter1 = V\u0161echny návrhy raket (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = Návrhy OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = Návrhy RockSim (*.rkt)
|
||||
FileHelper.ALL_DESIGNS_FILTER = V\u0161echny návrhy raket (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Návrhy OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Návrhy RockSim (*.rkt)
|
||||
FileHelper.CSV_FILTER = Soubory s cárkovým oddelovacem (*.csv)
|
||||
BasicFrame.tab.Rocketdesign = Návrh rakety
|
||||
BasicFrame.tab.Flightsim = Letová simulace
|
||||
BasicFrame.title.Addnewcomp = Pridej novou komponentu
|
||||
@ -94,7 +95,7 @@ dlg.but.close = Zavr
|
||||
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = Soubory PDF
|
||||
FileHelper.PDF_FILTER = Soubory PDF
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -410,7 +411,6 @@ RK4SimulationStepper.error.valuesTooLarge = Hodnoty simulace prekrocily limity.
|
||||
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Soubory s cárkovým oddelovacem (*.csv)
|
||||
SimExpPan.border.Vartoexport = Promenné k exportu
|
||||
SimExpPan.but.Selectall = Oznac v\u0161e
|
||||
SimExpPan.but.Selectnone = Nic neoznacuj
|
||||
@ -945,6 +945,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Vyber v
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Oddelovací zpo\u017Edení:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = Nic
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Pocet sekund nebo \"Nic\")
|
||||
TCMotorSelPan.lbl.Designation = Pojmenování:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Celkový impulse:
|
||||
TCMotorSelPan.lbl.Avgthrust = Prumerný tah:
|
||||
TCMotorSelPan.lbl.Maxthrust = Maximální tah:
|
||||
@ -1214,7 +1215,8 @@ FlightEvent.Type.ALTITUDE = Zmena v
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Výrobce
|
||||
TCurveMotorCol.DESIGNATION = Pojmenování
|
||||
TCurveMotorCol.COMMON_NAME = Jméno
|
||||
! TCurveMotorCol.DESIGNATION = Pojmenování
|
||||
TCurveMotorCol.TYPE = Druh
|
||||
TCurveMotorCol.DIAMETER = Prumer
|
||||
TCurveMotorCol.LENGTH = Délka
|
||||
|
@ -90,12 +90,13 @@ dlg.but.close = Schlie
|
||||
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files
|
||||
BasicFrame.SimpleFileFilter1 = Alle Raketendesigns (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket Designs (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim Designs (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = Image files
|
||||
FileHelper.PDF_FILTER = PDF files
|
||||
FileHelper.ALL_DESIGNS_FILTER = Alle Raketendesigns (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket Designs (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim Designs (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = Image files
|
||||
FileHelper.CSV_FILTER = Komma getrennte Werte (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -413,7 +414,6 @@ RK4SimulationStepper.error.valuesTooLarge = Simulationswerte
|
||||
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Komma getrennte Werte (*.csv)
|
||||
SimExpPan.border.Vartoexport = zu exportierende Variablen
|
||||
SimExpPan.but.Selectall = Alle auswählen
|
||||
SimExpPan.but.Selectnone = Keine auswählen
|
||||
@ -1002,6 +1002,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Schubkurve ausw
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Verzögerung der Ausstoßladung:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = keine
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Anzahl der Sekunden oder \«keine\«)
|
||||
TCMotorSelPan.lbl.Designation = Bezeichnung:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Gesamtimpuls:
|
||||
TCMotorSelPan.lbl.Avgthrust = Durchschn. Schub:
|
||||
TCMotorSelPan.lbl.Maxthrust = max. Schub
|
||||
@ -1273,7 +1274,8 @@ FlightEvent.Type.ALTITUDE = H
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Hersteller
|
||||
TCurveMotorCol.DESIGNATION = Bezeichnung
|
||||
TCurveMotorCol.COMMON_NAME = Name
|
||||
! TCurveMotorCol.DESIGNATION = Bezeichnung
|
||||
TCurveMotorCol.TYPE = Typ
|
||||
TCurveMotorCol.DIAMETER = Durchmesser
|
||||
TCurveMotorCol.LENGTH = Länge
|
||||
|
@ -42,10 +42,11 @@ AppearanceCfg.lbl.texture.repeat = Aspecto:
|
||||
AppearanceCfg.lbl.texture.rotation = Rotaci\u00f3n:
|
||||
AppearanceCfg.lbl.texture.scale = Escala:
|
||||
|
||||
BasicFrame.SimpleFileFilter1 = Todos los dise\u00f1os de cohete(*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = Dise\u00f1os OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = Dise\u00f1os RockSim (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = Preajustes OpenRocket (*.orc)
|
||||
FileHelper.ALL_DESIGNS_FILTER = Todos los dise\u00f1os de cohete(*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Dise\u00f1os OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Dise\u00f1os RockSim (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = Preajustes OpenRocket (*.orc)
|
||||
FileHelper.CSV_FILTER = Documentos separados por comas (*.csv)
|
||||
BasicFrame.StageName.Sustainer = Etapa principal
|
||||
BasicFrame.WarningDialog.title = Alertas al abrir el archivo
|
||||
BasicFrame.WarningDialog.txt1 = Mientras se abr\u00eda el archivo, se encontraron los siguiente problemas
|
||||
@ -991,7 +992,6 @@ SimExpPan.checkbox.ttip.Incflightevents = Incluye una l\u00ednea de comentario
|
||||
SimExpPan.checkbox.ttip.Includefielddesc = Incluye una l\u00ednea de comentario con las descripciones de las variables exportadas.
|
||||
SimExpPan.checkbox.ttip.Includesimudesc = Incluye un comentario en el inicio del documento describiendo la simulaci\u00f3n.
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Documentos separados por comas (*.csv)
|
||||
SimExpPan.lbl.Commentchar = Caracter de comentario:
|
||||
SimExpPan.lbl.Fieldsepstr = Caracter separador de campo:
|
||||
SimExpPan.lbl.longA1 = <html>Caracter para separar campos en el documento exportado.<br>
|
||||
@ -1110,6 +1110,7 @@ StreamerCfg.tab.Radialpos = Posici\u00f3n radial
|
||||
StreamerCfg.tab.ttip.General = Propiedades generales
|
||||
StreamerCfg.tab.ttip.Radialpos = Configuraci\u00f3n de posici\u00f3n radial
|
||||
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.Diameter = Di\u00e1metro
|
||||
TCMotorSelPan.Length = Longitud
|
||||
TCMotorSelPan.MotorMountDimensions = Dimensiones del porta motor:
|
||||
@ -1140,8 +1141,8 @@ TCMotorSelPan.lbl.Motormountdia = Di\u00e1metro del porta motor:
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (segundos)
|
||||
TCMotorSelPan.lbl.Search = Buscar:
|
||||
TCMotorSelPan.lbl.Selectthrustcurve = Seleccione curva de empuje:
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.lbl.Selrocketmotor = Seleccione el motor del cohete:
|
||||
TCMotorSelPan.lbl.Designation = Designaci\u00f3n
|
||||
TCMotorSelPan.lbl.Totalimpulse = Impulso total:
|
||||
TCMotorSelPan.noDescription = No hay una descripci\u00f3n disponible
|
||||
TCMotorSelPan.title.Thrust = Empuje
|
||||
@ -1156,10 +1157,11 @@ TCurveMotor.ttip.length = Longitud:
|
||||
TCurveMotor.ttip.maxThrust = Empuje m\u00e1ximo:
|
||||
TCurveMotor.ttip.totalImpulse = Impulso total:
|
||||
|
||||
TCurveMotorCol.DESIGNATION = Designaci\u00f3n
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.COMMON_NAME = Nombre
|
||||
! TCurveMotorCol.DESIGNATION = Designaci\u00f3n
|
||||
TCurveMotorCol.DIAMETER = Di\u00e1metro
|
||||
TCurveMotorCol.LENGTH = Longitud
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Fabricante
|
||||
TCurveMotorCol.TOTAL_IMPULSE = Impulso total
|
||||
TCurveMotorCol.TYPE = Tipo
|
||||
@ -1422,9 +1424,9 @@ exdesigndlg.lbl.Examplesnotfound = Ejemplos no encontrados
|
||||
exdesigndlg.lbl.Openexampledesign = Abrir un dise\u00f1o de ejemplo
|
||||
exdesigndlg.lbl.Selectexample = Dise\u00f1os de ejemplo:
|
||||
|
||||
filetypes.images = Archivos de imagen
|
||||
FileHelper.IMAGES = Archivos de imagen
|
||||
! General file type names
|
||||
filetypes.pdf = Archivos PDF
|
||||
FileHelper.PDF_FILTER = Archivos PDF
|
||||
|
||||
main.menu.analyze = Analizar
|
||||
main.menu.analyze.componentAnalysis = An\u00e1lisis de los componentes
|
||||
|
@ -39,10 +39,11 @@ AppearanceCfg.lbl.texture.repeat = R\u00E9p\u00E9ter:
|
||||
AppearanceCfg.lbl.texture.rotation = Rotation:
|
||||
AppearanceCfg.lbl.texture.scale = Echelle:
|
||||
|
||||
BasicFrame.SimpleFileFilter1 = Tous les fichiers fus\u00E9e (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = Fichiers OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = Fichiers RockSim (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = Pi\u00E8ces OpenRocket pr\u00E9configur\u00E9es (*.orc)
|
||||
FileHelper.ALL_DESIGNS_FILTER = Tous les fichiers fus\u00E9e (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Fichiers OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Fichiers RockSim (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = Pi\u00E8ces OpenRocket pr\u00E9configur\u00E9es (*.orc)
|
||||
FileHelper.CSV_FILTER = Fichiers dont les donn\u00E9es sont s\u00E9par\u00E9es par une virgule (*.csv)
|
||||
BasicFrame.StageName.Sustainer = Sustainer
|
||||
BasicFrame.WarningDialog.title = Avertissement lors de l'ouverture du fichier
|
||||
BasicFrame.WarningDialog.txt1 = Les probl\u00E8mes suivant sont survenus lors de l'ouverture de
|
||||
@ -983,7 +984,6 @@ SimExpPan.checkbox.ttip.Incflightevents = Inclure une ligne de commentaire pour
|
||||
SimExpPan.checkbox.ttip.Includefielddesc = Inclure une ligne de commentaire avec la description des variables export\u00E9es.
|
||||
SimExpPan.checkbox.ttip.Includesimudesc = Inclure un commentaire au d\u00E9but du fichier pour d\u00E9crire la simulation.
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Fichiers dont les donn\u00E9es sont s\u00E9par\u00E9es par une virgule (*.csv)
|
||||
SimExpPan.lbl.Commentchar = Symbole pour les commentaires:
|
||||
SimExpPan.lbl.Fieldsepstr = S\u00E9parateur de champ:
|
||||
SimExpPan.lbl.longA1 = <html>La cha\u00EEne utilis\u00E9e pour s\u00E9parer les champs dans le fichier export\u00E9.<br>
|
||||
@ -1104,6 +1104,7 @@ StreamerCfg.tab.Radialpos = Position sur le p\u00E9rim\u00E8tre
|
||||
StreamerCfg.tab.ttip.General = Propri\u00E9t\u00E9s g\u00E9n\u00E9rales
|
||||
StreamerCfg.tab.ttip.Radialpos = Configuration de la position sur le p\u00E9rim\u00E8tre
|
||||
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.Diameter = Diametre
|
||||
TCMotorSelPan.Length = Longueur
|
||||
TCMotorSelPan.MotorMountDimensions = Dimentions du porte moteur:
|
||||
@ -1134,8 +1135,8 @@ TCMotorSelPan.lbl.Motormountdia = Diam\u00E8tre du tube porte moteur:
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Nombre de secondes ou "Aucun")
|
||||
TCMotorSelPan.lbl.Search = Rechercher:
|
||||
TCMotorSelPan.lbl.Selectthrustcurve = Choisir la courbe de pouss\u00E9e:
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.lbl.Selrocketmotor = Choisir le moteur fus\u00E9e:
|
||||
TCMotorSelPan.lbl.Designation = D\u00E9signation
|
||||
TCMotorSelPan.lbl.Totalimpulse = Impulsion totale:
|
||||
TCMotorSelPan.noDescription = Aucune description disponible
|
||||
TCMotorSelPan.title.Thrust = Pouss\u00E9e
|
||||
@ -1150,10 +1151,11 @@ TCurveMotor.ttip.length = Longueur:
|
||||
TCurveMotor.ttip.maxThrust = Pouss\u00E9e Maximum:
|
||||
TCurveMotor.ttip.totalImpulse = Impulsion Totale:
|
||||
|
||||
TCurveMotorCol.DESIGNATION = D\u00E9signation
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.COMMON_NAME = Nom
|
||||
! TCurveMotorCol.DESIGNATION = D\u00E9signation
|
||||
TCurveMotorCol.DIAMETER = Diam\u00E8tre
|
||||
TCurveMotorCol.LENGTH = Longueur
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Fabricant
|
||||
TCurveMotorCol.TOTAL_IMPULSE = Impultion total
|
||||
TCurveMotorCol.TYPE = Type
|
||||
@ -1416,9 +1418,9 @@ exdesigndlg.lbl.Examplesnotfound = Exemples non trouv\u00E9s
|
||||
exdesigndlg.lbl.Openexampledesign = Ouvrir un exemple de projet
|
||||
exdesigndlg.lbl.Selectexample = Choisir l'exemple de projet \u00E0 ouvrir:
|
||||
|
||||
filetypes.images = Fichiers Image
|
||||
FileHelper.IMAGES = Fichiers Image
|
||||
! General file type names
|
||||
filetypes.pdf = fichier PDF
|
||||
FileHelper.PDF_FILTER = fichier PDF
|
||||
|
||||
main.menu.analyze = Analyse
|
||||
main.menu.analyze.componentAnalysis = Analyse des Pi\u00E8ces
|
||||
|
@ -92,12 +92,13 @@ dlg.but.close = Chiudi
|
||||
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files
|
||||
BasicFrame.SimpleFileFilter1 = Tutti i disegni di razzi (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = Disegni di OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = Disegni di RockSim (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = Image files
|
||||
FileHelper.PDF_FILTER = PDF files
|
||||
FileHelper.ALL_DESIGNS_FILTER = Tutti i disegni di razzi (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Disegni di OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Disegni di RockSim (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = Image files
|
||||
FileHelper.CSV_FILTER = Valori separati da virgola (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -415,7 +416,6 @@ RK4SimulationStepper.error.valuesTooLarge = I valori di simulazione anno eccedut
|
||||
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Valori separati da virgola (*.csv)
|
||||
SimExpPan.border.Vartoexport = Variabili da esportare
|
||||
SimExpPan.but.Selectall = Seleziona tutto
|
||||
SimExpPan.but.Selectnone = Deseleziona tutto
|
||||
@ -1004,6 +1004,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Seleziona la curva di spinta:
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Ritardo della carica di espulsione:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = Nessun
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Numero di secondi o \"Nessuno\")
|
||||
TCMotorSelPan.lbl.Designation = Classe:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Impulso totale:
|
||||
TCMotorSelPan.lbl.Avgthrust = Spinta media:
|
||||
TCMotorSelPan.lbl.Maxthrust = Spinta max.:
|
||||
@ -1277,7 +1278,8 @@ FlightEvent.Type.ALTITUDE = Cambio altitudine
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Produttore
|
||||
TCurveMotorCol.DESIGNATION = Classe
|
||||
TCurveMotorCol.COMMON_NAME = Nome
|
||||
! TCurveMotorCol.DESIGNATION = Classe
|
||||
TCurveMotorCol.TYPE = Tipo
|
||||
TCurveMotorCol.DIAMETER = Diametro
|
||||
TCurveMotorCol.LENGTH = Lunghezza
|
||||
|
@ -86,12 +86,13 @@ dlg.but.cancel = \u30AD\u30E3\u30F3\u30BB\u30EB
|
||||
dlg.but.close = \u9589\u3058\u308B
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = \u753B\u50CF\u30D5\u30A1\u30A4\u30EB
|
||||
FileHelper.PDF_FILTER = PDF files (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = All rocket designs (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket designs (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim designs (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = \u753B\u50CF\u30D5\u30A1\u30A4\u30EB
|
||||
FileHelper.CSV_FILTER = Comma Separated Files (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -421,7 +422,6 @@ RK4SimulationStepper.error.valuesTooLarge = \u30B7\u30DF\u30E5\u30EC\u30FC\u30B
|
||||
SimulationModifierTree.OptimizationParameters = \u6700\u9069\u5316\u30D1\u30E9\u30E1\u30FC\u30BF
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Comma Separated Files (*.csv)
|
||||
SimExpPan.border.Vartoexport = \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3059\u308B\u5909\u6570
|
||||
SimExpPan.but.Selectall = \u5168\u3066\u9078\u629E
|
||||
SimExpPan.but.Selectnone = \u5168\u3066\u975E\u9078\u629E
|
||||
@ -1035,6 +1035,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = \u63A8\u529B\u5C65\u6B74\uFF1A
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Ejection charge delay:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = None
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Number of seconds or \"None\")
|
||||
TCMotorSelPan.lbl.Designation = \u8A18\u53F7
|
||||
TCMotorSelPan.lbl.Totalimpulse = \u30C8\u30FC\u30BF\u30EB\u30A4\u30F3\u30D1\u30EB\u30B9\uFF1A
|
||||
TCMotorSelPan.lbl.Avgthrust = \u5E73\u5747\u63A8\u529B\uFF1A
|
||||
TCMotorSelPan.lbl.Maxthrust = \u6700\u5927\u63A8\u529B\uFF1A
|
||||
@ -1326,7 +1327,8 @@ FlightEvent.Type.ALTITUDE = \u59FF\u52E2\u5909\u66F4
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = \u30E1\u30FC\u30AB\u30FC
|
||||
TCurveMotorCol.DESIGNATION = \u8A18\u53F7
|
||||
! TCurveMotorCol.DESIGNATION = \u8A18\u53F7
|
||||
TCurveMotorCol.COMMON_NAME = \u8A18\u53F7
|
||||
TCurveMotorCol.TYPE = \u30BF\u30A4\u30D7
|
||||
TCurveMotorCol.DIAMETER = \u76F4\u5F84
|
||||
TCurveMotorCol.LENGTH = \u9577\u3055
|
||||
|
@ -92,12 +92,13 @@ dlg.but.cancel = Annuleer
|
||||
dlg.but.close = Sluit
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF-bestanden (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = Alle raketontwerpen (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket-ontwerpen (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim-ontwerpen (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket-presets (*.orc)
|
||||
filetypes.images = Afbeelding-bestanden
|
||||
FileHelper.PDF_FILTER = PDF-bestanden (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = Alle raketontwerpen (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket-ontwerpen (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim-ontwerpen (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket-presets (*.orc)
|
||||
FileHelper.IMAGES = Afbeelding-bestanden
|
||||
FileHelper.CSV_FILTER = Komma-gescheiden bestanden (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -513,7 +514,6 @@ RK4SimulationStepper.error.valuesTooLarge = Simulatiewaarden overschreden limiet
|
||||
SimulationModifierTree.OptimizationParameters = Optimalisatieparameters
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Komma-gescheiden bestanden (*.csv)
|
||||
SimExpPan.border.Vartoexport = Variabelen om te exporteren
|
||||
SimExpPan.border.Stage = Trap om te exporteren
|
||||
SimExpPan.but.Selectall = Selecteer alles
|
||||
@ -1201,6 +1201,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Selecteer stuwkrachtcurve:
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Vertraging schietlading:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = Geen
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Aantal seconden of \"Geen\")
|
||||
TCMotorSelPan.lbl.Designation = Benaming
|
||||
TCMotorSelPan.lbl.Totalimpulse = Totale impuls:
|
||||
TCMotorSelPan.lbl.Avgthrust = Gemiddelde stuwkracht:
|
||||
TCMotorSelPan.lbl.Maxthrust = Max. stuwkracht:
|
||||
@ -1576,7 +1577,8 @@ FlightEvent.Type.EXCEPTION = Uitzondering
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Fabrikant
|
||||
TCurveMotorCol.DESIGNATION = Benaming
|
||||
TCurveMotorCol.COMMON_NAME = Naam
|
||||
! TCurveMotorCol.DESIGNATION = Benaming
|
||||
TCurveMotorCol.CASEINFO = Behuizing
|
||||
TCurveMotorCol.DIAMETER = Diameter
|
||||
TCurveMotorCol.LENGTH = Lengte
|
||||
|
@ -91,12 +91,13 @@
|
||||
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = Pliki PDF (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = Wszystkie projekty rakiet (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = Projekty OpenRocket (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter3 = Projekty RockSim (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = Ustawienia OpenRocket (*.orc)
|
||||
filetypes.images = Pliki obrazów
|
||||
FileHelper.PDF_FILTER = Pliki PDF (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = Wszystkie projekty rakiet (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Projekty OpenRocket (*.ork; *.rkt)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Projekty RockSim (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = Ustawienia OpenRocket (*.orc)
|
||||
FileHelper.IMAGES = Pliki obrazów
|
||||
FileHelper.CSV_FILTER = Pliki rozdzielone przecinkiem (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -412,7 +413,6 @@
|
||||
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Pliki rozdzielone przecinkiem (*.csv)
|
||||
SimExpPan.border.Vartoexport = Zmienne do wyeksportowania
|
||||
SimExpPan.but.Selectall = Wybierz wszystko
|
||||
SimExpPan.but.Selectnone = Odznacz wszystko
|
||||
@ -947,6 +947,7 @@
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Opó\u017Anienie odpalenia \u0142adunku odrzucaj\u0105cego:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = \u017Badne
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (liczba sekund lub \"Brak\")
|
||||
TCMotorSelPan.lbl.Designation = Oznaczenie:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Ca\u0142kowity impuls:
|
||||
TCMotorSelPan.lbl.Avgthrust = \u015Arednia si\u0142a ci\u0105gu:
|
||||
TCMotorSelPan.lbl.Maxthrust = Maks. si\u0142a ci\u0105gu:
|
||||
@ -1218,7 +1219,8 @@
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Producent
|
||||
TCurveMotorCol.DESIGNATION = Oznaczenie
|
||||
TCurveMotorCol.COMMON_NAME = Nazwa
|
||||
! TCurveMotorCol.DESIGNATION = Oznaczenie
|
||||
TCurveMotorCol.TYPE = Typ
|
||||
TCurveMotorCol.DIAMETER = \u015Arednica
|
||||
TCurveMotorCol.LENGTH = D\u0142ugo\u015B\u0107
|
||||
|
@ -33,10 +33,11 @@ AppearanceCfg.lbl.texture.repeat = Repetir:
|
||||
AppearanceCfg.lbl.texture.rotation = Rota\u00e7\u00e3o:
|
||||
AppearanceCfg.lbl.texture.scale = Escala:
|
||||
|
||||
BasicFrame.SimpleFileFilter1 = Todos os projetos dos foguetes (*.ork; *.rtk)
|
||||
BasicFrame.SimpleFileFilter2 = Projetos OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = Desenhos RockSim (*.rtk)
|
||||
BasicFrame.SimpleFileFilter4 = Pr\u00e9-defini\u00e7\u00f5es OpenRocket (*.orc)
|
||||
FileHelper.ALL_DESIGNS_FILTER = Todos os projetos dos foguetes (*.ork; *.rtk)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = Projetos OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = Desenhos RockSim (*.rtk)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = Pr\u00e9-defini\u00e7\u00f5es OpenRocket (*.orc)
|
||||
FileHelper.CSV_FILTER = Arquivos Separados por V\u00edrgulas (*.csv)
|
||||
BasicFrame.StageName.Sustainer = Sustentador
|
||||
BasicFrame.WarningDialog.title = Avisos ao abrir arquivo
|
||||
BasicFrame.WarningDialog.txt1 = Os seguintes problemas foram encontrados durante a abertura
|
||||
@ -966,7 +967,6 @@ SimExpPan.checkbox.ttip.Incflightevents = Incluir uma linha de coment\u00e1rio
|
||||
SimExpPan.checkbox.ttip.Includefielddesc = Incluir uma linha de coment\u00e1rio com as descri\u00e7\u00f5es das vari\u00e1veis exportadas.
|
||||
SimExpPan.checkbox.ttip.Includesimudesc = Incluir um coment\u00e1rio no come\u00e7o do arquivo descrevendo a simula\u00e7\u00e3o.
|
||||
# SimulationExportPanel
|
||||
SimExpPan.desc = Arquivos Separados por V\u00edrgulas (*.csv)
|
||||
SimExpPan.lbl.Commentchar = Caracter de coment\u00e1rio:
|
||||
SimExpPan.lbl.Fieldsepstr = Caracteres separadores de campo:
|
||||
SimExpPan.lbl.longA1 = <html>Cadeia de caracteres utilizada para separar os campos no arquivo exportado.<br>
|
||||
@ -1081,6 +1081,7 @@ StreamerCfg.tab.Radialpos = Posi\u00e7\u00e3o radial
|
||||
StreamerCfg.tab.ttip.General = Propriedades gerais
|
||||
StreamerCfg.tab.ttip.Radialpos = Configura\u00e7\u00e3o posi\u00e7\u00e3o radial
|
||||
|
||||
# ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.SHOW_DESCRIPTIONS.desc1 = Mostrar todos os motores
|
||||
TCMotorSelPan.SHOW_DESCRIPTIONS.desc2 = Mostrar motores com um di\u00e2metro menor do que a montagem do motor
|
||||
TCMotorSelPan.SHOW_DESCRIPTIONS.desc3 = Mostrar motores com um di\u00e2metro igual ao da montagem do motor
|
||||
@ -1099,8 +1100,8 @@ TCMotorSelPan.lbl.Motormountdia = Di\u00e2metro da montagem do motor:
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (N\u00famero de segundos ou "Nenhum")
|
||||
TCMotorSelPan.lbl.Search = Pesquisar:
|
||||
TCMotorSelPan.lbl.Selectthrustcurve = Selecione curva de empuxo:
|
||||
# ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.lbl.Selrocketmotor = Selecione motor do foguete:
|
||||
TCMotorSelPan.lbl.Designation = Designa\u00e7\u00e3o
|
||||
TCMotorSelPan.lbl.Totalimpulse = Impulso total:
|
||||
TCMotorSelPan.noDescription = Nenhuma descri\u00e7\u00e3o dispon\u00edvel.
|
||||
TCMotorSelPan.title.Thrust = Impulso
|
||||
@ -1115,10 +1116,11 @@ TCurveMotor.ttip.length = Comprimento:
|
||||
TCurveMotor.ttip.maxThrust = M\u00e1ximo de impulso:
|
||||
TCurveMotor.ttip.totalImpulse = Impulso total:
|
||||
|
||||
TCurveMotorCol.DESIGNATION = Designa\u00e7\u00e3o
|
||||
# ThrustCurveMotorColumns
|
||||
TCurveMotorCol.COMMON_NAME = Nome
|
||||
! TCurveMotorCol.DESIGNATION = Designa\u00e7\u00e3o
|
||||
TCurveMotorCol.DIAMETER = Di\u00e2metro
|
||||
TCurveMotorCol.LENGTH = Comprimento
|
||||
# ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Fabricante
|
||||
TCurveMotorCol.TYPE = Tipo
|
||||
|
||||
@ -1378,9 +1380,9 @@ exdesigndlg.lbl.Examplesnotfound = Exemplos n\u00e3o encontrados
|
||||
exdesigndlg.lbl.Openexampledesign = Abrir exemplo de projeto
|
||||
exdesigndlg.lbl.Selectexample = Selecione projeto de exemplo para abrir:
|
||||
|
||||
filetypes.images = Arquivos de imagem
|
||||
FileHelper.IMAGES = Arquivos de imagem
|
||||
# General file type names
|
||||
filetypes.pdf = Arquivos PDF (*.pdf)
|
||||
FileHelper.PDF_FILTER = Arquivos PDF (*.pdf)
|
||||
|
||||
main.menu.analyze = Analisar
|
||||
main.menu.analyze.componentAnalysis = An\u00e1lise dos componentes
|
||||
|
@ -91,12 +91,13 @@ dlg.but.cancel = \u041e\u0442\u043c\u0435\u043d\u0430
|
||||
dlg.but.close = \u0417\u0430\u043a\u0440\u044b\u0442\u044c
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = \u0424\u0430\u0439\u043b\u044b PDF (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = \u0412\u0441\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043a\u0435\u0442 (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = \u0424\u0430\u0439\u043b\u044b OpenRocket (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = \u0424\u0430\u0439\u043b\u044b RockSim (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = \u0417\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438 OpenRocket (*.orc)
|
||||
filetypes.images = \u0424\u0430\u0439\u043b\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439
|
||||
FileHelper.PDF_FILTER = \u0424\u0430\u0439\u043b\u044b PDF (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = \u0412\u0441\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u0440\u0430\u043a\u0435\u0442 (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = \u0424\u0430\u0439\u043b\u044b OpenRocket (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = \u0424\u0430\u0439\u043b\u044b RockSim (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = \u0417\u0430\u0433\u043e\u0442\u043e\u0432\u043a\u0438 OpenRocket (*.orc)
|
||||
FileHelper.IMAGES = \u0424\u0430\u0439\u043b\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439
|
||||
FileHelper.CSV_FILTER = \u0422\u0435\u043a\u0441\u0442, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u0438 (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -465,7 +466,6 @@ RK4SimulationStepper.error.valuesTooLarge = \u0417\u043d\u0430\u0447\u0435\u043d
|
||||
SimulationModifierTree.OptimizationParameters = \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = \u0422\u0435\u043a\u0441\u0442, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u0438 (*.csv)
|
||||
SimExpPan.border.Vartoexport = \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435
|
||||
SimExpPan.border.Stage = \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0443\u043f\u0435\u043d\u044c
|
||||
SimExpPan.but.Selectall = \u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435
|
||||
@ -1103,6 +1103,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = \u0412\u044b\u0431\u043e\u0440 \u043f\u044
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = \u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u044b\u0431\u0440\u043e\u0441\u0430 \u0437\u0430\u0440\u044f\u0434\u0430:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = \u041d\u0435\u0442
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0435\u043a\u0443\u043d\u0434 \u0438\u043b\u0438 "\u041d\u0435\u0442")
|
||||
TCMotorSelPan.lbl.Designation = \u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:
|
||||
TCMotorSelPan.lbl.Totalimpulse = \u041e\u0431\u0449\u0438\u0439 \u0438\u043c\u043f\u0443\u043b\u044c\u0441:
|
||||
TCMotorSelPan.lbl.Avgthrust = \u0421\u0440\u0435\u0434\u043d\u044f\u044f \u0442\u044f\u0433\u0430:
|
||||
TCMotorSelPan.lbl.Maxthrust = \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u044f\u0433\u0430:
|
||||
@ -1417,7 +1418,8 @@ 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.DESIGNATION = \u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
|
||||
TCurveMotorCol.COMMON_NAME = \u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
|
||||
! TCurveMotorCol.DESIGNATION = \u041e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435
|
||||
TCurveMotorCol.TYPE = \u0422\u0438\u043f
|
||||
TCurveMotorCol.DIAMETER = \u0414\u0438\u0430\u043c\u0435\u0442\u0440
|
||||
TCurveMotorCol.LENGTH = \u0414\u043b\u0438\u043d\u0430
|
||||
|
@ -99,12 +99,12 @@ dlg.but.ok = Tamam
|
||||
dlg.but.cancel = \u00c7\u0131k\u0131\u015f
|
||||
dlg.but.close = Kapat
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = Resim Dosyalar\u0131
|
||||
FileHelper.PDF_FILTER = PDF files (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = All rocket designs (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket designs (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim designs (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = Resim Dosyalar\u0131
|
||||
|
||||
|
||||
! Diyolog Hakk\u0131nda
|
||||
|
@ -93,12 +93,13 @@ dlg.but.cancel = Cancel
|
||||
dlg.but.close = Close
|
||||
|
||||
! General file type names
|
||||
filetypes.pdf = PDF files (*.pdf)
|
||||
BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
|
||||
filetypes.images = Image files
|
||||
FileHelper.PDF_FILTER = PDF files (*.pdf)
|
||||
FileHelper.ALL_DESIGNS_FILTER = All rocket designs (*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket designs (*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim designs (*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket presets (*.orc)
|
||||
FileHelper.IMAGES = Image files
|
||||
FileHelper.CSV_FILTER = Comma Separated Files (*.csv)
|
||||
|
||||
|
||||
! About Dialog
|
||||
@ -469,7 +470,6 @@ RK4SimulationStepper.error.valuesTooLarge = Simulation values exceeded limits.
|
||||
SimulationModifierTree.OptimizationParameters = Optimization Parameters
|
||||
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = Comma Separated Files (*.csv)
|
||||
SimExpPan.border.Vartoexport = Variables to export
|
||||
SimExpPan.border.Stage = Stage to export
|
||||
SimExpPan.but.Selectall = Select all
|
||||
@ -1108,6 +1108,7 @@ TCMotorSelPan.lbl.Selectthrustcurve = Select thrust curve:
|
||||
TCMotorSelPan.lbl.Ejectionchargedelay = Ejection charge delay:
|
||||
TCMotorSelPan.equalsIgnoreCase.None = None
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (Number of seconds or \"None\")
|
||||
TCMotorSelPan.lbl.Designation = Designation:
|
||||
TCMotorSelPan.lbl.Totalimpulse = Total impulse:
|
||||
TCMotorSelPan.lbl.Avgthrust = Avg. thrust:
|
||||
TCMotorSelPan.lbl.Maxthrust = Max. thrust:
|
||||
@ -1423,7 +1424,8 @@ FlightEvent.Type.EXCEPTION = Exception
|
||||
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = Manufacturer
|
||||
TCurveMotorCol.DESIGNATION = Designation
|
||||
TCurveMotorCol.COMMON_NAME = Name
|
||||
! TCurveMotorCol.DESIGNATION = Designation
|
||||
TCurveMotorCol.TYPE = Type
|
||||
TCurveMotorCol.DIAMETER = Diameter
|
||||
TCurveMotorCol.LENGTH = Length
|
||||
|
@ -47,10 +47,11 @@ BasicEventSimulationEngine.error.earlyMotorBurnout = \u53D1\u52A8\u673A\u8D77\u9
|
||||
BasicEventSimulationEngine.error.noIgnition = \u53D1\u52A8\u673A\u672A\u70B9\u706B
|
||||
BasicEventSimulationEngine.error.noMotorsDefined = \u53D1\u52A8\u673A\u672A\u5B9A\u4E49
|
||||
|
||||
BasicFrame.SimpleFileFilter1 = \u652F\u6301\u7684\u706B\u7BAD\u8BBE\u8BA1\u7A3F(*.ork; *.rkt)
|
||||
BasicFrame.SimpleFileFilter2 = OpenRocket\u8BBE\u8BA1\u7A3F(*.ork)
|
||||
BasicFrame.SimpleFileFilter3 = RockSim\u8BBE\u8BA1\u7A3F(*.rkt)
|
||||
BasicFrame.SimpleFileFilter4 = OpenRocket\u914D\u7F6E(*.orc)
|
||||
FileHelper.ALL_DESIGNS_FILTER = \u652F\u6301\u7684\u706B\u7BAD\u8BBE\u8BA1\u7A3F(*.ork; *.rkt)
|
||||
FileHelper.OPENROCKET_DESIGN_FILTER = OpenRocket\u8BBE\u8BA1\u7A3F(*.ork)
|
||||
FileHelper.ROCKSIM_DESIGN_FILTER = RockSim\u8BBE\u8BA1\u7A3F(*.rkt)
|
||||
FileHelper.OPEN_ROCKET_COMPONENT_FILTER = OpenRocket\u914D\u7F6E(*.orc)
|
||||
FileHelper.CSV_FILTER = CSV\u6570\u636E\u6587\u4EF6 (*.csv)
|
||||
BasicFrame.StageName.Sustainer = \u4E3B\u53D1\u52A8\u673A
|
||||
BasicFrame.WarningDialog.title = \u6253\u5F00\u6587\u4EF6\u65F6\u8B66\u544A
|
||||
BasicFrame.WarningDialog.txt1 = \u6253\u5F00\u8BBE\u8BA1\u7A3F\u65F6\u9047\u5230\u4EE5\u4E0B\u95EE\u9898
|
||||
@ -1047,7 +1048,6 @@ SimExpPan.checkbox.ttip.Incflightevents = \u6CE8\u91CA\u884C\u7528\u4E8E\u63CF\
|
||||
SimExpPan.checkbox.ttip.Includefielddesc = \u6CE8\u91CA\u884C\u7528\u4E8E\u63CF\u8FF0\u8F93\u51FA\u53D8\u91CF.
|
||||
SimExpPan.checkbox.ttip.Includesimudesc = \u5728\u6587\u4EF6\u5934\u52A0\u4E0A\u6CE8\u91CA\u884C\u7528\u4E8E\u63CF\u8FF0\u4EFF\u771F\u5185\u5BB9.
|
||||
! SimulationExportPanel
|
||||
SimExpPan.desc = CSV\u6570\u636E\u6587\u4EF6 (*.csv)
|
||||
SimExpPan.lbl.Commentchar = \u6CE8\u91CA\u6807\u8BC6\u7B26:
|
||||
SimExpPan.lbl.Fieldsepstr = \u6570\u636E\u5206\u9694\u5B57\u7B26\u4E32:
|
||||
SimExpPan.lbl.longA1 = <html>\u5B57\u7B26\u4E32\u7528\u4E8E\u5206\u9694\u8F93\u51FA\u6587\u4EF6\u4E2D\u7684\u6570\u636E\u57DF.<br>
|
||||
@ -1177,6 +1177,7 @@ StreamerCfg.tab.Radialpos = \u5F84\u5411\u4F4D\u7F6E
|
||||
StreamerCfg.tab.ttip.General = \u5E38\u89C4\u5C5E\u6027
|
||||
StreamerCfg.tab.ttip.Radialpos = \u5F84\u5411\u4F4D\u7F6E\u8BBE\u7F6E
|
||||
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.Diameter = \u76F4\u5F84
|
||||
TCMotorSelPan.Length = \u957F\u5EA6
|
||||
TCMotorSelPan.MotorMountDimensions = \u53D1\u52A8\u673A\u5EA7\u5C3A\u5BF8:
|
||||
@ -1203,8 +1204,8 @@ TCMotorSelPan.lbl.Maxthrust = \u6700\u5927\u63A8\u529B:
|
||||
TCMotorSelPan.lbl.NumberofsecondsorNone = (\u79D2\u6570\u6216"\u65E0")
|
||||
TCMotorSelPan.lbl.Search = \u641C\u7D22:
|
||||
TCMotorSelPan.lbl.Selectthrustcurve = \u9009\u62E9\u63A8\u529B\u66F2\u7EBF:
|
||||
! ThrustCurveMotorSelectionPanel
|
||||
TCMotorSelPan.lbl.Selrocketmotor = \u9009\u62E9\u706B\u7BAD\u53D1\u52A8\u673A:
|
||||
TCMotorSelPan.lbl.Designation = \u540D\u79F0:
|
||||
TCMotorSelPan.lbl.Totalimpulse = \u603B\u51B2\u91CF:
|
||||
TCMotorSelPan.noDescription = \u63CF\u8FF0\u4E0D\u53EF\u7528.
|
||||
TCMotorSelPan.title.Thrust = \u63A8\u529B
|
||||
@ -1219,10 +1220,11 @@ TCurveMotor.ttip.length = \u957F\u5EA6:
|
||||
TCurveMotor.ttip.maxThrust = \u6700\u5927\u63A8\u529B:
|
||||
TCurveMotor.ttip.totalImpulse = \u603B\u51B2\u529B:
|
||||
|
||||
TCurveMotorCol.DESIGNATION = \u540D\u79F0
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.COMMON_NAME = \u540D\u79F0
|
||||
! TCurveMotorCol.DESIGNATION = \u540D\u79F0
|
||||
TCurveMotorCol.DIAMETER = \u76F4\u5F84
|
||||
TCurveMotorCol.LENGTH = \u957F\u5EA6
|
||||
! ThrustCurveMotorColumns
|
||||
TCurveMotorCol.MANUFACTURER = \u5236\u9020\u5546
|
||||
TCurveMotorCol.TOTAL_IMPULSE = \u603B\u51B2
|
||||
TCurveMotorCol.TYPE = \u7C7B\u578B
|
||||
@ -1497,9 +1499,9 @@ exdesigndlg.lbl.Examplesnotfound = \u8303\u4F8B\u672A\u627E\u5230
|
||||
exdesigndlg.lbl.Openexampledesign = \u6253\u5F00\u8303\u4F8B\u8BBE\u8BA1\u7A3F
|
||||
exdesigndlg.lbl.Selectexample = \u9009\u62E9\u8303\u4F8B\u8BBE\u8BA1\u7A3F:
|
||||
|
||||
filetypes.images = \u56FE\u50CF\u6587\u4EF6
|
||||
FileHelper.IMAGES = \u56FE\u50CF\u6587\u4EF6
|
||||
! General file type names
|
||||
filetypes.pdf = PDF \u6587\u4EF6 (*.pdf)
|
||||
FileHelper.PDF_FILTER = PDF \u6587\u4EF6 (*.pdf)
|
||||
|
||||
generalprefs.languages.default = \u7CFB\u7EDF\u9ED8\u8BA4
|
||||
generalprefs.lbl.language = \u754C\u9762\u8BED\u8A00
|
||||
|
@ -38,8 +38,8 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
private final List<Double> delays = new ArrayList<Double>();
|
||||
|
||||
private Manufacturer manufacturer = null;
|
||||
private String commonName = null;
|
||||
private String designation = null;
|
||||
private String simplifiedDesignation = null;
|
||||
private double diameter = -1;
|
||||
private double length = -1;
|
||||
private long totalImpulse = 0;
|
||||
@ -57,7 +57,6 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
checkFirstInsertion(motor);
|
||||
verifyMotor(motor);
|
||||
updateType(motor);
|
||||
checkChangeSimplifiedDesignation(motor);
|
||||
addStandardDelays(motor);
|
||||
if(!checkMotorOverwrite(motor)){
|
||||
motors.add(motor);
|
||||
@ -144,23 +143,6 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
Collections.sort(delays);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checks if simplified designation should be changed with the given motor
|
||||
* @param motor the motor to be checked with
|
||||
*/
|
||||
private void checkChangeSimplifiedDesignation(ThrustCurveMotor motor) {
|
||||
// Change the simplified designation if necessary
|
||||
if (!designation.equalsIgnoreCase(motor.getDesignation().trim())) {
|
||||
designation = simplifiedDesignation;
|
||||
}
|
||||
|
||||
if (caseInfo == null) {
|
||||
caseInfo = motor.getCaseInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* checks if the cached type should be changed with the given motor
|
||||
* if it's hybrid, delays will be added
|
||||
@ -206,7 +188,7 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
if (motors.isEmpty()) {
|
||||
manufacturer = motor.getManufacturer();
|
||||
designation = motor.getDesignation();
|
||||
simplifiedDesignation = simplifyDesignation(designation);
|
||||
commonName = motor.getCommonName();
|
||||
diameter = motor.getDiameter();
|
||||
length = motor.getLength();
|
||||
totalImpulse = Math.round((motor.getTotalImpulseEstimate()));
|
||||
@ -239,14 +221,14 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!simplifiedDesignation.equalsIgnoreCase(simplifyDesignation(m.getDesignation())))
|
||||
if (!commonName.equalsIgnoreCase(m.getCommonName()))
|
||||
return false;
|
||||
|
||||
if (caseInfo != null && !caseInfo.equalsIgnoreCase(m.getCaseInfo()))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a new list with the stored motors
|
||||
@ -283,11 +265,17 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
public Manufacturer getManufacturer() {
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the designation of this motor type. This is either the exact or simplified
|
||||
* designation, depending on what motors have been added.
|
||||
* Return the common name of this motor type.
|
||||
* @return the common name
|
||||
*/
|
||||
public String getCommonName() {
|
||||
return commonName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the designation of this motor type.
|
||||
* @return the designation
|
||||
*/
|
||||
public String getDesignation() {
|
||||
@ -352,25 +340,6 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
return "ThrustCurveMotorSet[" + manufacturer + " " + designation +
|
||||
", type=" + type + ", count=" + motors.size() + "]";
|
||||
}
|
||||
|
||||
private static final Pattern SIMPLIFY_PATTERN = Pattern.compile("^[0-9]*[ -]*([A-Z][0-9]+).*");
|
||||
|
||||
/**
|
||||
* Simplify a motor designation, if possible. This attempts to reduce the designation
|
||||
* into a simple letter + number notation for the impulse class and average thrust.
|
||||
*
|
||||
* @param str the designation to simplify
|
||||
* @return the simplified designation, or the string itself if the format was not detected
|
||||
*/
|
||||
public static String simplifyDesignation(String str) {
|
||||
str = str.trim();
|
||||
Matcher m = SIMPLIFY_PATTERN.matcher(str);
|
||||
if (m.matches()) {
|
||||
return m.group(1);
|
||||
} else {
|
||||
return str.replaceAll("\\s", "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparator for deciding in which order to display matching motors.
|
||||
@ -379,11 +348,12 @@ public class ThrustCurveMotorSet implements Comparable<ThrustCurveMotorSet> {
|
||||
|
||||
@Override
|
||||
public int compare(ThrustCurveMotor o1, ThrustCurveMotor o2) {
|
||||
|
||||
// 1. Designation
|
||||
if (!o1.getDesignation().equals(o2.getDesignation())) {
|
||||
return o1.getDesignation().compareTo(o2.getDesignation());
|
||||
}
|
||||
|
||||
|
||||
// 2. Number of data points (more is better)
|
||||
if (o1.getSampleSize() != o2.getSampleSize()) {
|
||||
return o2.getSampleSize() - o1.getSampleSize();
|
||||
|
@ -44,7 +44,9 @@ public class ThrustCurveMotorSetDatabase implements MotorDatabase {
|
||||
matchDescription = false;
|
||||
else if (manufacturer != null && !m.getManufacturer().matches(manufacturer))
|
||||
matchDescription = false;
|
||||
else if (designation != null && !designation.equalsIgnoreCase(m.getDesignation()))
|
||||
else if (designation != null &&
|
||||
!designation.equalsIgnoreCase(m.getDesignation()) &&
|
||||
!designation.equalsIgnoreCase(m.getCommonName()))
|
||||
matchDescription = false;
|
||||
else if (!Double.isNaN(diameter) && (Math.abs(diameter - m.getDiameter()) > 0.005))
|
||||
matchDescription = false;
|
||||
|
@ -810,7 +810,7 @@ public class OpenRocketDocument implements ComponentChangeListener {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
protected void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
||||
public void fireDocumentChangeEvent(DocumentChangeEvent event) {
|
||||
DocumentChangeListener[] array = listeners.toArray(new DocumentChangeListener[0]);
|
||||
for (DocumentChangeListener l : array) {
|
||||
l.documentChanged(event);
|
||||
|
@ -152,7 +152,7 @@ class DocumentConfig {
|
||||
// BodyTube
|
||||
setters.put("BodyTube:radius", new DoubleSetter(
|
||||
Reflection.findMethod(BodyTube.class, "setOuterRadius", double.class),
|
||||
"auto",
|
||||
"auto", " ",
|
||||
Reflection.findMethod(BodyTube.class, "setOuterRadiusAutomatic", boolean.class)));
|
||||
|
||||
// Parallel Stage
|
||||
@ -204,11 +204,11 @@ class DocumentConfig {
|
||||
|
||||
setters.put("Transition:foreradius", new DoubleSetter(
|
||||
Reflection.findMethod(Transition.class, "setForeRadius", double.class),
|
||||
"auto",
|
||||
"auto", " ",
|
||||
Reflection.findMethod(Transition.class, "setForeRadiusAutomatic", boolean.class)));
|
||||
setters.put("Transition:aftradius", new DoubleSetter(
|
||||
Reflection.findMethod(Transition.class, "setAftRadius", double.class),
|
||||
"auto",
|
||||
"auto", " ",
|
||||
Reflection.findMethod(Transition.class, "setAftRadiusAutomatic", boolean.class)));
|
||||
|
||||
setters.put("Transition:foreshoulderradius", new DoubleSetter(
|
||||
|
@ -1,6 +1,8 @@
|
||||
package net.sf.openrocket.file.openrocket.importt;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.sf.openrocket.aerodynamics.Warning;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
@ -17,6 +19,7 @@ class DoubleSetter implements Setter {
|
||||
private final String specialString;
|
||||
private final Reflection.Method specialMethod;
|
||||
private final double multiplier;
|
||||
private String separator;
|
||||
|
||||
/**
|
||||
* Set only the double value.
|
||||
@ -59,6 +62,23 @@ class DoubleSetter implements Setter {
|
||||
this.specialMethod = specialMethod;
|
||||
this.multiplier = 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the double value, or if the value equals the special string, use the
|
||||
* special setter and set it to true. If the input string contains more information
|
||||
* besides the special string, you can specify which separator should be used for
|
||||
* this extra information. The part before the separator is then the special string
|
||||
* and the part after the separator is the set value.
|
||||
*
|
||||
* @param set double setter.
|
||||
* @param special special string
|
||||
* @param specialMethod boolean setter.
|
||||
*/
|
||||
public DoubleSetter(Reflection.Method set, String special, String separator,
|
||||
Reflection.Method specialMethod) {
|
||||
this(set, special, specialMethod);
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -80,26 +100,39 @@ class DoubleSetter implements Setter {
|
||||
WarningSet warnings) {
|
||||
|
||||
s = s.trim();
|
||||
|
||||
// Check for special case
|
||||
if (specialMethod != null && s.equalsIgnoreCase(specialString)) {
|
||||
specialMethod.invoke(c, true);
|
||||
return;
|
||||
String special = s;
|
||||
String data = s;
|
||||
String[] args = null;
|
||||
|
||||
// Extract special string and data if s contains multiple data elements, separated by separator
|
||||
if (separator != null) {
|
||||
args = s.split(this.separator);
|
||||
if (args.length > 1) {
|
||||
special = args[0];
|
||||
data = String.join(separator, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
}
|
||||
|
||||
// Normal case
|
||||
try {
|
||||
double d = Double.parseDouble(s);
|
||||
|
||||
if (configGetter == null) {
|
||||
setMethod.invoke(c, d * multiplier);
|
||||
} else {
|
||||
FlightConfigurableParameterSet<?> config = (FlightConfigurableParameterSet<?>) configGetter.invoke(c);
|
||||
Object obj = config.getDefault();
|
||||
setMethod.invoke(obj, d * multiplier);
|
||||
if (!special.equalsIgnoreCase(specialString) || (args != null && args.length > 1)) {
|
||||
try {
|
||||
double d = Double.parseDouble(data);
|
||||
|
||||
if (configGetter == null) {
|
||||
setMethod.invoke(c, d * multiplier);
|
||||
} else {
|
||||
FlightConfigurableParameterSet<?> config = (FlightConfigurableParameterSet<?>) configGetter.invoke(c);
|
||||
Object obj = config.getDefault();
|
||||
setMethod.invoke(obj, d * multiplier);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
warnings.add(Warning.FILE_INVALID_PARAMETER + " data: '" + data + "' - " + c.getName());
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
warnings.add(Warning.FILE_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
// Check for special case
|
||||
if (specialMethod != null && special.equalsIgnoreCase(specialString)) {
|
||||
specialMethod.invoke(c, true);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,8 +22,9 @@ public class BodyTubeSaver extends SymmetricComponentSaver {
|
||||
super.addParams(c, elements);
|
||||
net.sf.openrocket.rocketcomponent.BodyTube tube = (net.sf.openrocket.rocketcomponent.BodyTube) c;
|
||||
|
||||
if (tube.isOuterRadiusAutomatic())
|
||||
elements.add("<radius>auto</radius>");
|
||||
if (tube.isOuterRadiusAutomatic()) {
|
||||
elements.add("<radius>auto " + tube.getOuterRadiusNoAutomatic() + "</radius>");
|
||||
}
|
||||
else
|
||||
elements.add("<radius>" + tube.getOuterRadius() + "</radius>");
|
||||
|
||||
|
@ -45,13 +45,13 @@ public class TransitionSaver extends SymmetricComponentSaver {
|
||||
|
||||
if (!nosecone) {
|
||||
if (trans.isForeRadiusAutomatic())
|
||||
elements.add("<foreradius>auto</foreradius>");
|
||||
elements.add("<foreradius>auto " + trans.getForeRadiusNoAutomatic() + "</foreradius>");
|
||||
else
|
||||
elements.add("<foreradius>" + trans.getForeRadius() + "</foreradius>");
|
||||
}
|
||||
|
||||
if (trans.isAftRadiusAutomatic())
|
||||
elements.add("<aftradius>auto</aftradius>");
|
||||
elements.add("<aftradius>auto " + trans.getAftRadiusNoAutomatic() + "</aftradius>");
|
||||
else
|
||||
elements.add("<aftradius>" + trans.getAftRadius() + "</aftradius>");
|
||||
|
||||
|
@ -18,10 +18,20 @@ public abstract class InterpolatingAtmosphericModel implements AtmosphericModel
|
||||
if (levels == null)
|
||||
computeLayers();
|
||||
|
||||
if (altitude <= 0)
|
||||
if (altitude <= 0) {
|
||||
// TODO: LOW: levels[0] returned null in some cases, see GitHub issue #952 for more information
|
||||
if (levels[0] == null) {
|
||||
computeLayers();
|
||||
}
|
||||
return levels[0];
|
||||
if (altitude >= DELTA * (levels.length - 1))
|
||||
}
|
||||
if (altitude >= DELTA * (levels.length - 1)) {
|
||||
// TODO: LOW: levels[levels.length - 1] returned null in some cases, see GitHub issue #952 for more information
|
||||
if (levels[levels.length - 1] == null) {
|
||||
computeLayers();
|
||||
}
|
||||
return levels[levels.length - 1];
|
||||
}
|
||||
|
||||
int n = (int) (altitude / DELTA);
|
||||
double d = (altitude - n * DELTA) / DELTA;
|
||||
|
@ -90,4 +90,4 @@ public class DesignationComparator implements Comparator<String> {
|
||||
return COLLATOR.compare(o1, o2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,28 @@ public interface Motor {
|
||||
public Type getMotorType();
|
||||
|
||||
|
||||
/**
|
||||
* Return the motor code
|
||||
*
|
||||
* @return the code
|
||||
*/
|
||||
public String getCode();
|
||||
|
||||
/**
|
||||
* Return the common name of the motor.
|
||||
*
|
||||
* @return the common name
|
||||
*/
|
||||
public String getCommonName();
|
||||
|
||||
/**
|
||||
* Return the common name of the motor, including a delay.
|
||||
*
|
||||
* @param delay the delay of the motor.
|
||||
* @return common name with delay.
|
||||
*/
|
||||
public String getCommonName(double delay);
|
||||
|
||||
/**
|
||||
* Return the designation of the motor.
|
||||
*
|
||||
|
@ -62,11 +62,11 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
return ignitionOveride;
|
||||
}
|
||||
|
||||
public String toMotorDesignation(){
|
||||
public String toMotorCommonName(){
|
||||
if( motor == null ){
|
||||
return trans.get("empty");
|
||||
}else{
|
||||
return this.motor.getDesignation(this.getEjectionDelay());
|
||||
return this.motor.getCommonName(this.getEjectionDelay());
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +115,8 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
|
||||
public void useDefaultIgnition() {
|
||||
this.ignitionOveride = false;
|
||||
setIgnitionDelay(0);
|
||||
setIgnitionEvent(IgnitionEvent.AUTOMATIC);
|
||||
}
|
||||
|
||||
public double getIgnitionDelay() {
|
||||
@ -235,7 +237,7 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
}
|
||||
|
||||
public String toDescription(){
|
||||
return ( this.toMotorDesignation()+
|
||||
return ( this.toMotorCommonName()+
|
||||
" in: "+mount.getDebugName()+
|
||||
" ign@: "+this.toIgnitionDescription() );
|
||||
}
|
||||
@ -251,7 +253,7 @@ public class MotorConfiguration implements FlightConfigurableParameter<MotorConf
|
||||
mount.getDebugName(),
|
||||
fcid.toShortKey(),
|
||||
mid.toDebug(),
|
||||
toMotorDesignation(),
|
||||
toMotorCommonName(),
|
||||
toIgnitionDescription() ));
|
||||
|
||||
return buf.toString();
|
||||
|
@ -58,7 +58,7 @@ public class MotorConfigurationSet extends FlightConfigurableParameterSet<MotorC
|
||||
loopFCID.toShortKey(),
|
||||
curConfig.getFCID().toShortKey(),
|
||||
curConfig.getMID().toShortKey(),
|
||||
curConfig.toMotorDesignation(),
|
||||
curConfig.toMotorCommonName(),
|
||||
curConfig.toIgnitionDescription() ));
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import java.io.Serializable;
|
||||
import java.text.Collator;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -33,7 +35,10 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
private String digest = "";
|
||||
|
||||
private Manufacturer manufacturer = Manufacturer.getManufacturer("Unknown");
|
||||
private String code = "";
|
||||
private String commonName = "";
|
||||
private String designation = "";
|
||||
|
||||
private String description = "";
|
||||
private Motor.Type type = Motor.Type.UNKNOWN;
|
||||
private double[] delays = {};
|
||||
@ -74,6 +79,16 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
motor.description = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCode(String c) {
|
||||
motor.code = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCommonName(String n) {
|
||||
motor.commonName = n;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDesignation(String d) {
|
||||
motor.designation = d;
|
||||
@ -130,10 +145,28 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAvailablity(boolean avail) {
|
||||
public Builder setAvailability(boolean avail) {
|
||||
motor.available = avail;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify a motor designation, if possible. This attempts to reduce the designation
|
||||
* into a simple letter + number notation for the impulse class and average thrust.
|
||||
*
|
||||
* @param str the designation to simplify
|
||||
* @return the simplified designation, or the string itself if the format was not detected
|
||||
*/
|
||||
private static final Pattern SIMPLIFY_PATTERN = Pattern.compile("^[0-9]*[ -]*([A-Z][0-9]+).*");
|
||||
public static String simplifyDesignation(String str) {
|
||||
str = str.trim();
|
||||
Matcher m = SIMPLIFY_PATTERN.matcher(str);
|
||||
if (m.matches()) {
|
||||
return m.group(1);
|
||||
} else {
|
||||
return str.replaceAll("\\s", "");
|
||||
}
|
||||
}
|
||||
|
||||
public ThrustCurveMotor build() {
|
||||
// Check argument validity
|
||||
@ -202,6 +235,19 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
motor.unitRotationalInertia = Inertia.filledCylinderRotational( motor.diameter / 2);
|
||||
motor.unitLongitudinalInertia = Inertia.filledCylinderLongitudinal( motor.diameter / 2, motor.length);
|
||||
|
||||
// If I don't have a motor designation (will be the case if I read the thrustcurve from a file)
|
||||
// use the motor code
|
||||
if (motor.designation.equals("")) {
|
||||
motor.designation = motor.code;
|
||||
}
|
||||
|
||||
// If I don't have a motor common name (will be the case if I read the thrustcurve from a flle)
|
||||
// apply the motor code simplification heuristics to generate a common name
|
||||
if (motor.commonName.equals("")) {
|
||||
motor.commonName = simplifyDesignation(motor.designation);
|
||||
}
|
||||
|
||||
|
||||
motor.computeStatistics();
|
||||
|
||||
return motor;
|
||||
@ -440,6 +486,21 @@ public class ThrustCurveMotor implements Motor, Comparable<ThrustCurveMotor>, Se
|
||||
public double getUnitIzz(){
|
||||
return this.unitLongitudinalInertia;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonName() {
|
||||
return commonName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonName(double delay) {
|
||||
return commonName + "-" + getDelayString(delay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDesignation() {
|
||||
|
@ -1,10 +1,7 @@
|
||||
package net.sf.openrocket.rocketcomponent;
|
||||
|
||||
import java.util.EventObject;
|
||||
import java.util.Iterator;
|
||||
|
||||
import net.sf.openrocket.appearance.Appearance;
|
||||
import net.sf.openrocket.appearance.Decal;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
import net.sf.openrocket.motor.MotorConfiguration;
|
||||
@ -25,6 +22,8 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
|
||||
private double outerRadius = 0;
|
||||
private boolean autoRadius = false; // Radius chosen automatically based on parent component
|
||||
|
||||
private SymmetricComponent refComp = null; // Reference component that is used for the autoRadius
|
||||
|
||||
// When changing the inner radius, thickness is modified
|
||||
private double overhang = 0;
|
||||
@ -79,13 +78,17 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
// Return auto radius from front or rear
|
||||
double r = -1;
|
||||
SymmetricComponent c = this.getPreviousSymmetricComponent();
|
||||
if (c != null) {
|
||||
// Don't use the radius of a component who already has its auto diameter enabled
|
||||
if (c != null && !c.usesNextCompAutomatic()) {
|
||||
r = c.getFrontAutoRadius();
|
||||
refComp = c;
|
||||
}
|
||||
if (r < 0) {
|
||||
c = this.getNextSymmetricComponent();
|
||||
if (c != null) {
|
||||
// Don't use the radius of a component who already has its auto diameter enabled
|
||||
if (c != null && !c.usesPreviousCompAutomatic()) {
|
||||
r = c.getRearAutoRadius();
|
||||
refComp = c;
|
||||
}
|
||||
}
|
||||
if (r < 0)
|
||||
@ -94,6 +97,14 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
}
|
||||
return outerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the outer radius that was manually entered, so not the value that the component received from automatic
|
||||
* outer radius.
|
||||
*/
|
||||
public double getOuterRadiusNoAutomatic() {
|
||||
return outerRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the outer radius of the body tube. If the radius is less than the wall thickness,
|
||||
@ -136,8 +147,17 @@ public class BodyTube extends SymmetricComponent implements BoxBounded, MotorMou
|
||||
fireComponentChangeEvent(ComponentChangeEvent.BOTH_CHANGE);
|
||||
clearPreset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean usesPreviousCompAutomatic() {
|
||||
return isOuterRadiusAutomatic() && refComp == getPreviousSymmetricComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesNextCompAutomatic() {
|
||||
return isOuterRadiusAutomatic() && refComp == getNextSymmetricComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadFromPreset(ComponentPreset preset) {
|
||||
this.autoRadius = false;
|
||||
|
@ -8,6 +8,8 @@ import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DeploymentConfiguration implements FlightConfigurableParameter<DeploymentConfiguration> {
|
||||
|
||||
|
||||
@ -154,5 +156,17 @@ public class DeploymentConfiguration implements FlightConfigurableParameter<Depl
|
||||
@Override
|
||||
public void update(){
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DeploymentConfiguration that = (DeploymentConfiguration) o;
|
||||
return Double.compare(that.deployAltitude, deployAltitude) == 0 && Double.compare(that.deployDelay, deployDelay) == 0 && deployEvent == that.deployEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(deployEvent, deployAltitude, deployDelay);
|
||||
}
|
||||
}
|
@ -441,7 +441,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
||||
}
|
||||
|
||||
if( ! motorConfig.isEmpty()){
|
||||
buff.append(motorConfig.toMotorDesignation());
|
||||
buff.append(motorConfig.toMotorCommonName());
|
||||
++activeMotorCount;
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,12 @@ public class NoseCone extends Transition implements InsideColorComponent {
|
||||
public void setForeRadiusAutomatic(boolean b) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean usesPreviousCompAutomatic() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getForeShoulderLength() {
|
||||
return 0;
|
||||
|
@ -5,6 +5,8 @@ import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class StageSeparationConfiguration implements FlightConfigurableParameter<StageSeparationConfiguration> {
|
||||
|
||||
public static enum SeparationEvent {
|
||||
@ -144,8 +146,20 @@ public class StageSeparationConfiguration implements FlightConfigurableParameter
|
||||
clone.separationDelay = this.separationDelay;
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StageSeparationConfiguration that = (StageSeparationConfiguration) o;
|
||||
return Double.compare(that.separationDelay, separationDelay) == 0 && separationEvent == that.separationEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(separationEvent, separationDelay);
|
||||
}
|
||||
|
||||
private void fireChangeEvent() {
|
||||
|
||||
}
|
||||
|
@ -644,5 +644,15 @@ public abstract class SymmetricComponent extends BodyComponent implements BoxBou
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the component uses the previous symmetric component for its auto diameter.
|
||||
*/
|
||||
public abstract boolean usesPreviousCompAutomatic();
|
||||
|
||||
/**
|
||||
* Checks whether the component uses the next symmetric component for its auto diameter.
|
||||
*/
|
||||
public abstract boolean usesNextCompAutomatic();
|
||||
|
||||
}
|
||||
|
@ -94,6 +94,14 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
||||
return foreRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fore radius that was manually entered, so not the value that the component received from automatic
|
||||
* fore radius.
|
||||
*/
|
||||
public double getForeRadiusNoAutomatic() {
|
||||
return foreRadius;
|
||||
}
|
||||
|
||||
public void setForeRadius(double radius) {
|
||||
if ((this.foreRadius == radius) && (autoForeRadius == false))
|
||||
return;
|
||||
@ -142,7 +150,13 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
||||
return aftRadius;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the aft radius that was manually entered, so not the value that the component received from automatic
|
||||
* zft radius.
|
||||
*/
|
||||
public double getAftRadiusNoAutomatic() {
|
||||
return aftRadius;
|
||||
}
|
||||
|
||||
public void setAftRadius(double radius) {
|
||||
if ((this.aftRadius == radius) && (autoAftRadius2 == false))
|
||||
@ -192,7 +206,15 @@ public class Transition extends SymmetricComponent implements InsideColorCompone
|
||||
return getForeRadius();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesPreviousCompAutomatic() {
|
||||
return isForeRadiusAutomatic();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesNextCompAutomatic() {
|
||||
return isAftRadiusAutomatic();
|
||||
}
|
||||
|
||||
|
||||
//////// Type & shape /////////
|
||||
|
@ -259,7 +259,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
private boolean handleEvents() throws SimulationException {
|
||||
boolean ret = true;
|
||||
FlightEvent event;
|
||||
|
||||
|
||||
log.trace("HandleEvents: current branch = " + currentStatus.getFlightData().getBranchName());
|
||||
for (event = nextEvent(); event != null; event = nextEvent()) {
|
||||
log.trace("Obtained event from queue: " + event.toString());
|
||||
@ -300,7 +300,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
// Ignore events for components that are no longer attached to the rocket
|
||||
if (event.getSource() != null && event.getSource().getParent() != null &&
|
||||
!currentStatus.getConfiguration().isComponentActive(event.getSource())) {
|
||||
log.trace("Ignoring event from unattached componenent");
|
||||
log.trace("Ignoring event from unattached component");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -332,6 +332,7 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
|
||||
|
||||
// Check for recovery device deployment, add events to queue
|
||||
// TODO: LOW: check if deprecated function getActiveComponents needs to be replaced
|
||||
for (RocketComponent c : currentStatus.getConfiguration().getActiveComponents()) {
|
||||
if (!(c instanceof RecoveryDevice))
|
||||
continue;
|
||||
@ -532,7 +533,8 @@ public class BasicEventSimulationEngine implements SimulationEngine {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// TODO : FUTURE : do not hard code the 1200 (maybe even make it configurable by the user)
|
||||
if( 1200 < currentStatus.getSimulationTime() ){
|
||||
ret = false;
|
||||
log.error("Simulation hit max time (1200s): aborting.");
|
||||
|
@ -220,7 +220,7 @@ public class FlightData {
|
||||
timeToApogee = Double.NaN;
|
||||
|
||||
|
||||
// Launch rod velocity
|
||||
// Launch rod velocity + deployment velocity + ground hit velocity
|
||||
for (FlightEvent event : branch.getEvents()) {
|
||||
if (event.getType() == FlightEvent.Type.LAUNCHROD) {
|
||||
double t = event.getTime();
|
||||
|
@ -0,0 +1,29 @@
|
||||
package net.sf.openrocket.simulation.listeners.system;
|
||||
|
||||
import net.sf.openrocket.simulation.FlightEvent;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.listeners.AbstractSimulationListener;
|
||||
|
||||
|
||||
/**
|
||||
* A simulation listeners that ends the simulation when the ground is hit.
|
||||
*
|
||||
* @author Sibo Van Gool <sibo.vangool@hotmail.com>
|
||||
*/
|
||||
public class GroundHitListener extends AbstractSimulationListener {
|
||||
|
||||
public static final GroundHitListener INSTANCE = new GroundHitListener();
|
||||
|
||||
@Override
|
||||
public boolean handleFlightEvent(SimulationStatus status, FlightEvent event) {
|
||||
if (event.getType() == FlightEvent.Type.GROUND_HIT) {
|
||||
status.getEventQueue().add(new FlightEvent(FlightEvent.Type.SIMULATION_END, status.getSimulationTime()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSystemListener() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -133,14 +133,12 @@ public class SerializeThrustcurveMotors {
|
||||
builder.setDiameter(mi.getDiameter() / 1000.0);
|
||||
builder.setLength(mi.getLength() / 1000.0);
|
||||
builder.setMotorType(type);
|
||||
|
||||
builder.setCommonName(mi.getCommon_name());
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
|
||||
if ("OOP".equals(mi.getAvailiability())) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
builder.setAvailablity(false);
|
||||
} else if (mi.getDesignation().startsWith("Micro")) {
|
||||
builder.setDesignation(mi.getDesignation());
|
||||
} else {
|
||||
builder.setDesignation(mi.getCommon_name());
|
||||
if ("OOP".equals(mi.getAvailability())) {
|
||||
builder.setAvailability(false);
|
||||
}
|
||||
|
||||
allMotors.add(builder.build());
|
||||
|
@ -270,7 +270,7 @@ public class TCMotor implements Cloneable {
|
||||
this.updated_on = updated_on;
|
||||
}
|
||||
|
||||
public String getAvailiability() {
|
||||
public String getAvailability() {
|
||||
return availability;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ public class ThrustCurveMotorSetTest {
|
||||
|
||||
private static final ThrustCurveMotor motor1 = new ThrustCurveMotor.Builder()
|
||||
.setManufacturer(Manufacturer.getManufacturer("A"))
|
||||
.setCommonName("F12")
|
||||
.setDesignation("F12X")
|
||||
.setDescription("Desc")
|
||||
.setMotorType(Motor.Type.UNKNOWN)
|
||||
@ -36,6 +37,7 @@ public class ThrustCurveMotorSetTest {
|
||||
|
||||
private static final ThrustCurveMotor motor2 = new ThrustCurveMotor.Builder()
|
||||
.setManufacturer(Manufacturer.getManufacturer("A"))
|
||||
.setCommonName("F12")
|
||||
.setDesignation("F12H")
|
||||
.setDescription("Desc")
|
||||
.setMotorType(Motor.Type.SINGLE)
|
||||
@ -50,7 +52,7 @@ public class ThrustCurveMotorSetTest {
|
||||
|
||||
private static final ThrustCurveMotor motor3 = new ThrustCurveMotor.Builder()
|
||||
.setManufacturer(Manufacturer.getManufacturer("A"))
|
||||
.setDesignation("F12")
|
||||
.setCode("F12")
|
||||
.setDescription("Desc")
|
||||
.setMotorType(Motor.Type.UNKNOWN)
|
||||
.setStandardDelays(new double[] { 0, Motor.PLUGGED_DELAY })
|
||||
@ -65,7 +67,7 @@ public class ThrustCurveMotorSetTest {
|
||||
private static final ThrustCurveMotor motor4 = new ThrustCurveMotor.Builder()
|
||||
.setManufacturer(Manufacturer.getManufacturer("A"))
|
||||
.setDesignation("F12")
|
||||
.setDesignation("Desc")
|
||||
.setDescription("Desc")
|
||||
.setMotorType(Motor.Type.HYBRID)
|
||||
.setStandardDelays(new double[] { 0 })
|
||||
.setDiameter(0.024)
|
||||
@ -75,20 +77,7 @@ public class ThrustCurveMotorSetTest {
|
||||
.setCGPoints(new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL })
|
||||
.setDigest("digestD")
|
||||
.build();
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimplifyDesignation() {
|
||||
assertEquals("J115", ThrustCurveMotorSet.simplifyDesignation("J115"));
|
||||
assertEquals("J115", ThrustCurveMotorSet.simplifyDesignation(" J115 "));
|
||||
assertEquals("H115", ThrustCurveMotorSet.simplifyDesignation("241H115-KS"));
|
||||
assertEquals("J115", ThrustCurveMotorSet.simplifyDesignation("384 J115"));
|
||||
assertEquals("J115", ThrustCurveMotorSet.simplifyDesignation("384-J115"));
|
||||
assertEquals("A2", ThrustCurveMotorSet.simplifyDesignation("A2T"));
|
||||
assertEquals("1/2A2T", ThrustCurveMotorSet.simplifyDesignation("1/2A2T"));
|
||||
assertEquals("MicroMaxxII", ThrustCurveMotorSet.simplifyDesignation("Micro Maxx II"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testAdding() {
|
||||
ThrustCurveMotorSet set = new ThrustCurveMotorSet();
|
||||
@ -108,7 +97,7 @@ public class ThrustCurveMotorSetTest {
|
||||
assertEquals(1, set.getMotors().size());
|
||||
assertEquals(motor1, set.getMotors().get(0));
|
||||
assertEquals(Collections.emptyList(), set.getDelays());
|
||||
|
||||
|
||||
// Add motor1 again
|
||||
assertTrue(set.matches(motor1));
|
||||
set.addMotor(motor1);
|
||||
@ -120,12 +109,12 @@ public class ThrustCurveMotorSetTest {
|
||||
assertEquals(1, set.getMotors().size());
|
||||
assertEquals(motor1, set.getMotors().get(0));
|
||||
assertEquals(Collections.emptyList(), set.getDelays());
|
||||
|
||||
|
||||
// Add motor2
|
||||
assertTrue(set.matches(motor2));
|
||||
set.addMotor(motor2);
|
||||
assertEquals(motor1.getManufacturer(), set.getManufacturer());
|
||||
assertEquals(motor3.getDesignation(), set.getDesignation());
|
||||
assertEquals(motor3.getCommonName(), set.getCommonName());
|
||||
assertEquals(Motor.Type.SINGLE, set.getType());
|
||||
assertEquals(motor1.getDiameter(), set.getDiameter(), 0.00001);
|
||||
assertEquals(motor1.getLength(), set.getLength(), 0.00001);
|
||||
@ -133,21 +122,26 @@ public class ThrustCurveMotorSetTest {
|
||||
assertEquals(motor2, set.getMotors().get(0));
|
||||
assertEquals(motor1, set.getMotors().get(1));
|
||||
assertEquals(Arrays.asList(5.0), set.getDelays());
|
||||
|
||||
|
||||
// Add motor3
|
||||
assertTrue(set.matches(motor3));
|
||||
set.addMotor(motor3);
|
||||
assertEquals(motor1.getManufacturer(), set.getManufacturer());
|
||||
assertEquals(motor3.getDesignation(), set.getDesignation());
|
||||
assertEquals(motor3.getCommonName(), set.getCommonName());
|
||||
assertEquals(Motor.Type.SINGLE, set.getType());
|
||||
assertEquals(motor1.getDiameter(), set.getDiameter(), 0.00001);
|
||||
assertEquals(motor1.getLength(), set.getLength(), 0.00001);
|
||||
assertEquals(3, set.getMotors().size());
|
||||
System.out.println("motor set");
|
||||
System.out.println(set.getMotors());
|
||||
System.out.println(motor3);
|
||||
System.out.println(motor2);
|
||||
System.out.println(motor1);
|
||||
assertEquals(motor3, set.getMotors().get(0));
|
||||
assertEquals(motor2, set.getMotors().get(1));
|
||||
assertEquals(motor1, set.getMotors().get(2));
|
||||
assertEquals(Arrays.asList(0.0, 5.0, Motor.PLUGGED_DELAY), set.getDelays());
|
||||
|
||||
|
||||
// Test that adding motor4 fails
|
||||
assertFalse(set.matches(motor4));
|
||||
try {
|
||||
|
@ -186,4 +186,16 @@ public class ThrustCurveMotorTest {
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSimplifyDesignation() {
|
||||
assertEquals("J115", ThrustCurveMotor.Builder.simplifyDesignation("J115"));
|
||||
assertEquals("J115", ThrustCurveMotor.Builder.simplifyDesignation(" J115 "));
|
||||
assertEquals("H115", ThrustCurveMotor.Builder.simplifyDesignation("241H115-KS"));
|
||||
assertEquals("J115", ThrustCurveMotor.Builder.simplifyDesignation("384 J115"));
|
||||
assertEquals("J115", ThrustCurveMotor.Builder.simplifyDesignation("384-J115"));
|
||||
assertEquals("A2", ThrustCurveMotor.Builder.simplifyDesignation("A2T"));
|
||||
assertEquals("1/2A2T", ThrustCurveMotor.Builder.simplifyDesignation("1/2A2T"));
|
||||
assertEquals("MicroMaxxII", ThrustCurveMotor.Builder.simplifyDesignation("Micro Maxx II"));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ public class SimulationExportPanel extends JPanel {
|
||||
|
||||
private void doExport() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setFileFilter(FileHelper.CSV_FILE_FILTER);
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
|
||||
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
|
||||
@ -204,7 +204,7 @@ public class SimulationExportPanel extends JPanel {
|
||||
if (file == null)
|
||||
return;
|
||||
|
||||
file = FileHelper.ensureExtension(file, "csv");
|
||||
file = FileHelper.forceExtension(file, "csv");
|
||||
if (!FileHelper.confirmWrite(file, this)) {
|
||||
return;
|
||||
}
|
||||
|
@ -15,8 +15,10 @@ import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
|
||||
@ -24,6 +26,7 @@ import net.sf.openrocket.unit.UnitGroup;
|
||||
public class BodyTubeConfig extends RocketComponentConfig {
|
||||
|
||||
private DoubleModel maxLength;
|
||||
private final JCheckBox checkAutoOuterRadius;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) {
|
||||
@ -58,9 +61,10 @@ public class BodyTubeConfig extends RocketComponentConfig {
|
||||
|
||||
//// Automatic
|
||||
javax.swing.Action outerAutoAction = od.getAutomaticAction();
|
||||
JCheckBox check = new JCheckBox(outerAutoAction);
|
||||
check.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
|
||||
panel.add(check, "skip, span 2, wrap");
|
||||
checkAutoOuterRadius = new JCheckBox(outerAutoAction);
|
||||
checkAutoOuterRadius.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
|
||||
panel.add(checkAutoOuterRadius, "skip, span 2, wrap");
|
||||
updateCheckboxAutoAftRadius();
|
||||
|
||||
//// Inner diameter
|
||||
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter")));
|
||||
@ -87,7 +91,7 @@ public class BodyTubeConfig extends RocketComponentConfig {
|
||||
panel.add(new BasicSlider(thicknessModel.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
|
||||
|
||||
//// Filled
|
||||
check = new JCheckBox(new BooleanModel(component, "Filled"));
|
||||
JCheckBox check = new JCheckBox(new BooleanModel(component, "Filled"));
|
||||
check.setText(trans.get("BodyTubecfg.checkbox.Filled"));
|
||||
panel.add(check, "skip, span 2, wrap");
|
||||
|
||||
@ -113,4 +117,33 @@ public class BodyTubeConfig extends RocketComponentConfig {
|
||||
super.updateFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checkAutoOuterRadius checkbox's enabled state and tooltip text, based on the state of its previous
|
||||
* component. If there is no next and previous symmetric component, the checkAutoOuterRadius checkbox is disabled.
|
||||
* If there is still a next or previous component which does not have its auto state enabled, meaning it can still
|
||||
* serve as a reference component for this component, the auto checkbox is enabled.
|
||||
*/
|
||||
private void updateCheckboxAutoAftRadius() {
|
||||
if (component == null || checkAutoOuterRadius == null) return;
|
||||
|
||||
// Disable check button if there is no component to get the diameter from
|
||||
SymmetricComponent prevComp = ((BodyTube) component).getPreviousSymmetricComponent();
|
||||
SymmetricComponent nextComp = ((BodyTube) component).getNextSymmetricComponent();
|
||||
if (prevComp == null && nextComp == null) {
|
||||
checkAutoOuterRadius.setEnabled(false);
|
||||
((BodyTube) component).setOuterRadiusAutomatic(false);
|
||||
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic_noReferenceComponent"));
|
||||
return;
|
||||
}
|
||||
if (!(prevComp != null && nextComp == null && prevComp.usesNextCompAutomatic()) &&
|
||||
!(nextComp != null && prevComp == null && nextComp.usesPreviousCompAutomatic()) &&
|
||||
!(nextComp != null && prevComp != null && prevComp.usesNextCompAutomatic() && nextComp.usesPreviousCompAutomatic())) {
|
||||
checkAutoOuterRadius.setEnabled(true);
|
||||
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic"));
|
||||
} else {
|
||||
checkAutoOuterRadius.setEnabled(false);
|
||||
((BodyTube) component).setOuterRadiusAutomatic(false);
|
||||
checkAutoOuterRadius.setToolTipText(trans.get("BodyTubecfg.checkbox.ttip.Automatic_alreadyAuto"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package net.sf.openrocket.gui.configdialog;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -18,7 +17,6 @@ import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
@ -35,7 +33,6 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -253,17 +250,22 @@ public class FreeformFinSetConfig extends FinSetConfig {
|
||||
// panel.add(new JLabel("Coordinates:"), "aligny bottom, alignx 50%");
|
||||
// panel.add(new JLabel(" View:"), "wrap, aligny bottom");
|
||||
|
||||
JButton exportCsvButton = new SelectColorButton("Export CSV");
|
||||
JButton exportCsvButton = new SelectColorButton(trans.get("FreeformFinSetConfig.lbl.exportCSV"));
|
||||
exportCsvButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.info(Markers.USER_MARKER, "Export CSV free-form fin");
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
// Demonstrate "Save" dialog:
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
|
||||
if (JFileChooser.APPROVE_OPTION == chooser.showSaveDialog(FreeformFinSetConfig.this)){
|
||||
File selectedFile= chooser.getSelectedFile();
|
||||
selectedFile = FileHelper.forceExtension(selectedFile, "csv");
|
||||
if (!FileHelper.confirmWrite(selectedFile, panel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FreeformFinSetConfig.writeCSVFile(table, selectedFile);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
@ -36,6 +37,7 @@ public class NoseConeConfig extends RocketComponentConfig {
|
||||
private JLabel shapeLabel;
|
||||
private JSpinner shapeSpinner;
|
||||
private JSlider shapeSlider;
|
||||
private final JCheckBox checkAutoAftRadius;
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
// Prepended to the description from NoseCone.DESCRIPTIONS
|
||||
@ -109,10 +111,11 @@ public class NoseConeConfig extends RocketComponentConfig {
|
||||
panel.add(new UnitSelector(aftRadiusModel), "growx");
|
||||
panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
|
||||
|
||||
JCheckBox check = new JCheckBox(aftRadiusModel.getAutomaticAction());
|
||||
checkAutoAftRadius = new JCheckBox(aftRadiusModel.getAutomaticAction());
|
||||
//// Automatic
|
||||
check.setText(trans.get("NoseConeCfg.checkbox.Automatic"));
|
||||
panel.add(check, "skip, span 2, wrap");
|
||||
checkAutoAftRadius.setText(trans.get("NoseConeCfg.checkbox.Automatic"));
|
||||
panel.add(checkAutoAftRadius, "skip, span 2, wrap");
|
||||
updateCheckboxAutoAftRadius();
|
||||
}
|
||||
|
||||
{//// Wall thickness:
|
||||
@ -165,6 +168,30 @@ public class NoseConeConfig extends RocketComponentConfig {
|
||||
shapeSpinner.setEnabled(e);
|
||||
shapeSlider.setEnabled(e);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the checkAutoAftRadius checkbox's enabled state and tooltip text, based on the state of its next component.
|
||||
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
|
||||
* checkAutoAftRadius checkbox is disabled.
|
||||
*/
|
||||
private void updateCheckboxAutoAftRadius() {
|
||||
if (component == null || checkAutoAftRadius == null) return;
|
||||
|
||||
// Disable check button if there is no component to get the diameter from
|
||||
SymmetricComponent nextComp = ((NoseCone) component).getNextSymmetricComponent();
|
||||
if (nextComp == null) {
|
||||
checkAutoAftRadius.setEnabled(false);
|
||||
((NoseCone) component).setAftRadiusAutomatic(false);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic_noReferenceComponent"));
|
||||
return;
|
||||
}
|
||||
if (!nextComp.usesPreviousCompAutomatic()) {
|
||||
checkAutoAftRadius.setEnabled(true);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic"));
|
||||
} else {
|
||||
checkAutoAftRadius.setEnabled(false);
|
||||
((NoseCone) component).setAftRadiusAutomatic(false);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("NoseConeCfg.checkbox.ttip.Automatic_alreadyAuto"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import net.sf.openrocket.gui.components.UnitSelector;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.rocketcomponent.Transition;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
@ -35,6 +36,8 @@ public class TransitionConfig extends RocketComponentConfig {
|
||||
private JLabel shapeLabel;
|
||||
private JSpinner shapeSpinner;
|
||||
private BasicSlider shapeSlider;
|
||||
private final JCheckBox checkAutoAftRadius;
|
||||
private final JCheckBox checkAutoForeRadius;
|
||||
private DescriptionArea description;
|
||||
|
||||
|
||||
@ -120,10 +123,11 @@ public class TransitionConfig extends RocketComponentConfig {
|
||||
panel.add(new UnitSelector(foreRadiusModel), "growx");
|
||||
panel.add(new BasicSlider(foreRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
|
||||
|
||||
final JCheckBox checkbox = new JCheckBox(foreRadiusModel.getAutomaticAction());
|
||||
checkAutoForeRadius = new JCheckBox(foreRadiusModel.getAutomaticAction());
|
||||
//// Automatic
|
||||
checkbox.setText(trans.get("TransitionCfg.checkbox.Automatic"));
|
||||
panel.add(checkbox, "skip, span 2, wrap");
|
||||
checkAutoForeRadius.setText(trans.get("TransitionCfg.checkbox.Automatic"));
|
||||
panel.add(checkAutoForeRadius, "skip, span 2, wrap");
|
||||
updateCheckboxAutoForeRadius();
|
||||
}
|
||||
|
||||
{ //// Aft diameter:
|
||||
@ -139,10 +143,11 @@ public class TransitionConfig extends RocketComponentConfig {
|
||||
panel.add(new UnitSelector(aftRadiusModel), "growx");
|
||||
panel.add(new BasicSlider(aftRadiusModel.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
|
||||
|
||||
final JCheckBox aftRadiusCheckbox = new JCheckBox(aftRadiusModel.getAutomaticAction());
|
||||
checkAutoAftRadius = new JCheckBox(aftRadiusModel.getAutomaticAction());
|
||||
//// Automatic
|
||||
aftRadiusCheckbox.setText(trans.get("TransitionCfg.checkbox.Automatic"));
|
||||
panel.add(aftRadiusCheckbox, "skip, span 2, wrap");
|
||||
checkAutoAftRadius.setText(trans.get("TransitionCfg.checkbox.Automatic"));
|
||||
panel.add(checkAutoAftRadius, "skip, span 2, wrap");
|
||||
updateCheckboxAutoAftRadius();
|
||||
}
|
||||
|
||||
{ /// Wall thickness:
|
||||
@ -194,5 +199,57 @@ public class TransitionConfig extends RocketComponentConfig {
|
||||
shapeSpinner.setEnabled(e);
|
||||
shapeSlider.setEnabled(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checkAutoAftRadius checkbox's enabled state and tooltip text, based on the state of its next component.
|
||||
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
|
||||
* checkAutoAftRadius checkbox is disabled.
|
||||
*/
|
||||
private void updateCheckboxAutoAftRadius() {
|
||||
if (component == null || checkAutoAftRadius == null) return;
|
||||
|
||||
// Disable check button if there is no component to get the diameter from
|
||||
SymmetricComponent nextComp = ((Transition) component).getNextSymmetricComponent();
|
||||
if (nextComp == null) {
|
||||
checkAutoAftRadius.setEnabled(false);
|
||||
((Transition) component).setAftRadiusAutomatic(false);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent"));
|
||||
return;
|
||||
}
|
||||
if (!nextComp.usesPreviousCompAutomatic()) {
|
||||
checkAutoAftRadius.setEnabled(true);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic"));
|
||||
} else {
|
||||
checkAutoAftRadius.setEnabled(false);
|
||||
((Transition) component).setAftRadiusAutomatic(false);
|
||||
checkAutoAftRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_alreadyAuto"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the checkAutoForeRadius checkbox's enabled state and tooltip text, based on the state of its next component.
|
||||
* If there is no next symmetric component or if that component already has its auto checkbox checked, the
|
||||
* checkAutoForeRadius checkbox is disabled.
|
||||
*/
|
||||
private void updateCheckboxAutoForeRadius() {
|
||||
if (component == null || checkAutoForeRadius == null) return;
|
||||
|
||||
// Disable check button if there is no component to get the diameter from
|
||||
SymmetricComponent prevComp = ((Transition) component).getPreviousSymmetricComponent();
|
||||
if (prevComp == null) {
|
||||
checkAutoForeRadius.setEnabled(false);
|
||||
((Transition) component).setForeRadiusAutomatic(false);
|
||||
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_noReferenceComponent"));
|
||||
return;
|
||||
}
|
||||
if (!prevComp.usesNextCompAutomatic()) {
|
||||
checkAutoForeRadius.setEnabled(true);
|
||||
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic"));
|
||||
} else {
|
||||
checkAutoForeRadius.setEnabled(false);
|
||||
((Transition) component).setForeRadiusAutomatic(false);
|
||||
checkAutoForeRadius.setToolTipText(trans.get("TransitionCfg.checkbox.ttip.Automatic_alreadyAuto"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ public class PrintDialog extends JDialog implements TreeSelectionListener {
|
||||
File file = chooser.getSelectedFile();
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION && file != null) {
|
||||
|
||||
file = FileHelper.ensureExtension(file, "pdf");
|
||||
file = FileHelper.forceExtension(file, "pdf");
|
||||
if (!FileHelper.confirmWrite(file, this)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
@ -56,112 +58,118 @@ public class ScaleDialog extends JDialog {
|
||||
* Scaler implementations
|
||||
*
|
||||
* Each scaled value (except override cg/mass) is defined using a Scaler instance.
|
||||
* There are two scaler instances; one for when the offset distances (axial/radial offset) don't need to be scaled
|
||||
* together with the other dimensions and one for when the offsets do need to scale.
|
||||
*/
|
||||
private static final Map<Class<? extends RocketComponent>, List<Scaler>> SCALERS =
|
||||
private static final Map<Class<? extends RocketComponent>, List<Scaler>> SCALERS_NO_OFFSET =
|
||||
new HashMap<Class<? extends RocketComponent>, List<Scaler>>();
|
||||
private static final Map<Class<? extends RocketComponent>, List<Scaler>> SCALERS_OFFSET =
|
||||
new HashMap<Class<? extends RocketComponent>, List<Scaler>>();
|
||||
static {
|
||||
List<Scaler> list;
|
||||
|
||||
// RocketComponent
|
||||
addScaler(RocketComponent.class, "AxialOffset");
|
||||
SCALERS.get(RocketComponent.class).add(new OverrideScaler());
|
||||
addScaler(RocketComponent.class, "AxialOffset", SCALERS_OFFSET);
|
||||
SCALERS_OFFSET.get(RocketComponent.class).add(new OverrideScaler());
|
||||
|
||||
// ComponentAssembly
|
||||
addScaler(ParallelStage.class, "RadiusOffset");
|
||||
addScaler(PodSet.class, "RadiusOffset");
|
||||
addScaler(ParallelStage.class, "RadiusOffset", SCALERS_OFFSET);
|
||||
addScaler(PodSet.class, "RadiusOffset", SCALERS_OFFSET);
|
||||
|
||||
// BodyComponent
|
||||
addScaler(BodyComponent.class, "Length");
|
||||
addScaler(BodyComponent.class, "Length", SCALERS_NO_OFFSET);
|
||||
|
||||
// SymmetricComponent
|
||||
addScaler(SymmetricComponent.class, "Thickness", "isFilled");
|
||||
addScaler(SymmetricComponent.class, "Thickness", "isFilled", SCALERS_NO_OFFSET);
|
||||
|
||||
// Transition + Nose cone
|
||||
addScaler(Transition.class, "ForeRadius", "isForeRadiusAutomatic");
|
||||
addScaler(Transition.class, "AftRadius", "isAftRadiusAutomatic");
|
||||
addScaler(Transition.class, "ForeShoulderRadius");
|
||||
addScaler(Transition.class, "ForeShoulderThickness");
|
||||
addScaler(Transition.class, "ForeShoulderLength");
|
||||
addScaler(Transition.class, "AftShoulderRadius");
|
||||
addScaler(Transition.class, "AftShoulderThickness");
|
||||
addScaler(Transition.class, "AftShoulderLength");
|
||||
addScaler(Transition.class, "ForeRadius", "isForeRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "AftRadius", "isAftRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "ForeShoulderRadius", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "ForeShoulderThickness", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "ForeShoulderLength", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "AftShoulderRadius", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "AftShoulderThickness", SCALERS_NO_OFFSET);
|
||||
addScaler(Transition.class, "AftShoulderLength", SCALERS_NO_OFFSET);
|
||||
|
||||
// Body tube
|
||||
addScaler(BodyTube.class, "OuterRadius", "isOuterRadiusAutomatic");
|
||||
addScaler(BodyTube.class, "MotorOverhang");
|
||||
addScaler(BodyTube.class, "OuterRadius", "isOuterRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
addScaler(BodyTube.class, "MotorOverhang", SCALERS_NO_OFFSET);
|
||||
|
||||
// Launch lug
|
||||
addScaler(LaunchLug.class, "OuterRadius");
|
||||
addScaler(LaunchLug.class, "Thickness");
|
||||
addScaler(LaunchLug.class, "Length");
|
||||
addScaler(LaunchLug.class, "OuterRadius", SCALERS_NO_OFFSET);
|
||||
addScaler(LaunchLug.class, "Thickness", SCALERS_NO_OFFSET);
|
||||
addScaler(LaunchLug.class, "Length", SCALERS_NO_OFFSET);
|
||||
|
||||
// FinSet
|
||||
addScaler(FinSet.class, "Thickness");
|
||||
addScaler(FinSet.class, "TabHeight");
|
||||
addScaler(FinSet.class, "TabLength");
|
||||
addScaler(FinSet.class, "TabOffset");
|
||||
addScaler(FinSet.class, "Thickness", SCALERS_NO_OFFSET);
|
||||
addScaler(FinSet.class, "TabHeight", SCALERS_NO_OFFSET);
|
||||
addScaler(FinSet.class, "TabLength", SCALERS_NO_OFFSET);
|
||||
addScaler(FinSet.class, "TabOffset", SCALERS_NO_OFFSET);
|
||||
|
||||
// TrapezoidFinSet
|
||||
addScaler(TrapezoidFinSet.class, "Sweep");
|
||||
addScaler(TrapezoidFinSet.class, "RootChord");
|
||||
addScaler(TrapezoidFinSet.class, "TipChord");
|
||||
addScaler(TrapezoidFinSet.class, "Height");
|
||||
addScaler(TrapezoidFinSet.class, "Sweep", SCALERS_NO_OFFSET);
|
||||
addScaler(TrapezoidFinSet.class, "RootChord", SCALERS_NO_OFFSET);
|
||||
addScaler(TrapezoidFinSet.class, "TipChord", SCALERS_NO_OFFSET);
|
||||
addScaler(TrapezoidFinSet.class, "Height", SCALERS_NO_OFFSET);
|
||||
|
||||
// EllipticalFinSet
|
||||
addScaler(EllipticalFinSet.class, "Length");
|
||||
addScaler(EllipticalFinSet.class, "Height");
|
||||
addScaler(EllipticalFinSet.class, "Length", SCALERS_NO_OFFSET);
|
||||
addScaler(EllipticalFinSet.class, "Height", SCALERS_NO_OFFSET);
|
||||
|
||||
// FreeformFinSet
|
||||
list = new ArrayList<ScaleDialog.Scaler>(1);
|
||||
list.add(new FreeformFinSetScaler());
|
||||
SCALERS.put(FreeformFinSet.class, list);
|
||||
SCALERS_NO_OFFSET.put(FreeformFinSet.class, list);
|
||||
|
||||
// MassObject
|
||||
addScaler(MassObject.class, "Length");
|
||||
addScaler(MassObject.class, "Radius");
|
||||
addScaler(MassObject.class, "RadialPosition");
|
||||
addScaler(MassObject.class, "Length", SCALERS_NO_OFFSET);
|
||||
addScaler(MassObject.class, "Radius", SCALERS_NO_OFFSET);
|
||||
addScaler(MassObject.class, "RadialPosition", SCALERS_OFFSET);
|
||||
|
||||
// MassComponent
|
||||
list = new ArrayList<ScaleDialog.Scaler>(1);
|
||||
list.add(new MassComponentScaler());
|
||||
SCALERS.put(MassComponent.class, list);
|
||||
SCALERS_NO_OFFSET.put(MassComponent.class, list);
|
||||
|
||||
// Parachute
|
||||
addScaler(Parachute.class, "Diameter");
|
||||
addScaler(Parachute.class, "LineLength");
|
||||
addScaler(Parachute.class, "Diameter", SCALERS_NO_OFFSET);
|
||||
addScaler(Parachute.class, "LineLength", SCALERS_NO_OFFSET);
|
||||
|
||||
// Streamer
|
||||
addScaler(Streamer.class, "StripLength");
|
||||
addScaler(Streamer.class, "StripWidth");
|
||||
addScaler(Streamer.class, "StripLength", SCALERS_NO_OFFSET);
|
||||
addScaler(Streamer.class, "StripWidth", SCALERS_NO_OFFSET);
|
||||
|
||||
// ShockCord
|
||||
addScaler(ShockCord.class, "CordLength");
|
||||
addScaler(ShockCord.class, "CordLength", SCALERS_NO_OFFSET);
|
||||
|
||||
// RingComponent
|
||||
addScaler(RingComponent.class, "Length");
|
||||
addScaler(RingComponent.class, "RadialPosition");
|
||||
addScaler(RingComponent.class, "Length", SCALERS_NO_OFFSET);
|
||||
addScaler(RingComponent.class, "RadialPosition", SCALERS_OFFSET);
|
||||
|
||||
// ThicknessRingComponent
|
||||
addScaler(ThicknessRingComponent.class, "OuterRadius", "isOuterRadiusAutomatic");
|
||||
addScaler(ThicknessRingComponent.class, "Thickness");
|
||||
addScaler(ThicknessRingComponent.class, "OuterRadius", "isOuterRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
addScaler(ThicknessRingComponent.class, "Thickness", SCALERS_NO_OFFSET);
|
||||
|
||||
// InnerTube
|
||||
addScaler(InnerTube.class, "MotorOverhang");
|
||||
addScaler(InnerTube.class, "MotorOverhang", SCALERS_NO_OFFSET);
|
||||
|
||||
// RadiusRingComponent
|
||||
addScaler(RadiusRingComponent.class, "OuterRadius", "isOuterRadiusAutomatic");
|
||||
addScaler(RadiusRingComponent.class, "InnerRadius", "isInnerRadiusAutomatic");
|
||||
addScaler(RadiusRingComponent.class, "OuterRadius", "isOuterRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
addScaler(RadiusRingComponent.class, "InnerRadius", "isInnerRadiusAutomatic", SCALERS_NO_OFFSET);
|
||||
}
|
||||
|
||||
private static void addScaler(Class<? extends RocketComponent> componentClass, String methodName) {
|
||||
addScaler(componentClass, methodName, null);
|
||||
private static void addScaler(Class<? extends RocketComponent> componentClass, String methodName,
|
||||
Map<Class<? extends RocketComponent>, List<Scaler>> scaler) {
|
||||
addScaler(componentClass, methodName, null, scaler);
|
||||
}
|
||||
|
||||
private static void addScaler(Class<? extends RocketComponent> componentClass, String methodName, String autoMethodName) {
|
||||
List<Scaler> list = SCALERS.get(componentClass);
|
||||
private static void addScaler(Class<? extends RocketComponent> componentClass, String methodName, String autoMethodName,
|
||||
Map<Class<? extends RocketComponent>, List<Scaler>> scaler) {
|
||||
List<Scaler> list = scaler.get(componentClass);
|
||||
if (list == null) {
|
||||
list = new ArrayList<ScaleDialog.Scaler>();
|
||||
SCALERS.put(componentClass, list);
|
||||
scaler.put(componentClass, list);
|
||||
}
|
||||
list.add(new GeneralScaler(componentClass, methodName, autoMethodName));
|
||||
}
|
||||
@ -447,7 +455,7 @@ public class ScaleDialog extends JDialog {
|
||||
try {
|
||||
document.startUndo(trans.get("undo.scaleRocket"));
|
||||
for (RocketComponent c : document.getRocket()) {
|
||||
scale(c, mul, scaleMass);
|
||||
scale(c, mul, scaleMass, true);
|
||||
}
|
||||
} finally {
|
||||
document.stopUndo();
|
||||
@ -458,8 +466,9 @@ public class ScaleDialog extends JDialog {
|
||||
// Scale component and subcomponents
|
||||
try {
|
||||
document.startUndo(trans.get("undo.scaleComponents"));
|
||||
for (RocketComponent c : selection) {
|
||||
scale(c, mul, scaleMass);
|
||||
scale(selection, mul, scaleMass, false);
|
||||
for (RocketComponent c : selection.getChildren()) {
|
||||
scale(c, mul, scaleMass, true);
|
||||
}
|
||||
} finally {
|
||||
document.stopUndo();
|
||||
@ -470,7 +479,7 @@ public class ScaleDialog extends JDialog {
|
||||
// Scale only the selected component
|
||||
try {
|
||||
document.startUndo(trans.get("undo.scaleComponent"));
|
||||
scale(selection, mul, scaleMass);
|
||||
scale(selection, mul, scaleMass, false);
|
||||
} finally {
|
||||
document.stopUndo();
|
||||
}
|
||||
@ -479,16 +488,28 @@ public class ScaleDialog extends JDialog {
|
||||
throw new BugException("Unknown item selected, item=" + item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform scaling on a single component.
|
||||
* @param component component to be scaled
|
||||
* @param mul scaling factor
|
||||
* @param scaleMass flag to check if the mass should be scaled as well
|
||||
* @param scaleOffset flag to check if the axial/radial offsets should be scaled as well
|
||||
*/
|
||||
private void scale(RocketComponent component, double mul, boolean scaleMass) {
|
||||
private void scale(RocketComponent component, double mul, boolean scaleMass, boolean scaleOffset) {
|
||||
|
||||
Class<?> clazz = component.getClass();
|
||||
while (clazz != null) {
|
||||
List<Scaler> list = SCALERS.get(clazz);
|
||||
List<Scaler> list = null;
|
||||
if (scaleOffset) {
|
||||
Stream<Scaler> strm_no_offset = SCALERS_NO_OFFSET.get(clazz) == null ? Stream.empty() : SCALERS_NO_OFFSET.get(clazz).stream();
|
||||
Stream<Scaler> strm_offset = SCALERS_OFFSET.get(clazz) == null ? Stream.empty() : SCALERS_OFFSET.get(clazz).stream();
|
||||
list = Stream.concat(strm_no_offset, strm_offset).distinct().collect(Collectors.toList());
|
||||
}
|
||||
else {
|
||||
list = SCALERS_NO_OFFSET.get(clazz);
|
||||
}
|
||||
if (list != null) {
|
||||
for (Scaler s : list) {
|
||||
s.scale(component, mul, scaleMass);
|
||||
|
@ -22,7 +22,7 @@ class MotorHolder {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return motor.getDesignation();
|
||||
return motor.getCommonName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -50,7 +50,8 @@ class MotorInformationPanel extends JPanel {
|
||||
private List<ThrustCurveMotor> selectedMotorSet;
|
||||
// Selected motor
|
||||
private ThrustCurveMotor selectedMotor;
|
||||
|
||||
|
||||
private final JLabel designationLabel;
|
||||
private final JLabel totalImpulseLabel;
|
||||
private final JLabel classificationLabel;
|
||||
private final JLabel avgThrustLabel;
|
||||
@ -76,8 +77,13 @@ class MotorInformationPanel extends JPanel {
|
||||
super(new MigLayout("fill"));
|
||||
|
||||
// Thrust curve info
|
||||
//// Total impulse:
|
||||
{
|
||||
//// Designation
|
||||
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Designation")));
|
||||
designationLabel = new JLabel();
|
||||
this.add(designationLabel, "wrap");
|
||||
|
||||
//// Total impulse:
|
||||
this.add(new JLabel(trans.get("TCMotorSelPan.lbl.Totalimpulse")));
|
||||
totalImpulseLabel = new JLabel();
|
||||
this.add(totalImpulseLabel, "split");
|
||||
@ -223,6 +229,7 @@ class MotorInformationPanel extends JPanel {
|
||||
public void clearData() {
|
||||
selectedMotor = null;
|
||||
selectedMotorSet = null;
|
||||
designationLabel.setText("");
|
||||
totalImpulseLabel.setText("");
|
||||
totalImpulseLabel.setToolTipText(null);
|
||||
classificationLabel.setText("");
|
||||
@ -254,6 +261,7 @@ class MotorInformationPanel extends JPanel {
|
||||
this.selectedMotor = selectedMotor;
|
||||
|
||||
// Update thrust curve data
|
||||
designationLabel.setText(selectedMotor.getDesignation());
|
||||
double impulse = selectedMotor.getTotalImpulseEstimate();
|
||||
MotorClass mc = MotorClass.getMotorClass(impulse);
|
||||
totalImpulseLabel.setText(UnitGroup.UNITS_IMPULSE.getDefaultUnit().toStringUnit(impulse));
|
||||
|
@ -30,11 +30,11 @@ enum ThrustCurveMotorColumns {
|
||||
return Collator.getInstance();
|
||||
}
|
||||
},
|
||||
//// Designation
|
||||
DESIGNATION("TCurveMotorCol.DESIGNATION") {
|
||||
//// Common name
|
||||
COMMON_NAME("TCurveMotorCol.COMMON_NAME") {
|
||||
@Override
|
||||
public String getValue(ThrustCurveMotorSet m) {
|
||||
return m.getDesignation();
|
||||
return m.getCommonName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,8 +48,6 @@ import javax.swing.table.TableColumnModel;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import net.sf.openrocket.optimization.rocketoptimization.modifiers.GenericComponentModifier;
|
||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -1112,7 +1110,7 @@ public class GeneralOptimizationDialog extends JDialog {
|
||||
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setFileFilter(FileHelper.CSV_FILE_FILTER);
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
chooser.setAccessory(csvOptions);
|
||||
|
||||
@ -1123,7 +1121,7 @@ public class GeneralOptimizationDialog extends JDialog {
|
||||
if (file == null)
|
||||
return;
|
||||
|
||||
file = FileHelper.ensureExtension(file, "csv");
|
||||
file = FileHelper.forceExtension(file, "csv");
|
||||
if (!FileHelper.confirmWrite(file, this)) {
|
||||
return;
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ public class BasicFrame extends JFrame {
|
||||
|
||||
// Bottom segment, rocket figure
|
||||
|
||||
rocketpanel = new RocketPanel(document);
|
||||
rocketpanel = new RocketPanel(document, this);
|
||||
vertical.setBottomComponent(rocketpanel);
|
||||
|
||||
rocketpanel.setSelectionModel(tree.getSelectionModel());
|
||||
@ -1099,6 +1099,9 @@ public class BasicFrame extends JFrame {
|
||||
tabbedPane.setSelectedIndex(tab);
|
||||
}
|
||||
|
||||
public int getSelectedTab() {
|
||||
return tabbedPane.getSelectedIndex();
|
||||
}
|
||||
|
||||
|
||||
private void openAction() {
|
||||
|
@ -576,7 +576,7 @@ public class SimulationPanel extends JPanel {
|
||||
public void documentChanged(DocumentChangeEvent event) {
|
||||
if (!(event instanceof SimulationChangeEvent))
|
||||
return;
|
||||
simulationTableModel.fireTableDataChanged();
|
||||
fireMaintainSelection();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -54,10 +54,14 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
|
||||
synchronizeConfigurationSelection();
|
||||
}
|
||||
|
||||
public void fireTableDataChanged() {
|
||||
/**
|
||||
* Update the data in the table, with component change event type {cce}
|
||||
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
||||
*/
|
||||
public void fireTableDataChanged(int cce) {
|
||||
int selectedRow = table.getSelectedRow();
|
||||
int selectedColumn = table.getSelectedColumn();
|
||||
this.rocket.fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
this.rocket.fireComponentChangeEvent(cce);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
restoreSelection(selectedRow,selectedColumn);
|
||||
updateButtonState();
|
||||
|
@ -15,6 +15,7 @@ import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.RenameConfigDialog;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
@ -79,7 +80,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
||||
int lastCol = motorConfigurationPanel.table.getColumnCount() - 1;
|
||||
motorConfigurationPanel.table.setRowSelectionInterval(lastRow, lastRow);
|
||||
motorConfigurationPanel.table.setColumnSelectionInterval(lastCol, lastCol);
|
||||
configurationChanged();
|
||||
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
|
||||
});
|
||||
@ -91,7 +92,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
renameConfiguration();
|
||||
configurationChanged();
|
||||
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
});
|
||||
this.add(renameConfButton,"gapright para");
|
||||
@ -101,7 +102,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
removeConfiguration();
|
||||
configurationChanged();
|
||||
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
});
|
||||
this.add(removeConfButton,"gapright para");
|
||||
@ -111,7 +112,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
addOrCopyConfiguration(true);
|
||||
configurationChanged();
|
||||
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
});
|
||||
this.add(copyConfButton, "wrap");
|
||||
@ -172,13 +173,13 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
||||
if (currentId == null)
|
||||
return;
|
||||
document.removeFlightConfigurationAndSimulations(currentId);
|
||||
configurationChanged();
|
||||
configurationChanged(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||
}
|
||||
|
||||
private void configurationChanged() {
|
||||
motorConfigurationPanel.fireTableDataChanged();
|
||||
recoveryConfigurationPanel.fireTableDataChanged();
|
||||
separationConfigurationPanel.fireTableDataChanged();
|
||||
private void configurationChanged(int cce) {
|
||||
motorConfigurationPanel.fireTableDataChanged(cce);
|
||||
recoveryConfigurationPanel.fireTableDataChanged(cce);
|
||||
separationConfigurationPanel.fireTableDataChanged(cce);
|
||||
}
|
||||
|
||||
private void updateButtonState() {
|
||||
|
@ -37,6 +37,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
import net.sf.openrocket.util.Chars;
|
||||
|
||||
@ -214,20 +215,25 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
throw new IllegalStateException("Attempting to set a motor on the default FCID.");
|
||||
}
|
||||
|
||||
double initDelay = curMount.getMotorConfig(fcid).getEjectionDelay();
|
||||
|
||||
motorChooserDialog.setMotorMountAndConfig( fcid, curMount );
|
||||
motorChooserDialog.setVisible(true);
|
||||
|
||||
Motor mtr = motorChooserDialog.getSelectedMotor();
|
||||
double d = motorChooserDialog.getSelectedDelay();
|
||||
if (mtr != null) {
|
||||
if (mtr == curMount.getMotorConfig(fcid).getMotor() && d == initDelay) {
|
||||
return;
|
||||
}
|
||||
final MotorConfiguration templateConfig = curMount.getMotorConfig(fcid);
|
||||
final MotorConfiguration newConfig = new MotorConfiguration( curMount, fcid, templateConfig);
|
||||
newConfig.setMotor(mtr);
|
||||
newConfig.setEjectionDelay(d);
|
||||
curMount.setMotorConfig( newConfig, fcid);
|
||||
}
|
||||
|
||||
fireTableDataChanged();
|
||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeMotor() {
|
||||
@ -239,24 +245,30 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
|
||||
curMount.setMotorConfig( null, fcid);
|
||||
|
||||
fireTableDataChanged();
|
||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
|
||||
private void selectIgnition() {
|
||||
MotorMount curMount = getSelectedComponent();
|
||||
FlightConfigurationId fcid= getSelectedConfigurationId();
|
||||
if ( (null == fcid )||( null == curMount )){
|
||||
return;
|
||||
}
|
||||
|
||||
MotorMount curMount = getSelectedComponent();
|
||||
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||
if ((null == fcid) || (null == curMount)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
|
||||
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent();
|
||||
double initialIgnitionDelay = curInstance.getIgnitionDelay();
|
||||
|
||||
// this call also performs the update changes
|
||||
IgnitionSelectionDialog ignitionDialog = new IgnitionSelectionDialog(
|
||||
SwingUtilities.getWindowAncestor(this.flightConfigurationPanel),
|
||||
fcid,
|
||||
curMount);
|
||||
ignitionDialog.setVisible(true);
|
||||
|
||||
fireTableDataChanged();
|
||||
|
||||
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) {
|
||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -267,10 +279,14 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
return;
|
||||
}
|
||||
MotorConfiguration curInstance = curMount.getMotorConfig(fcid);
|
||||
IgnitionEvent initialIgnitionEvent = curInstance.getIgnitionEvent();
|
||||
double initialIgnitionDelay = curInstance.getIgnitionDelay();
|
||||
|
||||
curInstance.useDefaultIgnition();
|
||||
|
||||
fireTableDataChanged();
|
||||
if (!initialIgnitionEvent.equals(curInstance.getIgnitionEvent()) || (initialIgnitionDelay != curInstance.getIgnitionDelay())) {
|
||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -304,7 +320,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
throw new NullPointerException("Motor has a null mount... this should never happen: "+curMotorInstance.getID());
|
||||
}
|
||||
|
||||
String str = motor.getDesignation(curMotorInstance.getEjectionDelay());
|
||||
String str = motor.getCommonName(curMotorInstance.getEjectionDelay());
|
||||
int count = mount.getInstanceCount();
|
||||
if (count > 1) {
|
||||
str = "" + count + Chars.TIMES + " " + str;
|
||||
|
@ -99,22 +99,31 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
||||
|
||||
private void selectDeployment() {
|
||||
RecoveryDevice c = getSelectedComponent();
|
||||
if (c == null) {
|
||||
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||
if ((c == null) || (fcid == null)) {
|
||||
return;
|
||||
}
|
||||
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
|
||||
JDialog d = new DeploymentSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, c);
|
||||
d.setVisible(true);
|
||||
fireTableDataChanged();
|
||||
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) {
|
||||
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resetDeployment() {
|
||||
RecoveryDevice c = getSelectedComponent();
|
||||
if (c == null) {
|
||||
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||
if ((c == null) || (fcid == null)) {
|
||||
return;
|
||||
}
|
||||
DeploymentConfiguration initialConfig = c.getDeploymentConfigurations().get(fcid).copy(fcid);
|
||||
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
c.getDeploymentConfigurations().reset(id);
|
||||
fireTableDataChanged();
|
||||
if (!initialConfig.equals(c.getDeploymentConfigurations().get(fcid))) {
|
||||
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateButtonState() {
|
||||
|
@ -47,7 +47,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
selectSeparationButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
selectDeployment();
|
||||
selectSeparation();
|
||||
}
|
||||
});
|
||||
this.add(selectSeparationButton, "split, align right, sizegroup button");
|
||||
@ -58,7 +58,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
resetDeploymentButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
resetDeployment();
|
||||
resetSeparation();
|
||||
}
|
||||
});
|
||||
this.add(resetDeploymentButton, "sizegroup button, wrap");
|
||||
@ -95,7 +95,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
updateButtonState();
|
||||
if (e.getClickCount() == 2) {
|
||||
// Double-click edits
|
||||
selectDeployment();
|
||||
selectSeparation();
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -104,27 +104,35 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
return separationTable;
|
||||
}
|
||||
|
||||
private void selectDeployment() {
|
||||
private void selectSeparation() {
|
||||
AxialStage stage = getSelectedComponent();
|
||||
if (stage == null) {
|
||||
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||
if ((stage == null) || (fcid == null)) {
|
||||
return;
|
||||
}
|
||||
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid);
|
||||
JDialog d = new SeparationSelectionDialog(SwingUtilities.getWindowAncestor(this), rocket, stage);
|
||||
d.setVisible(true);
|
||||
fireTableDataChanged();
|
||||
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) {
|
||||
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetDeployment() {
|
||||
private void resetSeparation() {
|
||||
AxialStage stage = getSelectedComponent();
|
||||
if (stage == null) {
|
||||
FlightConfigurationId fcid = getSelectedConfigurationId();
|
||||
if ((stage == null) || (fcid == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
StageSeparationConfiguration initialConfig = stage.getSeparationConfigurations().get(fcid).copy(fcid);
|
||||
// why?
|
||||
FlightConfigurationId id = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
stage.getSeparationConfigurations().reset(id);
|
||||
|
||||
fireTableDataChanged();
|
||||
|
||||
if (!initialConfig.equals(stage.getSeparationConfigurations().get(fcid))) {
|
||||
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
||||
}
|
||||
}
|
||||
public void updateButtonState() {
|
||||
boolean componentSelected = getSelectedComponent() != null;
|
||||
|
@ -8,22 +8,15 @@ import java.awt.Point;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EventListener;
|
||||
import java.util.EventObject;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.JViewport;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
@ -38,6 +31,7 @@ import net.sf.openrocket.aerodynamics.FlightConditions;
|
||||
import net.sf.openrocket.aerodynamics.WarningSet;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.document.events.SimulationChangeEvent;
|
||||
import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ConfigurationComboBox;
|
||||
@ -49,6 +43,7 @@ import net.sf.openrocket.gui.figureelements.CGCaret;
|
||||
import net.sf.openrocket.gui.figureelements.CPCaret;
|
||||
import net.sf.openrocket.gui.figureelements.Caret;
|
||||
import net.sf.openrocket.gui.figureelements.RocketInfo;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.main.componenttree.ComponentTreeModel;
|
||||
import net.sf.openrocket.gui.simulation.SimulationWorker;
|
||||
import net.sf.openrocket.gui.util.SwingPreferences;
|
||||
@ -63,10 +58,12 @@ import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
||||
import net.sf.openrocket.simulation.FlightData;
|
||||
import net.sf.openrocket.simulation.SimulationStatus;
|
||||
import net.sf.openrocket.simulation.customexpression.CustomExpression;
|
||||
import net.sf.openrocket.simulation.customexpression.CustomExpressionSimulationListener;
|
||||
import net.sf.openrocket.simulation.exception.SimulationException;
|
||||
import net.sf.openrocket.simulation.listeners.SimulationListener;
|
||||
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
|
||||
import net.sf.openrocket.simulation.listeners.system.GroundHitListener;
|
||||
import net.sf.openrocket.simulation.listeners.system.InterruptListener;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.unit.UnitGroup;
|
||||
@ -75,11 +72,13 @@ import net.sf.openrocket.util.Chars;
|
||||
import net.sf.openrocket.util.Coordinate;
|
||||
import net.sf.openrocket.util.MathUtil;
|
||||
import net.sf.openrocket.util.StateChangeListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
/**
|
||||
* A JPanel that contains a RocketFigure and buttons to manipulate the figure.
|
||||
*
|
||||
* A JPanel that contains a RocketFigure and buttons to manipulate the figure.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
* @author Bill Kuker <bkuker@billkuker.com>
|
||||
*/
|
||||
@ -87,6 +86,7 @@ import net.sf.openrocket.util.StateChangeListener;
|
||||
public class RocketPanel extends JPanel implements TreeSelectionListener, ChangeSource {
|
||||
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(RocketPanel.class);
|
||||
|
||||
public enum VIEW_TYPE {
|
||||
SideView(false, RocketFigure.VIEW_SIDE),
|
||||
@ -128,7 +128,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/* Calculation of CP and CG */
|
||||
private AerodynamicCalculator aerodynamicCalculator;
|
||||
|
||||
|
||||
private final OpenRocketDocument document;
|
||||
|
||||
private Caret extraCP = null;
|
||||
@ -148,13 +148,16 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
private List<EventListener> listeners = new ArrayList<EventListener>();
|
||||
|
||||
// Store the basic frame to know which tab is selected (Rocket design, Motors & Configuration, Flight simulations)
|
||||
private final BasicFrame basicFrame;
|
||||
|
||||
|
||||
/**
|
||||
* The executor service used for running the background simulations.
|
||||
* This uses a fixed-sized thread pool for all background simulations
|
||||
* with all threads in daemon mode and with minimum priority.
|
||||
*/
|
||||
private static final Executor backgroundSimulationExecutor;
|
||||
private static final ExecutorService backgroundSimulationExecutor;
|
||||
static {
|
||||
backgroundSimulationExecutor = Executors.newFixedThreadPool(SwingPreferences.getMaxThreadCount(),
|
||||
new ThreadFactory() {
|
||||
@ -170,13 +173,17 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public OpenRocketDocument getDocument(){
|
||||
return this.document;
|
||||
}
|
||||
|
||||
|
||||
public RocketPanel(OpenRocketDocument document) {
|
||||
this(document, null);
|
||||
}
|
||||
|
||||
public RocketPanel(OpenRocketDocument document, BasicFrame basicFrame) {
|
||||
this.document = document;
|
||||
this.basicFrame = basicFrame;
|
||||
Rocket rkt = document.getRocket();
|
||||
|
||||
|
||||
@ -216,6 +223,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
rkt.addComponentChangeListener(new ComponentChangeListener() {
|
||||
@Override
|
||||
public void componentChanged(ComponentChangeEvent e) {
|
||||
updateExtras();
|
||||
if (is3d) {
|
||||
if (e.isTextureChange()) {
|
||||
figure3d.flushTextureCaches();
|
||||
@ -367,7 +375,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/**
|
||||
* Get the center of pressure figure element.
|
||||
*
|
||||
*
|
||||
* @return center of pressure info
|
||||
*/
|
||||
public Caret getExtraCP() {
|
||||
@ -376,7 +384,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/**
|
||||
* Get the center of gravity figure element.
|
||||
*
|
||||
*
|
||||
* @return center of gravity info
|
||||
*/
|
||||
public Caret getExtraCG() {
|
||||
@ -385,7 +393,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/**
|
||||
* Get the extra text figure element.
|
||||
*
|
||||
*
|
||||
* @return extra text that contains info about the rocket design
|
||||
*/
|
||||
public RocketInfo getExtraText() {
|
||||
@ -490,12 +498,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/**
|
||||
* Handle clicking on figure shapes. The functioning is the following:
|
||||
*
|
||||
*
|
||||
* Get the components clicked.
|
||||
* If no component is clicked, do nothing.
|
||||
* If the currently selected component is in the set, keep it,
|
||||
* unless the selector specified is pressed. If it is pressed, cycle to
|
||||
* the next component. Otherwise select the first component in the list.
|
||||
* If the currently selected component is in the set, keep it,
|
||||
* unless the selector specified is pressed. If it is pressed, cycle to
|
||||
* the next component. Otherwise select the first component in the list.
|
||||
*/
|
||||
public static final int CYCLE_SELECTION_MODIFIER = InputEvent.SHIFT_DOWN_MASK;
|
||||
|
||||
@ -557,7 +565,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
|
||||
/**
|
||||
* Updates the extra data included in the figure. Currently this includes
|
||||
* the CP and CG carets.
|
||||
* the CP and CG carets. Also start the background simulator.
|
||||
*/
|
||||
private WarningSet warnings = new WarningSet();
|
||||
|
||||
@ -645,7 +653,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
figure3d.setCG(new Coordinate(Double.NaN, Double.NaN));
|
||||
figure3d.setCP(new Coordinate(Double.NaN, Double.NaN));
|
||||
}
|
||||
|
||||
|
||||
if (figure.getType() == RocketPanel.VIEW_TYPE.SideView && length > 0) {
|
||||
extraCP.setPosition(cpx, cpy);
|
||||
extraCG.setPosition(cgx, cgy);
|
||||
@ -683,35 +691,120 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
return;
|
||||
}
|
||||
|
||||
// Start calculation process
|
||||
if(((SwingPreferences) Application.getPreferences()).computeFlightInBackground()){
|
||||
extraText.setCalculatingData(true);
|
||||
// Update simulations
|
||||
if (Application.getPreferences().getAutoRunSimulations()) {
|
||||
// Update only current flight config simulation when you are not in the simulations tab
|
||||
updateSims(this.basicFrame != null && this.basicFrame.getSelectedTab() == BasicFrame.SIMULATION_TAB);
|
||||
}
|
||||
else {
|
||||
// Always update the simulation of the current configuration
|
||||
updateSims(false);
|
||||
}
|
||||
|
||||
Rocket duplicate = (Rocket) document.getRocket().copy();
|
||||
// Update flight data and add flight data update trigger upon simulation changes
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
sim.addChangeListener(new StateChangeListener() {
|
||||
@Override
|
||||
public void stateChanged(EventObject e) {
|
||||
if (updateFlightData(sim)) {
|
||||
updateFigures();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (updateFlightData(sim)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find a Simulation based on the current flight configuration
|
||||
FlightConfigurationId curID = curConfig.getFlightConfigurationID();
|
||||
Simulation simulation = null;
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
/**
|
||||
* Updates the simulations. If *currentConfig* is false, only update the simulation of the current flight
|
||||
* configuration. If it is true, update all the simulations.
|
||||
*
|
||||
* @param updateAllSims flag to check whether to update all the simulations (true) or only the current
|
||||
* flight config sim (false)
|
||||
*/
|
||||
private void updateSims(boolean updateAllSims) {
|
||||
// Stop previous computation (if any)
|
||||
stopBackgroundSimulation();
|
||||
|
||||
FlightConfigurationId curID = document.getSelectedConfiguration().getFlightConfigurationID();
|
||||
extraText.setCalculatingData(true);
|
||||
Rocket duplicate = (Rocket)document.getRocket().copy();
|
||||
|
||||
// Re-run the present simulation(s)
|
||||
List<Simulation> sims = new LinkedList<>();
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
if (sim.getStatus() == Simulation.Status.UPTODATE || sim.getStatus() == Simulation.Status.LOADED
|
||||
|| !document.getRocket().getFlightConfiguration(sim.getFlightConfigurationId()).hasMotors())
|
||||
continue;
|
||||
|
||||
// Find a Simulation based on the current flight configuration
|
||||
if (!updateAllSims) {
|
||||
if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
|
||||
simulation = sim;
|
||||
sims.add(sim);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong,
|
||||
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
|
||||
// default simulation conditions
|
||||
if (simulation == null) {
|
||||
System.out.println("creating new simulation");
|
||||
simulation = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(duplicate);
|
||||
simulation.setFlightConfigurationId( document.getSelectedConfiguration().getId());
|
||||
} else
|
||||
System.out.println("using pre-existing simulation");
|
||||
|
||||
backgroundSimulationWorker = new BackgroundSimulationWorker(document, simulation);
|
||||
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
||||
else {
|
||||
sims.add(sim);
|
||||
}
|
||||
}
|
||||
runBackgroundSimulations(sims, duplicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the flight data text with the data of {sim}. Only update if sim is the simulation of the current flight
|
||||
* configuration.
|
||||
* @param sim: simulation from which the flight data is taken
|
||||
* @return true if the flight data was updated, false if not
|
||||
*/
|
||||
private boolean updateFlightData(Simulation sim) {
|
||||
FlightConfigurationId curID = document.getSelectedConfiguration().getFlightConfigurationID();
|
||||
if (sim.getFlightConfigurationId().compareTo(curID) == 0) {
|
||||
if (sim.hasSimulationData()) {
|
||||
extraText.setFlightData(sim.getSimulatedData());
|
||||
} else {
|
||||
extraText.setFlightData(FlightData.NaN_DATA);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a new background simulation for simulations *sims*. It will run all the simulations in sims sequentially
|
||||
* in the background.
|
||||
*
|
||||
* @param sims simulations which should be run
|
||||
* @param rkt rocket for which the simulations are run
|
||||
*/
|
||||
private void runBackgroundSimulations(List<Simulation> sims, Rocket rkt) {
|
||||
if (sims.size() == 0) {
|
||||
extraText.setCalculatingData(false);
|
||||
for (Simulation sim : document.getSimulations()) {
|
||||
if (updateFlightData(sim)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
extraText.setFlightData(FlightData.NaN_DATA);
|
||||
return;
|
||||
}
|
||||
|
||||
// I *think* every FlightConfiguration has at least one associated simulation; just in case I'm wrong,
|
||||
// if there isn't one we'll create a new simulation to update the statistics in the panel using the
|
||||
// default simulation conditions
|
||||
for (Simulation sim : sims) {
|
||||
if (sim == null) {
|
||||
log.info("creating new simulation");
|
||||
sim = ((SwingPreferences) Application.getPreferences()).getBackgroundSimulation(rkt);
|
||||
sim.setFlightConfigurationId(document.getSelectedConfiguration().getId());
|
||||
} else
|
||||
log.info("using pre-existing simulation");
|
||||
}
|
||||
|
||||
backgroundSimulationWorker = new BackgroundSimulationWorker(document, sims);
|
||||
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,16 +825,20 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
private class BackgroundSimulationWorker extends SimulationWorker {
|
||||
|
||||
private final CustomExpressionSimulationListener exprListener;
|
||||
private final OpenRocketDocument doc;
|
||||
private List<Simulation> sims;
|
||||
|
||||
public BackgroundSimulationWorker(OpenRocketDocument doc, Simulation sim) {
|
||||
super(sim);
|
||||
public BackgroundSimulationWorker(OpenRocketDocument doc, List<Simulation> sims) {
|
||||
super(sims.get(0));
|
||||
this.sims = sims;
|
||||
this.doc = doc;
|
||||
List<CustomExpression> exprs = doc.getCustomExpressions();
|
||||
exprListener = new CustomExpressionSimulationListener(exprs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FlightData doInBackground() {
|
||||
|
||||
extraText.setCalculatingData(true);
|
||||
// Pause a little while to allow faster UI reaction
|
||||
try {
|
||||
Thread.sleep(300);
|
||||
@ -749,7 +846,6 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
}
|
||||
if (isCancelled() || backgroundSimulationWorker != this)
|
||||
return null;
|
||||
|
||||
return super.doInBackground();
|
||||
}
|
||||
|
||||
@ -758,19 +854,27 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
// Do nothing if cancelled
|
||||
if (isCancelled() || backgroundSimulationWorker != this)
|
||||
return;
|
||||
|
||||
backgroundSimulationWorker = null;
|
||||
extraText.setFlightData(simulation.getSimulatedData());
|
||||
|
||||
// Only set the flight data information of the current flight configuration
|
||||
extraText.setCalculatingData(false);
|
||||
figure.repaint();
|
||||
figure3d.repaint();
|
||||
document.fireDocumentChangeEvent(new SimulationChangeEvent(simulation));
|
||||
|
||||
// Run the new simulation after this one has ended
|
||||
this.sims.remove(0);
|
||||
if (this.sims.size() > 0) {
|
||||
backgroundSimulationWorker = new BackgroundSimulationWorker(this.doc, this.sims);
|
||||
backgroundSimulationExecutor.execute(backgroundSimulationWorker);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SimulationListener[] getExtraListeners() {
|
||||
return new SimulationListener[] {
|
||||
InterruptListener.INSTANCE,
|
||||
ApogeeEndListener.INSTANCE,
|
||||
GroundHitListener.INSTANCE,
|
||||
exprListener };
|
||||
|
||||
}
|
||||
@ -813,7 +917,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the selection in the FigureParameters and repaints the figure.
|
||||
* Updates the selection in the FigureParameters and repaints the figure.
|
||||
* Ignores the event itself.
|
||||
*/
|
||||
@Override
|
||||
@ -868,5 +972,5 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
||||
// putValue(Action.SELECTED_KEY, figure.getType() == type && !is3d);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ public class SimulationExportPanel extends JPanel {
|
||||
|
||||
public boolean doExport() {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setFileFilter(FileHelper.CSV_FILE_FILTER);
|
||||
chooser.setFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
|
||||
|
||||
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION)
|
||||
@ -230,7 +230,7 @@ public class SimulationExportPanel extends JPanel {
|
||||
if (file == null)
|
||||
return false;
|
||||
|
||||
file = FileHelper.ensureExtension(file, "csv");
|
||||
file = FileHelper.forceExtension(file, "csv");
|
||||
if (!FileHelper.confirmWrite(file, this)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -29,33 +29,32 @@ public final class FileHelper {
|
||||
private static final Logger log = LoggerFactory.getLogger(FileHelper.class);
|
||||
private static final Translator trans = Application.getTranslator();
|
||||
|
||||
|
||||
// TODO: HIGH: Rename translation keys
|
||||
|
||||
|
||||
/** File filter for any rocket designs (*.ork, *.rkt) */
|
||||
public static final FileFilter ALL_DESIGNS_FILTER =
|
||||
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter1"),
|
||||
new SimpleFileFilter(trans.get("FileHelper.ALL_DESIGNS_FILTER"),
|
||||
".ork", ".ork.gz", ".rkt", ".rkt.gz");
|
||||
|
||||
/** File filter for OpenRocket designs (*.ork) */
|
||||
public static final FileFilter OPENROCKET_DESIGN_FILTER =
|
||||
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter2"), ".ork", ".ork.gz");
|
||||
new SimpleFileFilter(trans.get("FileHelper.OPENROCKET_DESIGN_FILTER"), ".ork", ".ork.gz");
|
||||
|
||||
/** File filter for RockSim designs (*.rkt) */
|
||||
public static final FileFilter ROCKSIM_DESIGN_FILTER =
|
||||
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter3"), ".rkt", ".rkt.gz");
|
||||
new SimpleFileFilter(trans.get("FileHelper.ROCKSIM_DESIGN_FILTER"), ".rkt", ".rkt.gz");
|
||||
|
||||
/** File filter for OpenRocket components and presets (*.orc) */
|
||||
public static final FileFilter OPEN_ROCKET_COMPONENT_FILTER =
|
||||
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter4"), ".orc", ".orc.gz");
|
||||
new SimpleFileFilter(trans.get("FileHelper.OPEN_ROCKET_COMPONENT_FILTER"), ".orc", ".orc.gz");
|
||||
|
||||
/** File filter for PDF files (*.pdf) */
|
||||
public static final FileFilter PDF_FILTER =
|
||||
new SimpleFileFilter(trans.get("filetypes.pdf"), ".pdf");
|
||||
new SimpleFileFilter(trans.get("FileHelper.PDF_FILTER"), ".pdf");
|
||||
|
||||
/** File filter for CSV files (*.csv) */
|
||||
public static final FileFilter CSV_FILE_FILTER =
|
||||
new SimpleFileFilter(trans.get("SimExpPan.desc"), ".csv");
|
||||
public static final FileFilter CSV_FILTER =
|
||||
new SimpleFileFilter(trans.get("FileHelper.CSV_FILTER"), ".csv");
|
||||
|
||||
|
||||
|
||||
@ -73,7 +72,7 @@ public final class FileHelper {
|
||||
Arrays.sort(extensions);
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(trans.get("filetypes.images"));
|
||||
sb.append(trans.get("FileHelper.IMAGES"));
|
||||
sb.append(" (");
|
||||
for (int i = 0; i < extensions.length; i++) {
|
||||
sb.append("*.").append(extensions[i]);
|
||||
@ -120,7 +119,12 @@ public final class FileHelper {
|
||||
if ( original == null ) {
|
||||
return null;
|
||||
}
|
||||
if (!original.getName().toLowerCase(Locale.ENGLISH).endsWith(extension.toLowerCase(Locale.ENGLISH))) {
|
||||
int index = original.getName().lastIndexOf('.');
|
||||
String original_extension = "";
|
||||
if (index > 0) {
|
||||
original_extension = original.getName().substring(index + 1);
|
||||
}
|
||||
if (!original_extension.toLowerCase(Locale.ENGLISH).equals(extension.toLowerCase(Locale.ENGLISH))) {
|
||||
log.debug("File name does not contain extension, adding '" + extension + "'");
|
||||
String name = original.getAbsolutePath();
|
||||
if (extension.startsWith(".")) {
|
||||
|
@ -325,7 +325,7 @@ public class ComponentPresetEditor extends JPanel implements PresetResultListene
|
||||
private boolean openComponentFile() {
|
||||
final JFileChooser chooser = new JFileChooser();
|
||||
chooser.addChoosableFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
chooser.addChoosableFileFilter(FileHelper.CSV_FILE_FILTER);
|
||||
chooser.addChoosableFileFilter(FileHelper.CSV_FILTER);
|
||||
chooser.setFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
if (editContext.getLastDirectory() != null) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user