Merge branch 'release-notes' of https://github.com/neilweinstock/openrocket into release-notes
This commit is contained in:
commit
fe9979a416
BIN
.github/OpenRocket_home.png
vendored
Normal file
BIN
.github/OpenRocket_home.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
9
CITATION.cff
Normal file
9
CITATION.cff
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
cff-version: 1.2.0
|
||||||
|
message: "If you use this software, please cite it as below."
|
||||||
|
authors:
|
||||||
|
- family-names: "Niskanen"
|
||||||
|
given-names: "Sampo"
|
||||||
|
title: "OpenRocket"
|
||||||
|
version: 15.03
|
||||||
|
date-released: 2015-03-28
|
||||||
|
url: "https://github.com/openrocket/openrocket"
|
133
CODE_OF_CONDUCT.md
Normal file
133
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
# Contributor Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We as members, contributors, and leaders pledge to make participation in our
|
||||||
|
community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||||
|
identity and expression, level of experience, education, socio-economic status,
|
||||||
|
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||||
|
identity and orientation.
|
||||||
|
|
||||||
|
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||||
|
diverse, inclusive, and healthy community.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to a positive environment for our
|
||||||
|
community include:
|
||||||
|
|
||||||
|
* Demonstrating empathy and kindness toward other people
|
||||||
|
* Being respectful of differing opinions, viewpoints, and experiences
|
||||||
|
* Giving and gracefully accepting constructive feedback
|
||||||
|
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||||
|
and learning from the experience
|
||||||
|
* Focusing on what is best not just for us as individuals, but for the overall
|
||||||
|
community
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||||
|
any kind
|
||||||
|
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or email address,
|
||||||
|
without their explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
Community leaders are responsible for clarifying and enforcing our standards of
|
||||||
|
acceptable behavior and will take appropriate and fair corrective action in
|
||||||
|
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||||
|
or harmful.
|
||||||
|
|
||||||
|
Community leaders have the right and responsibility to remove, edit, or reject
|
||||||
|
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||||
|
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||||
|
decisions when appropriate.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all community spaces, and also applies when
|
||||||
|
an individual is officially representing the community in public spaces.
|
||||||
|
Examples of representing our community include using an official e-mail address,
|
||||||
|
posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported to the community leaders responsible for enforcement by sending them a
|
||||||
|
private email, message on Slack, or any other communication method that you find
|
||||||
|
suitable.
|
||||||
|
All complaints will be reviewed and investigated promptly and fairly.
|
||||||
|
|
||||||
|
All community leaders are obligated to respect the privacy and security of the
|
||||||
|
reporter of any incident.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
|
||||||
|
Community leaders will follow these Community Impact Guidelines in determining
|
||||||
|
the consequences for any action they deem in violation of this Code of Conduct:
|
||||||
|
|
||||||
|
### 1. Correction
|
||||||
|
|
||||||
|
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||||
|
unprofessional or unwelcome in the community.
|
||||||
|
|
||||||
|
**Consequence**: A private, written warning from community leaders, providing
|
||||||
|
clarity around the nature of the violation and an explanation of why the
|
||||||
|
behavior was inappropriate. A public apology may be requested.
|
||||||
|
|
||||||
|
### 2. Warning
|
||||||
|
|
||||||
|
**Community Impact**: A violation through a single incident or series of
|
||||||
|
actions.
|
||||||
|
|
||||||
|
**Consequence**: A warning with consequences for continued behavior. No
|
||||||
|
interaction with the people involved, including unsolicited interaction with
|
||||||
|
those enforcing the Code of Conduct, for a specified period of time. This
|
||||||
|
includes avoiding interactions in community spaces as well as external channels
|
||||||
|
like social media. Violating these terms may lead to a temporary or permanent
|
||||||
|
ban.
|
||||||
|
|
||||||
|
### 3. Temporary Ban
|
||||||
|
|
||||||
|
**Community Impact**: A serious violation of community standards, including
|
||||||
|
sustained inappropriate behavior.
|
||||||
|
|
||||||
|
**Consequence**: A temporary ban from any sort of interaction or public
|
||||||
|
communication with the community for a specified period of time. No public or
|
||||||
|
private interaction with the people involved, including unsolicited interaction
|
||||||
|
with those enforcing the Code of Conduct, is allowed during this period.
|
||||||
|
Violating these terms may lead to a permanent ban.
|
||||||
|
|
||||||
|
### 4. Permanent Ban
|
||||||
|
|
||||||
|
**Community Impact**: Demonstrating a pattern of violation of community
|
||||||
|
standards, including sustained inappropriate behavior, harassment of an
|
||||||
|
individual, or aggression toward or disparagement of classes of individuals.
|
||||||
|
|
||||||
|
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||||
|
community.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||||
|
version 2.1, available at
|
||||||
|
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||||
|
|
||||||
|
Community Impact Guidelines were inspired by
|
||||||
|
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see the FAQ at
|
||||||
|
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||||
|
[https://www.contributor-covenant.org/translations][translations].
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||||
|
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||||
|
[FAQ]: https://www.contributor-covenant.org/faq
|
||||||
|
[translations]: https://www.contributor-covenant.org/translations
|
80
CONTRIBUTING.md
Normal file
80
CONTRIBUTING.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
# Contributing to OpenRocket 🚀
|
||||||
|
Hi, thank you for your interest in OpenRocket! 😊
|
||||||
|
|
||||||
|
I will guide you to contributing to OpenRocket, be it as a developer, tester or any other type of help that will launch - *pun intended* - OpenRocket to the next level.
|
||||||
|
|
||||||
|
Before I move on: time is money, so to save you time, get used to how OpenRocket is abbreviated with _OR_.
|
||||||
|
|
||||||
|
#### Table Of Contents
|
||||||
|
[Testing](#testing)
|
||||||
|
* [Reporting bugs](#reporting-bugs)
|
||||||
|
* [Suggesting new features](#suggesting-new-features)
|
||||||
|
|
||||||
|
[Development](#development)
|
||||||
|
* [Commit etiquette](#commit-etiquette)
|
||||||
|
* [Pull requests](#pull-requests)
|
||||||
|
|
||||||
|
[Translation](#translation)
|
||||||
|
|
||||||
|
[Documentation](#documentation)
|
||||||
|
|
||||||
|
[Anything else](#anything-else)
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
OpenRocket is not perfect, but we need people to discover and clearly document all of its imperfections. The job of a tester is to discover bugs, formulate new feature requests and to test out software updates. 📝
|
||||||
|
|
||||||
|
### Reporting bugs
|
||||||
|
Please be very concise when you post a new issue. Give a short and appropriate title, preferably with the '[Bug]'-tag in the beginning to indicate a bug.
|
||||||
|
|
||||||
|
When explaining the issue, the following elements are important:
|
||||||
|
* Explain how you expected OpenRocket to behave, and how it behaved instead
|
||||||
|
* Go through the different steps that you took to (re)create the issue
|
||||||
|
* Include information about your operating system (e.g. 'macOS Monterey version 12.1') and which version of OpenRocket you are using (e.g. 'the latest unstable branch')
|
||||||
|
* If applicable, include a Bug Report (preferably in a separate .txt file) of the exception that OpenRocket threw
|
||||||
|
|
||||||
|
Providing extra information like a screenshot, a screen recording, the .ork file that produced an error etc. really help understand and solve the issue more quickly.
|
||||||
|
|
||||||
|
### Suggesting new features
|
||||||
|
If you would like to see a new feature implemented in OR, make a new issue for it. Preferably include the tag '[Feature Request]' in the issue's title.
|
||||||
|
|
||||||
|
Explain the new feature in detail:
|
||||||
|
* Which new behavior would you like OR to have
|
||||||
|
* Why is this new feature important
|
||||||
|
|
||||||
|
## Development
|
||||||
|
Please read our [Developer's Guide](https://github.com/openrocket/openrocket/wiki/Developer%27s-Guide). If you still have questions about how to set up your environment, with which issues you should start etc., then don't be afraid to send us a message on [Slack](https://join.slack.com/t/openrocket/shared_invite/zt-dh0wtpc4-WmkSK1ysqAOqHa6eFN7zgA).
|
||||||
|
|
||||||
|
Developing OpenRocket may be daunting at first, but if you keep Google, your IDE's search and debug features, and the other developers as close friends, then you will easily create your first pull request.
|
||||||
|
|
||||||
|
If you want to work on a certain issue, you should first communicate that you want to work on that issue. This can be done by commenting on the issue something like 'I would like to work on this issue'. This ensures that no more than one person works on a given issue.
|
||||||
|
|
||||||
|
### Commit etiquette
|
||||||
|
Please make use of **atomic commits**. This means: don't fix 10 different issues and cram them in one commit. Split up commits into smaller commits that fix only one issue/feature.
|
||||||
|
|
||||||
|
For example: I fixed an issue where a button was displayed as red instead of blue, but I also found that there was a typo in a text somewhere else. Then put the button-fix in a one commit, give it an appropriate name, and put the typo-fix in another commit. Atomic commits make it much easier for code reviewers to review the code changes.
|
||||||
|
|
||||||
|
Also give **useful names** to your commits. A good naming convention of a commit is in the form of '[#{GitHub issue number of the issue you are trying to fix}] {Commit subject}'.
|
||||||
|
|
||||||
|
Take the example of fixing the red button from issue #123: '[#123] Display red button as blue'. Mentioning '#123' will also automatically link your pull request to the corresponding issue. The commit subject should be short and precise. It is also very useful to include a git commit message body besides just the commit subject to explain why and how you made that commit.
|
||||||
|
|
||||||
|
### Pull requests
|
||||||
|
Right, you've dug into the codebase, found that one nasty line that caused all your troubles and fixed it. It is now time to push your code and create a pull request of the branch from your own repository to the official repository. As your PR (Pull Request) text, it is good to have the following structure:
|
||||||
|
|
||||||
|
1. Explain briefly which issue that you are trying to solve, e.g. 'This PR solves #123 in which buttons were displayed as red instead of blue'
|
||||||
|
2. Next explain what the underlying issue was, e.g. 'The problem was that by default Java swing displays buttons as red.'
|
||||||
|
3. Next is how you fixed the issue, e.g. 'Fixed it by overriding the default button color to blue'
|
||||||
|
4. Finally, for other people to test your code, it is good to include a jar file of your fixed OpenRocket. This can be done using ant ([more info here](https://github.com/openrocket/openrocket/wiki/Instructions-to-Build-from-Terminal)). You can upload this jar-file to e.g. Dropbox or Google Drive and include it in your PR, e.g. 'Here is a jar file for testing: ' or if you're really GitHub-savvy, you can add a hyperlink to the 'jar file'-text. If necessary, you can also include information on how to recreate the original issue so that testers can check whether your code solved the issue. If needed, you can also included information about the expected behavior so that others know what your solution should do.
|
||||||
|
|
||||||
|
You can take a look at example PR [#979](https://github.com/openrocket/openrocket/pull/979).
|
||||||
|
|
||||||
|
## Translation
|
||||||
|
Both the OpenRocket software and the end-user documentation wiki site are multilingual. The job of a translator is to maintain the existing languages, or to make a new translation of an unlisted language. During the development sometimes new translation keys get added in the English language that are not simultaneously translated to other languages. The translator must therefor check which translation keys are still missing in his/her/they language.
|
||||||
|
|
||||||
|
How you can make/edit a translation can be found on [this site](http://openrocket.trans.free.fr/index.php?lang=en) or the [GitHub wiki](https://github.com/openrocket/openrocket/wiki/Instructions-for-translators).
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
We have two main documentation channels: a [GitHub wiki](https://github.com/openrocket/openrocket/wiki) and an [OpenRocket wiki page](http://wiki.openrocket.info/Main_Page), both of which require regular updates to keep up to date with the latest developments in the software.
|
||||||
|
|
||||||
|
## Anything else
|
||||||
|
Do you have the perfect voice for making OpenRocket tutorials, are you a graphical designer that screams to improve OR's design, or are you the salesman that can grow OR's influence? Then go for it! We highly appreciate any help that we get, in any shape or form. 🙃
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
OpenRocket - A model rocket simulator
|
OpenRocket - A model rocket simulator
|
||||||
|
|
||||||
Copyright (C) 2007-2020 Sampo Niskanen and others
|
Copyright (C) 2007-2022 Sampo Niskanen and others
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
23
README.md
23
README.md
@ -8,6 +8,8 @@ Overview
|
|||||||
|
|
||||||
OpenRocket is a free, fully featured model rocket simulator that allows you to design and simulate your rockets before actually building and flying them.
|
OpenRocket is a free, fully featured model rocket simulator that allows you to design and simulate your rockets before actually building and flying them.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
The main features include:
|
The main features include:
|
||||||
|
|
||||||
* Six-degree-of-freedom flight simulation
|
* Six-degree-of-freedom flight simulation
|
||||||
@ -20,15 +22,16 @@ Read more about it on the [OpenRocket Wiki](http://wiki.openrocket.info).
|
|||||||
|
|
||||||
Installers
|
Installers
|
||||||
----------
|
----------
|
||||||
OpenRocket maintains an installer for installing the software and Java runtime. You can find the installer for Windows at the link below. Installers for macOS and Linux are coming and will be added to this page when ready.
|
OpenRocket maintains an installer for installing the software and Java runtime. You can find the installer below.
|
||||||
|
|
||||||
[OpenRocket 15.03 Installer (Windows)](https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03-installer.exe)
|
* [OpenRocket 15.03 Installer (Windows)](https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03-installer.exe)
|
||||||
|
* [OpenRocket 15.03 Installer (Mac OS)](https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.dmg)
|
||||||
|
* [OpenRocket 15.03 Installer (Linux)](https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.AppImage)
|
||||||
|
* [OpenRocket 15.03 JAR file](https://github.com/openrocket/openrocket/releases/download/release-15.03/OpenRocket-15.03.jar)
|
||||||
|
|
||||||
Release Notes
|
Release Notes
|
||||||
-------------
|
-------------
|
||||||
Release notes for all releases of OpenRocket are available at the following link.
|
Release notes are available on each [release's page](https://github.com/openrocket/openrocket/releases) or on [our website](https://openrocket.info/release_notes.html).
|
||||||
|
|
||||||
[OpenRocket Release Notes](https://github.com/openrocket/openrocket/wiki/Release-Notes)
|
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
@ -37,7 +40,7 @@ OpenRocket is an Open Source project licensed under the [GNU GPL](https://www.gn
|
|||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
OpenRocket needs help to become even better. Implementing features, writing documentation and creating example designs are just a few ways of helping. If you are interested in helping make OpenRocket the best rocket simulator out there, please [click here for information on how to get involved!](http://openrocket.sourceforge.net/getinvolved.html)
|
OpenRocket needs help to become even better. Implementing features, writing documentation and creating example designs are just a few ways of helping. If you are interested in helping make OpenRocket the best rocket simulator out there, please [click here for information on how to get involved](http://openrocket.sourceforge.net/getinvolved.html) and [read the practicalities of contributing here](.github/CONTRIBUTING.md).
|
||||||
|
|
||||||
**Contributors**
|
**Contributors**
|
||||||
- Sampo Niskanen, main developer
|
- Sampo Niskanen, main developer
|
||||||
@ -47,6 +50,13 @@ OpenRocket needs help to become even better. Implementing features, writing docu
|
|||||||
- Richard Graham, geodetic computations
|
- Richard Graham, geodetic computations
|
||||||
- Jason Blood, freeform fin set import
|
- Jason Blood, freeform fin set import
|
||||||
- Boris du Reau, internationalization
|
- Boris du Reau, internationalization
|
||||||
|
- Daniel Williams, pod support, maintainer
|
||||||
|
- Joe Pfeiffer (maintainer)
|
||||||
|
- Billy Olsen (maintainer)
|
||||||
|
- Sibo Van Gool (maintainer)
|
||||||
|
- Neil Weinstock (tester, icons, forum support)
|
||||||
|
- H. Craig Miller (tester)
|
||||||
|
|
||||||
|
|
||||||
**Translators**
|
**Translators**
|
||||||
- Tripoli France
|
- Tripoli France
|
||||||
@ -56,3 +66,4 @@ OpenRocket needs help to become even better. Implementing features, writing docu
|
|||||||
- Sky Dart Team
|
- Sky Dart Team
|
||||||
- Vladimir Beran
|
- Vladimir Beran
|
||||||
- Polish Rocketry Society / Łukasz & Alex Kazanski
|
- Polish Rocketry Society / Łukasz & Alex Kazanski
|
||||||
|
- Sibo Van Gool
|
||||||
|
@ -76,7 +76,6 @@ OpenRocket 22.00.beta.01
|
|||||||
|
|
||||||
..._plus many, many additional bug fixes and refinements_
|
..._plus many, many additional bug fixes and refinements_
|
||||||
|
|
||||||
|
|
||||||
OpenRocket 15.03 (2015-03-28)
|
OpenRocket 15.03 (2015-03-28)
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
12
SUPPORT.md
Normal file
12
SUPPORT.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# OpenRocket support
|
||||||
|
|
||||||
|
OpenRocket has two main Wiki-pages for documentation:
|
||||||
|
* [GitHub wiki](https://github.com/openrocket/openrocket/wiki)
|
||||||
|
* [OpenRocket wiki](http://wiki.openrocket.info/Main_Page)
|
||||||
|
* [OpenRocket website](https://openrocket.info/index.html)
|
||||||
|
|
||||||
|
Our main communication channel are:
|
||||||
|
* [Slack](https://www.rocketryforum.com/forums/rocketry-electronics-software.36/) = **primary communication channel**
|
||||||
|
* [OpenRocket forum](https://www.rocketryforum.com/forums/rocketry-electronics-software.36/)
|
||||||
|
* [OpenRocket-devel mailing list](https://sourceforge.net/projects/openrocket/lists/openrocket-devel) for discussion related to OpenRocket development, documentation and upcoming features
|
||||||
|
* [OpenRocket-announce mailing list](https://sourceforge.net/projects/openrocket/lists/openrocket-announce) for announcements of new OpenRocket versions and developments
|
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- Include metafiles about OR -->
|
<!-- Include metafiles about OR -->
|
||||||
<fileset dir="${basedir}" includes="LICENSE.TXT README.TXT ChangeLog ReleaseNotes fileformat.txt" />
|
<fileset dir="${basedir}/.." includes="LICENSE.TXT README.md ChangeLog ReleaseNotes.md fileformat.txt" />
|
||||||
</jar>
|
</jar>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
|
BIN
core/resources-src/pix/splashscreen-1.4.png
Normal file
BIN
core/resources-src/pix/splashscreen-1.4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 185 KiB |
BIN
core/resources-src/pix/splashscreen-1.4.xcf.gz
Normal file
BIN
core/resources-src/pix/splashscreen-1.4.xcf.gz
Normal file
Binary file not shown.
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
# The OpenRocket build version
|
# The OpenRocket build version
|
||||||
build.version=20.11.alpha.16
|
build.version=22.00.beta.01
|
||||||
|
|
||||||
# The copyright year for the build. Displayed in the about dialog.
|
# The copyright year for the build. Displayed in the about dialog.
|
||||||
# Will show as Copyright 2013-${build.copyright}
|
# Will show as Copyright 2013-${build.copyright}
|
||||||
build.copyright=2021
|
build.copyright=2022
|
||||||
|
|
||||||
# The source of the package. When building a package for a specific
|
# The source of the package. When building a package for a specific
|
||||||
# distribution (Debian, Fedora etc.), this should be changed appropriately!
|
# distribution (Debian, Fedora etc.), this should be changed appropriately!
|
||||||
|
@ -503,7 +503,6 @@ simpanel.col.Timetoapogee = Time to apogee
|
|||||||
simpanel.col.Flighttime = Flight time
|
simpanel.col.Flighttime = Flight time
|
||||||
simpanel.col.Groundhitvelocity = Ground hit velocity
|
simpanel.col.Groundhitvelocity = Ground hit velocity
|
||||||
simpanel.ttip.uptodate = <i>Up to date</i>
|
simpanel.ttip.uptodate = <i>Up to date</i>
|
||||||
simpanel.ttip.loaded = <i>Data loaded from a file</i>
|
|
||||||
simpanel.ttip.outdated = <i><font color=\"red\">Data is out of date</font></i><br>Click <i><b>Run simulations</b></i> to simulate.
|
simpanel.ttip.outdated = <i><font color=\"red\">Data is out of date</font></i><br>Click <i><b>Run simulations</b></i> to simulate.
|
||||||
simpanel.ttip.external = <i>Imported data</i>
|
simpanel.ttip.external = <i>Imported data</i>
|
||||||
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
||||||
|
@ -1835,7 +1835,6 @@ simpanel.dlg.lbl.DeleteSim2 = <html><i>Esta operaci\u00f3n no puede deshacer
|
|||||||
simpanel.dlg.lbl.DeleteSim3 = Borrar las simulaciones
|
simpanel.dlg.lbl.DeleteSim3 = Borrar las simulaciones
|
||||||
simpanel.lbl.defpref = Puede cambiar la operaci\u00f3n por defecto por las preferencias
|
simpanel.lbl.defpref = Puede cambiar la operaci\u00f3n por defecto por las preferencias
|
||||||
simpanel.ttip.external = <i>Datos importados</i>
|
simpanel.ttip.external = <i>Datos importados</i>
|
||||||
simpanel.ttip.loaded = <i>Datos recientes.</i>
|
|
||||||
simpanel.ttip.noData = No hay datos de simulaci\u00f3n disponibles.
|
simpanel.ttip.noData = No hay datos de simulaci\u00f3n disponibles.
|
||||||
simpanel.ttip.noWarnings = <font color="gray">Sin alertas.</font>
|
simpanel.ttip.noWarnings = <font color="gray">Sin alertas.</font>
|
||||||
simpanel.ttip.notSimulated = <i>A\u00fan no ejecutada</i><br>Seleccione y haga Click en <i><b>Lanzar las simulaciones</b></i> para obtener datos.
|
simpanel.ttip.notSimulated = <i>A\u00fan no ejecutada</i><br>Seleccione y haga Click en <i><b>Lanzar las simulaciones</b></i> para obtener datos.
|
||||||
|
@ -1827,7 +1827,6 @@ simpanel.dlg.lbl.DeleteSim2 = <html><i>Cette op\u00E9ration n'est pas r\u00E
|
|||||||
simpanel.dlg.lbl.DeleteSim3 = Effacer les simulations
|
simpanel.dlg.lbl.DeleteSim3 = Effacer les simulations
|
||||||
simpanel.lbl.defpref = Vous pouvez changer le mode op\u00E9ratoire par d\u00E9faut dans pr\u00E9f\u00E9rences.
|
simpanel.lbl.defpref = Vous pouvez changer le mode op\u00E9ratoire par d\u00E9faut dans pr\u00E9f\u00E9rences.
|
||||||
simpanel.ttip.external = <i>Donn\u00E9es import\u00E9es</i>
|
simpanel.ttip.external = <i>Donn\u00E9es import\u00E9es</i>
|
||||||
simpanel.ttip.loaded = <i>Donn\u00E9es charg\u00E9es depuis un fichier</i>
|
|
||||||
simpanel.ttip.noData = Pas de donn\u00E9es de simulations disponible.
|
simpanel.ttip.noData = Pas de donn\u00E9es de simulations disponible.
|
||||||
simpanel.ttip.noWarnings = <font color="gray">Pas d'avertissements.</font>
|
simpanel.ttip.noWarnings = <font color="gray">Pas d'avertissements.</font>
|
||||||
simpanel.ttip.notSimulated = <i>Pas encore simul\u00E9</i><br>Cliquez <i><b>Lancer simulations</b></i> pour simuler.
|
simpanel.ttip.notSimulated = <i>Pas encore simul\u00E9</i><br>Cliquez <i><b>Lancer simulations</b></i> pour simuler.
|
||||||
|
@ -395,7 +395,6 @@ simpanel.col.Timetoapogee = \u9060\u5730\u70B9\u306E\u6642\u523B
|
|||||||
simpanel.col.Flighttime = \u30D5\u30E9\u30A4\u30C8\u6642\u9593
|
simpanel.col.Flighttime = \u30D5\u30E9\u30A4\u30C8\u6642\u9593
|
||||||
simpanel.col.Groundhitvelocity = \u5730\u9762\u885D\u7A81\u901F\u5EA6
|
simpanel.col.Groundhitvelocity = \u5730\u9762\u885D\u7A81\u901F\u5EA6
|
||||||
simpanel.ttip.uptodate = <i>Up to date</i>
|
simpanel.ttip.uptodate = <i>Up to date</i>
|
||||||
simpanel.ttip.loaded = <i>Data loaded from a file</i>
|
|
||||||
simpanel.ttip.outdated = <i><font color
|
simpanel.ttip.outdated = <i><font color
|
||||||
simpanel.ttip.external = <i>Imported data</i>
|
simpanel.ttip.external = <i>Imported data</i>
|
||||||
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
||||||
|
@ -487,7 +487,6 @@ simpanel.col.Timetoapogee = Tijd tot apogee
|
|||||||
simpanel.col.Flighttime = Vluchttijd
|
simpanel.col.Flighttime = Vluchttijd
|
||||||
simpanel.col.Groundhitvelocity = Snelheid bij grondcontact
|
simpanel.col.Groundhitvelocity = Snelheid bij grondcontact
|
||||||
simpanel.ttip.uptodate = <i>Up-to-date</i>
|
simpanel.ttip.uptodate = <i>Up-to-date</i>
|
||||||
simpanel.ttip.loaded = <i>Uit een bestand geladen gegevens</i>
|
|
||||||
simpanel.ttip.outdated = <i><font color=\"red\">Gegevens zijn verouderd</font></i><br>Klik <i><b>Voer simulaties uit</b></i> om te simuleren.
|
simpanel.ttip.outdated = <i><font color=\"red\">Gegevens zijn verouderd</font></i><br>Klik <i><b>Voer simulaties uit</b></i> om te simuleren.
|
||||||
simpanel.ttip.external = <i>Geïmporteerde data</i>
|
simpanel.ttip.external = <i>Geïmporteerde data</i>
|
||||||
simpanel.ttip.notSimulated = <i>Nog niet gesimuleerd</i><br>Klik <i><b>Voer simulaties uit</b></i> om te simuleren.
|
simpanel.ttip.notSimulated = <i>Nog niet gesimuleerd</i><br>Klik <i><b>Voer simulaties uit</b></i> om te simuleren.
|
||||||
|
@ -1780,7 +1780,6 @@ simpanel.dlg.lbl.DeleteSim2 = <html><i>Esta opera\u00e7\u00e3o n\u00e3o pode
|
|||||||
simpanel.dlg.lbl.DeleteSim3 = Excluir simula\u00e7\u00f5es
|
simpanel.dlg.lbl.DeleteSim3 = Excluir simula\u00e7\u00f5es
|
||||||
simpanel.lbl.defpref = Voc\u00ea pode alterar a opera\u00e7\u00e3o padr\u00e3o em Prefer\u00eancias.
|
simpanel.lbl.defpref = Voc\u00ea pode alterar a opera\u00e7\u00e3o padr\u00e3o em Prefer\u00eancias.
|
||||||
simpanel.ttip.external = <i>Dados importados </i>
|
simpanel.ttip.external = <i>Dados importados </i>
|
||||||
simpanel.ttip.loaded = <i>Dados carregado de um arquivo</i>
|
|
||||||
simpanel.ttip.noData = N\u00e3o h\u00e1 dados dispon\u00edveis para simula\u00e7\u00e3o.
|
simpanel.ttip.noData = N\u00e3o h\u00e1 dados dispon\u00edveis para simula\u00e7\u00e3o.
|
||||||
simpanel.ttip.noWarnings = <font color="gray">Nenhuma advert\u00eancia.</font>
|
simpanel.ttip.noWarnings = <font color="gray">Nenhuma advert\u00eancia.</font>
|
||||||
simpanel.ttip.notSimulated = <i>N\u00e3o simulado ainda</i><br>Clique<i><b>Executar simula\u00e7\u00f5es</b></i> para simular.
|
simpanel.ttip.notSimulated = <i>N\u00e3o simulado ainda</i><br>Clique<i><b>Executar simula\u00e7\u00f5es</b></i> para simular.
|
||||||
|
@ -440,7 +440,6 @@ simpanel.col.Timetoapogee = \u0412\u0440\u0435\u043c\u044f \u0434\u043e \u0430\u
|
|||||||
simpanel.col.Flighttime = \u0412\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u0435\u0442\u0430
|
simpanel.col.Flighttime = \u0412\u0440\u0435\u043c\u044f \u043f\u043e\u043b\u0435\u0442\u0430
|
||||||
simpanel.col.Groundhitvelocity = \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0437\u0435\u043c\u043b\u0435\u043d\u0438\u044f
|
simpanel.col.Groundhitvelocity = \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438\u0437\u0435\u043c\u043b\u0435\u043d\u0438\u044f
|
||||||
simpanel.ttip.uptodate = <i>\u0414\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b</i>
|
simpanel.ttip.uptodate = <i>\u0414\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b</i>
|
||||||
simpanel.ttip.loaded = <i>\u0414\u0430\u043d\u043d\u044b\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0438\u0437 \u0444\u0430\u0439\u043b\u0430</i>
|
|
||||||
simpanel.ttip.outdated = <i><font color=\"red\">\u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438</font></i><br>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 <i><b>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b</b></i> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430.
|
simpanel.ttip.outdated = <i><font color=\"red\">\u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0441\u0442\u0430\u0440\u0435\u043b\u0438</font></i><br>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 <i><b>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b</b></i> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430.
|
||||||
simpanel.ttip.external = <i>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435</i>
|
simpanel.ttip.external = <i>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435</i>
|
||||||
simpanel.ttip.notSimulated = <i>\u0420\u0430\u0441\u0447\u0435\u0442 \u0435\u0449\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f</i><br>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 <i><b>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b</b></i> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430.
|
simpanel.ttip.notSimulated = <i>\u0420\u0430\u0441\u0447\u0435\u0442 \u0435\u0449\u0435 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0441\u044f</i><br>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 <i><b>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442\u044b</b></i> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430.
|
||||||
|
@ -444,7 +444,6 @@ simpanel.col.Timetoapogee = Time to apogee
|
|||||||
simpanel.col.Flighttime = Flight time
|
simpanel.col.Flighttime = Flight time
|
||||||
simpanel.col.Groundhitvelocity = Ground hit velocity
|
simpanel.col.Groundhitvelocity = Ground hit velocity
|
||||||
simpanel.ttip.uptodate = <i>Up to date</i>
|
simpanel.ttip.uptodate = <i>Up to date</i>
|
||||||
simpanel.ttip.loaded = <i>Data loaded from a file</i>
|
|
||||||
simpanel.ttip.outdated = <i><font color=\"red\">Data is out of date</font></i><br>Click <i><b>Run simulations</b></i> to simulate.
|
simpanel.ttip.outdated = <i><font color=\"red\">Data is out of date</font></i><br>Click <i><b>Run simulations</b></i> to simulate.
|
||||||
simpanel.ttip.external = <i>Imported data</i>
|
simpanel.ttip.external = <i>Imported data</i>
|
||||||
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
simpanel.ttip.notSimulated = <i>Not simulated yet</i><br>Click <i><b>Run simulations</b></i> to simulate.
|
||||||
|
@ -1928,7 +1928,6 @@ simpanel.dlg.lbl.DeleteSim2 = <html><i>\u8BE5\u64CD\u4F5C\u65E0\u6CD5\u64
|
|||||||
simpanel.dlg.lbl.DeleteSim3 = \u5220\u9664\u4EFF\u771F
|
simpanel.dlg.lbl.DeleteSim3 = \u5220\u9664\u4EFF\u771F
|
||||||
simpanel.lbl.defpref = \u60A8\u53EF\u5728\u9996\u9009\u9879\u4E2D\u4FEE\u6539\u9ED8\u8BA4\u64CD\u4F5C.
|
simpanel.lbl.defpref = \u60A8\u53EF\u5728\u9996\u9009\u9879\u4E2D\u4FEE\u6539\u9ED8\u8BA4\u64CD\u4F5C.
|
||||||
simpanel.ttip.external = <i>\u5BFC\u5165\u7684\u6570\u636E</i>
|
simpanel.ttip.external = <i>\u5BFC\u5165\u7684\u6570\u636E</i>
|
||||||
simpanel.ttip.loaded = <i>\u4ECE\u6587\u4EF6\u8F7D\u5165\u6570\u636E</i>
|
|
||||||
simpanel.ttip.noData = \u6CA1\u6709\u53EF\u7528\u7684\u4EFF\u771F\u6570\u636E.
|
simpanel.ttip.noData = \u6CA1\u6709\u53EF\u7528\u7684\u4EFF\u771F\u6570\u636E.
|
||||||
simpanel.ttip.noWarnings = <font color="gray">\u6CA1\u6709\u8B66\u544A.</font>
|
simpanel.ttip.noWarnings = <font color="gray">\u6CA1\u6709\u8B66\u544A.</font>
|
||||||
simpanel.ttip.notSimulated = <i>\u672A\u8FDB\u884C\u8FC7\u4EFF\u771F</i><br>\u70B9\u51FB<i><b>\u8FD0\u884C\u4EFF\u771F</b></i>.
|
simpanel.ttip.notSimulated = <i>\u672A\u8FDB\u884C\u8FC7\u4EFF\u771F</i><br>\u70B9\u51FB<i><b>\u8FD0\u884C\u4EFF\u771F</b></i>.
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 185 KiB After Width: | Height: | Size: 185 KiB |
@ -318,8 +318,11 @@ public class OpenRocketSaver extends RocketSaver {
|
|||||||
|
|
||||||
private void saveSimulation(Simulation simulation, double timeSkip) throws IOException {
|
private void saveSimulation(Simulation simulation, double timeSkip) throws IOException {
|
||||||
SimulationOptions cond = simulation.getOptions();
|
SimulationOptions cond = simulation.getOptions();
|
||||||
|
|
||||||
writeln("<simulation status=\"" + enumToXMLName(simulation.getStatus()) + "\">");
|
Simulation.Status simStatus;
|
||||||
|
simStatus = timeSkip != StorageOptions.SIMULATION_DATA_NONE ? simulation.getStatus() : Simulation.Status.NOT_SIMULATED;
|
||||||
|
|
||||||
|
writeln("<simulation status=\"" + enumToXMLName(simStatus) + "\">");
|
||||||
indent++;
|
indent++;
|
||||||
|
|
||||||
writeln("<name>" + TextUtil.escapeXML(simulation.getName()) + "</name>");
|
writeln("<name>" + TextUtil.escapeXML(simulation.getName()) + "</name>");
|
||||||
|
@ -91,7 +91,13 @@ class FlightDataHandler extends AbstractElementHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void endHandler(String element, HashMap<String, String> attributes,
|
public void endHandler(String element, HashMap<String, String> attributes,
|
||||||
String content, WarningSet warnings) {
|
String content, WarningSet warnings) {
|
||||||
|
|
||||||
|
// If no <databranch> tag in XML, then there is no sim data
|
||||||
|
if (dataHandler == null) {
|
||||||
|
data = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (branches.size() > 0) {
|
if (branches.size() > 0) {
|
||||||
data = new FlightData(branches.toArray(new FlightDataBranch[0]));
|
data = new FlightData(branches.toArray(new FlightDataBranch[0]));
|
||||||
} else {
|
} else {
|
||||||
|
@ -134,6 +134,10 @@ class SingleSimulationHandler extends AbstractElementHandler {
|
|||||||
data = null;
|
data = null;
|
||||||
else
|
else
|
||||||
data = dataHandler.getFlightData();
|
data = dataHandler.getFlightData();
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
status = Status.NOT_SIMULATED;
|
||||||
|
}
|
||||||
|
|
||||||
Simulation simulation = new Simulation(doc.getRocket(), status, name,
|
Simulation simulation = new Simulation(doc.getRocket(), status, name,
|
||||||
options, extensions, data);
|
options, extensions, data);
|
||||||
|
@ -3,6 +3,8 @@ package net.sf.openrocket.file.openrocket.savers;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.AxialMethod;
|
||||||
import net.sf.openrocket.util.MathUtil;
|
import net.sf.openrocket.util.MathUtil;
|
||||||
|
|
||||||
public class FinSetSaver extends ExternalComponentSaver {
|
public class FinSetSaver extends ExternalComponentSaver {
|
||||||
@ -28,6 +30,22 @@ public class FinSetSaver extends ExternalComponentSaver {
|
|||||||
|
|
||||||
elements.add("<tabheight>" + fins.getTabHeight() + "</tabheight>");
|
elements.add("<tabheight>" + fins.getTabHeight() + "</tabheight>");
|
||||||
elements.add("<tablength>" + fins.getTabLength() + "</tablength>");
|
elements.add("<tablength>" + fins.getTabLength() + "</tablength>");
|
||||||
|
// TODO: delete this when no backward compatibility with OR 15.03 is needed anymore
|
||||||
|
String offset = "center";
|
||||||
|
double offsetVal = fins.getTabOffset();
|
||||||
|
switch (fins.getTabOffsetMethod()) {
|
||||||
|
case TOP:
|
||||||
|
offset = "front";
|
||||||
|
break;
|
||||||
|
case BOTTOM:
|
||||||
|
offset = "end";
|
||||||
|
break;
|
||||||
|
case MIDDLE:
|
||||||
|
offset = "center";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elements.add("<tabposition relativeto=\"" + offset + "\">" +
|
||||||
|
offsetVal + "</tabposition>");
|
||||||
elements.add("<tabposition relativeto=\"" +
|
elements.add("<tabposition relativeto=\"" +
|
||||||
fins.getTabOffsetMethod().name().toLowerCase(Locale.ENGLISH) + "\">" +
|
fins.getTabOffsetMethod().name().toLowerCase(Locale.ENGLISH) + "\">" +
|
||||||
fins.getTabOffset() + "</tabposition>");
|
fins.getTabOffset() + "</tabposition>");
|
||||||
|
@ -83,6 +83,10 @@ public class RocketComponentSaver {
|
|||||||
// no-op. Instance counts are set via named cluster configurations
|
// no-op. Instance counts are set via named cluster configurations
|
||||||
} else {
|
} else {
|
||||||
emitInteger(elements, "instancecount", c.getInstanceCount());
|
emitInteger(elements, "instancecount", c.getInstanceCount());
|
||||||
|
// TODO: delete this when no backward compatibility with OR 15.03 is needed anymore
|
||||||
|
if (c instanceof FinSet || c instanceof TubeFinSet) {
|
||||||
|
emitInteger(elements, "fincount", c.getInstanceCount());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c instanceof LineInstanceable) {
|
if (c instanceof LineInstanceable) {
|
||||||
@ -103,6 +107,13 @@ public class RocketComponentSaver {
|
|||||||
final String angleMethod = anglePos.getAngleMethod().name().toLowerCase(Locale.ENGLISH);
|
final String angleMethod = anglePos.getAngleMethod().name().toLowerCase(Locale.ENGLISH);
|
||||||
final double angleOffset = anglePos.getAngleOffset()*180.0/Math.PI;
|
final double angleOffset = anglePos.getAngleOffset()*180.0/Math.PI;
|
||||||
elements.add("<angleoffset method=\"" + angleMethod + "\">" + angleOffset + "</angleoffset>");
|
elements.add("<angleoffset method=\"" + angleMethod + "\">" + angleOffset + "</angleoffset>");
|
||||||
|
// TODO: delete this when no backward compatibility with OR 15.03 is needed anymore
|
||||||
|
if (c instanceof FinSet || c instanceof TubeFinSet) {
|
||||||
|
elements.add("<rotation>" + angleOffset + "</rotation>");
|
||||||
|
}
|
||||||
|
else if (!(c instanceof RailButton)) {
|
||||||
|
elements.add("<radialdirection>" + angleOffset + "</radialdirection>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save position unless "AFTER"
|
// Save position unless "AFTER"
|
||||||
@ -110,6 +121,8 @@ public class RocketComponentSaver {
|
|||||||
// The type names are currently equivalent to the enum names except for case.
|
// The type names are currently equivalent to the enum names except for case.
|
||||||
String axialMethod = c.getAxialMethod().name().toLowerCase(Locale.ENGLISH);
|
String axialMethod = c.getAxialMethod().name().toLowerCase(Locale.ENGLISH);
|
||||||
elements.add("<axialoffset method=\"" + axialMethod + "\">" + c.getAxialOffset() + "</axialoffset>");
|
elements.add("<axialoffset method=\"" + axialMethod + "\">" + c.getAxialOffset() + "</axialoffset>");
|
||||||
|
// TODO: delete this when no backward compatibility with OR 15.03 is needed anymore
|
||||||
|
elements.add("<position type=\"" + axialMethod + "\">" + c.getAxialOffset() + "</position>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overrides
|
// Overrides
|
||||||
|
@ -200,6 +200,10 @@ the .jar file
|
|||||||
<copy todir="${resources.dir}/datafiles/presets">
|
<copy todir="${resources.dir}/datafiles/presets">
|
||||||
<fileset dir="${resources-src.dir}/datafiles/components/orc"/>
|
<fileset dir="${resources-src.dir}/datafiles/components/orc"/>
|
||||||
</copy>
|
</copy>
|
||||||
|
<copy
|
||||||
|
file="${resources-src.dir}/datafiles/components/LICENSE"
|
||||||
|
todir="${resources.dir}/datafiles/presets">
|
||||||
|
</copy>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<!-- DIST-SRC -->
|
<!-- DIST-SRC -->
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,10 +1,21 @@
|
|||||||
package net.sf.openrocket.gui.components;
|
package net.sf.openrocket.gui.components;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Desktop;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
|
||||||
|
import javax.swing.JTextPane;
|
||||||
|
import javax.swing.event.HyperlinkEvent;
|
||||||
|
import javax.swing.event.HyperlinkListener;
|
||||||
import javax.swing.JEditorPane;
|
import javax.swing.JEditorPane;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
@ -65,7 +76,71 @@ public class DescriptionArea extends JScrollPane {
|
|||||||
Font font = editorPane.getFont();
|
Font font = editorPane.getFont();
|
||||||
editorPane.setFont(font.deriveFont(font.getSize2D() + size));
|
editorPane.setFont(font.deriveFont(font.getSize2D() + size));
|
||||||
editorPane.setEditable(false);
|
editorPane.setEditable(false);
|
||||||
|
editorPane.addHyperlinkListener(new HyperlinkListener() {
|
||||||
|
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||||
|
if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||||
|
URI uri = null;
|
||||||
|
try {
|
||||||
|
uri = e.getURL().toURI();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the uri scheme indicates this is a resource in a jar file,
|
||||||
|
// extract and write to a temporary file
|
||||||
|
if (uri.getScheme().equals("jar")) {
|
||||||
|
|
||||||
|
// get the resource
|
||||||
|
final String uriString = uri.toString();
|
||||||
|
final String resourceName = uriString.substring(uriString.indexOf("!") + 1);
|
||||||
|
final BufferedInputStream is = new BufferedInputStream(getClass().getResourceAsStream(resourceName));
|
||||||
|
|
||||||
|
// construct filename from resource name
|
||||||
|
String prefix = resourceName.substring(1);
|
||||||
|
String suffix;
|
||||||
|
final int dotIndex = prefix.lastIndexOf(".");
|
||||||
|
if (dotIndex > 0) {
|
||||||
|
prefix = resourceName.substring(0, dotIndex);
|
||||||
|
suffix = resourceName.substring(dotIndex+1);
|
||||||
|
} else {
|
||||||
|
// if there is no suffix, assume it's a raw text file.
|
||||||
|
suffix = ".txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create temporary file and copy resource to it
|
||||||
|
File of = null;
|
||||||
|
BufferedOutputStream os = null;
|
||||||
|
try {
|
||||||
|
of = File.createTempFile(prefix, suffix);
|
||||||
|
os = new BufferedOutputStream(new FileOutputStream(of));
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
of.deleteOnExit();
|
||||||
|
uri = of.toURI();
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte buffer[] = is.readAllBytes();
|
||||||
|
os.write(buffer);
|
||||||
|
os.close();
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().browse(uri);
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
if (!opaque) {
|
if (!opaque) {
|
||||||
Color bg = new JPanel().getBackground();
|
Color bg = new JPanel().getBackground();
|
||||||
editorPane.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue()));
|
editorPane.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue()));
|
||||||
@ -103,5 +178,17 @@ public class DescriptionArea extends JScrollPane {
|
|||||||
});
|
});
|
||||||
editorPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
|
editorPane.scrollRectToVisible(new Rectangle(0, 0, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the font to use for the text pane. If null, then the default font from OR is used.
|
||||||
|
* @param font font to use
|
||||||
|
*/
|
||||||
|
public void setTextFont(Font font) {
|
||||||
|
if (editorPane == null) return;
|
||||||
|
editorPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true);
|
||||||
|
if (font != null) {
|
||||||
|
editorPane.setFont(font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public class CustomExpressionPanel extends JPanel {
|
|||||||
//expressionSelectorPanel.add(scroll);
|
//expressionSelectorPanel.add(scroll);
|
||||||
|
|
||||||
//this.add(expressionSelectorPanel, "spany 1, height 10px, wmin 600lp, grow 100, gapright para");
|
//this.add(expressionSelectorPanel, "spany 1, height 10px, wmin 600lp, grow 100, gapright para");
|
||||||
this.add(scroll, "hmin 200lp, wmin 700lp, grow 100, wrap");
|
this.add(scroll, "hmin 200lp, wmin 700lp, grow, pushy, wrap");
|
||||||
|
|
||||||
//DescriptionArea desc = new DescriptionArea(trans.get("customExpressionPanel.lbl.UpdateNote")+"\n\n"+trans.get("customExpressionPanel.lbl.CalcNote"), 8, -2f);
|
//DescriptionArea desc = new DescriptionArea(trans.get("customExpressionPanel.lbl.UpdateNote")+"\n\n"+trans.get("customExpressionPanel.lbl.CalcNote"), 8, -2f);
|
||||||
//desc.setViewportBorder(BorderFactory.createEmptyBorder());
|
//desc.setViewportBorder(BorderFactory.createEmptyBorder());
|
||||||
|
@ -8,6 +8,7 @@ import javax.swing.JDialog;
|
|||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.openrocket.gui.components.DescriptionArea;
|
import net.sf.openrocket.gui.components.DescriptionArea;
|
||||||
@ -25,42 +26,60 @@ import net.sf.openrocket.gui.widgets.SelectColorButton;
|
|||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class AboutDialog extends JDialog {
|
public class AboutDialog extends JDialog {
|
||||||
|
|
||||||
public static final String OPENROCKET_URL = "http://openrocket.info/";
|
public final String OPENROCKET_URL = "http://openrocket.info/";
|
||||||
private static final Translator trans = Application.getTranslator();
|
|
||||||
|
private final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private static final String CREDITS = "<html><center>" +
|
private final String CREDITS = "<html><center>" +
|
||||||
"<font size=\"+1\"><b>OpenRocket has been developed by:</b></font><br><br>" +
|
"<font size=\"+1\"><b>OpenRocket has been developed by:</b></font><br>" +
|
||||||
"Sampo Niskanen (main developer)<br>" +
|
"<br>" +
|
||||||
"Doug Pedrick (RockSim file format, printing)<br>" +
|
"Sampo Niskanen (main developer)<br>" +
|
||||||
"Kevin Ruland (Android version)<br>" +
|
"Doug Pedrick (RockSim file format, printing)<br>" +
|
||||||
"Bill Kuker (3D visualization)<br>" +
|
"Kevin Ruland (Android version)<br>" +
|
||||||
"Boris du Reau (internationalization, translation lead)<br>" +
|
"Bill Kuker (3D visualization)<br>" +
|
||||||
"Richard Graham (geodetic computations)<br>" +
|
"Boris du Reau (internationalization, translation lead)<br>" +
|
||||||
"Jason Blood (finset import)<br>" +
|
"Richard Graham (geodetic computations)<br>" +
|
||||||
"Daniel Williams (pod support, maintainer)<br>" +
|
"Jason Blood (finset import)<br>" +
|
||||||
"Joe Pfeiffer (maintainer)<br>" +
|
"Daniel Williams (pod support, maintainer)<br>" +
|
||||||
"Billy Olsen (maintainer)<br>" +
|
"Joe Pfeiffer (maintainer)<br>" +
|
||||||
"Neil Weinstock (tester, icons, forum support)<br>" +
|
"Billy Olsen (maintainer)<br>" +
|
||||||
"H. Craig Miller (tester)<br><br>" +
|
"Sibo Van Gool (maintainer)<br>" +
|
||||||
"<b>Translations by:</b><br><br>" +
|
"Justin Hanney (maintainer)<br>" +
|
||||||
"Tripoli France (French)<br>" +
|
"Neil Weinstock (tester, icons, forum support)<br>" +
|
||||||
"Stefan Lobas / ERIG e.V. (German)<br>" +
|
"H. Craig Miller (tester)<br><br>" +
|
||||||
"Tripoli Spain (Spanish)<br>" +
|
"<b>Translations by:</b><br><br>" +
|
||||||
"Sky Dart Team (Russian)<br>" +
|
"Tripoli France (French)<br>" +
|
||||||
"Mauro Biasutti (Italian)<br>" +
|
"Stefan Lobas / ERIG e.V. (German)<br>" +
|
||||||
"Vladimir Beran (Czech)<br>" +
|
"Tripoli Spain (Spanish)<br>" +
|
||||||
"Polish Rocketry Society / \u0141ukasz & Alex Kazanski (Polish)<br>" +
|
"Sky Dart Team (Russian)<br>" +
|
||||||
"Sibo Van Gool (Dutch)<br><br>" +
|
"Mauro Biasutti (Italian)<br>" +
|
||||||
"See all contributors at <br>https://github.com/openrocket/openrocket/graphs/contributors<br><br>" +
|
"Vladimir Beran (Czech)<br>" +
|
||||||
"<b>OpenRocket utilizes the following libraries:</b><br><br>" +
|
"Polish Rocketry Society / \u0141ukasz & Alex Kazanski (Polish)<br>" +
|
||||||
"MiG Layout (http://www.miglayout.com/)<br>" +
|
"Sibo Van Gool (Dutch)<br>" +
|
||||||
"JFreeChart (http://www.jfree.org/jfreechart/)<br>" +
|
"<br>" +
|
||||||
"iText (http://www.itextpdf.com/)<br>" +
|
"See all contributors at <br>" +
|
||||||
"exp4j (http://projects.congrace.de/exp4j/index.html)<br>" +
|
href("https://github.com/openrocket/openrocket/graphs/contributors") + "<br>" +
|
||||||
"JOGL (http://jogamp.org/jogl/www/)<br>" +
|
"<br>" +
|
||||||
"Guava (https://github.com/google/guava)<br>" +
|
"<b>OpenRocket utilizes the following libraries:</b><br>" +
|
||||||
"Opencsv (http://opencsv.sourceforge.net/)<br>" +
|
"<br>" +
|
||||||
"Simple Logging Facade for Java (http://www.slf4j.org/)";
|
"MiG Layout (" + href("http://www.miglayout.com/") + ")<br>" +
|
||||||
|
"JFreeChart (" + href("http://www.jfree.org/jfreechart/") + ")<br>" +
|
||||||
|
"iText (" + href("http://www.itextpdf.com/") + ")<br>" +
|
||||||
|
"exp4j (" + href("http://projects.congrace.de/exp4j/index.html") + ")<br>" +
|
||||||
|
"JOGL (" + href("http://jogamp.org/jogl/www/") + ")<br>" +
|
||||||
|
"Guava (" + href("https://github.com/google/guava") + ")<br>" +
|
||||||
|
"Opencsv (" + href("http://opencsv.sourceforge.net/") + ")<br>" +
|
||||||
|
"Simple Logging Facade for Java (" + href("http://www.slf4j.org/") + ")<br>" +
|
||||||
|
"Java library for parsing and rendering CommonMark (" + href("https://github.com/commonmark/commonmark-java") + ")<br>" +
|
||||||
|
"<br>" +
|
||||||
|
"<b>OpenRocket gratefully acknowledges our use of the following databases:</b><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"Rocket Motor Data (" + href("https://www.thrustcurve.org/") + ")<br>" +
|
||||||
|
"Enhanced components database for OpenRocket" + href("https://github.com/dbcook/openrocket-database/") + ")<br>";
|
||||||
|
|
||||||
|
private String href(String url) {
|
||||||
|
return "<a href=\"" + url + "\">" + url + "</a>";
|
||||||
|
}
|
||||||
|
|
||||||
public AboutDialog(JFrame parent) {
|
public AboutDialog(JFrame parent) {
|
||||||
super(parent, true);
|
super(parent, true);
|
||||||
@ -85,7 +104,7 @@ public class AboutDialog extends JDialog {
|
|||||||
sub.add(new StyledLabel(copyright), "ax 50%, growy, wrap para");
|
sub.add(new StyledLabel(copyright), "ax 50%, growy, wrap para");
|
||||||
|
|
||||||
sub.add(new URLLabel(OPENROCKET_URL), "ax 50%, growy, wrap para");
|
sub.add(new URLLabel(OPENROCKET_URL), "ax 50%, growy, wrap para");
|
||||||
panel.add(sub, "grow");
|
panel.add(sub, "grow, pushx");
|
||||||
|
|
||||||
|
|
||||||
// Translation information (if present)
|
// Translation information (if present)
|
||||||
@ -116,7 +135,8 @@ public class AboutDialog extends JDialog {
|
|||||||
|
|
||||||
DescriptionArea info = new DescriptionArea(5);
|
DescriptionArea info = new DescriptionArea(5);
|
||||||
info.setText(CREDITS);
|
info.setText(CREDITS);
|
||||||
panel.add(info, "newline, width 10px, height 150lp, grow, spanx, wrap para");
|
info.setTextFont(UIManager.getFont("Label.font"));
|
||||||
|
panel.add(info, "newline, width 10px, height 250lp, pushy, grow, spanx, wrap para");
|
||||||
|
|
||||||
// JTextArea area = new JTextArea(CREATORS);
|
// JTextArea area = new JTextArea(CREATORS);
|
||||||
// area.setEditable(false);
|
// area.setEditable(false);
|
||||||
@ -138,7 +158,6 @@ public class AboutDialog extends JDialog {
|
|||||||
this.add(panel);
|
this.add(panel);
|
||||||
this.setTitle("OpenRocket " + version);
|
this.setTitle("OpenRocket " + version);
|
||||||
this.pack();
|
this.pack();
|
||||||
this.setResizable(false);
|
|
||||||
this.setLocationRelativeTo(parent);
|
this.setLocationRelativeTo(parent);
|
||||||
|
|
||||||
GUIUtil.setDisposableDialogOptions(this, close);
|
GUIUtil.setDisposableDialogOptions(this, close);
|
||||||
|
@ -18,8 +18,8 @@ import javax.swing.JEditorPane;
|
|||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTextArea;
|
|
||||||
import javax.swing.JTextPane;
|
import javax.swing.JTextPane;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
import com.jogamp.opengl.JoglVersion;
|
import com.jogamp.opengl.JoglVersion;
|
||||||
|
|
||||||
@ -73,6 +73,7 @@ public class BugReportDialog extends JDialog {
|
|||||||
|
|
||||||
final JEditorPane editorPane = new JEditorPane("text/html", formatNewlineHTML(message));
|
final JEditorPane editorPane = new JEditorPane("text/html", formatNewlineHTML(message));
|
||||||
editorPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true);
|
editorPane.putClientProperty(JTextPane.HONOR_DISPLAY_PROPERTIES, true);
|
||||||
|
editorPane.setFont(UIManager.getFont("Label.font"));
|
||||||
editorPane.setPreferredSize(new Dimension(600, 400));
|
editorPane.setPreferredSize(new Dimension(600, 400));
|
||||||
editorPane.setEditable(true);
|
editorPane.setEditable(true);
|
||||||
editorPane.setCaretPosition(0); // Scroll to the top by default
|
editorPane.setCaretPosition(0); // Scroll to the top by default
|
||||||
@ -180,7 +181,8 @@ public class BugReportDialog extends JDialog {
|
|||||||
StringWriter sw = new StringWriter();
|
StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = new PrintWriter(sw);
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
e.printStackTrace(pw);
|
e.printStackTrace(pw);
|
||||||
sb.append(sw.getBuffer());
|
String stackTrace = unformatHTML(String.valueOf(sw.getBuffer()));
|
||||||
|
sb.append(stackTrace);
|
||||||
sb.append('\n');
|
sb.append('\n');
|
||||||
|
|
||||||
|
|
||||||
@ -207,39 +209,47 @@ public class BugReportDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void addSystemInformation(StringBuilder sb) {
|
private static void addSystemInformation(StringBuilder sb) {
|
||||||
sb.append("OpenRocket version: " + BuildProperties.getVersion() + "\n");
|
StringBuilder sbTemp = new StringBuilder();
|
||||||
sb.append("OpenRocket source: " + BuildProperties.getBuildSource() + "\n");
|
sbTemp.append("OpenRocket version: " + BuildProperties.getVersion() + "\n");
|
||||||
sb.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
|
sbTemp.append("OpenRocket source: " + BuildProperties.getBuildSource() + "\n");
|
||||||
sb.append("JOGL version: " + JoglVersion.getInstance().getImplementationVersion() + "\n");
|
sbTemp.append("OpenRocket location: " + JarUtil.getCurrentJarFile() + "\n");
|
||||||
sb.append("Current default locale: " + Locale.getDefault() + "\n");
|
sbTemp.append("JOGL version: " + JoglVersion.getInstance().getImplementationVersion() + "\n");
|
||||||
sb.append("System properties:\n");
|
sbTemp.append("Current default locale: " + Locale.getDefault() + "\n");
|
||||||
|
sbTemp.append("System properties:\n");
|
||||||
|
|
||||||
// Sort the keys
|
// Sort the keys
|
||||||
SortedSet<String> keys = new TreeSet<String>();
|
SortedSet<String> keys = new TreeSet<String>();
|
||||||
for (Object key : System.getProperties().keySet()) {
|
for (Object key : System.getProperties().keySet()) {
|
||||||
keys.add((String) key);
|
keys.add((String) key);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String key : keys) {
|
for (String key : keys) {
|
||||||
String value = System.getProperty(key);
|
String value = System.getProperty(key);
|
||||||
sb.append(" " + key + "=");
|
sbTemp.append(" " + key + "=");
|
||||||
if (key.equals("line.separator")) {
|
if (key.equals("line.separator")) {
|
||||||
for (char c : value.toCharArray()) {
|
for (char c : value.toCharArray()) {
|
||||||
sb.append(String.format("\\u%04x", (int) c));
|
sbTemp.append(String.format("\\u%04x", (int) c));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sb.append(value);
|
sbTemp.append(value);
|
||||||
}
|
}
|
||||||
sb.append('\n');
|
sbTemp.append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String message = unformatHTML(sbTemp.toString());
|
||||||
|
sb.append(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addErrorLog(StringBuilder sb) {
|
private static void addErrorLog(StringBuilder sb) {
|
||||||
|
StringBuilder sbTemp = new StringBuilder();
|
||||||
LogLevelBufferLogger buffer = LoggingSystemSetup.getBufferLogger();
|
LogLevelBufferLogger buffer = LoggingSystemSetup.getBufferLogger();
|
||||||
List<LogLine> logs = buffer.getLogs();
|
List<LogLine> logs = buffer.getLogs();
|
||||||
for (LogLine l : logs) {
|
for (LogLine l : logs) {
|
||||||
sb.append(l.toString()).append('\n');
|
sbTemp.append(l.toString()).append('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String message = unformatHTML(sbTemp.toString());
|
||||||
|
sb.append(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -252,5 +262,14 @@ public class BugReportDialog extends JDialog {
|
|||||||
private static String formatNewlineHTML(String text) {
|
private static String formatNewlineHTML(String text) {
|
||||||
return text.replaceAll("\n(.*?)(?=(\n|$))", "<p style=\"margin-top: 0\">$1</p>");
|
return text.replaceAll("\n(.*?)(?=(\n|$))", "<p style=\"margin-top: 0\">$1</p>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes text HTML unformatted by replacing '<' and '>' by the HTML character equivalent
|
||||||
|
* @param text text to be replaced
|
||||||
|
* @return HTML unformatted text
|
||||||
|
*/
|
||||||
|
private static String unformatHTML(String text) {
|
||||||
|
return text.replace("<", "<").replace(">", ">");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.event.WindowListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -82,6 +83,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
private final JToggleButton worstToggle;
|
private final JToggleButton worstToggle;
|
||||||
private boolean fakeChange = false;
|
private boolean fakeChange = false;
|
||||||
private AerodynamicCalculator aerodynamicCalculator;
|
private AerodynamicCalculator aerodynamicCalculator;
|
||||||
|
private double initTheta;
|
||||||
|
|
||||||
private final ColumnTableModel longitudeStabilityTableModel;
|
private final ColumnTableModel longitudeStabilityTableModel;
|
||||||
private final ColumnTableModel dragTableModel;
|
private final ColumnTableModel dragTableModel;
|
||||||
@ -115,6 +117,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
aoa = new DoubleModel(rocketPanel, "CPAOA", UnitGroup.UNITS_ANGLE, 0, Math.PI);
|
aoa = new DoubleModel(rocketPanel, "CPAOA", UnitGroup.UNITS_ANGLE, 0, Math.PI);
|
||||||
rocketPanel.setCPMach(Application.getPreferences().getDefaultMach());
|
rocketPanel.setCPMach(Application.getPreferences().getDefaultMach());
|
||||||
mach = new DoubleModel(rocketPanel, "CPMach", UnitGroup.UNITS_COEFFICIENT, 0);
|
mach = new DoubleModel(rocketPanel, "CPMach", UnitGroup.UNITS_COEFFICIENT, 0);
|
||||||
|
initTheta = rocketPanel.getFigure().getRotation();
|
||||||
rocketPanel.setCPTheta(rocketPanel.getFigure().getRotation());
|
rocketPanel.setCPTheta(rocketPanel.getFigure().getRotation());
|
||||||
theta = new DoubleModel(rocketPanel, "CPTheta", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI);
|
theta = new DoubleModel(rocketPanel, "CPTheta", UnitGroup.UNITS_ANGLE, 0, 2 * Math.PI);
|
||||||
rocketPanel.setCPRoll(0);
|
rocketPanel.setCPRoll(0);
|
||||||
@ -148,7 +151,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
JScrollPane scrollPane = new JScrollPane(warningList);
|
JScrollPane scrollPane = new JScrollPane(warningList);
|
||||||
////Warnings:
|
////Warnings:
|
||||||
scrollPane.setBorder(BorderFactory.createTitledBorder(trans.get("componentanalysisdlg.TitledBorder.warnings")));
|
scrollPane.setBorder(BorderFactory.createTitledBorder(trans.get("componentanalysisdlg.TitledBorder.warnings")));
|
||||||
panel.add(scrollPane, "gap paragraph, spany 4, width 300lp!, growy 1, height :100lp:, wrap");
|
panel.add(scrollPane, "gap paragraph, spany 4, wmin 300lp, grow, height :100lp:, wrap");
|
||||||
|
|
||||||
////Angle of attack:
|
////Angle of attack:
|
||||||
panel.add(new JLabel(trans.get("componentanalysisdlg.lbl.angleofattack")), "width 120lp!");
|
panel.add(new JLabel(trans.get("componentanalysisdlg.lbl.angleofattack")), "width 120lp!");
|
||||||
@ -183,7 +186,7 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
// Tabbed pane
|
// Tabbed pane
|
||||||
|
|
||||||
JTabbedPane tabbedPane = new JTabbedPane();
|
JTabbedPane tabbedPane = new JTabbedPane();
|
||||||
panel.add(tabbedPane, "spanx, growx, growy");
|
panel.add(tabbedPane, "spanx, growx, growy, pushy");
|
||||||
|
|
||||||
|
|
||||||
// Create the Longitudinal Stability (CM vs CP) data table
|
// Create the Longitudinal Stability (CM vs CP) data table
|
||||||
@ -428,6 +431,8 @@ public class ComponentAnalysisDialog extends JDialog implements StateChangeListe
|
|||||||
this.addWindowListener(new WindowAdapter() {
|
this.addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void windowClosed(WindowEvent e) {
|
public void windowClosed(WindowEvent e) {
|
||||||
|
theta.setValue(initTheta);
|
||||||
|
|
||||||
//System.out.println("Closing method called: " + this);
|
//System.out.println("Closing method called: " + this);
|
||||||
theta.removeChangeListener(ComponentAnalysisDialog.this);
|
theta.removeChangeListener(ComponentAnalysisDialog.this);
|
||||||
aoa.removeChangeListener(ComponentAnalysisDialog.this);
|
aoa.removeChangeListener(ComponentAnalysisDialog.this);
|
||||||
|
@ -1,68 +1,147 @@
|
|||||||
package net.sf.openrocket.gui.dialogs;
|
package net.sf.openrocket.gui.dialogs;
|
||||||
|
|
||||||
import java.awt.Font;
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.JTextArea;
|
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
import net.sf.openrocket.gui.components.DescriptionArea;
|
||||||
import net.sf.openrocket.gui.components.StyledLabel;
|
import net.sf.openrocket.gui.components.StyledLabel;
|
||||||
import net.sf.openrocket.gui.util.GUIUtil;
|
import net.sf.openrocket.gui.util.GUIUtil;
|
||||||
import net.sf.openrocket.l10n.Translator;
|
import net.sf.openrocket.l10n.Translator;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
|
import net.sf.openrocket.gui.util.Icons;
|
||||||
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||||
|
import net.sf.openrocket.util.BuildProperties;
|
||||||
|
import net.sf.openrocket.util.Chars;
|
||||||
|
|
||||||
public class LicenseDialog extends JDialog {
|
public class LicenseDialog extends JDialog {
|
||||||
private static final String LICENSE_FILENAME = "LICENSE.TXT";
|
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
private static final String DEFAULT_LICENSE_TEXT =
|
|
||||||
"\n" +
|
|
||||||
"Error: Unable to load " + LICENSE_FILENAME + "!\n" +
|
|
||||||
"\n" +
|
|
||||||
"OpenRocket is licensed under the GNU GPL version 3, with additional permissions.\n" +
|
|
||||||
"See http://openrocket.sourceforge.net/ for details.";
|
|
||||||
|
|
||||||
public LicenseDialog(JFrame parent) {
|
public LicenseDialog(JFrame parent) {
|
||||||
super(parent, true);
|
super(parent, true);
|
||||||
|
|
||||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||||
|
|
||||||
panel.add(new StyledLabel("OpenRocket license", 10), "ax 50%, wrap para");
|
// OpenRocket logo
|
||||||
|
panel.add(new JLabel(Icons.loadImageIcon("pix/icon/icon-about.png", "OpenRocket")), "top");
|
||||||
String licenseText;
|
|
||||||
try {
|
|
||||||
|
|
||||||
BufferedReader reader = new BufferedReader(
|
|
||||||
new InputStreamReader(ClassLoader.getSystemResourceAsStream(LICENSE_FILENAME)));
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
for (String s = reader.readLine(); s != null; s = reader.readLine()) {
|
|
||||||
sb.append(s);
|
|
||||||
sb.append('\n');
|
|
||||||
}
|
|
||||||
licenseText = sb.toString();
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
|
|
||||||
licenseText = DEFAULT_LICENSE_TEXT;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
JTextArea text = new JTextArea(licenseText);
|
panel.add(new StyledLabel("Software Licenses", 10), "ax 50%, pushx, wrap para");
|
||||||
text.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
|
|
||||||
text.setRows(20);
|
final String jarUrl = "jar:" + getClass().getProtectionDomain().getCodeSource().getLocation().toString();
|
||||||
text.setColumns(80);
|
final String copyrightYear = BuildProperties.getCopyrightYear();
|
||||||
text.setEditable(false);
|
|
||||||
panel.add(new JScrollPane(text),"grow, wrap para");
|
/*****************************************************************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* LICENSE TEXT: each of the licenses we're using is described here. At the end, they are all concatenated for insertion */
|
||||||
|
/* in the description window */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
/* GPL: overall project */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
final String orLicense = "<strong>GNU GENERAL PUBLIC LICENSE</strong>" + "<br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket - A model rocket simulator<br>" +
|
||||||
|
"Copyright " + Chars.COPY + " 2007-" + copyrightYear + " Sampo Niskanen and others<br>" +
|
||||||
|
"Project page: <a href=\"https://openrocket.info/\">https://openrocket.info/</a><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"This program is free software: you can redistribute it and/or modify it under the terms of the " +
|
||||||
|
"GNU General Public License as published by the Free Software Foundation, either version 3 " +
|
||||||
|
"of the License, or any later version. " +
|
||||||
|
"The license may be viewed " +
|
||||||
|
"<a href=\"" + jarUrl + "!/LICENSE.TXT\">here</a>.<br>" +
|
||||||
|
"<br>" +
|
||||||
|
"This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; " +
|
||||||
|
"without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. " +
|
||||||
|
"See the GNU General Public License for more details.<br>" +
|
||||||
|
"<br>" +
|
||||||
|
"You should have received a copy of the GNU Public License along with this program. If not, you may obtain a copy at " +
|
||||||
|
"<a href=\"https://www.gnu.org/licenses/gpl-3.0.html\">https://www.gnu.org/licenses/gpl-3.0.html</a><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket developers may be contacted electronically at:<br>" +
|
||||||
|
"<a href=\"mailto:openrocket-devel@lists.sourceforge.net\">mailto:openrocket-devel@lists.sourceforge.net</a><br>" +
|
||||||
|
"<a href=\"https://openrocket.slack.com\">https://openrocket.slack.com</a><br>" +
|
||||||
|
"<a href=\"https://github.com/openrocket\">https://github.com/openrocket</a><br>" +
|
||||||
|
"<br>";
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
/* APACHE: components library */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
final String componentsLicense =
|
||||||
|
"<strong>APACHE LICENSE</strong><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket features the enhanced components database created by David B. Cook<br>" +
|
||||||
|
"Copyright " + Chars.COPY + " 2015-" + copyrightYear + " David B. Cook<br>" +
|
||||||
|
"Project page: <a href=\"https://github.com/dbcook/openrocket-database\">https://github.com/dbcook/openrocket-database</a><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this work except in compliance with the License. " +
|
||||||
|
"You may view the License " +
|
||||||
|
"<a href=\"" + jarUrl + "!/datafiles/presets/LICENSE\">here</a>.<br>" +
|
||||||
|
"You may also obtain a copy of the License at " +
|
||||||
|
"<a href=\"http://www.apache.org/licenses/LICENSE-2.0\">http://www.apache.org/licenses/LICENSE-2.0</a><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket uses the Work or Derivative Works of Ant, a product which includes software developed by the Apache " +
|
||||||
|
"Software Foundation<br>" +
|
||||||
|
"<br>" +
|
||||||
|
"Ant also includes software developed by:" +
|
||||||
|
"<ul style=\"margin-top: 0;\">" +
|
||||||
|
"<li>the W3C Consortium (<a href=\"http://www.w3c.org\">http://www.w3c.org</a>)</li>" +
|
||||||
|
"<li>the SAX project (<a href=\"http://www.saxproject.org\">http://www.saxproject.org</a></li>" +
|
||||||
|
"</ul>" +
|
||||||
|
"The names \"Ant\" and \"Apache Software Foundation\" must not be used to endorse or " +
|
||||||
|
"promote products derived from this software without prior written permission. For written permission, "+
|
||||||
|
"please contact <a href=\"mailto:apache@apache.org\">apache@apache.org</a>.<br>" +
|
||||||
|
"<br>";
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
/* BITSTREAM VERA: Deja Vu font */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
final String fontLicense =
|
||||||
|
"<strong>BITSTREAM VERA FONT LICENSE</strong><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket makes use of the DejaVu Serif Font<br>" +
|
||||||
|
"Fonts are Copyright " + Chars.COPY + " 2003 by Bitstream, Inc. All Rights Reserved. " +
|
||||||
|
"Bitstream Vera is a trademark of Bitstream, Inc.<br>" +
|
||||||
|
"DejaVu changes are in the public domain<br>" +
|
||||||
|
"Glyphs imported from Arev Fonts Copyright " + Chars.COPY + " 2006 by Tavmjong Bah. All Rights Reserved.<br>" +
|
||||||
|
"Project page: <a href=\"https://github.com/dejavu-fonts/dejavu-fonts/\">https://github.com/dejavu-fonts/dejavu-fonts/<a/><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"Licensed according to the Bitstream Vera Font License which may be found " +
|
||||||
|
"<a href=\"" + jarUrl + "!/dejavu-font/LICENSE\">here</a>." +
|
||||||
|
"<br>" +
|
||||||
|
"You may also obtain a copy of the License at " +
|
||||||
|
"<a href=\"https://github.com/dejavu-fonts/dejavu-fonts/blob/master/LICENSE\">https://github.com/dejavu-fonts/dejavu-fonts/blob/master/LICENSE</a><br>" +
|
||||||
|
"<br>";
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
/* BSD 2-Clause: commonmark-java library */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
final String commonmarkLicense =
|
||||||
|
"<strong>BSD 2-Clause License</strong><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"OpenRocket makes use of the Commonmark-Java Library<br>" +
|
||||||
|
"Copyright " + Chars.COPY + " 2015-2016 Atlassian Pty Ltd. All rights reserved.<br>" +
|
||||||
|
"Project page: <a href=\"https://github.com/commonmark/commonmark-java/\">https://github.com/commonmark/commonmark-java/<a/><br>" +
|
||||||
|
"<br>" +
|
||||||
|
"You may obtain a copy of the License at <a href=\"https://github.com/commonmark/commonmark-java/blob/main/LICENSE.txt\">https://github.com/commonmark/commonmark-java/blob/main/LICENSE.txt</a>." +
|
||||||
|
"<br>";
|
||||||
|
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
/* End of license text */
|
||||||
|
/*****************************************************************************************************************************/
|
||||||
|
|
||||||
|
DescriptionArea info = new DescriptionArea(20);
|
||||||
|
info.setTextFont(UIManager.getFont("Label.font"));
|
||||||
|
info.setText(orLicense + componentsLicense + fontLicense + commonmarkLicense);
|
||||||
|
panel.add(info, "newline, width 700lp, height 250lp, pushy, grow, spanx, wrap para");
|
||||||
|
|
||||||
//Close button
|
//Close button
|
||||||
JButton close = new SelectColorButton(trans.get("dlg.but.close"));
|
JButton close = new SelectColorButton(trans.get("dlg.but.close"));
|
||||||
@ -72,7 +151,7 @@ public class LicenseDialog extends JDialog {
|
|||||||
LicenseDialog.this.dispose();
|
LicenseDialog.this.dispose();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
panel.add(close, "right");
|
panel.add(close, "spanx, right");
|
||||||
|
|
||||||
this.add(panel);
|
this.add(panel);
|
||||||
this.setTitle("OpenRocket license");
|
this.setTitle("OpenRocket license");
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package net.sf.openrocket.gui.dialogs.optimization;
|
package net.sf.openrocket.gui.dialogs.optimization;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Toolkit;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
@ -205,7 +207,7 @@ public class GeneralOptimizationDialog extends JDialog {
|
|||||||
JScrollPane scroll;
|
JScrollPane scroll;
|
||||||
String tip;
|
String tip;
|
||||||
|
|
||||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
JPanel panel = new JPanel(new MigLayout("fill, w 1200"));
|
||||||
|
|
||||||
ChangeListener clearHistoryChangeListener = e -> clearHistory();
|
ChangeListener clearHistoryChangeListener = e -> clearHistory();
|
||||||
ActionListener clearHistoryActionListener = e -> clearHistory();
|
ActionListener clearHistoryActionListener = e -> clearHistory();
|
||||||
@ -251,10 +253,10 @@ public class GeneralOptimizationDialog extends JDialog {
|
|||||||
label = new StyledLabel(trans.get("lbl.paramsToOptimize"), Style.BOLD);
|
label = new StyledLabel(trans.get("lbl.paramsToOptimize"), Style.BOLD);
|
||||||
disableComponents.add(label);
|
disableComponents.add(label);
|
||||||
panel.add(label, "split 3, flowy");
|
panel.add(label, "split 3, flowy");
|
||||||
panel.add(scroll, "wmin 300lp, height 200lp, grow");
|
panel.add(scroll, "wmin 300lp, height 150lp, grow");
|
||||||
selectedModifierDescription = new DescriptionArea(2, -3);
|
selectedModifierDescription = new DescriptionArea(2, -3);
|
||||||
disableComponents.add(selectedModifierDescription);
|
disableComponents.add(selectedModifierDescription);
|
||||||
panel.add(selectedModifierDescription, "growx");
|
panel.add(selectedModifierDescription, "hmin 20lp, growx");
|
||||||
|
|
||||||
// // Add/remove buttons
|
// // Add/remove buttons
|
||||||
sub = new JPanel(new MigLayout("fill"));
|
sub = new JPanel(new MigLayout("fill"));
|
||||||
@ -601,16 +603,16 @@ public class GeneralOptimizationDialog extends JDialog {
|
|||||||
});
|
});
|
||||||
panel.add(closeButton, "right");
|
panel.add(closeButton, "right");
|
||||||
|
|
||||||
this.add(panel);
|
this.add(new JScrollPane(panel));
|
||||||
clearHistory();
|
clearHistory();
|
||||||
updateComponents();
|
updateComponents();
|
||||||
GUIUtil.setDisposableDialogOptions(this, null);
|
GUIUtil.setDisposableDialogOptions(this, null);
|
||||||
|
|
||||||
// seem like a reasonable defaults
|
int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
|
||||||
this.setSize(1200, 600);
|
this.setSize(new Dimension(this.getWidth(), Math.min(this.getHeight(), screenHeight - 150)));
|
||||||
// System.err.println("OptimizationDialog.size: " + this.getSize());
|
this.pack();
|
||||||
this.setLocation(100, 100);
|
|
||||||
// System.err.println("OptimizationDialog.location: " + this.getLocation());
|
this.setLocation((parent.getWidth() - 1200)/2, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startOptimization() {
|
private void startOptimization() {
|
||||||
|
@ -209,7 +209,7 @@ public class BasicFrame extends JFrame {
|
|||||||
//// Rocket design
|
//// Rocket design
|
||||||
tabbedPane.addTab(trans.get("BasicFrame.tab.Rocketdesign"), null, designTab());
|
tabbedPane.addTab(trans.get("BasicFrame.tab.Rocketdesign"), null, designTab());
|
||||||
//// Flight configurations
|
//// Flight configurations
|
||||||
tabbedPane.addTab(trans.get("BasicFrame.tab.Flightconfig"), null, new FlightConfigurationPanel(document));
|
tabbedPane.addTab(trans.get("BasicFrame.tab.Flightconfig"), null, new FlightConfigurationPanel(this, document));
|
||||||
//// Flight simulations
|
//// Flight simulations
|
||||||
tabbedPane.addTab(trans.get("BasicFrame.tab.Flightsim"), null, simulationPanel);
|
tabbedPane.addTab(trans.get("BasicFrame.tab.Flightsim"), null, simulationPanel);
|
||||||
|
|
||||||
@ -1690,10 +1690,14 @@ public class BasicFrame extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectedComponent(RocketComponent component) {
|
||||||
|
this.selectionModel.setSelectedComponent(component);
|
||||||
|
}
|
||||||
|
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
JTabbedPane tabSource = (JTabbedPane) e.getSource();
|
JTabbedPane tabSource = (JTabbedPane) e.getSource();
|
||||||
String tab = tabSource.getTitleAt(tabSource.getSelectedIndex());
|
int tab = tabSource.getSelectedIndex();
|
||||||
if (tab.equals(trans.get("BasicFrame.tab.Flightsim"))) {
|
if (tab == SIMULATION_TAB) {
|
||||||
simulationPanel.activating();
|
simulationPanel.activating();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -814,14 +814,11 @@ public class SimulationPanel extends JPanel {
|
|||||||
case CANT_RUN:
|
case CANT_RUN:
|
||||||
tip += trans.get("simpanel.ttip.noData")+"<br>";
|
tip += trans.get("simpanel.ttip.noData")+"<br>";
|
||||||
break;
|
break;
|
||||||
|
case LOADED:
|
||||||
case UPTODATE:
|
case UPTODATE:
|
||||||
tip += trans.get("simpanel.ttip.uptodate") + "<br>";
|
tip += trans.get("simpanel.ttip.uptodate") + "<br>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LOADED:
|
|
||||||
tip += trans.get("simpanel.ttip.loaded") + "<br>";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OUTDATED:
|
case OUTDATED:
|
||||||
tip += trans.get("simpanel.ttip.outdated") + "<br>";
|
tip += trans.get("simpanel.ttip.outdated") + "<br>";
|
||||||
break;
|
break;
|
||||||
|
@ -25,8 +25,8 @@ public class Splash {
|
|||||||
|
|
||||||
// The right edge of the text base line for the version string
|
// The right edge of the text base line for the version string
|
||||||
private static final int VERSION_POSITION_X = 617;
|
private static final int VERSION_POSITION_X = 617;
|
||||||
private static final int VERSION_POSITION_Y = 138;
|
private static final int VERSION_POSITION_Y = 150;
|
||||||
private static final Font VERSION_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 9);
|
private static final Font VERSION_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 14);
|
||||||
private static final Color VERSION_COLOR = Color.WHITE;
|
private static final Color VERSION_COLOR = Color.WHITE;
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ public class ComponentTreeModel implements TreeModel, ComponentChangeListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void componentChanged(ComponentChangeEvent e) {
|
public void componentChanged(ComponentChangeEvent e) {
|
||||||
if (e.isTreeChange() || e.isUndoChange() || e.isMassChange()) {
|
if (e.isTreeChange() || e.isUndoChange()) {
|
||||||
// Tree must be fully updated also in case of an undo change
|
// Tree must be fully updated also in case of an undo change
|
||||||
fireTreeStructureChanged(e.getSource());
|
fireTreeStructureChanged(e.getSource());
|
||||||
if (e.isTreeChange() && e.isUndoChange()) {
|
if (e.isTreeChange() && e.isUndoChange()) {
|
||||||
|
@ -132,7 +132,7 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
|
|||||||
table.changeSelection(row, col, true, false);
|
table.changeSelection(row, col, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void installTableListener() {
|
protected void installTableListener() {
|
||||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,7 +36,8 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
|
|
||||||
private final OpenRocketDocument document;
|
private final OpenRocketDocument document;
|
||||||
private final Rocket rocket;
|
private final Rocket rocket;
|
||||||
|
|
||||||
|
private final BasicFrame basicFrame;
|
||||||
private final JButton newConfButton, renameConfButton, removeConfButton, copyConfButton;
|
private final JButton newConfButton, renameConfButton, removeConfButton, copyConfButton;
|
||||||
|
|
||||||
private final JTabbedPane tabs;
|
private final JTabbedPane tabs;
|
||||||
@ -48,9 +49,10 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
private final static int RECOVERY_TAB_INDEX = 1;
|
private final static int RECOVERY_TAB_INDEX = 1;
|
||||||
private final static int SEPARATION_TAB_INDEX = 2;
|
private final static int SEPARATION_TAB_INDEX = 2;
|
||||||
|
|
||||||
public FlightConfigurationPanel(OpenRocketDocument doc) {
|
public FlightConfigurationPanel(BasicFrame basicFrame, OpenRocketDocument doc) {
|
||||||
super(new MigLayout("fill","[grow][][][][][grow]"));
|
super(new MigLayout("fill","[grow][][][][][grow]"));
|
||||||
|
|
||||||
|
this.basicFrame = basicFrame;
|
||||||
this.document = doc;
|
this.document = doc;
|
||||||
this.rocket = doc.getRocket();
|
this.rocket = doc.getRocket();
|
||||||
this.rocket.addChangeListener(this);
|
this.rocket.addChangeListener(this);
|
||||||
@ -252,7 +254,11 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSelectedComponent(RocketComponent component) {
|
||||||
|
this.basicFrame.setSelectedComponent(component);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stateChanged(EventObject e) {
|
public void stateChanged(EventObject e) {
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
|
@ -4,6 +4,8 @@ import java.awt.CardLayout;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.FocusEvent;
|
||||||
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
@ -21,12 +23,12 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.ListSelectionModel;
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.event.TableModelEvent;
|
import javax.swing.event.TableModelEvent;
|
||||||
import javax.swing.event.TableModelListener;
|
import javax.swing.event.TableModelListener;
|
||||||
|
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.openrocket.gui.components.StyledLabel;
|
|
||||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
|
||||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.IgnitionSelectionDialog;
|
import net.sf.openrocket.gui.dialogs.flightconfiguration.IgnitionSelectionDialog;
|
||||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfigurationPanel;
|
import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfigurationPanel;
|
||||||
import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
|
import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
|
||||||
@ -40,6 +42,7 @@ import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
|||||||
import net.sf.openrocket.rocketcomponent.InnerTube;
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
import net.sf.openrocket.rocketcomponent.MotorMount;
|
import net.sf.openrocket.rocketcomponent.MotorMount;
|
||||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.unit.UnitGroup;
|
import net.sf.openrocket.unit.UnitGroup;
|
||||||
import net.sf.openrocket.util.Chars;
|
import net.sf.openrocket.util.Chars;
|
||||||
|
|
||||||
@ -205,6 +208,40 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
return configurationTable;
|
return configurationTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installTableListener() {
|
||||||
|
super.installTableListener();
|
||||||
|
|
||||||
|
table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||||
|
@Override
|
||||||
|
public void valueChanged(ListSelectionEvent e) {
|
||||||
|
updateComponentSelection(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
table.addFocusListener(new FocusListener() {
|
||||||
|
@Override
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
updateComponentSelection(new ListSelectionEvent(this, 0, 0, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateComponentSelection(ListSelectionEvent e) {
|
||||||
|
if (e.getValueIsAdjusting()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MotorMount mount = getSelectedComponent();
|
||||||
|
if (mount instanceof RocketComponent) {
|
||||||
|
flightConfigurationPanel.setSelectedComponent((RocketComponent) mount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void updateButtonState() {
|
protected void updateButtonState() {
|
||||||
if( configurationTableModel.getColumnCount() > 1 ) {
|
if( configurationTableModel.getColumnCount() > 1 ) {
|
||||||
showContent();
|
showContent();
|
||||||
|
@ -616,13 +616,13 @@ public class DesignReport {
|
|||||||
log.warn("Simulation " + simulation.getId() + " has no motors, skipping");
|
log.warn("Simulation " + simulation.getId() + " has no motors, skipping");
|
||||||
// Continue so we don't simulate
|
// Continue so we don't simulate
|
||||||
continue;
|
continue;
|
||||||
|
case LOADED:
|
||||||
case UPTODATE:
|
case UPTODATE:
|
||||||
log.trace("Simulation " + simulation.getId() + "is up to date, not running simulation");
|
log.trace("Simulation " + simulation.getId() + "is up to date, not running simulation");
|
||||||
simulate = false;
|
simulate = false;
|
||||||
break;
|
break;
|
||||||
case NOT_SIMULATED:
|
case NOT_SIMULATED:
|
||||||
case OUTDATED:
|
case OUTDATED:
|
||||||
case LOADED:
|
|
||||||
log.trace("Running simulation for " + simulation.getId());
|
log.trace("Running simulation for " + simulation.getId());
|
||||||
simulate = true;
|
simulate = true;
|
||||||
break;
|
break;
|
||||||
|
@ -3,6 +3,7 @@ package net.sf.openrocket.gui.rocketfigure;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
@ -89,37 +90,72 @@ public class FinSetShapes extends RocketComponentShape {
|
|||||||
|
|
||||||
double thickness = finset.getThickness();
|
double thickness = finset.getThickness();
|
||||||
double height = finset.getSpan();
|
double height = finset.getSpan();
|
||||||
|
double tabHeight = finset.getTabHeight();
|
||||||
|
|
||||||
// Generate base coordinates for a single fin
|
// Generate base coordinates for a single fin
|
||||||
Coordinate c[] = new Coordinate[4];
|
Coordinate[] c = new Coordinate[4];
|
||||||
c[0]=new Coordinate(0, 0,-thickness/2);
|
c[0]=new Coordinate(0, 0,-thickness/2);
|
||||||
c[1]=new Coordinate(0, 0,thickness/2);
|
c[1]=new Coordinate(0, 0,thickness/2);
|
||||||
c[2]=new Coordinate(0,height,thickness/2);
|
c[2]=new Coordinate(0,height,thickness/2);
|
||||||
c[3]=new Coordinate(0,height,-thickness/2);
|
c[3]=new Coordinate(0,height,-thickness/2);
|
||||||
|
|
||||||
|
// Generate base coordinates for a single fin tab
|
||||||
|
Coordinate[] cTab = new Coordinate[4];
|
||||||
|
cTab[0]=new Coordinate(0, 0,-thickness/2);
|
||||||
|
cTab[1]=new Coordinate(0, 0,thickness/2);
|
||||||
|
cTab[2]=new Coordinate(0, -tabHeight,thickness/2);
|
||||||
|
cTab[3]=new Coordinate(0, -tabHeight,-thickness/2);
|
||||||
|
|
||||||
// Apply base rotation
|
// Apply base rotation
|
||||||
c = transformation.transform(c);
|
c = transformation.transform(c);
|
||||||
|
cTab = transformation.transform(cTab);
|
||||||
|
|
||||||
// Make polygon
|
// Make polygon
|
||||||
|
Path2D.Double p = createUncantedPolygon(c);
|
||||||
|
|
||||||
|
if (tabHeight != 0 && finset.getTabLength() != 0) {
|
||||||
|
Path2D.Double pTab = createUncantedPolygon(cTab);
|
||||||
|
return new Shape[]{p, pTab};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Shape[]{p};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Path2D.Double createUncantedPolygon(Coordinate[] c) {
|
||||||
Coordinate a;
|
Coordinate a;
|
||||||
Path2D.Double p = new Path2D.Double();
|
Path2D.Double p = new Path2D.Double();
|
||||||
|
|
||||||
a = c[0];
|
a = c[0];
|
||||||
p.moveTo(a.z, a.y);
|
p.moveTo(a.z, a.y);
|
||||||
a = c[1];
|
a = c[1];
|
||||||
p.lineTo(a.z, a.y);
|
p.lineTo(a.z, a.y);
|
||||||
a = c[2];
|
a = c[2];
|
||||||
p.lineTo(a.z, a.y);
|
p.lineTo(a.z, a.y);
|
||||||
a = c[3];
|
a = c[3];
|
||||||
p.lineTo(a.z, a.y);
|
p.lineTo(a.z, a.y);
|
||||||
p.closePath();
|
p.closePath();
|
||||||
|
return p;
|
||||||
return new Shape[]{p};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Shape[] cantedShapesBack(FinSet finset,
|
|
||||||
Transformation transformation) {
|
|
||||||
|
|
||||||
|
private static Shape[] cantedShapesBack(FinSet finset,
|
||||||
|
Transformation transformation) {
|
||||||
|
if (finset.getTabHeight() == 0 || finset.getTabLength() == 0) {
|
||||||
|
return cantedShapesBackFins(finset, transformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape[] toReturn;
|
||||||
|
Shape[] shapesFin = cantedShapesBackFins(finset, transformation);
|
||||||
|
Shape[] shapesTab = cantedShapesBackTabs(finset, transformation);
|
||||||
|
|
||||||
|
toReturn = Arrays.copyOf(shapesFin, shapesFin.length + shapesTab.length);
|
||||||
|
System.arraycopy(shapesTab, 0, toReturn, shapesFin.length, shapesTab.length);
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Shape[] cantedShapesBackFins(FinSet finset,
|
||||||
|
Transformation transformation) {
|
||||||
double thickness = finset.getThickness();
|
double thickness = finset.getThickness();
|
||||||
|
|
||||||
Coordinate[] sidePoints;
|
Coordinate[] sidePoints;
|
||||||
@ -168,6 +204,57 @@ public class FinSetShapes extends RocketComponentShape {
|
|||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Shape[] cantedShapesBackTabs(FinSet finset,
|
||||||
|
Transformation transformation) {
|
||||||
|
double thickness = finset.getThickness();
|
||||||
|
|
||||||
|
Coordinate[] sidePoints;
|
||||||
|
Coordinate[] backPoints;
|
||||||
|
int minIndex;
|
||||||
|
|
||||||
|
Coordinate[] points = finset.getTabPoints();
|
||||||
|
|
||||||
|
// this loop finds the index @ min-y, as visible from the back
|
||||||
|
for (minIndex = points.length-1; minIndex > 0; minIndex--) {
|
||||||
|
if (points[minIndex-1].y > points[minIndex].y)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transformation cantTransform = finset.getCantRotation();
|
||||||
|
final Transformation compositeTransform = transformation.applyTransformation(cantTransform);
|
||||||
|
|
||||||
|
sidePoints = new Coordinate[points.length];
|
||||||
|
backPoints = new Coordinate[2*(points.length-minIndex)];
|
||||||
|
double sign = Math.copySign(1.0, finset.getCantAngle());
|
||||||
|
|
||||||
|
// Calculate points for the visible side panel
|
||||||
|
for (int i=0; i < points.length; i++) {
|
||||||
|
sidePoints[i] = points[i].add(0,0,sign*thickness/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate points for the back portion
|
||||||
|
int i=0;
|
||||||
|
for (int j=points.length-1; j >= minIndex; j--, i++) {
|
||||||
|
backPoints[i] = points[j].add(0,0,sign*thickness/2);
|
||||||
|
}
|
||||||
|
for (int j=minIndex; j <= points.length-1; j++, i++) {
|
||||||
|
backPoints[i] = points[j].add(0,0,-sign*thickness/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate shapes
|
||||||
|
Shape[] s;
|
||||||
|
if (thickness > 0.0005) {
|
||||||
|
s = new Shape[2];
|
||||||
|
s[0] = makePolygonBack(sidePoints,compositeTransform);
|
||||||
|
s[1] = makePolygonBack(backPoints,compositeTransform);
|
||||||
|
} else {
|
||||||
|
s = new Shape[1];
|
||||||
|
s[0] = makePolygonBack(sidePoints,compositeTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
private static Shape makePolygonBack(Coordinate[] array, final Transformation t) {
|
private static Shape makePolygonBack(Coordinate[] array, final Transformation t) {
|
||||||
Path2D.Float p;
|
Path2D.Float p;
|
||||||
|
@ -33,7 +33,7 @@ public class Icons {
|
|||||||
map.put(Simulation.Status.NOT_SIMULATED, loadImageIcon("pix/spheres/gray-16x16.png", "Not simulated"));
|
map.put(Simulation.Status.NOT_SIMULATED, loadImageIcon("pix/spheres/gray-16x16.png", "Not simulated"));
|
||||||
map.put(Simulation.Status.CANT_RUN, loadImageIcon("pix/spheres/yellow-16x16.png", "Can't run, no motors assigned."));
|
map.put(Simulation.Status.CANT_RUN, loadImageIcon("pix/spheres/yellow-16x16.png", "Can't run, no motors assigned."));
|
||||||
map.put(Simulation.Status.UPTODATE, loadImageIcon("pix/spheres/green-16x16.png", "Up to date"));
|
map.put(Simulation.Status.UPTODATE, loadImageIcon("pix/spheres/green-16x16.png", "Up to date"));
|
||||||
map.put(Simulation.Status.LOADED, loadImageIcon("pix/spheres/yellow-16x16.png", "Loaded from file"));
|
map.put(Simulation.Status.LOADED, loadImageIcon("pix/spheres/green-16x16.png", "Up to date"));
|
||||||
map.put(Simulation.Status.OUTDATED, loadImageIcon("pix/spheres/red-16x16.png", "Out-of-date"));
|
map.put(Simulation.Status.OUTDATED, loadImageIcon("pix/spheres/red-16x16.png", "Out-of-date"));
|
||||||
map.put(Simulation.Status.EXTERNAL, loadImageIcon("pix/spheres/blue-16x16.png", "Imported data"));
|
map.put(Simulation.Status.EXTERNAL, loadImageIcon("pix/spheres/blue-16x16.png", "Imported data"));
|
||||||
SIMULATION_STATUS_ICON_MAP = Collections.unmodifiableMap(map);
|
SIMULATION_STATUS_ICON_MAP = Collections.unmodifiableMap(map);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user