Merge lp:~daggerstab/stellarium/comets-asteroids-importer into lp:stellarium
- comets-asteroids-importer
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~daggerstab/stellarium/comets-asteroids-importer |
Merge into: | lp:stellarium |
Diff against target: |
7637 lines (+7199/-32) 36 files modified
CMakeLists.txt (+1/-0) Doxyfile.cmake (+1/-1) data/gui/nightStyle.css (+8/-0) data/gui/normalStyle.css (+8/-0) data/ssystem.ini (+10/-5) plugins/CMakeLists.txt (+3/-0) plugins/SolarSystemEditor/CMakeLists.txt (+19/-0) plugins/SolarSystemEditor/UnpackProvisionalDesignation.pro (+12/-0) plugins/SolarSystemEditor/src/CMakeLists.txt (+76/-0) plugins/SolarSystemEditor/src/SolarSystemEditor.cpp (+1535/-0) plugins/SolarSystemEditor/src/SolarSystemEditor.hpp (+312/-0) plugins/SolarSystemEditor/src/gui/MPCImporterDialogPrototype02.ui (+171/-0) plugins/SolarSystemEditor/src/gui/ManualImportWindow.cpp (+257/-0) plugins/SolarSystemEditor/src/gui/ManualImportWindow.hpp (+79/-0) plugins/SolarSystemEditor/src/gui/MpcImportWindow.cpp (+958/-0) plugins/SolarSystemEditor/src/gui/MpcImportWindow.hpp (+135/-0) plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.cpp (+170/-0) plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.hpp (+73/-0) plugins/SolarSystemEditor/src/gui/manualImportWindow.ui (+890/-0) plugins/SolarSystemEditor/src/gui/mpcImportWindow.ui (+679/-0) plugins/SolarSystemEditor/src/gui/solarSystemManagerWindow.ui (+426/-0) plugins/SolarSystemEditor/src/gui/solarSystemManagerWindow_prototype01.ui (+130/-0) plugins/SolarSystemEditor/ssystem_ini format.txt (+76/-0) plugins/SolarSystemEditor/unpackProvisionalDesignationTest.cpp (+180/-0) src/CMakeLists.txt (+9/-0) src/StelMainGraphicsView.cpp (+4/-0) src/core/StelFileMgr.cpp (+52/-0) src/core/StelFileMgr.hpp (+7/-0) src/core/modules/Comet.cpp (+171/-0) src/core/modules/Comet.hpp (+83/-0) src/core/modules/MinorPlanet.cpp (+296/-0) src/core/modules/MinorPlanet.hpp (+113/-0) src/core/modules/Planet.hpp (+1/-1) src/core/modules/SolarSystem.cpp (+215/-24) src/core/modules/SolarSystem.hpp (+15/-1) src/translations.h (+24/-0) |
To merge this branch: | bzr merge lp:~daggerstab/stellarium/comets-asteroids-importer |
Related bugs: | |
Related blueprints: |
Solar System editor
(Undefined)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthew Gates | usage | Abstain | |
Review via email: mp+40744@code.launchpad.net |
This proposal has been superseded by a proposal from 2010-11-16.
Commit message
Description of the change
This is the first version (0.0.1) of the Solar System Editor plug-in (formerly the Comets and Asteroids Importer plug-in).
It's not a complete Solar System editor yet - the window that would allow manual editing of all parameters of Solar System objects is not finished yet, so it is hidden in this release. You can open manualImportWin
In addition to the plug-in itself, the branch contains changes to Stellarium's core (SolarSystem + 2 new classes derived from Planet) that allow better handling of asteroids and comets, including name rendering and visual magnitude calculation.
Feel free to comment on the interface and the texts used in it. :)
Fabien Chéreau (xalioth) wrote : | # |
Matthew Gates (matthew-porpoisehead) wrote : | # |
First impressions - really good plugin - I think a lot of people will appreciate this one.
GUI:
1 Not sure if we need the path of the ssystem.ini printed. Perhaps just a "reset" option to delete user copy. I realize this won't if the ssystem.ini is messed up so much the program won't start, but then this message can't be seen, and for sure users won't remember it.
(2) If we don't have to have the big warning and path of user ssystem.ini, maybe we can also dispense with the Copy / Restore thing?
(3) Internet search timer somewhat annoying. It makes user wait for a minute if they /didn't/ find what they were looking for (at which point they will probably want to re-search straight away). Unless we get complaints of overloading from the search server people, I don't think we need the limit, although maybe we should set the user agent to something they can use to throttle us if they want rather than have a generic user agent (assuming we use http to connect).
(4) Maybe the search can just be a tab in the main window rather than a separate tab (if (1) & (2) are accepted, the first tab is not really necessary - just a restore button somewhere.
Just my 2 pence worth!
-
Minor bugs noticed:
- long names of downloaded objects get truncated to 20 characters.
barrykgerdes (barrygastro) wrote : | # |
Hi
I compiled 4786 last night in Widows (4782 was OK). I causes a major lock up. It reaches the stellarium display and
then stops nothing but a total shut down unlocks the computer. As a restart then takes about 7 minutes I have not got very far but I suspect it may be in the config.ini or ssystem.ini files. The log.txt gives no indication
Barry Gerdes
Beaumont Hills Observatory
S 33' 41' 44" E 150' 56' 32"
> To: <email address hidden>
> From: <email address hidden>
> Subject: [Merge] lp:~daggerstab/stellarium/comets-asteroids-importer into lp:stellarium
> Date: Fri, 12 Nov 2010 17:23:10 +0000
>
> Bogdan Marinov has proposed merging lp:~daggerstab/stellarium/comets-asteroids-importer into lp:stellarium.
>
> Requested reviews:
> Stellarium (stellarium)
>
>
> This is the first version (0.0.1) of the Solar System Editor plug-in (formerly the Comets and Asteroids Importer plug-in).
>
> It's not a complete Solar System editor yet - the window that would allow manual editing of all parameters of Solar System objects is not finished yet, so it is hidden in this release. You can open manualImportWin
>
> In addition to the plug-in itself, the branch contains changes to Stellarium's core (SolarSystem + 2 new classes derived from Planet) that allow better handling of asteroids and comets, including name rendering and visual magnitude calculation.
>
> Feel free to comment on the interface and the texts used in it. :)
> --
> https:/
> Your team Stellarium is requested to review the proposed merge of lp:~daggerstab/stellarium/comets-asteroids-importer into lp:stellarium.
- 4856. By Bogdan Marinov
-
+ support for XEphem format; on-line search now uses it to prevent truncating of object names
- 4857. By Bogdan Marinov
-
commenting why one orbit function is used and not the other
- 4858. By Bogdan Marinov
-
improved generation of section/group names; + comments
- 4859. By Bogdan Marinov
-
+ fallback mechanism for the ssystem.ini file; SolarSystem now skips invalid entries instead of crashing Stellarium
- 4860. By Bogdan Marinov
-
adding or discarding search results should not reset the timer
- 4861. By Bogdan Marinov
-
removed search query countdown display;
the import window now remains open after an import - 4862. By Bogdan Marinov
-
if the loading of the user ssystem.ini fails, move it
- 4863. By Bogdan Marinov
-
some additions to translations.h: potentially added asteroids
- 4864. By Bogdan Marinov
-
+ style for checkbox icons for the QListWidget items
- 4865. By Bogdan Marinov
-
merged trunk
Unmerged revisions
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2010-11-08 15:26:58 +0000 |
3 | +++ CMakeLists.txt 2010-11-16 20:00:15 +0000 |
4 | @@ -136,6 +136,7 @@ |
5 | SET(USE_PLUGIN_TEXTUSERINTERFACE 1 CACHE BOOL "Define whether the TextUserInterface plugin should be created.") |
6 | SET(USE_PLUGIN_TIMEZONECONFIGURATION 1 CACHE BOOL "Define whether the TimeZoneConfiguration plugin should be created.") |
7 | SET(USE_PLUGIN_VIRGO 0 CACHE BOOL "Define whether the VirGO plugin should be created.") |
8 | +SET(USE_PLUGIN_SOLARSYSTEMEDITOR 1 CACHE BOOL "Define whether the Solar System Editor should be built.") |
9 | |
10 | ########## Static plugins need to define includes and libraries |
11 | ########## for the compilation of Stellarium itself |
12 | |
13 | === modified file 'Doxyfile.cmake' |
14 | --- Doxyfile.cmake 2010-09-03 09:54:30 +0000 |
15 | +++ Doxyfile.cmake 2010-11-16 20:00:15 +0000 |
16 | @@ -463,7 +463,7 @@ |
17 | # disable (NO) the deprecated list. This list is created by putting |
18 | # \deprecated commands in the documentation. |
19 | |
20 | -GENERATE_DEPRECATEDLIST= NO |
21 | +GENERATE_DEPRECATEDLIST= YES |
22 | |
23 | # The ENABLED_SECTIONS tag can be used to enable conditional |
24 | # documentation sections, marked by \if sectionname ... \endif. |
25 | |
26 | === modified file 'data/gui/nightStyle.css' |
27 | --- data/gui/nightStyle.css 2010-11-16 19:33:22 +0000 |
28 | +++ data/gui/nightStyle.css 2010-11-16 20:00:15 +0000 |
29 | @@ -514,6 +514,14 @@ |
30 | image: url(:/graphicGui/nv_checkbox-unchecked.png); |
31 | } |
32 | |
33 | +QListWidget::indicator::checked { |
34 | + image: url(:/graphicGui/nv_checkbox-checked.png); |
35 | +} |
36 | + |
37 | +QListWidget::indicator:unchecked { |
38 | + image: url(:/graphicGui/nv_checkbox-unchecked.png); |
39 | +} |
40 | + |
41 | /*QCheckBox:disabled { |
42 | color: rgb(210, 0, 0); |
43 | font-weight: 500; |
44 | |
45 | === modified file 'data/gui/normalStyle.css' |
46 | --- data/gui/normalStyle.css 2010-11-14 03:12:37 +0000 |
47 | +++ data/gui/normalStyle.css 2010-11-16 20:00:15 +0000 |
48 | @@ -513,6 +513,14 @@ |
49 | image: url(:/graphicGui/checkbox-unchecked.png); |
50 | } |
51 | |
52 | +QListWidget::indicator::checked { |
53 | + image: url(:/graphicGui/checkbox-checked.png); |
54 | +} |
55 | + |
56 | +QListWidget::indicator:unchecked { |
57 | + image: url(:/graphicGui/checkbox-unchecked.png); |
58 | +} |
59 | + |
60 | /*QCheckBox:disabled { |
61 | color: rgb(210, 0, 0); |
62 | font-weight: 500; |
63 | |
64 | === modified file 'data/ssystem.ini' |
65 | --- data/ssystem.ini 2010-07-16 14:09:25 +0000 |
66 | +++ data/ssystem.ini 2010-11-16 20:00:15 +0000 |
67 | @@ -586,8 +586,9 @@ |
68 | albedo = 1 |
69 | orbit_visualization_period = 365.25 |
70 | |
71 | -[ceres] |
72 | +[1ceres] |
73 | name = Ceres |
74 | +minor_planet_number = 1 |
75 | parent = Sun |
76 | radius = 470 |
77 | oblateness = 0.0 |
78 | @@ -607,8 +608,9 @@ |
79 | orbit_AscendingNode = 80.40696 |
80 | orbit_Inclination = 10.58671 |
81 | |
82 | -[pallas] |
83 | +[2pallas] |
84 | name = Pallas |
85 | +minor_planet_number = 2 |
86 | parent = Sun |
87 | radius = 220 |
88 | oblateness = 0.0 |
89 | @@ -628,8 +630,9 @@ |
90 | orbit_AscendingNode = 173.13579 |
91 | orbit_Inclination = 34.84182 |
92 | |
93 | -[juno] |
94 | +[3juno] |
95 | name = Juno |
96 | +minor_planet_number = 3 |
97 | parent = Sun |
98 | radius = 130 |
99 | oblateness = 0.0 |
100 | @@ -649,8 +652,9 @@ |
101 | orbit_AscendingNode = 170.12007 |
102 | orbit_Inclination = 12.97036 |
103 | |
104 | -[vesta] |
105 | +[4vesta] |
106 | name = Vesta |
107 | +minor_planet_number = 4 |
108 | parent = Sun |
109 | radius = 280 |
110 | oblateness = 0.0 |
111 | @@ -670,8 +674,9 @@ |
112 | orbit_AscendingNode = 103.91841 |
113 | orbit_Inclination = 7.13380 |
114 | |
115 | -[eris] |
116 | +[136199eris] |
117 | name = Eris |
118 | +minor_planet_number = 136199 |
119 | parent = Sun |
120 | radius = 1300 |
121 | oblateness = 0.0 |
122 | |
123 | === modified file 'plugins/CMakeLists.txt' |
124 | --- plugins/CMakeLists.txt 2010-11-08 15:24:12 +0000 |
125 | +++ plugins/CMakeLists.txt 2010-11-16 20:00:15 +0000 |
126 | @@ -41,3 +41,6 @@ |
127 | SET(VIRGO_PROJECT_PATH "../extmodules/VirGO/" CACHE PATH "The location of the VirGO plugin main directory i.e. the one containing the top level CMakeLists.txt") |
128 | ADD_SUBDIRECTORY( ${VIRGO_PROJECT_PATH} VirGO ) |
129 | ENDIF() |
130 | +IF (USE_PLUGIN_SOLARSYSTEMEDITOR) |
131 | + ADD_SUBDIRECTORY( SolarSystemEditor ) |
132 | +ENDIF() |
133 | |
134 | === added directory 'plugins/SolarSystemEditor' |
135 | === added file 'plugins/SolarSystemEditor/CMakeLists.txt' |
136 | --- plugins/SolarSystemEditor/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
137 | +++ plugins/SolarSystemEditor/CMakeLists.txt 2010-11-16 20:00:15 +0000 |
138 | @@ -0,0 +1,19 @@ |
139 | + |
140 | +SET(SOLARSYSTEMEDITOR_MAJOR "0") |
141 | +SET(SOLARSYSTEMEDITOR_MINOR "0") |
142 | +SET(SOLARSYSTEMEDITOR_PATCH "1") |
143 | +SET(SOLARSYSTEMEDITOR_VERSION "${SOLARSYSTEMEDITOR_MAJOR}.${SOLARSYSTEMEDITOR_MINOR}.${SOLARSYSTEMEDITOR_PATCH}") |
144 | + |
145 | +IF(APPLE) |
146 | + SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/Library/Application\ Support/Stellarium) |
147 | +ElSE(APPLE) |
148 | + SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/.stellarium) |
149 | +ENDIF(APPLE) |
150 | + |
151 | +ADD_DEFINITIONS(-DPLUGIN_VERSION="${SOLARSYSTEMEDITOR_VERSION}") |
152 | + |
153 | +ADD_SUBDIRECTORY( src ) |
154 | + |
155 | +INSTALL(FILES DESTINATION "modules/SolarSystemEditor") |
156 | + |
157 | + |
158 | |
159 | === added file 'plugins/SolarSystemEditor/UnpackProvisionalDesignation.pro' |
160 | --- plugins/SolarSystemEditor/UnpackProvisionalDesignation.pro 1970-01-01 00:00:00 +0000 |
161 | +++ plugins/SolarSystemEditor/UnpackProvisionalDesignation.pro 2010-11-16 20:00:15 +0000 |
162 | @@ -0,0 +1,12 @@ |
163 | +#------------------------------------------------- |
164 | +# |
165 | +# Project created by QtCreator 2010-09-18T15:18:26 |
166 | +# |
167 | +#------------------------------------------------- |
168 | + |
169 | +TARGET = UnpackProvisionalDesignation |
170 | +CONFIG += qtestlib |
171 | +CONFIG -= app_bundle |
172 | + |
173 | + |
174 | +SOURCES += unpackProvisionalDesignationTest.cpp |
175 | |
176 | === added directory 'plugins/SolarSystemEditor/src' |
177 | === added file 'plugins/SolarSystemEditor/src/CMakeLists.txt' |
178 | --- plugins/SolarSystemEditor/src/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
179 | +++ plugins/SolarSystemEditor/src/CMakeLists.txt 2010-11-16 20:00:15 +0000 |
180 | @@ -0,0 +1,76 @@ |
181 | + |
182 | +INCLUDE_DIRECTORIES( |
183 | + ${CMAKE_BINARY_DIR} |
184 | + ${CMAKE_BINARY_DIR}/plugins/SolarSystemEditor/src |
185 | + ${CMAKE_BINARY_DIR}/plugins/SolarSystemEditor/src/gui |
186 | + . gui) |
187 | + |
188 | +LINK_DIRECTORIES(/src) |
189 | + |
190 | +SET(SolarSystemEditor_SRCS |
191 | + SolarSystemEditor.hpp |
192 | + SolarSystemEditor.cpp |
193 | + gui/SolarSystemManagerWindow.hpp |
194 | + gui/SolarSystemManagerWindow.cpp |
195 | + gui/MpcImportWindow.hpp |
196 | + gui/MpcImportWindow.cpp |
197 | + gui/ManualImportWindow.hpp |
198 | + gui/ManualImportWindow.cpp |
199 | + ) |
200 | + |
201 | +SET(SolarSystemEditor_UIS |
202 | + gui/solarSystemManagerWindow.ui |
203 | + gui/mpcImportWindow.ui |
204 | + gui/manualImportWindow.ui |
205 | +) |
206 | + |
207 | +QT4_WRAP_UI(SolarSystemEditor_UIS_H ${SolarSystemEditor_UIS}) |
208 | + |
209 | +#SET(SolarSystemEditor_RES ../resources/resources.qrc) |
210 | +#QT4_ADD_RESOURCES(SolarSystemEditor_RES_CXX ${SolarSystemEditor_RES}) |
211 | + |
212 | +SET(SolarSystemEditor_MOC_HDRS |
213 | + gui/SolarSystemManagerWindow.hpp |
214 | + gui/MpcImportWindow.hpp |
215 | + gui/ManualImportWindow.hpp |
216 | + SolarSystemEditor.hpp |
217 | + ) |
218 | + |
219 | +QT4_WRAP_CPP(SolarSystemEditor_MOC_SRCS ${SolarSystemEditor_MOC_HDRS}) |
220 | + |
221 | +SET(extLinkerOption ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${ICONV_LIBRARIES} ${INTL_LIBRARIES}) |
222 | + |
223 | +#Dynamic library |
224 | +IF(BUILD_DYNAMIC_PLUGINS) |
225 | + ADD_LIBRARY(SolarSystemEditor MODULE ${SolarSystemEditor_SRCS} ${SolarSystemEditor_MOC_SRCS} ${SolarSystemEditor_RES_CXX} ${SolarSystemEditor_UIS_H}) |
226 | + |
227 | + IF(APPLE) |
228 | + FIND_LIBRARY(OPENGL_LIBRARY OpenGL) |
229 | + MARK_AS_ADVANCED(OPENGL_LIBRARY) |
230 | + SET_TARGET_PROPERTIES(SolarSystemEditor PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" SUFFIX ".dylib") |
231 | + ENDIF(APPLE) |
232 | + |
233 | + IF(WIN32) |
234 | + SET_TARGET_PROPERTIES(SolarSystemEditor PROPERTIES LINK_FLAGS "-enable-runtime-pseudo-reloc -Wl,--allow-multiple-definition" ) |
235 | + SET(StelMain stelMain) |
236 | + ELSE(WIN32) |
237 | + SET(StelMain ) |
238 | + ENDIF(WIN32) |
239 | + |
240 | + TARGET_LINK_LIBRARIES(SolarSystemEditor ${StelMain} ${extLinkerOption}) |
241 | + |
242 | + INSTALL(TARGETS SolarSystemEditor DESTINATION "modules/SolarSystemEditor") |
243 | +ENDIF() |
244 | + |
245 | +#Static library |
246 | +IF(BUILD_STATIC_PLUGINS) |
247 | + ADD_LIBRARY(SolarSystemEditor-static STATIC ${SolarSystemEditor_SRCS} ${SolarSystemEditor_MOC_SRCS} ${SolarSystemEditor_RES_CXX} ${SolarSystemEditor_UIS_H}) |
248 | + SET_TARGET_PROPERTIES(SolarSystemEditor-static PROPERTIES OUTPUT_NAME "SolarSystemEditor") |
249 | + TARGET_LINK_LIBRARIES(SolarSystemEditor-static ${extLinkerOption}) |
250 | + IF(WIN32) |
251 | + SET_TARGET_PROPERTIES(SolarSystemEditor-static PROPERTIES COMPILE_FLAGS "-DQT_STATICPLUGIN") |
252 | + ELSE() |
253 | + SET_TARGET_PROPERTIES(SolarSystemEditor-static PROPERTIES COMPILE_FLAGS "-fPIC -DQT_STATICPLUGIN") |
254 | + ENDIF() |
255 | + ADD_DEPENDENCIES(AllStaticPlugins SolarSystemEditor-static) |
256 | +ENDIF() |
257 | |
258 | === added file 'plugins/SolarSystemEditor/src/SolarSystemEditor.cpp' |
259 | --- plugins/SolarSystemEditor/src/SolarSystemEditor.cpp 1970-01-01 00:00:00 +0000 |
260 | +++ plugins/SolarSystemEditor/src/SolarSystemEditor.cpp 2010-11-16 20:00:15 +0000 |
261 | @@ -0,0 +1,1535 @@ |
262 | +/* |
263 | + * Solar System editor plug-in for Stellarium |
264 | + * |
265 | + * Copyright (C) 2010 Bogdan Marinov |
266 | + * |
267 | + * This program is free software; you can redistribute it and/or |
268 | + * modify it under the terms of the GNU General Public License |
269 | + * as published by the Free Software Foundation; either version 2 |
270 | + * of the License, or (at your option) any later version. |
271 | + * |
272 | + * This program is distributed in the hope that it will be useful, |
273 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
274 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
275 | + * GNU General Public License for more details. |
276 | + * |
277 | + * You should have received a copy of the GNU General Public License |
278 | + * along with this program; if not, write to the Free Software |
279 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
280 | + */ |
281 | + |
282 | +#include "SolarSystemEditor.hpp" |
283 | +#include "SolarSystemManagerWindow.hpp" |
284 | + |
285 | +#include "StelApp.hpp" |
286 | +#include "StelGui.hpp" |
287 | +#include "StelGuiItems.hpp" |
288 | +#include "StelFileMgr.hpp" |
289 | +#include "StelIniParser.hpp" |
290 | +#include "StelLocaleMgr.hpp" |
291 | +#include "StelModuleMgr.hpp" |
292 | +#include "StelObjectMgr.hpp" |
293 | +#include "SolarSystem.hpp" |
294 | + |
295 | +#include <QDate> |
296 | +#include <QDebug> |
297 | +#include <QDir> |
298 | +#include <QFile> |
299 | +#include <QSettings> |
300 | +#include <QString> |
301 | + |
302 | +#include <cmath> |
303 | +#include <stdexcept> |
304 | + |
305 | + |
306 | +StelModule* SolarSystemEditorStelPluginInterface::getStelModule() const |
307 | +{ |
308 | + return new SolarSystemEditor(); |
309 | +} |
310 | + |
311 | +StelPluginInfo SolarSystemEditorStelPluginInterface::getPluginInfo() const |
312 | +{ |
313 | + //Q_INIT_RESOURCE(solarSystemEditor); |
314 | + |
315 | + StelPluginInfo info; |
316 | + info.id = "SolarSystemEditor"; |
317 | + info.displayedName = "Solar System Editor"; |
318 | + info.authors = "Bogdan Marinov"; |
319 | + info.contact = "http://stellarium.org"; |
320 | + info.description = "An interface for adding asteroids and comets to Stellarium. It can download object lists from the Minor Planet Center's website and perform searches in its online database. Still a work in progress."; |
321 | + return info; |
322 | +} |
323 | + |
324 | +Q_EXPORT_PLUGIN2(SolarSystemEditor, SolarSystemEditorStelPluginInterface) |
325 | + |
326 | +SolarSystemEditor::SolarSystemEditor() |
327 | +{ |
328 | + setObjectName("SolarSystemEditor"); |
329 | + |
330 | + isInitialized = false; |
331 | + mainWindow = NULL; |
332 | + solarSystemConfigurationFile = NULL; |
333 | + solarSystemManager = GETSTELMODULE(SolarSystem); |
334 | + |
335 | + //I really hope that the file manager is instantiated before this |
336 | + defaultSolarSystemFilePath = QFileInfo(StelFileMgr::getInstallationDir() + "/data/ssystem.ini").absoluteFilePath(); |
337 | + customSolarSystemFilePath = QFileInfo(StelFileMgr::getUserDir() + "/data/ssystem.ini").absoluteFilePath(); |
338 | +} |
339 | + |
340 | +SolarSystemEditor::~SolarSystemEditor() |
341 | +{ |
342 | + if (solarSystemConfigurationFile != NULL) |
343 | + { |
344 | + delete solarSystemConfigurationFile; |
345 | + } |
346 | +} |
347 | + |
348 | +void SolarSystemEditor::init() |
349 | +{ |
350 | + //Get a list of the "default" Solar System objects' names: |
351 | + //TODO: Use it as validation for the loading of the plug-in |
352 | + if (QFile::exists(defaultSolarSystemFilePath)) |
353 | + { |
354 | + defaultSsoIdentifiers = listAllLoadedObjectsInFile(defaultSolarSystemFilePath); |
355 | + } |
356 | + else |
357 | + { |
358 | + //TODO: Better error message |
359 | + qDebug() << "Something is horribly wrong:" << StelFileMgr::getInstallationDir(); |
360 | + return; |
361 | + } |
362 | + |
363 | + try |
364 | + { |
365 | + //Make sure that a user ssystem.ini actually exists |
366 | + if (!cloneSolarSystemConfigurationFile()) |
367 | + return; |
368 | + |
369 | + mainWindow = new SolarSystemManagerWindow(); |
370 | + } |
371 | + catch (std::runtime_error &e) |
372 | + { |
373 | + qWarning() << "init() error: " << e.what(); |
374 | + return; |
375 | + } |
376 | + |
377 | + isInitialized = true; |
378 | +} |
379 | + |
380 | +void SolarSystemEditor::deinit() |
381 | +{ |
382 | + // |
383 | +} |
384 | + |
385 | +void SolarSystemEditor::update(double) //deltaTime |
386 | +{ |
387 | + // |
388 | +} |
389 | + |
390 | +void SolarSystemEditor::draw(StelCore*) //core |
391 | +{ |
392 | + // |
393 | +} |
394 | + |
395 | +double SolarSystemEditor::getCallOrder(StelModuleActionName) const// actionName |
396 | +{ |
397 | + return 0.; |
398 | +} |
399 | + |
400 | +bool SolarSystemEditor::configureGui(bool show) |
401 | +{ |
402 | + //If the plug-in has failed to initialize, disable the button |
403 | + //TODO: Display a message in the window instead. |
404 | + if (!isInitialized) |
405 | + return false; |
406 | + |
407 | + if(show) |
408 | + { |
409 | + mainWindow->setVisible(true); |
410 | + |
411 | + //Debugging block |
412 | + //if (cloneSolarSystemConfigurationFile()) |
413 | + { |
414 | + //Import Encke for a start |
415 | + /*SsoElements SSO = readMpcOneLineCometElements("0002P 2010 08 6.5102 0.336152 0.848265 186.5242 334.5718 11.7843 20100104 11.5 6.0 2P/Encke MPC 59600"); |
416 | + if (!appendToSolarSystemConfigurationFile(SSO)) |
417 | + return true; |
418 | + */ |
419 | + |
420 | + //Import a list of comets on the desktop. The file is from |
421 | + //http://www.minorplanetcenter.org/iau/Ephemerides/Comets/Soft00Cmt.txt |
422 | + //It seems that some entries in the list don't match the described format |
423 | + /*QList<SsoElements> objectList = readMpcOneLineCometElementsFromFile(StelFileMgr::getDesktopDir() + "/Soft00Cmt.txt"); |
424 | + if (!appendToSolarSystemConfigurationFile(objectList)) |
425 | + return true; |
426 | + */ |
427 | + |
428 | + //Import Cruithne |
429 | + /*SsoElements asteroid = readMpcOneLineMinorPlanetElements("03753 15.6 0.15 K107N 205.95453 43.77037 126.27658 19.80793 0.5149179 0.98898552 0.9977217 3 MPO183459 488 28 1973-2010 0.58 M-h 3Eh MPC 0000 (3753) Cruithne 20100822"); |
430 | + if (!appendToSolarSystemConfigurationFile(asteroid)) |
431 | + return true; |
432 | + */ |
433 | + |
434 | + //Import a list of asteroids. The file is from |
435 | + //http://www.minorplanetcenter.org/iau/Ephemerides/Bright/2010/Soft00Bright.txt |
436 | + /*QList<SsoElements> objectList = readMpcOneLineMinorPlanetElementsFromFile(StelFileMgr::getDesktopDir() + "/Soft00Bright.txt"); |
437 | + if (!appendToSolarSystemConfigurationFile(objectList)) |
438 | + return true;*/ |
439 | + |
440 | + //Destroy and re-create the Solal System |
441 | + //solarSystemManager->reloadPlanets(); |
442 | + } |
443 | + } |
444 | + return true; |
445 | +} |
446 | + |
447 | +void SolarSystemEditor::updateI18n() |
448 | +{ |
449 | + //The Solar System MUST be translated before updating the window |
450 | + //TODO: Remove this if/when you merge this module in the Solar System module |
451 | + solarSystemManager->updateI18n(); |
452 | + |
453 | + if (mainWindow) |
454 | + { |
455 | + mainWindow->languageChanged(); |
456 | + } |
457 | +} |
458 | + |
459 | +bool SolarSystemEditor::cloneSolarSystemConfigurationFile() |
460 | +{ |
461 | + QDir userDataDirectory(StelFileMgr::getUserDir()); |
462 | + if (!userDataDirectory.exists()) |
463 | + { |
464 | + qDebug() << "Unable to find user data directory:" << userDataDirectory.absolutePath(); |
465 | + return false; |
466 | + } |
467 | + if (!userDataDirectory.exists("data") && !userDataDirectory.mkdir("data")) |
468 | + { |
469 | + qDebug() << "Unable to create a \"data\" subdirectory in" << userDataDirectory.absolutePath(); |
470 | + return false; |
471 | + } |
472 | + |
473 | + if (QFile::exists(customSolarSystemFilePath)) |
474 | + { |
475 | + qDebug() << "Using the ssystem.ini file that already exists in the user directory..."; |
476 | + return true; |
477 | + } |
478 | + |
479 | + if (QFile::exists(defaultSolarSystemFilePath)) |
480 | + { |
481 | + qDebug() << "Trying to copy ssystem.ini to" << customSolarSystemFilePath; |
482 | + return QFile::copy(defaultSolarSystemFilePath, customSolarSystemFilePath); |
483 | + } |
484 | + else |
485 | + { |
486 | + qDebug() << "This should be impossible."; |
487 | + return false; |
488 | + } |
489 | +} |
490 | + |
491 | +bool SolarSystemEditor::resetSolarSystemConfigurationFile() |
492 | +{ |
493 | + if (QFile::exists(customSolarSystemFilePath)) |
494 | + { |
495 | + if (!QFile::remove((customSolarSystemFilePath))) |
496 | + { |
497 | + qWarning() << "Unable to delete" << customSolarSystemFilePath |
498 | + << endl << "Please remove the file manually."; |
499 | + return false; |
500 | + } |
501 | + } |
502 | + |
503 | + return cloneSolarSystemConfigurationFile(); |
504 | +} |
505 | + |
506 | +void SolarSystemEditor::resetSolarSystemToDefault() |
507 | +{ |
508 | + if (isInitialized) |
509 | + { |
510 | + if (resetSolarSystemConfigurationFile()) |
511 | + { |
512 | + //Deselect all currently selected objects |
513 | + StelObjectMgr * objectManager = GETSTELMODULE(StelObjectMgr); |
514 | + //TODO |
515 | + objectManager->unSelect(); |
516 | + |
517 | + solarSystemManager->reloadPlanets(); |
518 | + emit solarSystemChanged(); |
519 | + } |
520 | + } |
521 | +} |
522 | + |
523 | +bool SolarSystemEditor::copySolarSystemConfigurationFileTo(QString filePath) |
524 | +{ |
525 | + if (QFile::exists(customSolarSystemFilePath)) |
526 | + { |
527 | + QFileInfo targetFile(filePath); |
528 | + return QFile::copy(customSolarSystemFilePath, targetFile.absoluteFilePath()); |
529 | + } |
530 | + else |
531 | + { |
532 | + return false; |
533 | + } |
534 | +} |
535 | + |
536 | +bool SolarSystemEditor::replaceSolarSystemConfigurationFileWith(QString filePath) |
537 | +{ |
538 | + if (!QFile::exists(filePath)) |
539 | + { |
540 | + //TODO: Message |
541 | + return false; |
542 | + } |
543 | + |
544 | + //Is it a valid configuration file? |
545 | + QSettings settings(filePath, QSettings::IniFormat); |
546 | + if (settings.status() != QSettings::NoError) |
547 | + { |
548 | + qWarning() << filePath << "is not a valid configuration file."; |
549 | + return false; |
550 | + } |
551 | + |
552 | + //Remove the existingfile |
553 | + if (QFile::exists(customSolarSystemFilePath)) |
554 | + { |
555 | + if(!QFile::remove(customSolarSystemFilePath)) |
556 | + { |
557 | + //TODO: Message |
558 | + return false; |
559 | + } |
560 | + } |
561 | + |
562 | + //Copy the new file |
563 | + //If the copy fails, reset to the default configuration |
564 | + if (QFile::copy(filePath, customSolarSystemFilePath)) |
565 | + { |
566 | + solarSystemManager->reloadPlanets(); |
567 | + emit solarSystemChanged(); |
568 | + return true; |
569 | + } |
570 | + else |
571 | + { |
572 | + //TODO: Message |
573 | + if (cloneSolarSystemConfigurationFile()) |
574 | + { |
575 | + solarSystemManager->reloadPlanets(); |
576 | + emit solarSystemChanged(); |
577 | + return true; |
578 | + } |
579 | + else |
580 | + { |
581 | + //TODO: Message |
582 | + return false; |
583 | + } |
584 | + } |
585 | +} |
586 | + |
587 | +QHash<QString,QString> SolarSystemEditor::listAllLoadedObjectsInFile(QString filePath) |
588 | +{ |
589 | + if (!QFile::exists(filePath)) |
590 | + return QHash<QString,QString>(); |
591 | + |
592 | + QSettings solarSystem(filePath, QSettings::IniFormat); |
593 | + if (solarSystem.status() != QSettings::NoError) |
594 | + return QHash<QString,QString>(); |
595 | + |
596 | + QStringList groups = solarSystem.childGroups(); |
597 | + QStringList planetNames = solarSystemManager->getAllPlanetEnglishNames(); |
598 | + QHash<QString,QString> loadedObjects; |
599 | + foreach (QString group, groups) |
600 | + { |
601 | + QString name = solarSystem.value(group + "/name").toString(); |
602 | + if (planetNames.contains(name)) |
603 | + { |
604 | + loadedObjects.insert(name, group); |
605 | + } |
606 | + } |
607 | + return loadedObjects; |
608 | +} |
609 | + |
610 | +QHash<QString,QString> SolarSystemEditor::listAllLoadedSsoIdentifiers() |
611 | +{ |
612 | + if (QFile::exists(customSolarSystemFilePath)) |
613 | + { |
614 | + return listAllLoadedObjectsInFile(customSolarSystemFilePath); |
615 | + } |
616 | + else |
617 | + { |
618 | + //TODO: Error message |
619 | + return QHash<QString,QString>(); |
620 | + } |
621 | +} |
622 | + |
623 | +bool SolarSystemEditor::removeSsoWithName(QString name) |
624 | +{ |
625 | + if (name.isEmpty()) |
626 | + return false; |
627 | + |
628 | + //qDebug() << name; |
629 | + if (defaultSsoIdentifiers.keys().contains(name)) |
630 | + { |
631 | + qWarning() << "You can't delete the default Solar System objects for the moment."; |
632 | + return false; |
633 | + } |
634 | + |
635 | + //Make sure that the file exists |
636 | + if (!QFile::exists(customSolarSystemFilePath)) |
637 | + { |
638 | + qDebug() << "Can't remove" << name << "to ssystem.ini: Unable to find" << customSolarSystemFilePath; |
639 | + return false; |
640 | + } |
641 | + |
642 | + //Open the file |
643 | + QSettings settings(customSolarSystemFilePath, QSettings::IniFormat); |
644 | + if (settings.status() != QSettings::NoError) |
645 | + { |
646 | + qDebug() << "Error opening ssystem.ini:" << customSolarSystemFilePath; |
647 | + return false; |
648 | + } |
649 | + |
650 | + //Remove the section |
651 | + foreach (QString group, settings.childGroups()) |
652 | + { |
653 | + if (settings.value(group + "/name").toString() == name) |
654 | + { |
655 | + settings.remove(group); |
656 | + settings.sync(); |
657 | + break; |
658 | + } |
659 | + } |
660 | + |
661 | + //Deselect all currently selected objects |
662 | + //TODO: I bet that someone will complains, so: unselect only the removed one |
663 | + GETSTELMODULE(StelObjectMgr)->unSelect(); |
664 | + |
665 | + //Reload the Solar System |
666 | + solarSystemManager->reloadPlanets(); |
667 | + emit solarSystemChanged(); |
668 | + |
669 | + return true; |
670 | +} |
671 | + |
672 | +//TODO: Strings that have failed to be parsed. The usual source of discrepancies is |
673 | +//http://www.minorplanetcenter.org/iau/Ephemerides/Comets/Soft00Cmt.txt |
674 | +//It seems that some entries in the list don't match the described format. |
675 | +/* |
676 | + " CJ95O010 1997 03 31.4141 0.906507 0.994945 130.5321 282.6820 89.3193 20100723 -2.0 4.0 C/1995 O1 (Hale-Bopp) MPC 61436" -> minus sign, fixed |
677 | + " CK09K030 2011 01 9.266 3.90156 1.00000 251.413 0.032 146.680 8.5 4.0 C/2009 K3 (Beshore) MPC 66205" -> lower precision than the spec, fixed |
678 | + " CK10F040 2010 04 6.109 0.61383 1.00000 120.718 237.294 89.143 13.5 4.0 C/2010 F4 (Machholz) MPC 69906" -> lower precision than the spec, fixed |
679 | + " CK10M010 2012 02 7.840 2.29869 1.00000 265.318 82.150 78.373 9.0 4.0 C/2010 M1 (Gibbs) MPC 70817" -> lower precision than the spec, fixed |
680 | + " CK10R010 2011 11 28.457 6.66247 1.00000 96.009 345.949 157.437 6.0 4.0 C/2010 R1 (LINEAR) MPEC 2010-R99" -> lower precision than the spec, fixed |
681 | + "0128P b 2007 06 13.8064 3.062504 0.320891 210.3319 214.3583 4.3606 20100723 8.5 4.0 128P/Shoemaker-Holt MPC 51822" -> fragment, fixed |
682 | + "0141P d 2010 05 29.7106 0.757809 0.749215 149.3298 246.0849 12.8032 20100723 12.0 12.0 141P/Machholz MPC 59599" -> fragment, fixed |
683 | +*/ |
684 | +SsoElements SolarSystemEditor::readMpcOneLineCometElements(QString oneLineElements) |
685 | +{ |
686 | + SsoElements result; |
687 | + |
688 | + QRegExp mpcParser("^\\s*(\\d{4})?([A-Z])((?:\\w{6}|\\s{6})?[0a-zA-Z])?\\s+(\\d{4})\\s+(\\d{2})\\s+(\\d{1,2}\\.\\d{3,4})\\s+(\\d{1,2}\\.\\d{5,6})\\s+(\\d\\.\\d{5,6})\\s+(\\d{1,3}\\.\\d{3,4})\\s+(\\d{1,3}\\.\\d{3,4})\\s+(\\d{1,3}\\.\\d{3,4})\\s+(?:(\\d{4})(\\d\\d)(\\d\\d))?\\s+(\\-?\\d{1,2}\\.\\d)\\s+(\\d{1,2}\\.\\d)\\s+(\\S.{1,54}\\S)(?:\\s+(\\S.*))?$");// |
689 | + |
690 | + int match = mpcParser.indexIn(oneLineElements); |
691 | + //qDebug() << "RegExp captured:" << match << mpcParser.capturedTexts(); |
692 | + |
693 | + if (match < 0) |
694 | + { |
695 | + qWarning() << "No match for" << oneLineElements; |
696 | + return result; |
697 | + } |
698 | + |
699 | + QString numberString = mpcParser.cap(1).trimmed(); |
700 | + //QChar cometType = mpcParser.cap(2).at(0); |
701 | + QString provisionalDesignation = mpcParser.cap(3).trimmed(); |
702 | + |
703 | + if (numberString.isEmpty() && provisionalDesignation.isEmpty()) |
704 | + { |
705 | + qWarning() << "Comet is missing both comet number AND provisional designation."; |
706 | + return result; |
707 | + } |
708 | + |
709 | + QString name = mpcParser.cap(17).trimmed(); |
710 | + |
711 | + //Fragment suffix |
712 | + if (provisionalDesignation.length() == 1) |
713 | + { |
714 | + QChar fragmentIndex = provisionalDesignation.at(0); |
715 | + name.append(' '); |
716 | + name.append(fragmentIndex.toUpper()); |
717 | + } |
718 | + |
719 | + if (name.isEmpty()) |
720 | + { |
721 | + return SsoElements(); |
722 | + } |
723 | + result.insert("name", name); |
724 | + |
725 | + QString sectionName = convertToGroupName(name); |
726 | + if (sectionName.isEmpty()) |
727 | + { |
728 | + return SsoElements(); |
729 | + } |
730 | + result.insert("section_name", sectionName); |
731 | + |
732 | + //After a name has been determined, insert the essential keys |
733 | + result.insert("parent", "Sun"); |
734 | + result.insert("type", "comet"); |
735 | + //"comet_orbit" is used for all cases: |
736 | + //"ell_orbit" interprets distances as kilometers, not AUs |
737 | + result.insert("coord_func","comet_orbit"); |
738 | + |
739 | + result.insert("lighting", false); |
740 | + result.insert("color", "1.0, 1.0, 1.0"); |
741 | + result.insert("tex_map", "nomap.png"); |
742 | + |
743 | + bool ok = false; |
744 | + //TODO: Use this for VALIDATION! |
745 | + |
746 | + int year = mpcParser.cap(4).toInt(); |
747 | + int month = mpcParser.cap(5).toInt(); |
748 | + double dayFraction = mpcParser.cap(6).toDouble(&ok); |
749 | + int day = (int) dayFraction; |
750 | + QDate datePerihelionPassage(year, month, day); |
751 | + int fraction = (int) ((dayFraction - day) * 24 * 60 * 60); |
752 | + int seconds = fraction % 60; fraction /= 60; |
753 | + int minutes = fraction % 60; fraction /= 60; |
754 | + int hours = fraction % 24; |
755 | + //qDebug() << hours << minutes << seconds << fraction; |
756 | + QTime timePerihelionPassage(hours, minutes, seconds, 0); |
757 | + QDateTime dtPerihelionPassage(datePerihelionPassage, timePerihelionPassage, Qt::UTC); |
758 | + double jdPerihelionPassage = StelUtils::qDateTimeToJd(dtPerihelionPassage); |
759 | + result.insert("orbit_TimeAtPericenter", jdPerihelionPassage); |
760 | + |
761 | + double perihelionDistance = mpcParser.cap(7).toDouble(&ok);//AU |
762 | + result.insert("orbit_PericenterDistance", perihelionDistance); |
763 | + |
764 | + double eccentricity = mpcParser.cap(8).toDouble(&ok);//degrees |
765 | + result.insert("orbit_Eccentricity", eccentricity); |
766 | + |
767 | + double argumentOfPerihelion = mpcParser.cap(9).toDouble(&ok);//J2000.0, degrees |
768 | + result.insert("orbit_ArgOfPericenter", argumentOfPerihelion); |
769 | + |
770 | + double longitudeOfTheAscendingNode = mpcParser.cap(10).toDouble(&ok);//J2000.0, degrees |
771 | + result.insert("orbit_AscendingNode", longitudeOfTheAscendingNode); |
772 | + |
773 | + double inclination = mpcParser.cap(11).toDouble(&ok); |
774 | + result.insert("orbit_Inclination", inclination); |
775 | + |
776 | + double absoluteMagnitude = mpcParser.cap(15).toDouble(&ok); |
777 | + result.insert("absolute_magnitude", absoluteMagnitude); |
778 | + |
779 | + //This is not the same "slope parameter" as used in asteroids. Better name? |
780 | + double slopeParameter = mpcParser.cap(16).toDouble(&ok); |
781 | + result.insert("slope_parameter", slopeParameter); |
782 | + |
783 | + double radius = 5; //Fictitious |
784 | + result.insert("radius", radius); |
785 | + result.insert("albedo", 1); |
786 | + |
787 | + return result; |
788 | +} |
789 | + |
790 | +SsoElements SolarSystemEditor::readMpcOneLineMinorPlanetElements(QString oneLineElements) |
791 | +{ |
792 | + SsoElements result; |
793 | + |
794 | + //This time I'll try splitting the line to columns, instead of |
795 | + //using a regular expression. |
796 | + //Using QString::mid() allows parsing it in a random sequence. |
797 | + |
798 | + //Length validation |
799 | + if (oneLineElements.isEmpty() || |
800 | + oneLineElements.length() > 202 || |
801 | + oneLineElements.length() < 152) //The column ends at 160, but is left-aligned |
802 | + { |
803 | + return result; |
804 | + } |
805 | + |
806 | + QString column; |
807 | + bool ok = false; |
808 | + //bool isLongForm = (oneLineElements.length() > 160) ? true : false; |
809 | + |
810 | + //Minor planet number or provisional designation |
811 | + column = oneLineElements.mid(0, 7).trimmed(); |
812 | + if (column.isEmpty()) |
813 | + { |
814 | + return result; |
815 | + } |
816 | + int minorPlanetNumber = 0; |
817 | + QString provisionalDesignation; |
818 | + QString name; |
819 | + if (column.toInt(&ok) || ok) |
820 | + { |
821 | + minorPlanetNumber = column.toInt(); |
822 | + } |
823 | + else |
824 | + { |
825 | + //See if it is a number, but packed |
826 | + //I hope the format is right (I've seen prefixes only between A and P) |
827 | + QRegExp packedMinorPlanetNumber("^([A-Za-z])(\\d+)$"); |
828 | + if (packedMinorPlanetNumber.indexIn(column) == 0) |
829 | + { |
830 | + minorPlanetNumber = packedMinorPlanetNumber.cap(2).toInt(&ok); |
831 | + //TODO: Validation |
832 | + QChar prefix = packedMinorPlanetNumber.cap(1).at(0); |
833 | + if (prefix.isUpper()) |
834 | + { |
835 | + minorPlanetNumber += ((10 + prefix.toAscii() - 'A') * 10000); |
836 | + } |
837 | + else |
838 | + { |
839 | + minorPlanetNumber += ((10 + prefix.toAscii() - 'a' + 26) * 10000); |
840 | + } |
841 | + } |
842 | + else |
843 | + { |
844 | + provisionalDesignation = unpackMinorPlanetProvisionalDesignation(column); |
845 | + } |
846 | + } |
847 | + |
848 | + if (minorPlanetNumber) |
849 | + { |
850 | + name = QString::number(minorPlanetNumber); |
851 | + } |
852 | + else if(provisionalDesignation.isEmpty()) |
853 | + { |
854 | + qDebug() << "readMpcOneLineMinorPlanetElements():" |
855 | + << column |
856 | + << "is not a valid number or packed provisional designation"; |
857 | + return SsoElements(); |
858 | + } |
859 | + else |
860 | + { |
861 | + name = provisionalDesignation; |
862 | + } |
863 | + |
864 | + //In case the longer format is used, extract the human-readable name |
865 | + column = oneLineElements.mid(166, 28).trimmed(); |
866 | + if (!column.isEmpty()) |
867 | + { |
868 | + if (minorPlanetNumber) |
869 | + { |
870 | + QRegExp asteroidName("^\\((\\d+)\\)\\s+(\\S.+)$"); |
871 | + if (asteroidName.indexIn(column) == 0) |
872 | + { |
873 | + name = asteroidName.cap(2); |
874 | + result.insert("minor_planet_number", minorPlanetNumber); |
875 | + } |
876 | + else |
877 | + { |
878 | + //Use the whole string, just in case |
879 | + name = column; |
880 | + } |
881 | + } |
882 | + //In the other case, the name is already the provisional designation |
883 | + } |
884 | + if (name.isEmpty()) |
885 | + { |
886 | + return SsoElements(); |
887 | + } |
888 | + result.insert("name", name); |
889 | + |
890 | + //Section name |
891 | + QString sectionName = convertToGroupName(name, minorPlanetNumber); |
892 | + if (sectionName.isEmpty()) |
893 | + { |
894 | + return SsoElements(); |
895 | + } |
896 | + result.insert("section_name", sectionName); |
897 | + |
898 | + //After a name has been determined, insert the essential keys |
899 | + result.insert("parent", "Sun"); |
900 | + result.insert("type", "asteroid"); |
901 | + //"comet_orbit" is used for all cases: |
902 | + //"ell_orbit" interprets distances as kilometers, not AUs |
903 | + result.insert("coord_func","comet_orbit"); |
904 | + |
905 | + result.insert("lighting", false); |
906 | + result.insert("color", "1.0, 1.0, 1.0"); |
907 | + result.insert("tex_map", "nomap.png"); |
908 | + |
909 | + //Magnitude and slope parameter |
910 | + column = oneLineElements.mid(8,5).trimmed(); |
911 | + double absoluteMagnitude = column.toDouble(&ok); |
912 | + if (!ok) |
913 | + return SsoElements(); |
914 | + column = oneLineElements.mid(14,5).trimmed(); |
915 | + double slopeParameter = column.toDouble(&ok); |
916 | + if (!ok) |
917 | + return SsoElements(); |
918 | + result.insert("absolute_magnitude", absoluteMagnitude); |
919 | + result.insert("slope_parameter", slopeParameter); |
920 | + |
921 | + //Orbital parameters |
922 | + column = oneLineElements.mid(37, 9).trimmed(); |
923 | + double argumentOfPerihelion = column.toDouble(&ok);//J2000.0, degrees |
924 | + if (!ok) |
925 | + return SsoElements(); |
926 | + result.insert("orbit_ArgOfPericenter", argumentOfPerihelion); |
927 | + |
928 | + column = oneLineElements.mid(48, 9).trimmed(); |
929 | + double longitudeOfTheAscendingNode = column.toDouble(&ok);//J2000.0, degrees |
930 | + if (!ok) |
931 | + return SsoElements(); |
932 | + result.insert("orbit_AscendingNode", longitudeOfTheAscendingNode); |
933 | + |
934 | + column = oneLineElements.mid(59, 9).trimmed(); |
935 | + double inclination = column.toDouble(&ok);//J2000.0, degrees |
936 | + if (!ok) |
937 | + return SsoElements(); |
938 | + result.insert("orbit_Inclination", inclination); |
939 | + |
940 | + column = oneLineElements.mid(70, 9).trimmed(); |
941 | + double eccentricity = column.toDouble(&ok);//degrees |
942 | + if (!ok) |
943 | + return SsoElements(); |
944 | + result.insert("orbit_Eccentricity", eccentricity); |
945 | + |
946 | + column = oneLineElements.mid(80, 11).trimmed(); |
947 | + double meanDailyMotion = column.toDouble(&ok);//degrees per day |
948 | + if (!ok) |
949 | + return SsoElements(); |
950 | + result.insert("orbit_MeanMotion", meanDailyMotion); |
951 | + |
952 | + column = oneLineElements.mid(92, 11).trimmed(); |
953 | + double semiMajorAxis = column.toDouble(&ok); |
954 | + if (!ok) |
955 | + return SsoElements(); |
956 | + result.insert("orbit_SemiMajorAxis", semiMajorAxis); |
957 | + |
958 | + column = oneLineElements.mid(20, 5).trimmed();//Epoch, in packed form |
959 | + QRegExp packedDateFormat("^([IJK])(\\d\\d)([1-9A-C])([1-9A-V])$"); |
960 | + if (packedDateFormat.indexIn(column) != 0) |
961 | + { |
962 | + qDebug() << "readMpcOneLineMinorPlanetElements():" |
963 | + << column << "is not a date in packed format"; |
964 | + return SsoElements(); |
965 | + } |
966 | + int year = packedDateFormat.cap(2).toInt(); |
967 | + switch (packedDateFormat.cap(1).at(0).toAscii()) |
968 | + { |
969 | + case 'I': |
970 | + year += 1800; |
971 | + break; |
972 | + case 'J': |
973 | + year += 1900; |
974 | + break; |
975 | + case 'K': |
976 | + default: |
977 | + year += 2000; |
978 | + } |
979 | + int month = unpackDayOrMonthNumber(packedDateFormat.cap(3).at(0)); |
980 | + int day = unpackDayOrMonthNumber(packedDateFormat.cap(4).at(0)); |
981 | + //qDebug() << column << year << month << day; |
982 | + QDate epochDate(year, month, day); |
983 | + if (!epochDate.isValid()) |
984 | + { |
985 | + qDebug() << "readMpcOneLineMinorPlanetElements():" |
986 | + << column << "unpacks to" |
987 | + << QString("%1-%2-%3").arg(year).arg(month).arg(day) |
988 | + << "This is not a valid date for an Epoch."; |
989 | + return SsoElements(); |
990 | + } |
991 | + int epochJD = epochDate.toJulianDay(); |
992 | + result.insert("orbit_Epoch", epochJD); |
993 | + |
994 | + column = oneLineElements.mid(26, 9).trimmed(); |
995 | + double meanAnomalyAtEpoch = column.toDouble(&ok);//degrees |
996 | + if (!ok) |
997 | + return SsoElements(); |
998 | + result.insert("orbit_MeanAnomaly", meanAnomalyAtEpoch); |
999 | + |
1000 | + //Radius and albedo |
1001 | + //Assume albedo of 0.15 and calculate a radius based on the absolute magnitude |
1002 | + //as described here: http://www.physics.sfasu.edu/astro/asteroids/sizemagnitude.html |
1003 | + double albedo = 0.15; //Assumed |
1004 | + double radius = std::ceil((1329 / std::sqrt(albedo)) * std::pow(10, -0.2 * absoluteMagnitude)); |
1005 | + result.insert("albedo", albedo); |
1006 | + result.insert("radius", radius); |
1007 | + |
1008 | + return result; |
1009 | +} |
1010 | + |
1011 | +SsoElements SolarSystemEditor::readXEphemOneLineElements(QString oneLineElements) |
1012 | +{ |
1013 | + SsoElements result; |
1014 | + |
1015 | + enum OrbitType {Elliptic, Hyperbolic, Parabolic} orbitType; |
1016 | + |
1017 | + QStringList fields = oneLineElements.split(','); |
1018 | + if (fields.isEmpty() || fields.count() < 10 || fields.count() > 14) |
1019 | + return result; |
1020 | + //qDebug() << fields; |
1021 | + |
1022 | + QString name = fields.at(0).trimmed(); |
1023 | + if (name.isEmpty() || fields.at(1).isEmpty()) |
1024 | + return result; |
1025 | + |
1026 | + QChar orbitTypeFlag = fields.at(1).trimmed().at(0); |
1027 | + if (orbitTypeFlag == 'e') |
1028 | + orbitType = Elliptic; |
1029 | + else if(orbitTypeFlag == 'h') |
1030 | + orbitType = Hyperbolic; |
1031 | + else if (orbitTypeFlag == 'p') |
1032 | + orbitType = Parabolic; |
1033 | + else |
1034 | + { |
1035 | + qDebug() << "Unrecognised orbit type:" << orbitTypeFlag; |
1036 | + return result; |
1037 | + } |
1038 | + |
1039 | + //"comet_orbit" is used for all cases: |
1040 | + //"ell_orbit" interprets distances as kilometers, not AUs |
1041 | + result.insert("coord_func", "comet_orbit"); |
1042 | + |
1043 | + //Type detection and name parsing |
1044 | + QString objectType; |
1045 | + int minorPlanetNumber = 0; |
1046 | + QRegExp cometProvisionalDesignationStart("^[PCDX]/"); |
1047 | + QRegExp cometDesignationStart("^(\\d)+[PCDX]/"); |
1048 | + if (cometDesignationStart.indexIn(name) == 0 || |
1049 | + cometProvisionalDesignationStart.indexIn(name) == 0) |
1050 | + { |
1051 | + objectType = "comet"; |
1052 | + } |
1053 | + else |
1054 | + { |
1055 | + objectType = "asteroid"; |
1056 | + QRegExp asteroidProvisionalDesignation("(\\d{4}\\s[A-Z]{2})(\\d*)$"); |
1057 | + int pdIndex = asteroidProvisionalDesignation.indexIn(name); |
1058 | + if (pdIndex != 0) |
1059 | + { |
1060 | + int spaceIndex = name.indexOf(' '); |
1061 | + if (spaceIndex > 0) |
1062 | + { |
1063 | + QString numberString = name.left(spaceIndex); |
1064 | + //qDebug() << numberString; |
1065 | + minorPlanetNumber = numberString.toInt(); |
1066 | + if (minorPlanetNumber) |
1067 | + name = name.right(name.length() - spaceIndex - 1); |
1068 | + //qDebug() << name; |
1069 | + } |
1070 | + } |
1071 | + } |
1072 | + if (name.isEmpty()) |
1073 | + { |
1074 | + return SsoElements(); |
1075 | + } |
1076 | + result.insert("name", name); |
1077 | + result.insert("type", objectType); |
1078 | + if (minorPlanetNumber) |
1079 | + result.insert("minor_planet_number", minorPlanetNumber); |
1080 | + |
1081 | + //Section name |
1082 | + QString sectionName = convertToGroupName(name, minorPlanetNumber); |
1083 | + if (sectionName.isEmpty()) |
1084 | + { |
1085 | + return SsoElements(); |
1086 | + } |
1087 | + result.insert("section_name", sectionName); |
1088 | + |
1089 | + //After a name has been determined, insert the essential keys |
1090 | + result.insert("parent", "Sun"); |
1091 | + |
1092 | + result.insert("lighting", false); |
1093 | + result.insert("color", "1.0, 1.0, 1.0"); |
1094 | + result.insert("tex_map", "nomap.png"); |
1095 | + |
1096 | + //Orbital elements |
1097 | + bool ok; |
1098 | + QString field; |
1099 | + |
1100 | + if (orbitType == Elliptic) |
1101 | + field = fields.at(2);//Field 3 |
1102 | + else |
1103 | + field = fields.at(3);//Field 4 |
1104 | + double inclination = field.trimmed().toDouble(&ok); |
1105 | + if (!ok) |
1106 | + return SsoElements(); |
1107 | + result.insert("orbit_Inclination", inclination); |
1108 | + |
1109 | + if (orbitType == Elliptic) |
1110 | + field = fields.at(3);//Field 4 |
1111 | + else if (orbitType == Hyperbolic) |
1112 | + field = fields.at(4);//Field 5 |
1113 | + else |
1114 | + field = fields.at(6);//Field 7 |
1115 | + double longitudeOfTheAscendingNode = field.toDouble(&ok);//J2000.0, degrees |
1116 | + if (!ok) |
1117 | + return SsoElements(); |
1118 | + result.insert("orbit_AscendingNode", longitudeOfTheAscendingNode); |
1119 | + |
1120 | + if (orbitType == Hyperbolic) |
1121 | + field = fields.at(5);//Field 6 |
1122 | + else |
1123 | + field = fields.at(4);//Field 5 |
1124 | + double argumentOfPerihelion = field.toDouble(&ok);//J2000.0, degrees |
1125 | + if (!ok) |
1126 | + return SsoElements(); |
1127 | + result.insert("orbit_ArgOfPericenter", argumentOfPerihelion); |
1128 | + |
1129 | + if (orbitType == Elliptic) |
1130 | + { |
1131 | + field = fields.at(5);//Field 6 |
1132 | + double semiMajorAxis = field.toDouble(&ok); |
1133 | + if (!ok) |
1134 | + return SsoElements(); |
1135 | + result.insert("orbit_SemiMajorAxis", semiMajorAxis); |
1136 | + |
1137 | + field = fields.at(6);//Field 7 |
1138 | + double meanDailyMotion = field.toDouble(&ok);//degrees per day |
1139 | + if (!ok) |
1140 | + return SsoElements(); |
1141 | + result.insert("orbit_MeanMotion", meanDailyMotion); |
1142 | + } |
1143 | + |
1144 | + double eccentricity; |
1145 | + if (orbitType == Elliptic) |
1146 | + eccentricity = fields.at(7).toDouble(&ok);//Field 8 |
1147 | + else if (orbitType == Hyperbolic) |
1148 | + eccentricity = fields.at(6).toDouble(&ok);//Field 7 |
1149 | + else |
1150 | + { |
1151 | + //Parabolic orbit |
1152 | + eccentricity = 1.0; |
1153 | + ok = true; |
1154 | + } |
1155 | + if (!ok) |
1156 | + return SsoElements(); |
1157 | + result.insert("orbit_Eccentricity", eccentricity); |
1158 | + |
1159 | + if (orbitType == Elliptic) |
1160 | + { |
1161 | + double meanAnomalyAtEpoch = fields.at(8).toDouble(&ok);//degrees |
1162 | + if (!ok) |
1163 | + return SsoElements(); |
1164 | + result.insert("orbit_MeanAnomaly", meanAnomalyAtEpoch); |
1165 | + } |
1166 | + |
1167 | + if (orbitType == Elliptic) |
1168 | + field = fields.at(9);//Field 10 |
1169 | + else |
1170 | + field = fields.at(2);//Field 3 |
1171 | + QStringList dateStrings = field.trimmed().split('/'); |
1172 | + //TODO: Validation |
1173 | + int year = dateStrings.at(2).toInt(); |
1174 | + int month = dateStrings.at(0).toInt(); |
1175 | + double dayFraction = dateStrings.at(1).toDouble(&ok); |
1176 | + int day = (int) dayFraction; |
1177 | + QDate date(year, month, day); |
1178 | + int fraction = (int) ((dayFraction - day) * 24 * 60 * 60); |
1179 | + int seconds = fraction % 60; fraction /= 60; |
1180 | + int minutes = fraction % 60; fraction /= 60; |
1181 | + int hours = fraction % 24; |
1182 | + //qDebug() << hours << minutes << seconds << fraction; |
1183 | + QTime time(hours, minutes, seconds, 0); |
1184 | + QDateTime dt(date, time, Qt::UTC); |
1185 | + double jd = StelUtils::qDateTimeToJd(dt); |
1186 | + if (orbitType == Elliptic) |
1187 | + result.insert("orbit_Epoch", jd); |
1188 | + else |
1189 | + result.insert("orbit_TimeAtPericenter", jd); |
1190 | + |
1191 | + if (orbitType != Elliptic) |
1192 | + { |
1193 | + if (orbitType == Hyperbolic) |
1194 | + field = fields.at(7);//Field 8 |
1195 | + else |
1196 | + field = fields.at(5);//Field 6 |
1197 | + double perihelionDistance = field.toDouble(&ok);//AU |
1198 | + if (!ok) |
1199 | + return SsoElements(); |
1200 | + result.insert("orbit_PericenterDistance", perihelionDistance); |
1201 | + } |
1202 | + |
1203 | + //Magnitude |
1204 | + if (orbitType == Elliptic) |
1205 | + field = fields.at(11);//Field 12 |
1206 | + else if (orbitType == Hyperbolic) |
1207 | + field = fields.at(9);//Field 10 |
1208 | + else |
1209 | + field = fields.at(8);//Field 9 |
1210 | + QRegExp magnitudePrefix("^([Hg]\\s*)?(\\d.+)"); |
1211 | + if (magnitudePrefix.indexIn(field) != 0) |
1212 | + return SsoElements(); |
1213 | + field = magnitudePrefix.cap(2); |
1214 | + double absoluteMagnitude = field.toDouble(&ok); |
1215 | + if (!ok) |
1216 | + return SsoElements(); |
1217 | + result.insert("absolute_magnitude", absoluteMagnitude); |
1218 | + |
1219 | + if (orbitType == Elliptic) |
1220 | + field = fields.at(12);//Field 13 |
1221 | + else if (orbitType == Hyperbolic) |
1222 | + field = fields.at(10);//Field 11 |
1223 | + else |
1224 | + field = fields.at(9);//Field 10 |
1225 | + double slopeParameter = field.toDouble(&ok); |
1226 | + if (!ok) |
1227 | + return SsoElements(); |
1228 | + result.insert("slope_parameter", slopeParameter); |
1229 | + |
1230 | + //Radius and albedo |
1231 | + double albedo = 0.04; |
1232 | + double radius = 5.0; |
1233 | + if (objectType == "asteroid") |
1234 | + { |
1235 | + //Assume albedo of 0.15 and calculate a radius based on the absolute magnitude |
1236 | + //http://www.physics.sfasu.edu/astro/asteroids/sizemagnitude.html |
1237 | + albedo = 0.15; |
1238 | + radius = std::ceil((1329 / std::sqrt(albedo)) * std::pow(10, -0.2 * absoluteMagnitude)); |
1239 | + } |
1240 | + result.insert("albedo", albedo); |
1241 | + result.insert("radius", radius); |
1242 | + |
1243 | + return result; |
1244 | +} |
1245 | + |
1246 | +QList<SsoElements> SolarSystemEditor::readMpcOneLineCometElementsFromFile(QString filePath) |
1247 | +{ |
1248 | + QList<SsoElements> objectList; |
1249 | + |
1250 | + if (!QFile::exists(filePath)) |
1251 | + { |
1252 | + qDebug() << "Can't find" << filePath; |
1253 | + return objectList; |
1254 | + } |
1255 | + |
1256 | + QFile mpcElementsFile(filePath); |
1257 | + if (mpcElementsFile.open(QFile::ReadOnly | QFile::Text ))//| QFile::Unbuffered |
1258 | + { |
1259 | + int candidatesCount = 0; |
1260 | + int lineCount = 0; |
1261 | + |
1262 | + while(!mpcElementsFile.atEnd()) |
1263 | + { |
1264 | + QString oneLineElements = QString(mpcElementsFile.readLine(200)); |
1265 | + if(oneLineElements.endsWith('\n')) |
1266 | + { |
1267 | + oneLineElements.chop(1); |
1268 | + } |
1269 | + if (oneLineElements.isEmpty()) |
1270 | + { |
1271 | + qDebug() << "Empty line skipped."; |
1272 | + continue; |
1273 | + } |
1274 | + lineCount++; |
1275 | + |
1276 | + SsoElements ssObject = readMpcOneLineCometElements(oneLineElements); |
1277 | + if(!ssObject.isEmpty() && !ssObject.value("section_name").toString().isEmpty()) |
1278 | + { |
1279 | + objectList << ssObject; |
1280 | + candidatesCount++; |
1281 | + } |
1282 | + } |
1283 | + mpcElementsFile.close(); |
1284 | + qDebug() << "Done reading comet orbital elements." |
1285 | + << "Recognized" << candidatesCount << "candidate objects" |
1286 | + << "out of" << lineCount << "lines."; |
1287 | + |
1288 | + return objectList; |
1289 | + } |
1290 | + else |
1291 | + { |
1292 | + qDebug() << "Unable to open for reading" << filePath; |
1293 | + qDebug() << "File error:" << mpcElementsFile.errorString(); |
1294 | + return objectList; |
1295 | + } |
1296 | + |
1297 | + return objectList; |
1298 | +} |
1299 | + |
1300 | +QList<SsoElements> SolarSystemEditor::readMpcOneLineMinorPlanetElementsFromFile(QString filePath) |
1301 | +{ |
1302 | + QList<SsoElements> objectList; |
1303 | + |
1304 | + if (!QFile::exists(filePath)) |
1305 | + { |
1306 | + qDebug() << "Can't find" << filePath; |
1307 | + return objectList; |
1308 | + } |
1309 | + |
1310 | + QFile mpcElementsFile(filePath); |
1311 | + if (mpcElementsFile.open(QFile::ReadOnly | QFile::Text ))//| QFile::Unbuffered |
1312 | + { |
1313 | + int candidatesCount = 0; |
1314 | + int lineCount = 0; |
1315 | + |
1316 | + while(!mpcElementsFile.atEnd()) |
1317 | + { |
1318 | + QString oneLineElements = QString(mpcElementsFile.readLine(202 + 2));//Allow for end-of-line characters |
1319 | + if(oneLineElements.endsWith('\n')) |
1320 | + { |
1321 | + oneLineElements.chop(1); |
1322 | + } |
1323 | + if (oneLineElements.isEmpty()) |
1324 | + { |
1325 | + qDebug() << "Empty line skipped."; |
1326 | + continue; |
1327 | + } |
1328 | + lineCount++; |
1329 | + |
1330 | + SsoElements ssObject = readMpcOneLineMinorPlanetElements(oneLineElements); |
1331 | + if(!ssObject.isEmpty() && !ssObject.value("section_name").toString().isEmpty()) |
1332 | + { |
1333 | + objectList << ssObject; |
1334 | + candidatesCount++; |
1335 | + } |
1336 | + } |
1337 | + mpcElementsFile.close(); |
1338 | + qDebug() << "Done reading minor planet orbital elements." |
1339 | + << "Recognized" << candidatesCount << "candidate objects" |
1340 | + << "out of" << lineCount << "lines."; |
1341 | + |
1342 | + return objectList; |
1343 | + } |
1344 | + else |
1345 | + { |
1346 | + qDebug() << "Unable to open for reading" << filePath; |
1347 | + qDebug() << "File error:" << mpcElementsFile.errorString(); |
1348 | + return objectList; |
1349 | + } |
1350 | + |
1351 | + return objectList; |
1352 | +} |
1353 | + |
1354 | +QList<SsoElements> SolarSystemEditor::readXEphemOneLineElementsFromFile(QString filePath) |
1355 | +{ |
1356 | + QList<SsoElements> objectList; |
1357 | + |
1358 | + if (!QFile::exists(filePath)) |
1359 | + { |
1360 | + qDebug() << "Can't find" << filePath; |
1361 | + return objectList; |
1362 | + } |
1363 | + |
1364 | + QFile xEphemElementsFile(filePath); |
1365 | + if (xEphemElementsFile.open(QFile::ReadOnly | QFile::Text )) |
1366 | + { |
1367 | + int candidatesCount = 0; |
1368 | + int lineCount = 0; |
1369 | + |
1370 | + while(!xEphemElementsFile.atEnd()) |
1371 | + { |
1372 | + QString oneLineElements = QString(xEphemElementsFile.readLine()); |
1373 | + if(oneLineElements.endsWith('\n')) |
1374 | + { |
1375 | + oneLineElements.chop(1); |
1376 | + } |
1377 | + if (oneLineElements.isEmpty()) |
1378 | + { |
1379 | + qDebug() << "Empty line skipped."; |
1380 | + continue; |
1381 | + } |
1382 | + if (oneLineElements.startsWith('#')) |
1383 | + { |
1384 | + qDebug() << "Comment skipped."; |
1385 | + continue; |
1386 | + } |
1387 | + lineCount++; |
1388 | + |
1389 | + SsoElements ssObject = readXEphemOneLineElements(oneLineElements); |
1390 | + if(!ssObject.isEmpty() && !ssObject.value("section_name").toString().isEmpty()) |
1391 | + { |
1392 | + objectList << ssObject; |
1393 | + candidatesCount++; |
1394 | + } |
1395 | + } |
1396 | + xEphemElementsFile.close(); |
1397 | + qDebug() << "Done reading minor planet orbital elements." |
1398 | + << "Recognized" << candidatesCount << "candidate objects" |
1399 | + << "out of" << lineCount << "lines."; |
1400 | + |
1401 | + return objectList; |
1402 | + } |
1403 | + else |
1404 | + { |
1405 | + qDebug() << "Unable to open for reading" << filePath; |
1406 | + qDebug() << "File error:" << xEphemElementsFile.errorString(); |
1407 | + return objectList; |
1408 | + } |
1409 | + |
1410 | + return objectList; |
1411 | +} |
1412 | + |
1413 | +bool SolarSystemEditor::appendToSolarSystemConfigurationFile(QList<SsoElements> objectList) |
1414 | +{ |
1415 | + if (objectList.isEmpty()) |
1416 | + { |
1417 | + return false; |
1418 | + } |
1419 | + |
1420 | + //Check if the configuration file exists |
1421 | + if (!QFile::exists(customSolarSystemFilePath)) |
1422 | + { |
1423 | + qDebug() << "Can't append object data to ssystem.ini: Unable to find" << customSolarSystemFilePath; |
1424 | + return false; |
1425 | + } |
1426 | + |
1427 | + |
1428 | + QHash<QString,QString> loadedObjects = listAllLoadedSsoIdentifiers(); |
1429 | + |
1430 | + //Remove duplicates (identified by name, not by section name) |
1431 | + QSettings * solarSystemSettings = new QSettings(customSolarSystemFilePath, QSettings::IniFormat); |
1432 | + if (solarSystemSettings->status() != QSettings::NoError) |
1433 | + { |
1434 | + qDebug() << "Error opening ssystem.ini:" << customSolarSystemFilePath; |
1435 | + return false; |
1436 | + } |
1437 | + foreach (SsoElements object, objectList) |
1438 | + { |
1439 | + QString name = object.value("name").toString(); |
1440 | + if (name.isEmpty()) |
1441 | + continue; |
1442 | + |
1443 | + QString group = object.value("section_name").toString(); |
1444 | + if (group.isEmpty()) |
1445 | + continue; |
1446 | + |
1447 | + if (loadedObjects.contains(name)) |
1448 | + { |
1449 | + solarSystemSettings->remove(loadedObjects.value(name)); |
1450 | + loadedObjects.remove(name); |
1451 | + } |
1452 | + else if (solarSystemSettings->childGroups().contains(group)) |
1453 | + { |
1454 | + loadedObjects.remove(solarSystemSettings->value(group + "/name").toString()); |
1455 | + solarSystemSettings->remove(group); |
1456 | + } |
1457 | + } |
1458 | + solarSystemSettings->sync(); |
1459 | + delete solarSystemSettings; |
1460 | + solarSystemSettings = NULL; |
1461 | + |
1462 | + //Write to file |
1463 | + //TODO: The usual validation |
1464 | + qDebug() << "Appending to file..."; |
1465 | + QFile solarSystemConfigurationFile(customSolarSystemFilePath); |
1466 | + if(solarSystemConfigurationFile.open(QFile::WriteOnly | QFile::Append | QFile::Text)) |
1467 | + { |
1468 | + QTextStream output (&solarSystemConfigurationFile); |
1469 | + bool appendedAtLeastOne = false; |
1470 | + |
1471 | + foreach (SsoElements object, objectList) |
1472 | + { |
1473 | + if (!object.contains("section_name")) |
1474 | + continue; |
1475 | + |
1476 | + QString sectionName = object.value("section_name").toString(); |
1477 | + if (sectionName.isEmpty()) |
1478 | + continue; |
1479 | + object.remove("section_name"); |
1480 | + |
1481 | + QString name = object.value("name").toString(); |
1482 | + if (name.isEmpty()) |
1483 | + continue; |
1484 | + |
1485 | + output << endl << QString("[%1]").arg(sectionName) << endl; |
1486 | + foreach(QString key, object.keys()) |
1487 | + { |
1488 | + output << QString("%1 = %2").arg(key).arg(object.value(key).toString()) << endl; |
1489 | + } |
1490 | + output.flush(); |
1491 | + qDebug() << "Appended successfully" << sectionName; |
1492 | + appendedAtLeastOne = true; |
1493 | + } |
1494 | + |
1495 | + solarSystemConfigurationFile.close(); |
1496 | + return appendedAtLeastOne; |
1497 | + } |
1498 | + else |
1499 | + { |
1500 | + qDebug() << "Unable to open for writing" << customSolarSystemFilePath; |
1501 | + return false; |
1502 | + } |
1503 | +} |
1504 | + |
1505 | +bool SolarSystemEditor::appendToSolarSystemConfigurationFile(SsoElements object) |
1506 | +{ |
1507 | + if (!object.contains("section_name") || object.value("section_name").toString().isEmpty()) |
1508 | + { |
1509 | + qDebug() << "appendToSolarSystemConfigurationFile(): Invalid object:" << object; |
1510 | + return false; |
1511 | + } |
1512 | + |
1513 | + QList<SsoElements> list; |
1514 | + list << object; |
1515 | + return appendToSolarSystemConfigurationFile(list); |
1516 | +} |
1517 | + |
1518 | +bool SolarSystemEditor::updateSolarSystemConfigurationFile(QList<SsoElements> objectList, UpdateFlags flags) |
1519 | +{ |
1520 | + if (objectList.isEmpty()) |
1521 | + { |
1522 | + //Empty lists can be added without any problem. :) |
1523 | + qWarning() << "updateSolarSystemConfigurationFile(): The source list is empty."; |
1524 | + return true; |
1525 | + } |
1526 | + |
1527 | + //Check if the configuration file exists |
1528 | + if (!QFile::exists(customSolarSystemFilePath)) |
1529 | + { |
1530 | + qDebug() << "Can't update ssystem.ini: Unable to find" << customSolarSystemFilePath; |
1531 | + return false; |
1532 | + } |
1533 | + |
1534 | + QSettings solarSystem(customSolarSystemFilePath, QSettings::IniFormat); |
1535 | + if (solarSystem.status() != QSettings::NoError) |
1536 | + { |
1537 | + qDebug() << "Error opening ssystem.ini:" << customSolarSystemFilePath; |
1538 | + return false; |
1539 | + } |
1540 | + QStringList existingSections = solarSystem.childGroups(); |
1541 | + QHash<QString,QString> loadedObjects = listAllLoadedSsoIdentifiers(); |
1542 | + //TODO: Move to contstructor? |
1543 | + QStringList orbitalElementsKeys; |
1544 | + orbitalElementsKeys << "coord_func" |
1545 | + << "orbit_ArgOfPericenter" |
1546 | + << "orbit_AscendingNode" |
1547 | + << "orbit_Eccentricity" |
1548 | + << "orbit_Epoch" |
1549 | + << "orbit_Inclination" |
1550 | + << "orbit_LongOfPericenter" |
1551 | + << "orbit_MeanAnomaly" |
1552 | + << "orbit_MeanLongitude" |
1553 | + << "orbit_MeanMotion" |
1554 | + << "orbit_PericenterDistance" |
1555 | + << "orbit_Period" |
1556 | + << "orbit_SemiMajorAxis" |
1557 | + << "orbit_TimeAtPericenter"; |
1558 | + |
1559 | + qDebug() << "Updating objects..."; |
1560 | + foreach (SsoElements object, objectList) |
1561 | + { |
1562 | + QString name = object.value("name").toString(); |
1563 | + if (name.isEmpty()) |
1564 | + continue; |
1565 | + |
1566 | + QString sectionName = object.value("section_name").toString(); |
1567 | + if (sectionName.isEmpty()) |
1568 | + continue; |
1569 | + object.remove("section_name"); |
1570 | + |
1571 | + if (loadedObjects.contains(name)) |
1572 | + { |
1573 | + if (sectionName != loadedObjects.value(name)) |
1574 | + { |
1575 | + //Is this a name conflict between an asteroid and a moon? |
1576 | + QString currentParent = solarSystem.value(loadedObjects.value(name) + "/parent").toString(); |
1577 | + QString newParent = object.value("parent").toString(); |
1578 | + if (newParent != currentParent) |
1579 | + { |
1580 | + name.append('*'); |
1581 | + object.insert("name", name); |
1582 | + |
1583 | + if (!existingSections.contains(sectionName)) |
1584 | + { |
1585 | + solarSystem.beginGroup(sectionName); |
1586 | + foreach (QString property, object.keys()) |
1587 | + { |
1588 | + solarSystem.setValue(property, object.value(property)); |
1589 | + } |
1590 | + solarSystem.endGroup(); |
1591 | + } |
1592 | + } |
1593 | + else |
1594 | + { |
1595 | + //If the parent is the same, update that object |
1596 | + sectionName = loadedObjects.value(name); |
1597 | + } |
1598 | + } |
1599 | + } |
1600 | + else |
1601 | + { |
1602 | + qDebug() << "Skipping update of" << sectionName << ", as no object with this name exists."; |
1603 | + continue; |
1604 | + } |
1605 | + |
1606 | + solarSystem.beginGroup(sectionName); |
1607 | + |
1608 | + if (flags.testFlag(UpdateNameAndNumber)) |
1609 | + { |
1610 | + updateSsoProperty(solarSystem, object, "name"); |
1611 | + updateSsoProperty(solarSystem, object, "minor_planet_number"); |
1612 | + } |
1613 | + |
1614 | + if (flags.testFlag(UpdateType)) |
1615 | + { |
1616 | + updateSsoProperty(solarSystem, object, "type"); |
1617 | + } |
1618 | + |
1619 | + if (flags.testFlag(UpdateOrbitalElements)) |
1620 | + { |
1621 | + //Remove all orbital elements first, in case |
1622 | + //the new ones use another coordinate function |
1623 | + foreach (QString key, orbitalElementsKeys) |
1624 | + { |
1625 | + solarSystem.remove(key); |
1626 | + } |
1627 | + |
1628 | + foreach (QString key, orbitalElementsKeys) |
1629 | + { |
1630 | + updateSsoProperty(solarSystem, object, key); |
1631 | + } |
1632 | + } |
1633 | + |
1634 | + if (flags.testFlag(UpdateMagnitudeParameters)) |
1635 | + { |
1636 | + if (object.contains("absolute_magnitude") && object.contains("slope_parameter")) |
1637 | + { |
1638 | + QString type = solarSystem.value("type").toString(); |
1639 | + if (type == "asteroid" || type == "comet" ) |
1640 | + { |
1641 | + updateSsoProperty(solarSystem, object, "absolute_magnitude"); |
1642 | + updateSsoProperty(solarSystem, object, "slope_parameter"); |
1643 | + } |
1644 | + else |
1645 | + { |
1646 | + //TODO: Do what, log a message? |
1647 | + } |
1648 | + } |
1649 | + } |
1650 | + |
1651 | + solarSystem.endGroup(); |
1652 | + qDebug() << "Updated successfully" << sectionName; |
1653 | + } |
1654 | + |
1655 | + return true; |
1656 | +} |
1657 | + |
1658 | +void SolarSystemEditor::updateSsoProperty(QSettings & settings, SsoElements & properties, QString key) |
1659 | +{ |
1660 | + if (properties.contains(key)) |
1661 | + { |
1662 | + settings.setValue(key, properties.value(key)); |
1663 | + } |
1664 | +} |
1665 | + |
1666 | +QString SolarSystemEditor::convertToGroupName(QString &name, int minorPlanetNumber) |
1667 | +{ |
1668 | + //TODO: Should I remove all non-alphanumeric, or only the obviously problematic? |
1669 | + QString groupName(name); |
1670 | + groupName.remove('\\'); |
1671 | + groupName.remove('/'); |
1672 | + groupName.remove('#'); |
1673 | + groupName.remove(' '); |
1674 | + groupName.remove('-'); |
1675 | + groupName = groupName.toLower(); |
1676 | + |
1677 | + //To prevent mix-up between asteroids and satellites: |
1678 | + //insert the minor planet number in the section name |
1679 | + //(if an asteroid is named, it must be numbered) |
1680 | + if (minorPlanetNumber) |
1681 | + { |
1682 | + groupName.prepend(QString::number(minorPlanetNumber)); |
1683 | + } |
1684 | + |
1685 | + return groupName; |
1686 | +} |
1687 | + |
1688 | +int SolarSystemEditor::unpackDayOrMonthNumber(QChar digit) |
1689 | +{ |
1690 | + //0-9, 0 is an invalid value, but the function is supposed to return 0 on failure. |
1691 | + if (digit.isDigit()) |
1692 | + { |
1693 | + return digit.digitValue(); |
1694 | + } |
1695 | + |
1696 | + if (digit.isUpper()) |
1697 | + { |
1698 | + char letter = digit.toAscii(); |
1699 | + if (letter < 'A' || letter > 'V') |
1700 | + return 0; |
1701 | + return (10 + (letter - 'A')); |
1702 | + } |
1703 | + else |
1704 | + { |
1705 | + return 0; |
1706 | + } |
1707 | +} |
1708 | + |
1709 | +int SolarSystemEditor::unpackYearNumber (QChar prefix, int lastTwoDigits) |
1710 | +{ |
1711 | + int year = lastTwoDigits; |
1712 | + if (prefix == 'I') |
1713 | + year += 1800; |
1714 | + else if (prefix == 'J') |
1715 | + year += 1900; |
1716 | + else if (prefix == 'K') |
1717 | + year += 2000; |
1718 | + else |
1719 | + year = 0; //Error |
1720 | + |
1721 | + return year; |
1722 | +} |
1723 | + |
1724 | +//Can be used both for minor planets and comets with no additional modification, |
1725 | +//as the regular expression for comets will match only capital letters. |
1726 | +int SolarSystemEditor::unpackAlphanumericNumber (QChar prefix, int lastDigit) |
1727 | +{ |
1728 | + int cycleCount = lastDigit; |
1729 | + if (prefix.isDigit()) |
1730 | + cycleCount += prefix.digitValue() * 10; |
1731 | + else if (prefix.isLetter() && prefix.isUpper()) |
1732 | + cycleCount += (10 + prefix.toAscii() - QChar('A').toAscii()) * 10; |
1733 | + else if (prefix.isLetter() && prefix.isLower()) |
1734 | + cycleCount += (10 + prefix.toAscii() - QChar('a').toAscii()) * 10 + 26*10; |
1735 | + else |
1736 | + cycleCount = 0; //Error |
1737 | + |
1738 | + return cycleCount; |
1739 | +} |
1740 | + |
1741 | +QString SolarSystemEditor::unpackMinorPlanetProvisionalDesignation (QString packedDesignation) |
1742 | +{ |
1743 | + QRegExp packedFormat("^([IJK])(\\d\\d)([A-Z])([\\dA-Za-z])(\\d)([A-Z])$"); |
1744 | + if (packedFormat.indexIn(packedDesignation) != 0) |
1745 | + { |
1746 | + QRegExp packedSurveyDesignation("^(PL|T1|T2|T3)S(\\d+)$"); |
1747 | + if (packedSurveyDesignation.indexIn(packedDesignation) == 0) |
1748 | + { |
1749 | + int number = packedSurveyDesignation.cap(2).toInt(); |
1750 | + if (packedSurveyDesignation.cap(1) == "PL") |
1751 | + { |
1752 | + return QString("%1 P-L").arg(number); |
1753 | + } |
1754 | + else if (packedSurveyDesignation.cap(1) == "T1") |
1755 | + { |
1756 | + return QString("%1 T-1").arg(number); |
1757 | + } |
1758 | + else if (packedSurveyDesignation.cap(1) == "T2") |
1759 | + { |
1760 | + return QString("%1 T-2").arg(number); |
1761 | + } |
1762 | + else |
1763 | + { |
1764 | + return QString("%1 T-3").arg(number); |
1765 | + } |
1766 | + //TODO: Are there any other surveys? |
1767 | + } |
1768 | + else |
1769 | + { |
1770 | + return QString(); |
1771 | + } |
1772 | + } |
1773 | + |
1774 | + //Year |
1775 | + QChar yearPrefix = packedFormat.cap(1).at(0); |
1776 | + int yearLastTwoDigits = packedFormat.cap(2).toInt(); |
1777 | + int year = unpackYearNumber(yearPrefix, yearLastTwoDigits); |
1778 | + |
1779 | + //Letters |
1780 | + QString halfMonthLetter = packedFormat.cap(3); |
1781 | + QString secondLetter = packedFormat.cap(6); |
1782 | + |
1783 | + //Second letter cycle count |
1784 | + QChar cycleCountPrefix = packedFormat.cap(4).at(0); |
1785 | + int cycleCountLastDigit = packedFormat.cap(5).toInt(); |
1786 | + int cycleCount = unpackAlphanumericNumber(cycleCountPrefix, cycleCountLastDigit); |
1787 | + |
1788 | + //Assemble the unpacked provisional designation |
1789 | + QString result = QString("%1 %2%3").arg(year).arg(halfMonthLetter).arg(secondLetter); |
1790 | + if (cycleCount != 0) |
1791 | + { |
1792 | + result.append(QString::number(cycleCount)); |
1793 | + } |
1794 | + |
1795 | + return result; |
1796 | +} |
1797 | |
1798 | === added file 'plugins/SolarSystemEditor/src/SolarSystemEditor.hpp' |
1799 | --- plugins/SolarSystemEditor/src/SolarSystemEditor.hpp 1970-01-01 00:00:00 +0000 |
1800 | +++ plugins/SolarSystemEditor/src/SolarSystemEditor.hpp 2010-11-16 20:00:15 +0000 |
1801 | @@ -0,0 +1,312 @@ |
1802 | +/* |
1803 | + * Solar System editor plug-in for Stellarium |
1804 | + * |
1805 | + * Copyright (C) 2010 Bogdan Marinov |
1806 | + * |
1807 | + * This program is free software; you can redistribute it and/or |
1808 | + * modify it under the terms of the GNU General Public License |
1809 | + * as published by the Free Software Foundation; either version 2 |
1810 | + * of the License, or (at your option) any later version. |
1811 | + * |
1812 | + * This program is distributed in the hope that it will be useful, |
1813 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1814 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1815 | + * GNU General Public License for more details. |
1816 | + * |
1817 | + * You should have received a copy of the GNU General Public License |
1818 | + * along with this program; if not, write to the Free Software |
1819 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
1820 | + */ |
1821 | + |
1822 | +#ifndef _SOLAR_SYSTEM_EDITOR_HPP_ |
1823 | +#define _SOLAR_SYSTEM_EDITOR_HPP_ |
1824 | + |
1825 | +#include "StelGui.hpp" |
1826 | +#include "StelModule.hpp" |
1827 | +//#include "CAIMainWindow.hpp" |
1828 | + |
1829 | +#include <QHash> |
1830 | +#include <QList> |
1831 | +#include <QString> |
1832 | +#include <QVariant> |
1833 | + |
1834 | +class SolarSystemManagerWindow; |
1835 | +class SolarSystem; |
1836 | +class QSettings; |
1837 | + |
1838 | +//! Convenience type for storage of SSO properties in ssystem.ini format. |
1839 | +//! This is an easy way of storing data in the format used in Stellarium's |
1840 | +//! solar system configuration file. |
1841 | +//! What would be key/value pairs in a section in the ssystem.ini file |
1842 | +//! are key/value pairs in the hash. The section name is stored with key |
1843 | +//! "section_name". |
1844 | +//! As it is a hash, key names are not stored alphabetically. This allows |
1845 | +//! for rapid addition and look-up of values, unlike a real QSettings |
1846 | +//! object in StelIniFormat. |
1847 | +//! Also, using this way may allow scripts to define SSOs. |
1848 | +//! \todo Better name. |
1849 | +typedef QHash<QString, QVariant> SsoElements; |
1850 | + |
1851 | +/*! |
1852 | + \class SolarSystemEditor |
1853 | + \brief Main class of the Solar System Editor plug-in. |
1854 | + \author Bogdan Marinov |
1855 | + |
1856 | + Solar System bodies are identified by their names in Stellarium, but entries |
1857 | + in the configuration file are identified by their group (section) names. |
1858 | + This makes more difficult the detection of duplicates. |
1859 | +*/ |
1860 | +class SolarSystemEditor : public StelModule |
1861 | +{ |
1862 | + Q_OBJECT |
1863 | + |
1864 | +public: |
1865 | + SolarSystemEditor(); |
1866 | + virtual ~SolarSystemEditor(); |
1867 | + |
1868 | + /////////////////////////////////////////////////////////////////////////// |
1869 | + // Methods inherited from the StelModule class |
1870 | + //! called when the plug-in is loaded. |
1871 | + //! All initializations should be done here. |
1872 | + virtual void init(); |
1873 | + //! called before the plug-in is un-loaded. |
1874 | + //! Useful for stopping processes, unloading textures, etc. |
1875 | + virtual void deinit(); |
1876 | + virtual void update(double deltaTime); |
1877 | + //! draws on the view port. |
1878 | + //! Dialog windows don't need explicit drawing, it's done automatically. |
1879 | + //! If a plug-in draws on the screen, it should be able to respect |
1880 | + //! the night vision mode. |
1881 | + virtual void draw(StelCore * core); |
1882 | + virtual double getCallOrder(StelModuleActionName actionName) const; |
1883 | + //! called when the "configure" button in the "Plugins" tab is pressed |
1884 | + virtual bool configureGui(bool show); |
1885 | + virtual void updateI18n(); |
1886 | + |
1887 | + //! Reads a single comet's orbital elements from a string. |
1888 | + //! This function converts a line of comet orbital elements in MPC format |
1889 | + //! to a hash in Stellarium's ssystem.ini format. |
1890 | + //! The MPC's one-line orbital elements format for comets |
1891 | + //! is described on their website: |
1892 | + //! http://www.minorplanetcenter.org/iau/info/CometOrbitFormat.html |
1893 | + //! \returns an empty hash if there is an error or the source string is not |
1894 | + //! a valid line in MPC format. |
1895 | + //! \todo Recognise the long form packed designations (to handle fragments) |
1896 | + //! \todo Handle better any unusual symbols in section names (URL encoding?) |
1897 | + //! \todo Use column cuts intead of a regular expression? |
1898 | + SsoElements readMpcOneLineCometElements(QString oneLineElements); |
1899 | + |
1900 | + //! Reads a single minor planet's orbital elements from a string. |
1901 | + //! This function converts a line of minor planet orbital elements in |
1902 | + //! MPC format to a hash in Stellarium's ssystem.ini format. |
1903 | + //! The MPC's one-line orbital elements format for minor planets |
1904 | + //! is described on their website: |
1905 | + //! http://www.minorplanetcenter.org/iau/info/MPOrbitFormat.html |
1906 | + //! \returns an empty hash if there is an error or the source string is not |
1907 | + //! a valid line in MPC format. |
1908 | + //! \todo Handle better any unusual symbols in section names (URL encoding?) |
1909 | + SsoElements readMpcOneLineMinorPlanetElements(QString oneLineElements); |
1910 | + |
1911 | + //! Reads a single object's orbital elements from a string. |
1912 | + //! This function converts a line of orbital elements in XEphem format |
1913 | + //! to a hash in Stellarium's ssystem.ini format. |
1914 | + //! http://www.clearskyinstitute.com/xephem/help/xephem.html#mozTocId468501 |
1915 | + //! It recognises only the 'e', 'h' and 'p' types of orbits in XEphem's |
1916 | + //! format (comets and minor planets). It is used in handling on-line search |
1917 | + //! queries to the MPC's Minor Planet and Comet Ephemeris System, as |
1918 | + //! using the MPC format causes long object names to be truncated |
1919 | + //! due to the fixed width of the columns. |
1920 | + //! An object's type (comet or asteroid) is determined based on its name. |
1921 | + SsoElements readXEphemOneLineElements(QString oneLineElements); |
1922 | + |
1923 | + //! Reads a list of comet orbital elements from a file. |
1924 | + //! This function reads a list of comet orbital elements in MPC's one-line |
1925 | + //! format from a file (one comet per line) and converts it to a list of |
1926 | + //! hashes in Stellarium's ssystem.ini format. |
1927 | + //! Example source file is the list of observable comets on the MPC's site: |
1928 | + //! http://www.minorplanetcenter.org/iau/Ephemerides/Comets/Soft00Cmt.txt |
1929 | + //! readMpcOneLineCometElements() is used internally to parse each line. |
1930 | + QList<SsoElements> readMpcOneLineCometElementsFromFile(QString filePath); |
1931 | + |
1932 | + //! Reads a list of minor planet orbital elements from a file. |
1933 | + //! This function reads a list of minor planets orbital elements in MPC's |
1934 | + //! one-line format from a file (one comet per line) and converts it to |
1935 | + //! a list of hashes in Stellarium's ssystem.ini format. |
1936 | + //! Example source file is the list of bright asteroids on the MPC's site: |
1937 | + //! http://www.minorplanetcenter.org/iau/Ephemerides/Bright/2010/Soft00Bright.txt |
1938 | + //! readMpcOneLineMinorPlanetElements() is used internally to parse each line. |
1939 | + QList<SsoElements> readMpcOneLineMinorPlanetElementsFromFile(QString filePath); |
1940 | + |
1941 | + //! Reads a list of Solar System object orbital elements from a file. |
1942 | + //! This function reads a list of Solar System object orbital elements in |
1943 | + //! XEphem's one-line format (one object per line, comment lines starting |
1944 | + //! with # are skipped) and converts it to a list of hashes in Stellarium's |
1945 | + //! ssystem.ini format. XEphem's file format is described in its manual: |
1946 | + //! http://www.clearskyinstitute.com/xephem/help/xephem.html#mozTocId468501 |
1947 | + //! Example source file can be any of the lists of objects on the MPC site: |
1948 | + //! http://www.minorplanetcenter.org/iau/Ephemerides/Comets/Soft03Cmt.txt |
1949 | + //! http://www.minorplanetcenter.org/iau/Ephemerides/Bright/2010/Soft03Bright.txt |
1950 | + //! readXEphemOneLineElements() is used internally to parse each line. |
1951 | + QList<SsoElements> readXEphemOneLineElementsFromFile(QString filePath); |
1952 | + |
1953 | + //! Adds a new entry at the end of the user solar system configuration file. |
1954 | + //! This function writes directly to the file. See the note on why QSettings |
1955 | + //! was not used in the description of |
1956 | + //! appendToSolarSystemConfigurationFile(QList<SsoElements>) |
1957 | + //! Duplicates are removed: If any section in the file matches the |
1958 | + //! "section_name" value of the inserted entry, it is removed. |
1959 | + bool appendToSolarSystemConfigurationFile(SsoElements object); |
1960 | + |
1961 | + //! Adds new entries at the end of the user solar system configuration file. |
1962 | + //! This function writes directly to the file. QSettings was not used, as: |
1963 | + //! - Using QSettings with QSettings::IniFormat causes the list in the |
1964 | + //! "color" field (e.g. "1.0, 1.0, 1.0") to be wrapped in double quotation |
1965 | + //! marks (Stellarium requires no quotation marks). |
1966 | + //! - Using QSettings with StelIniFormat causes unaccepptable append times |
1967 | + //! when the file grows (>~40 entries). This most probably happens because |
1968 | + //! StelIniParser uses QMap internally for the entry list. QMap orders its |
1969 | + //! keys (in the case of strings - alphabetically) and it has to find |
1970 | + //! the appropriate place in the ordering for every new key, which takes |
1971 | + //! more and more time as the list grows. |
1972 | + //! |
1973 | + //! Duplicates are removed: If any section in the file matches the |
1974 | + //! "section_name" value of a new entry, it is removed. |
1975 | + //! Invalid entries in the list (that don't contain a value for |
1976 | + //! "section_name" or it is an empty string) are skipped and the processing |
1977 | + //! continues from the next entry. |
1978 | + //! \todo Protect the default Solar System configuration? |
1979 | + //! \todo At least warn when overwriting old entries? |
1980 | + bool appendToSolarSystemConfigurationFile(QList<SsoElements>); |
1981 | + |
1982 | + //! Flags to control the updateSolarSystemConfigurationFile() function. |
1983 | + enum UpdateFlag { |
1984 | + UpdateNameAndNumber = 0x01,//!< Update the name and minor planet number, if any. |
1985 | + UpdateType = 0x02, //!< Update objects that lack the "type" parameter |
1986 | + UpdateOrbitalElements = 0x04, //!< Update the orbital elements, including the orbit function. |
1987 | + UpdateMagnitudeParameters = 0x08 //!< Update the values in the two parameter system, or add them if they are missing and the type allows. |
1988 | + }; |
1989 | + Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag) |
1990 | + |
1991 | + //! Updates entries in the user solar system configuration file. |
1992 | + //! \param objects a list of data for already existing objects (non-existing ones are skipped); |
1993 | + //! \param flags flags controlling what is being updated. See UpdateFlag. |
1994 | + //! \returns false if the operation has failed completely for some reason. |
1995 | + bool updateSolarSystemConfigurationFile(QList<SsoElements> objects, UpdateFlags flags); |
1996 | + |
1997 | + //! Returns the names of the objects listed in the default ssystem.ini. |
1998 | + //! The default solar system configuration file is assumed to be the one |
1999 | + //! in the installation directory. |
2000 | + QHash<QString,QString> getDefaultSsoIdentifiers() {return defaultSsoIdentifiers;} |
2001 | + |
2002 | + //! Lists the objects listed in the current user ssystem.ini. |
2003 | + //! As the name suggests, the list is compiled when the function is run. |
2004 | + QHash<QString,QString> listAllLoadedSsoIdentifiers(); |
2005 | + |
2006 | + //! Removes an object from the user Solar System configuration file. |
2007 | + //! Reloads the Solar System on successfull removal. |
2008 | + //! \arg name true name of the object ("name" parameter in the configuration file) |
2009 | + //! \returns true if the entry has been removed successfully or there is |
2010 | + //! no such entry |
2011 | + //! \returns false if there was an error |
2012 | + bool removeSsoWithName(QString name); |
2013 | + |
2014 | + //! |
2015 | + bool copySolarSystemConfigurationFileTo(QString filePath); |
2016 | + //! |
2017 | + bool replaceSolarSystemConfigurationFileWith(QString filePath); |
2018 | + |
2019 | + //! returns the path |
2020 | + QString getCustomSolarSystemFilePath() const {return customSolarSystemFilePath;} |
2021 | + |
2022 | +public slots: |
2023 | + //! Resets the Solar System configuration file and reloads the Solar System. |
2024 | + //! \todo Return a bool and make the GUI display a message if it was not successful. |
2025 | + void resetSolarSystemToDefault(); |
2026 | + |
2027 | +signals: |
2028 | + //TODO: This should be part of SolarSystem::reloadPlanets() |
2029 | + void solarSystemChanged(); |
2030 | + |
2031 | +private: |
2032 | + bool isInitialized; |
2033 | + |
2034 | + //! Main window of the module's GUI |
2035 | + SolarSystemManagerWindow * mainWindow; |
2036 | + |
2037 | + QSettings * solarSystemConfigurationFile; |
2038 | + SolarSystem * solarSystemManager; |
2039 | + |
2040 | + QString customSolarSystemFilePath; |
2041 | + QString defaultSolarSystemFilePath; |
2042 | + |
2043 | + //! A hash matching SSO names with the group names used to identify them |
2044 | + //! in the configuration file. |
2045 | + |
2046 | + //! The names and group names of all objects in the default ssystem.ini. |
2047 | + //! The keys are the names, the values are the group names. |
2048 | + //! Initialized in init(). |
2049 | + QHash<QString,QString> defaultSsoIdentifiers; |
2050 | + |
2051 | + //! Gets the names of the objects listed in a ssystem.ini-formatted file. |
2052 | + //! Used internally in readAllCurrentSsoNames() and in init() to initialize |
2053 | + //! defaultSsoNames. |
2054 | + //! Does not check if the file exists. |
2055 | + QHash<QString,QString> listAllLoadedObjectsInFile(QString filePath); |
2056 | + |
2057 | + //! Creates a copy of the default ssystem.ini file in the user data directory. |
2058 | + //! \returns true if a file already exists or the copying has been successful |
2059 | + bool cloneSolarSystemConfigurationFile(); |
2060 | + |
2061 | + //! Replaces the user copy of ssystem.ini with the default one. |
2062 | + //! This function simply deletes the file, if it exists, and calls |
2063 | + //! cloneSolarSystemConfigurationFile(). |
2064 | + //! \returns true if the replacement has been successfull. |
2065 | + bool resetSolarSystemConfigurationFile(); |
2066 | + |
2067 | + //! Converts an alphanumeric digit as used in MPC packed dates to an integer. |
2068 | + //! See http://www.minorplanetcenter.org/iau/info/PackedDates.html |
2069 | + //! Interprets the digits from 1 to 9 normally, and the capital leters |
2070 | + //! from A to V as numbers between 10 and 31. |
2071 | + //! \returns 0 if the digit is invalid (0 is also an invalid ordinal number |
2072 | + //! for a day or month, so this is not a problem) |
2073 | + int unpackDayOrMonthNumber (QChar digit); |
2074 | + //! Converts an alphanumeric year number as used in MPC packed dates to an integer. |
2075 | + //! See http://www.minorplanetcenter.org/iau/info/PackedDates.html |
2076 | + //! Also used in packed provisional designations, see |
2077 | + //! http://www.minorplanetcenter.org/iau/info/PackedDes.html |
2078 | + int unpackYearNumber (QChar prefix, int lastTwoDigits); |
2079 | + //! Converts a two-character number used in MPC packed provisional designations. |
2080 | + //! See http://www.minorplanetcenter.org/iau/info/PackedDes.html |
2081 | + //! This function is used for both asteroid and comet designations. |
2082 | + int unpackAlphanumericNumber (QChar prefix, int lastDigit); |
2083 | + |
2084 | + //TODO: This should be public and static, perhaps? |
2085 | + //! Unpacks an MPC packed minor planet provisional designation. |
2086 | + //! See http://www.minorplanetcenter.org/iau/info/PackedDes.html |
2087 | + //! \returns an empty string if the argument is not a valid packed |
2088 | + //! provisional designation. |
2089 | + QString unpackMinorPlanetProvisionalDesignation(QString packedDesignation); |
2090 | + |
2091 | + //! Updates a value in a configuration file with a value with the same key in a SsoElements hash. |
2092 | + void updateSsoProperty(QSettings& configuration, SsoElements& properties, QString key); |
2093 | + |
2094 | + //! Converts an object name to a key (group) name in a configuration file. |
2095 | + QString convertToGroupName(QString& name, int minorPlanetNumber = 0); |
2096 | +}; |
2097 | + |
2098 | + |
2099 | +#include "fixx11h.h" |
2100 | +#include <QObject> |
2101 | +#include "StelPluginInterface.hpp" |
2102 | + |
2103 | +//! This class is used by Qt to manage a plug-in interface |
2104 | +class SolarSystemEditorStelPluginInterface : public QObject, public StelPluginInterface |
2105 | +{ |
2106 | + Q_OBJECT |
2107 | + Q_INTERFACES(StelPluginInterface) |
2108 | +public: |
2109 | + virtual StelModule* getStelModule() const; |
2110 | + virtual StelPluginInfo getPluginInfo() const; |
2111 | +}; |
2112 | + |
2113 | +#endif //_SOLAR_SYSTEM_EDITOR_HPP_ |
2114 | |
2115 | === added directory 'plugins/SolarSystemEditor/src/gui' |
2116 | === added file 'plugins/SolarSystemEditor/src/gui/MPCImporterDialogPrototype02.ui' |
2117 | --- plugins/SolarSystemEditor/src/gui/MPCImporterDialogPrototype02.ui 1970-01-01 00:00:00 +0000 |
2118 | +++ plugins/SolarSystemEditor/src/gui/MPCImporterDialogPrototype02.ui 2010-11-16 20:00:15 +0000 |
2119 | @@ -0,0 +1,171 @@ |
2120 | +<?xml version="1.0" encoding="UTF-8"?> |
2121 | +<ui version="4.0"> |
2122 | + <author>Bogdan Marinov</author> |
2123 | + <class>Form</class> |
2124 | + <widget class="QWidget" name="Form"> |
2125 | + <property name="geometry"> |
2126 | + <rect> |
2127 | + <x>0</x> |
2128 | + <y>0</y> |
2129 | + <width>400</width> |
2130 | + <height>300</height> |
2131 | + </rect> |
2132 | + </property> |
2133 | + <layout class="QVBoxLayout" name="verticalLayout_5"> |
2134 | + <property name="spacing"> |
2135 | + <number>0</number> |
2136 | + </property> |
2137 | + <property name="margin"> |
2138 | + <number>0</number> |
2139 | + </property> |
2140 | + <item> |
2141 | + <widget class="QStackedWidget" name="stackedWidget"> |
2142 | + <property name="currentIndex"> |
2143 | + <number>0</number> |
2144 | + </property> |
2145 | + <widget class="QWidget" name="page"> |
2146 | + <layout class="QVBoxLayout" name="verticalLayout"> |
2147 | + <property name="spacing"> |
2148 | + <number>0</number> |
2149 | + </property> |
2150 | + <property name="margin"> |
2151 | + <number>0</number> |
2152 | + </property> |
2153 | + <item> |
2154 | + <widget class="QGroupBox" name="groupBox"> |
2155 | + <property name="title"> |
2156 | + <string>Select source</string> |
2157 | + </property> |
2158 | + <layout class="QVBoxLayout" name="verticalLayout_2"> |
2159 | + <item> |
2160 | + <widget class="QRadioButton" name="radioButton"> |
2161 | + <property name="text"> |
2162 | + <string>Import a single line (one body)</string> |
2163 | + </property> |
2164 | + </widget> |
2165 | + </item> |
2166 | + <item> |
2167 | + <layout class="QHBoxLayout" name="horizontalLayout"> |
2168 | + <item> |
2169 | + <widget class="QLineEdit" name="lineEdit"/> |
2170 | + </item> |
2171 | + <item> |
2172 | + <widget class="QPushButton" name="pushButton_3"> |
2173 | + <property name="text"> |
2174 | + <string>Paste</string> |
2175 | + </property> |
2176 | + </widget> |
2177 | + </item> |
2178 | + </layout> |
2179 | + </item> |
2180 | + <item> |
2181 | + <widget class="QRadioButton" name="radioButton_2"> |
2182 | + <property name="text"> |
2183 | + <string>Import bodies from a file</string> |
2184 | + </property> |
2185 | + </widget> |
2186 | + </item> |
2187 | + <item> |
2188 | + <layout class="QHBoxLayout" name="horizontalLayout_2"> |
2189 | + <item> |
2190 | + <widget class="QLineEdit" name="lineEdit_2"/> |
2191 | + </item> |
2192 | + <item> |
2193 | + <widget class="QPushButton" name="pushButton_4"> |
2194 | + <property name="text"> |
2195 | + <string>Browse</string> |
2196 | + </property> |
2197 | + </widget> |
2198 | + </item> |
2199 | + </layout> |
2200 | + </item> |
2201 | + <item> |
2202 | + <spacer name="verticalSpacer"> |
2203 | + <property name="orientation"> |
2204 | + <enum>Qt::Vertical</enum> |
2205 | + </property> |
2206 | + <property name="sizeHint" stdset="0"> |
2207 | + <size> |
2208 | + <width>20</width> |
2209 | + <height>40</height> |
2210 | + </size> |
2211 | + </property> |
2212 | + </spacer> |
2213 | + </item> |
2214 | + </layout> |
2215 | + </widget> |
2216 | + </item> |
2217 | + </layout> |
2218 | + </widget> |
2219 | + <widget class="QWidget" name="page_2"> |
2220 | + <layout class="QVBoxLayout" name="verticalLayout_3"> |
2221 | + <property name="spacing"> |
2222 | + <number>0</number> |
2223 | + </property> |
2224 | + <property name="margin"> |
2225 | + <number>0</number> |
2226 | + </property> |
2227 | + <item> |
2228 | + <widget class="QGroupBox" name="groupBox_2"> |
2229 | + <property name="title"> |
2230 | + <string>Objects found</string> |
2231 | + </property> |
2232 | + <layout class="QVBoxLayout" name="verticalLayout_4"> |
2233 | + <item> |
2234 | + <widget class="QLabel" name="label"> |
2235 | + <property name="text"> |
2236 | + <string>Mark the objects you wish to be imported.</string> |
2237 | + </property> |
2238 | + </widget> |
2239 | + </item> |
2240 | + <item> |
2241 | + <widget class="QListWidget" name="listWidget"> |
2242 | + <item> |
2243 | + <property name="text"> |
2244 | + <string notr="true">2P/Encke</string> |
2245 | + </property> |
2246 | + <property name="checkState"> |
2247 | + <enum>Unchecked</enum> |
2248 | + </property> |
2249 | + <property name="flags"> |
2250 | + <set>ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled</set> |
2251 | + </property> |
2252 | + </item> |
2253 | + </widget> |
2254 | + </item> |
2255 | + </layout> |
2256 | + </widget> |
2257 | + </item> |
2258 | + </layout> |
2259 | + </widget> |
2260 | + </widget> |
2261 | + </item> |
2262 | + <item> |
2263 | + <layout class="QHBoxLayout" name="horizontalLayout_3"> |
2264 | + <property name="leftMargin"> |
2265 | + <number>10</number> |
2266 | + </property> |
2267 | + <property name="rightMargin"> |
2268 | + <number>10</number> |
2269 | + </property> |
2270 | + <item> |
2271 | + <widget class="QPushButton" name="pushButton"> |
2272 | + <property name="text"> |
2273 | + <string>Next</string> |
2274 | + </property> |
2275 | + </widget> |
2276 | + </item> |
2277 | + <item> |
2278 | + <widget class="QPushButton" name="pushButton_2"> |
2279 | + <property name="text"> |
2280 | + <string>Cancel</string> |
2281 | + </property> |
2282 | + </widget> |
2283 | + </item> |
2284 | + </layout> |
2285 | + </item> |
2286 | + </layout> |
2287 | + </widget> |
2288 | + <resources/> |
2289 | + <connections/> |
2290 | +</ui> |
2291 | |
2292 | === added file 'plugins/SolarSystemEditor/src/gui/ManualImportWindow.cpp' |
2293 | --- plugins/SolarSystemEditor/src/gui/ManualImportWindow.cpp 1970-01-01 00:00:00 +0000 |
2294 | +++ plugins/SolarSystemEditor/src/gui/ManualImportWindow.cpp 2010-11-16 20:00:15 +0000 |
2295 | @@ -0,0 +1,257 @@ |
2296 | +/* |
2297 | + * Solar System editor plug-in for Stellarium |
2298 | + * |
2299 | + * Copyright (C) 2010 Bogdan Marinov |
2300 | + * |
2301 | + * This program is free software; you can redistribute it and/or |
2302 | + * modify it under the terms of the GNU General Public License |
2303 | + * as published by the Free Software Foundation; either version 2 |
2304 | + * of the License, or (at your option) any later version. |
2305 | + * |
2306 | + * This program is distributed in the hope that it will be useful, |
2307 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2308 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2309 | + * GNU General Public License for more details. |
2310 | + * |
2311 | + * You should have received a copy of the GNU General Public License |
2312 | + * along with this program; if not, write to the Free Software |
2313 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
2314 | + */ |
2315 | + |
2316 | +#include "SolarSystemEditor.hpp" |
2317 | + |
2318 | +#include "ManualImportWindow.hpp" |
2319 | +#include "ui_manualImportWindow.h" |
2320 | + |
2321 | +#include <QColor> |
2322 | +#include <QColorDialog> |
2323 | +#include <QFileDialog> |
2324 | +#include <QImageReader> |
2325 | + |
2326 | +#include "StelApp.hpp" |
2327 | +#include "StelFileMgr.hpp" |
2328 | +#include "StelModuleMgr.hpp" |
2329 | + |
2330 | + |
2331 | +ManualImportWindow::ManualImportWindow() |
2332 | +{ |
2333 | + ui = new Ui_manualImportWindow(); |
2334 | + ssoManager = GETSTELMODULE(SolarSystemEditor); |
2335 | +} |
2336 | + |
2337 | +ManualImportWindow::~ManualImportWindow() |
2338 | +{ |
2339 | + delete ui; |
2340 | +} |
2341 | + |
2342 | +void ManualImportWindow::createDialogContent() |
2343 | +{ |
2344 | + ui->setupUi(dialog); |
2345 | + |
2346 | + //Signals |
2347 | + connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close())); |
2348 | + |
2349 | + connect(ui->lineEditColor, SIGNAL(textChanged(QString)), this, SLOT(parseColorString(QString))); |
2350 | + connect(ui->pushButtonSelectColor, SIGNAL(clicked()), this, SLOT(selectColor())); |
2351 | + |
2352 | + connect(ui->pushButtonSelectTexture, SIGNAL(clicked()), this, SLOT(selectPlanetTextureFile())); |
2353 | + connect(ui->pushButtonSelectRingTexture, SIGNAL(clicked()), this, SLOT(selectRingTextureFile())); |
2354 | + |
2355 | + ui->labelLongitudeOfTheAscendingNode->setText(QString("Longitude of the ascending node %1:").arg(QChar(0x03A9)));//Capital omega |
2356 | + ui->radioButtonArgumentOfPeriapsis->setText(QString("Argument of periapsis %1:").arg(QChar(0x3C9)));//Lowercase omega |
2357 | + ui->radioButtonLongitudeOfPeriapsis->setText(QString("Longitude of periapsis %1:").arg(QChar(0x3D6))); |
2358 | + |
2359 | + //TODO: Move to "set defaults" function |
2360 | + ui->lineEditColor->setText("1.0, 1.0, 1.0"); |
2361 | + ui->lineEditTexture->setText("nomap.png"); |
2362 | + ui->lineEditRingTexture->setText("saturn_rings_radial.png"); |
2363 | +} |
2364 | + |
2365 | +void ManualImportWindow::languageChanged() |
2366 | +{ |
2367 | + if (dialog) |
2368 | + ui->retranslateUi(dialog); |
2369 | +} |
2370 | + |
2371 | +void ManualImportWindow::selectColor() |
2372 | +{ |
2373 | + QColor color = QColorDialog::getColor(objectColor); |
2374 | + objectColor = color; |
2375 | + ui->lineEditColor->setText(QString("%1, %2, %3").arg(color.redF()).arg(color.greenF()).arg(color.blueF())); |
2376 | + setColorButtonColor(color); |
2377 | +} |
2378 | + |
2379 | +void ManualImportWindow::parseColorString(QString colorCode) |
2380 | +{ |
2381 | + QStringList colorComponents = colorCode.split(QChar(',')); |
2382 | + int count = colorComponents.count(); |
2383 | + if (count < 3 || count > 4) |
2384 | + return; |
2385 | + |
2386 | + bool ok; |
2387 | + double red = colorComponents.at(0).toDouble(&ok); |
2388 | + if (!ok || red < 0.0 || red > 1.0) |
2389 | + return; |
2390 | + double green = colorComponents.at(1).toDouble(&ok); |
2391 | + if (!ok || green < 0.0 || green > 1.0) |
2392 | + return; |
2393 | + double blue = colorComponents.at(2).toDouble(&ok); |
2394 | + if (!ok || blue < 0.0 || blue > 1.0) |
2395 | + return; |
2396 | + |
2397 | + QColor color; |
2398 | + color.setRedF(red); |
2399 | + color.setGreenF(green); |
2400 | + color.setBlueF(blue); |
2401 | + |
2402 | + if (count == 4) |
2403 | + { |
2404 | + double alpha = colorComponents.at(3).toDouble(&ok); |
2405 | + if (!ok || alpha < 0.0 || alpha > 1.0) |
2406 | + return; |
2407 | + color.setAlphaF(alpha); |
2408 | + } |
2409 | + |
2410 | + objectColor = color; |
2411 | + setColorButtonColor(color); |
2412 | +} |
2413 | + |
2414 | +void ManualImportWindow::setColorButtonColor(QColor newColor) |
2415 | +{ |
2416 | + qDebug() << "setColorButtonColor()"; |
2417 | + QPixmap pixmap(16, 16); |
2418 | + pixmap.fill(newColor); |
2419 | + ui->pushButtonSelectColor->setIcon(QIcon(pixmap)); |
2420 | +} |
2421 | + |
2422 | +void ManualImportWindow::toggleCometOrbit(bool) |
2423 | +{ |
2424 | + // |
2425 | +} |
2426 | + |
2427 | +void ManualImportWindow::toggleEllipticOrbit(bool) |
2428 | +{ |
2429 | + // |
2430 | +} |
2431 | + |
2432 | +void ManualImportWindow::toggleObjectSpecificOrbit(bool) |
2433 | +{ |
2434 | + // |
2435 | +} |
2436 | + |
2437 | +void ManualImportWindow::toggleMeanMotionOrPeriod(bool) |
2438 | +{ |
2439 | + // |
2440 | +} |
2441 | + |
2442 | +void ManualImportWindow::selectPlanetTextureFile() |
2443 | +{ |
2444 | + selectTextureFile(ui->lineEditTexture); |
2445 | +} |
2446 | + |
2447 | +void ManualImportWindow::selectRingTextureFile() |
2448 | +{ |
2449 | + selectTextureFile(ui->lineEditRingTexture); |
2450 | +} |
2451 | + |
2452 | +void ManualImportWindow::selectTextureFile(QLineEdit * filePathLineEdit) |
2453 | +{ |
2454 | + //Find out the parent directory of the last selected file. |
2455 | + //Open the textures directory if no file have been selected. |
2456 | + QString texturesDirectoryPath; |
2457 | + QString currentFileName = filePathLineEdit->text(); |
2458 | + if (currentFileName.isEmpty()) |
2459 | + { |
2460 | + try |
2461 | + { |
2462 | + texturesDirectoryPath = StelFileMgr::findFile("textures", StelFileMgr::Directory); |
2463 | + } |
2464 | + catch (std::runtime_error &e) |
2465 | + { |
2466 | + qDebug() << e.what(); |
2467 | + return; |
2468 | + } |
2469 | + } |
2470 | + else |
2471 | + { |
2472 | + QString currentFilePath; |
2473 | + try |
2474 | + { |
2475 | + currentFilePath = StelFileMgr::findFile("textures/" + currentFileName, StelFileMgr::File); |
2476 | + } |
2477 | + catch (std::runtime_error &e) |
2478 | + { |
2479 | + qDebug() << e.what(); |
2480 | + filePathLineEdit->clear(); |
2481 | + return; |
2482 | + } |
2483 | + if (currentFilePath.isEmpty()) |
2484 | + { |
2485 | + filePathLineEdit->clear(); |
2486 | + return; |
2487 | + } |
2488 | + QFileInfo currentFileInfo(currentFilePath); |
2489 | + texturesDirectoryPath = currentFileInfo.canonicalPath(); |
2490 | + } |
2491 | + |
2492 | + //Select an existing file |
2493 | + QStringList supportedFormats; |
2494 | + foreach (QByteArray format, QImageReader::supportedImageFormats()) |
2495 | + { |
2496 | + supportedFormats.append(QString("*.%1").arg(QString(format)));//It's a wee bit long... |
2497 | + } |
2498 | + QString fileFilter = QString("Texture files (%1)").arg(supportedFormats.join(" ")); |
2499 | + QString newFilePath = QFileDialog::getOpenFileName(0, QString(), texturesDirectoryPath, fileFilter); |
2500 | + |
2501 | + //Is the file in one of the two "textures" directories? |
2502 | + if (newFilePath.isEmpty()) |
2503 | + return; |
2504 | + QFileInfo newFileInfo(newFilePath); |
2505 | + QDir newFileParentDirectory = newFileInfo.dir(); |
2506 | + if (newFileParentDirectory.dirName() != "textures") |
2507 | + return; |
2508 | + QDir installedTexturesDirectory(StelFileMgr::getInstallationDir() + "/textures"); |
2509 | + QDir userTexturesDirectory(StelFileMgr::getUserDir() + "/textures"); |
2510 | + if (newFileParentDirectory != installedTexturesDirectory && newFileParentDirectory != userTexturesDirectory) |
2511 | + return; |
2512 | + |
2513 | + if (verifyTextureFile(newFileInfo.canonicalFilePath())) |
2514 | + filePathLineEdit->setText(newFileInfo.fileName()); |
2515 | +} |
2516 | + |
2517 | +bool ManualImportWindow::verifyTextureFile(QString filePath) |
2518 | +{ |
2519 | + //TODO: Absolute path? File exists? |
2520 | + |
2521 | + QPixmap texture(filePath); |
2522 | + |
2523 | + if (texture.isNull()) |
2524 | + { |
2525 | + qDebug() << "File doesn't exist or is not an accepted texure format:" |
2526 | + << filePath; |
2527 | + return false; |
2528 | + } |
2529 | + |
2530 | + if (!verifyPowerOfTwo(texture.height())) |
2531 | + { |
2532 | + qDebug() << "Invalid texure height:" << texture.height() |
2533 | + << "for file" << filePath; |
2534 | + return false; |
2535 | + } |
2536 | + if (!verifyPowerOfTwo(texture.width())) |
2537 | + { |
2538 | + qDebug() << "Invalid texture width:" << texture.width() |
2539 | + << "for file" << filePath; |
2540 | + return false; |
2541 | + } |
2542 | + |
2543 | + return true; |
2544 | +} |
2545 | + |
2546 | +bool ManualImportWindow::verifyPowerOfTwo(int value) |
2547 | +{ |
2548 | + if (value > 0 && (value & (value-1)) == 0) |
2549 | + return true; |
2550 | + else |
2551 | + return false; |
2552 | +} |
2553 | |
2554 | === added file 'plugins/SolarSystemEditor/src/gui/ManualImportWindow.hpp' |
2555 | --- plugins/SolarSystemEditor/src/gui/ManualImportWindow.hpp 1970-01-01 00:00:00 +0000 |
2556 | +++ plugins/SolarSystemEditor/src/gui/ManualImportWindow.hpp 2010-11-16 20:00:15 +0000 |
2557 | @@ -0,0 +1,79 @@ |
2558 | +/* |
2559 | + * Solar System editor plug-in for Stellarium |
2560 | + * |
2561 | + * Copyright (C) 2010 Bogdan Marinov |
2562 | + * |
2563 | + * This program is free software; you can redistribute it and/or |
2564 | + * modify it under the terms of the GNU General Public License |
2565 | + * as published by the Free Software Foundation; either version 2 |
2566 | + * of the License, or (at your option) any later version. |
2567 | + * |
2568 | + * This program is distributed in the hope that it will be useful, |
2569 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2570 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2571 | + * GNU General Public License for more details. |
2572 | + * |
2573 | + * You should have received a copy of the GNU General Public License |
2574 | + * along with this program; if not, write to the Free Software |
2575 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
2576 | + */ |
2577 | + |
2578 | +#ifndef _MANUAL_IMPORT_WINDOW_ |
2579 | +#define _MANUAL_IMPORT_WINDOW_ |
2580 | + |
2581 | +#include <QObject> |
2582 | +#include "StelDialog.hpp" |
2583 | + |
2584 | +#include "SolarSystemEditor.hpp" |
2585 | + |
2586 | +#include <QColor> |
2587 | + |
2588 | +class Ui_manualImportWindow; |
2589 | +class QLineEdit; |
2590 | + |
2591 | +/*! \brief Window for manual entry of Solar System object properties. |
2592 | + \author Bogdan Marinov |
2593 | +*/ |
2594 | +class ManualImportWindow : public StelDialog |
2595 | +{ |
2596 | + Q_OBJECT |
2597 | +public: |
2598 | + ManualImportWindow(); |
2599 | + virtual ~ManualImportWindow(); |
2600 | + void languageChanged(); |
2601 | + |
2602 | +private slots: |
2603 | + //TODO: Object type |
2604 | + |
2605 | + void selectColor(); |
2606 | + void parseColorString(QString); |
2607 | + |
2608 | + void toggleCometOrbit(bool); |
2609 | + void toggleEllipticOrbit(bool); |
2610 | + void toggleObjectSpecificOrbit(bool); |
2611 | + |
2612 | + void toggleMeanMotionOrPeriod(bool); |
2613 | + |
2614 | + void selectPlanetTextureFile(); |
2615 | + void selectRingTextureFile(); |
2616 | + //TODO: Parse input in the line edits? (Otherwise, leave them read-only.) |
2617 | + |
2618 | +private: |
2619 | + SolarSystemEditor * ssoManager; |
2620 | + |
2621 | + QColor objectColor; |
2622 | + |
2623 | + void setColorButtonColor(QColor newColor); |
2624 | + |
2625 | + void selectTextureFile(QLineEdit * filePathLineEdit); |
2626 | + //! Check if a file is a valid graphics file with OpenGL texture dimensions. |
2627 | + //! OpenGL accepts only dimentions that are powers of 2 (512, 1024, etc.) |
2628 | + bool verifyTextureFile(QString filePath); |
2629 | + bool verifyPowerOfTwo(int value); |
2630 | + |
2631 | +protected: |
2632 | + virtual void createDialogContent(); |
2633 | + Ui_manualImportWindow * ui; |
2634 | +}; |
2635 | + |
2636 | +#endif //_MANUAL_IMPORT_WINDOW_ |
2637 | |
2638 | === added file 'plugins/SolarSystemEditor/src/gui/MpcImportWindow.cpp' |
2639 | --- plugins/SolarSystemEditor/src/gui/MpcImportWindow.cpp 1970-01-01 00:00:00 +0000 |
2640 | +++ plugins/SolarSystemEditor/src/gui/MpcImportWindow.cpp 2010-11-16 20:00:15 +0000 |
2641 | @@ -0,0 +1,958 @@ |
2642 | +/* |
2643 | + * Solar System editor plug-in for Stellarium |
2644 | + * |
2645 | + * Copyright (C) 2010 Bogdan Marinov |
2646 | + * |
2647 | + * This program is free software; you can redistribute it and/or |
2648 | + * modify it under the terms of the GNU General Public License |
2649 | + * as published by the Free Software Foundation; either version 2 |
2650 | + * of the License, or (at your option) any later version. |
2651 | + * |
2652 | + * This program is distributed in the hope that it will be useful, |
2653 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2654 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2655 | + * GNU General Public License for more details. |
2656 | + * |
2657 | + * You should have received a copy of the GNU General Public License |
2658 | + * along with this program; if not, write to the Free Software |
2659 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
2660 | + */ |
2661 | + |
2662 | +#include "SolarSystemEditor.hpp" |
2663 | + |
2664 | +#include "MpcImportWindow.hpp" |
2665 | +#include "ui_mpcImportWindow.h" |
2666 | + |
2667 | +#include "StelApp.hpp" |
2668 | +#include "StelFileMgr.hpp" |
2669 | +#include "StelJsonParser.hpp" |
2670 | +#include "StelModuleMgr.hpp" |
2671 | +#include "SolarSystem.hpp" |
2672 | + |
2673 | +#include <QApplication> |
2674 | +#include <QClipboard> |
2675 | +#include <QFileDialog> |
2676 | +#include <QHash> |
2677 | +#include <QList> |
2678 | +#include <QNetworkAccessManager> |
2679 | +#include <QNetworkRequest> |
2680 | +#include <QNetworkReply> |
2681 | +#include <QString> |
2682 | +#include <QTemporaryFile> |
2683 | +#include <QTimer> |
2684 | +#include <QUrl> |
2685 | + |
2686 | +MpcImportWindow::MpcImportWindow() |
2687 | +{ |
2688 | + ui = new Ui_mpcImportWindow(); |
2689 | + ssoManager = GETSTELMODULE(SolarSystemEditor); |
2690 | + |
2691 | + networkManager = StelApp::getInstance().getNetworkAccessManager(); |
2692 | + |
2693 | + downloadReply = NULL; |
2694 | + queryReply = NULL; |
2695 | + downloadProgressBar = NULL; |
2696 | + queryProgressBar = NULL; |
2697 | + |
2698 | + countdownTimer = new QTimer(this); |
2699 | + |
2700 | + QHash<QString,QString> asteroidBookmarks; |
2701 | + QHash<QString,QString> cometBookmarks; |
2702 | + bookmarks.insert(MpcComets, cometBookmarks); |
2703 | + bookmarks.insert(MpcMinorPlanets, asteroidBookmarks); |
2704 | +} |
2705 | + |
2706 | +MpcImportWindow::~MpcImportWindow() |
2707 | +{ |
2708 | + delete ui; |
2709 | + delete countdownTimer; |
2710 | + if (downloadReply) |
2711 | + downloadReply->deleteLater(); |
2712 | + if (queryReply) |
2713 | + queryReply->deleteLater(); |
2714 | + if (downloadProgressBar) |
2715 | + downloadProgressBar->deleteLater(); |
2716 | + if (queryProgressBar) |
2717 | + queryProgressBar->deleteLater(); |
2718 | +} |
2719 | + |
2720 | +void MpcImportWindow::createDialogContent() |
2721 | +{ |
2722 | + ui->setupUi(dialog); |
2723 | + |
2724 | + //Signals |
2725 | + connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close())); |
2726 | + |
2727 | + connect(ui->pushButtonAcquire, SIGNAL(clicked()), this, SLOT(acquireObjectData())); |
2728 | + connect(ui->pushButtonAbortDownload, SIGNAL(clicked()), this, SLOT(abortDownload())); |
2729 | + connect(ui->pushButtonAdd, SIGNAL(clicked()), this, SLOT(addObjects())); |
2730 | + connect(ui->pushButtonDiscard, SIGNAL(clicked()), this, SLOT(discardObjects())); |
2731 | + |
2732 | + connect(ui->pushButtonBrowse, SIGNAL(clicked()), this, SLOT(selectFile())); |
2733 | + connect(ui->pushButtonPasteURL, SIGNAL(clicked()), this, SLOT(pasteClipboardURL())); |
2734 | + connect(ui->comboBoxBookmarks, SIGNAL(currentIndexChanged(QString)), this, SLOT(bookmarkSelected(QString))); |
2735 | + |
2736 | + //connect(ui->radioButtonSingle, SIGNAL(toggled(bool)), ui->frameSingle, SLOT(setVisible(bool))); |
2737 | + connect(ui->radioButtonFile, SIGNAL(toggled(bool)), ui->frameFile, SLOT(setVisible(bool))); |
2738 | + connect(ui->radioButtonURL, SIGNAL(toggled(bool)), ui->frameURL, SLOT(setVisible(bool))); |
2739 | + |
2740 | + connect(ui->radioButtonAsteroids, SIGNAL(toggled(bool)), this, SLOT(switchImportType(bool))); |
2741 | + connect(ui->radioButtonComets, SIGNAL(toggled(bool)), this, SLOT(switchImportType(bool))); |
2742 | + |
2743 | + connect(ui->pushButtonMarkAll, SIGNAL(clicked()), this, SLOT(markAll())); |
2744 | + connect(ui->pushButtonMarkNone, SIGNAL(clicked()), this, SLOT(unmarkAll())); |
2745 | + |
2746 | + connect(ui->pushButtonSendQuery, SIGNAL(clicked()), this, SLOT(sendQuery())); |
2747 | + connect(ui->pushButtonAbortQuery, SIGNAL(clicked()), this, SLOT(abortQuery())); |
2748 | + connect(ui->lineEditQuery, SIGNAL(textEdited(QString)), this, SLOT(resetNotFound())); |
2749 | + //connect(ui->lineEditQuery, SIGNAL(editingFinished()), this, SLOT(sendQuery())); |
2750 | + connect(countdownTimer, SIGNAL(timeout()), this, SLOT(updateCountdown())); |
2751 | + |
2752 | + loadBookmarks(); |
2753 | + |
2754 | + resetCountdown(); |
2755 | + resetDialog(); |
2756 | +} |
2757 | + |
2758 | +void MpcImportWindow::resetDialog() |
2759 | +{ |
2760 | + ui->stackedWidget->setCurrentIndex(0); |
2761 | + |
2762 | + //ui->tabWidget->setCurrentIndex(0); |
2763 | + ui->groupBoxType->setVisible(true); |
2764 | + ui->radioButtonAsteroids->setChecked(true); |
2765 | + |
2766 | + ui->radioButtonFile->setChecked(true); |
2767 | + ui->frameURL->setVisible(false); |
2768 | + |
2769 | + ui->lineEditFilePath->clear(); |
2770 | + ui->lineEditQuery->clear(); |
2771 | + ui->lineEditURL->setText("http://"); |
2772 | + ui->checkBoxAddBookmark->setChecked(false); |
2773 | + ui->frameBookmarkTitle->setVisible(false); |
2774 | + ui->comboBoxBookmarks->setCurrentIndex(0); |
2775 | + |
2776 | + ui->radioButtonUpdate->setChecked(true); |
2777 | + ui->checkBoxOnlyOrbitalElements->setChecked(true); |
2778 | + |
2779 | + //TODO: Is this the right place? |
2780 | + ui->pushButtonAbortQuery->setVisible(false); |
2781 | + ui->pushButtonAbortDownload->setVisible(false); |
2782 | + |
2783 | + //Resetting the dialog should not reset the timer |
2784 | + //resetCountdown(); |
2785 | + resetNotFound(); |
2786 | + enableInterface(true); |
2787 | +} |
2788 | + |
2789 | +void MpcImportWindow::populateBookmarksList() |
2790 | +{ |
2791 | + ui->comboBoxBookmarks->clear(); |
2792 | + ui->comboBoxBookmarks->addItem("Select bookmark..."); |
2793 | + QStringList bookmarkTitles(bookmarks.value(importType).keys()); |
2794 | + bookmarkTitles.sort(); |
2795 | + ui->comboBoxBookmarks->addItems(bookmarkTitles); |
2796 | +} |
2797 | + |
2798 | +void MpcImportWindow::languageChanged() |
2799 | +{ |
2800 | + if (dialog) |
2801 | + ui->retranslateUi(dialog); |
2802 | +} |
2803 | + |
2804 | +void MpcImportWindow::acquireObjectData() |
2805 | +{ |
2806 | + if (ui->radioButtonFile->isChecked()) |
2807 | + { |
2808 | + QString filePath = ui->lineEditFilePath->text(); |
2809 | + if (filePath.isEmpty()) |
2810 | + return; |
2811 | + |
2812 | + QList<SsoElements> objects = readElementsFromFile(importType, filePath); |
2813 | + if (objects.isEmpty()) |
2814 | + return; |
2815 | + |
2816 | + //Temporary, until the slot/socket mechanism is ready |
2817 | + populateCandidateObjects(objects); |
2818 | + ui->stackedWidget->setCurrentIndex(1); |
2819 | + } |
2820 | + else if (ui->radioButtonURL->isChecked()) |
2821 | + { |
2822 | + QString url = ui->lineEditURL->text(); |
2823 | + if (url.isEmpty()) |
2824 | + return; |
2825 | + startDownload(url); |
2826 | + } |
2827 | + //close(); |
2828 | +} |
2829 | + |
2830 | +void MpcImportWindow::addObjects() |
2831 | +{ |
2832 | + disconnect(ssoManager, SIGNAL(solarSystemChanged()), this, SLOT(resetDialog())); |
2833 | + |
2834 | + QList<QString> checkedObjectsNames; |
2835 | + |
2836 | + //Extract the marked objects |
2837 | + while (ui->listWidgetObjects->count() > 0) |
2838 | + { |
2839 | + QListWidgetItem * item = ui->listWidgetObjects->takeItem(0); |
2840 | + if (item->checkState() == Qt::Checked) |
2841 | + { |
2842 | + checkedObjectsNames.append(item->text()); |
2843 | + } |
2844 | + delete item; |
2845 | + } |
2846 | + //qDebug() << "Checked:" << checkedObjectsNames; |
2847 | + |
2848 | + QList<SsoElements> approvedForAddition; |
2849 | + for (int i = 0; i < candidatesForAddition.count(); i++) |
2850 | + { |
2851 | + QString name = candidatesForAddition.at(i).value("name").toString(); |
2852 | + if (checkedObjectsNames.contains(name)) |
2853 | + approvedForAddition.append(candidatesForAddition.at(i)); |
2854 | + } |
2855 | + |
2856 | + bool overwrite = ui->radioButtonOverwrite->isChecked(); |
2857 | + QList<SsoElements> approvedForUpdate; |
2858 | + for (int j = 0; j < candidatesForUpdate.count(); j++) |
2859 | + { |
2860 | + QString name = candidatesForUpdate.at(j).value("name").toString(); |
2861 | + if (checkedObjectsNames.contains(name)) |
2862 | + { |
2863 | + if (overwrite) |
2864 | + { |
2865 | + approvedForAddition.append(candidatesForUpdate.at(j)); |
2866 | + } |
2867 | + else |
2868 | + { |
2869 | + approvedForUpdate.append(candidatesForUpdate.at(j)); |
2870 | + } |
2871 | + } |
2872 | + } |
2873 | + |
2874 | + //Write to file |
2875 | + ssoManager->appendToSolarSystemConfigurationFile(approvedForAddition); |
2876 | + |
2877 | + if (ui->radioButtonUpdate->isChecked()) |
2878 | + { |
2879 | + SolarSystemEditor::UpdateFlags flags(SolarSystemEditor::UpdateNameAndNumber | SolarSystemEditor::UpdateOrbitalElements); |
2880 | + if (!ui->checkBoxOnlyOrbitalElements->isChecked()) |
2881 | + { |
2882 | + flags |= SolarSystemEditor::UpdateType; |
2883 | + flags |= SolarSystemEditor::UpdateMagnitudeParameters; |
2884 | + } |
2885 | + |
2886 | + ssoManager->updateSolarSystemConfigurationFile(approvedForUpdate, flags); |
2887 | + } |
2888 | + |
2889 | + //Refresh the Solar System |
2890 | + GETSTELMODULE(SolarSystem)->reloadPlanets(); |
2891 | + |
2892 | + resetDialog(); |
2893 | + emit objectsImported(); |
2894 | +} |
2895 | + |
2896 | +void MpcImportWindow::discardObjects() |
2897 | +{ |
2898 | + resetDialog(); |
2899 | +} |
2900 | + |
2901 | +void MpcImportWindow::pasteClipboardURL() |
2902 | +{ |
2903 | + ui->lineEditURL->setText(QApplication::clipboard()->text()); |
2904 | +} |
2905 | + |
2906 | +void MpcImportWindow::selectFile() |
2907 | +{ |
2908 | + QString filePath = QFileDialog::getOpenFileName(NULL, "Select a text file", StelFileMgr::getDesktopDir()); |
2909 | + ui->lineEditFilePath->setText(filePath); |
2910 | +} |
2911 | + |
2912 | +void MpcImportWindow::bookmarkSelected(QString bookmarkTitle) |
2913 | +{ |
2914 | + if (bookmarkTitle.isEmpty() || bookmarkTitle == "Select bookmark...") |
2915 | + { |
2916 | + ui->lineEditURL->clear(); |
2917 | + return; |
2918 | + } |
2919 | + QString bookmarkUrl = bookmarks.value(importType).value(bookmarkTitle); |
2920 | + ui->lineEditURL->setText(bookmarkUrl); |
2921 | +} |
2922 | + |
2923 | +void MpcImportWindow::populateCandidateObjects(QList<SsoElements> objects) |
2924 | +{ |
2925 | + candidatesForAddition.clear(); |
2926 | + |
2927 | + //Get a list of the current objects |
2928 | + QHash<QString,QString> defaultSsoIdentifiers = ssoManager->getDefaultSsoIdentifiers(); |
2929 | + QHash<QString,QString> loadedSsoIdentifiers = ssoManager->listAllLoadedSsoIdentifiers(); |
2930 | + |
2931 | + //Separating the objects into visual groups in the list |
2932 | + int newDefaultSsoIndex = 0; |
2933 | + int newLoadedSsoIndex = 0; |
2934 | + int newNovelSsoIndex = 0; |
2935 | + int insertionIndex = 0; |
2936 | + |
2937 | + QListWidget * list = ui->listWidgetObjects; |
2938 | + list->clear(); |
2939 | + foreach (SsoElements object, objects) |
2940 | + { |
2941 | + QString name = object.value("name").toString(); |
2942 | + if (name.isEmpty()) |
2943 | + continue; |
2944 | + |
2945 | + QString group = object.value("section_name").toString(); |
2946 | + if (group.isEmpty()) |
2947 | + continue; |
2948 | + |
2949 | + //Prevent name conflicts between asteroids and moons |
2950 | + if (loadedSsoIdentifiers.contains(name)) |
2951 | + { |
2952 | + if (loadedSsoIdentifiers.value(name) != group) |
2953 | + { |
2954 | + name.append('*'); |
2955 | + object.insert("name", name); |
2956 | + } |
2957 | + } |
2958 | + |
2959 | + QListWidgetItem * item = new QListWidgetItem(); |
2960 | + item->setText(name); |
2961 | + item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); |
2962 | + item->setCheckState(Qt::Unchecked); |
2963 | + |
2964 | + if (defaultSsoIdentifiers.contains(name)) |
2965 | + { |
2966 | + //Duplicate of a default solar system object |
2967 | + QFont itemFont(item->font()); |
2968 | + itemFont.setBold(true); |
2969 | + item->setFont(itemFont); |
2970 | + |
2971 | + candidatesForUpdate.append(object); |
2972 | + |
2973 | + insertionIndex = newDefaultSsoIndex; |
2974 | + newDefaultSsoIndex++; |
2975 | + newLoadedSsoIndex++; |
2976 | + newNovelSsoIndex++; |
2977 | + } |
2978 | + else if (loadedSsoIdentifiers.contains(name)) |
2979 | + { |
2980 | + //Duplicate of another existing object |
2981 | + QFont itemFont(item->font()); |
2982 | + itemFont.setItalic(true); |
2983 | + item->setFont(itemFont); |
2984 | + |
2985 | + candidatesForUpdate.append(object); |
2986 | + |
2987 | + insertionIndex = newLoadedSsoIndex; |
2988 | + newLoadedSsoIndex++; |
2989 | + newNovelSsoIndex++; |
2990 | + } |
2991 | + else |
2992 | + { |
2993 | + candidatesForAddition.append(object); |
2994 | + |
2995 | + insertionIndex = newNovelSsoIndex; |
2996 | + newNovelSsoIndex++; |
2997 | + } |
2998 | + |
2999 | + list->insertItem(insertionIndex, item); |
3000 | + } |
3001 | + |
3002 | + //Select the first item |
3003 | + if (list->count() > 0) |
3004 | + list->setCurrentRow(0); |
3005 | +} |
3006 | + |
3007 | +void MpcImportWindow::enableInterface(bool enable) |
3008 | +{ |
3009 | + ui->groupBoxType->setVisible(enable); |
3010 | + |
3011 | + ui->frameFile->setEnabled(enable); |
3012 | + ui->frameURL->setEnabled(enable); |
3013 | + |
3014 | + ui->radioButtonFile->setEnabled(enable); |
3015 | + ui->radioButtonURL->setEnabled(enable); |
3016 | + |
3017 | + ui->pushButtonAcquire->setEnabled(enable); |
3018 | +} |
3019 | + |
3020 | +SsoElements MpcImportWindow::readElementsFromString (QString elements) |
3021 | +{ |
3022 | + Q_ASSERT(ssoManager); |
3023 | + |
3024 | + switch (importType) |
3025 | + { |
3026 | + case MpcComets: |
3027 | + return ssoManager->readMpcOneLineCometElements(elements); |
3028 | + case MpcMinorPlanets: |
3029 | + default: |
3030 | + return ssoManager->readMpcOneLineMinorPlanetElements(elements); |
3031 | + } |
3032 | +} |
3033 | + |
3034 | +QList<SsoElements> MpcImportWindow::readElementsFromFile(ImportType type, QString filePath) |
3035 | +{ |
3036 | + Q_ASSERT(ssoManager); |
3037 | + |
3038 | + switch (type) |
3039 | + { |
3040 | + case MpcComets: |
3041 | + return ssoManager->readMpcOneLineCometElementsFromFile(filePath); |
3042 | + case MpcMinorPlanets: |
3043 | + default: |
3044 | + return ssoManager->readMpcOneLineMinorPlanetElementsFromFile(filePath); |
3045 | + } |
3046 | +} |
3047 | + |
3048 | +void MpcImportWindow::switchImportType(bool) |
3049 | +{ |
3050 | + if (ui->radioButtonAsteroids->isChecked()) |
3051 | + { |
3052 | + importType = MpcMinorPlanets; |
3053 | + } |
3054 | + else |
3055 | + { |
3056 | + importType = MpcComets; |
3057 | + } |
3058 | + |
3059 | + populateBookmarksList(); |
3060 | + |
3061 | + //Clear the fields |
3062 | + //ui->lineEditSingle->clear(); |
3063 | + ui->lineEditFilePath->clear(); |
3064 | + ui->lineEditURL->clear(); |
3065 | + |
3066 | + //If one of the options is selected, show the rest of the dialog |
3067 | + ui->groupBoxSource->setVisible(true); |
3068 | +} |
3069 | + |
3070 | +void MpcImportWindow::markAll() |
3071 | +{ |
3072 | + QListWidget * const list = ui->listWidgetObjects; |
3073 | + int rowCount = list->count(); |
3074 | + if (rowCount < 1) |
3075 | + return; |
3076 | + |
3077 | + for (int row = 0; row < rowCount; row++) |
3078 | + { |
3079 | + QListWidgetItem * item = list->item(row); |
3080 | + if (item) |
3081 | + { |
3082 | + item->setCheckState(Qt::Checked); |
3083 | + } |
3084 | + } |
3085 | +} |
3086 | + |
3087 | +void MpcImportWindow::unmarkAll() |
3088 | +{ |
3089 | + QListWidget * const list = ui->listWidgetObjects; |
3090 | + int rowCount = list->count(); |
3091 | + if (rowCount < 1) |
3092 | + return; |
3093 | + |
3094 | + for (int row = 0; row < rowCount; row++) |
3095 | + { |
3096 | + QListWidgetItem * item = list->item(row); |
3097 | + if (item) |
3098 | + { |
3099 | + item->setCheckState(Qt::Unchecked); |
3100 | + } |
3101 | + } |
3102 | +} |
3103 | + |
3104 | +void MpcImportWindow::updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) |
3105 | +{ |
3106 | + if (downloadProgressBar == NULL) |
3107 | + return; |
3108 | + |
3109 | + int currentValue = 0; |
3110 | + int endValue = 0; |
3111 | + |
3112 | + if (bytesTotal > -1 && bytesReceived <= bytesTotal) |
3113 | + { |
3114 | + //Round to the greatest possible derived unit |
3115 | + while (bytesTotal > 1024) |
3116 | + { |
3117 | + bytesReceived = std::floor(bytesReceived / 1024); |
3118 | + bytesTotal = std::floor(bytesTotal / 1024); |
3119 | + } |
3120 | + currentValue = bytesReceived; |
3121 | + endValue = bytesTotal; |
3122 | + } |
3123 | + |
3124 | + downloadProgressBar->setValue(currentValue); |
3125 | + downloadProgressBar->setMaximum(endValue); |
3126 | +} |
3127 | + |
3128 | +void MpcImportWindow::updateQueryProgress(qint64, qint64) |
3129 | +{ |
3130 | + if (queryProgressBar == NULL) |
3131 | + return; |
3132 | + |
3133 | + //Just show activity |
3134 | + queryProgressBar->setValue(0); |
3135 | + queryProgressBar->setMaximum(0); |
3136 | +} |
3137 | + |
3138 | +void MpcImportWindow::startDownload(QString urlString) |
3139 | +{ |
3140 | + if (downloadReply) |
3141 | + { |
3142 | + //There's already an operation in progress? |
3143 | + //TODO |
3144 | + return; |
3145 | + } |
3146 | + |
3147 | + QUrl url(urlString); |
3148 | + if (!url.isValid() || url.isRelative() || url.scheme() != "http") |
3149 | + { |
3150 | + qWarning() << "Invalid URL:" << urlString; |
3151 | + return; |
3152 | + } |
3153 | + //qDebug() << url.toString(); |
3154 | + |
3155 | + //TODO: Interface changes! |
3156 | + |
3157 | + downloadProgressBar = StelApp::getInstance().getGui()->addProgressBar(); |
3158 | + downloadProgressBar->setValue(0); |
3159 | + downloadProgressBar->setMaximum(0); |
3160 | + //downloadProgressBar->setFormat("%v/%m"); |
3161 | + downloadProgressBar->setVisible(true); |
3162 | + |
3163 | + //TODO: Better handling of the interface |
3164 | + //dialog->setVisible(false); |
3165 | + enableInterface(false); |
3166 | + ui->pushButtonAbortDownload->setVisible(true); |
3167 | + |
3168 | + connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadComplete(QNetworkReply*))); |
3169 | + downloadReply = networkManager->get(QNetworkRequest(url)); |
3170 | + connect(downloadReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDownloadProgress(qint64,qint64))); |
3171 | +} |
3172 | + |
3173 | +void MpcImportWindow::abortDownload() |
3174 | +{ |
3175 | + if (downloadReply == NULL || downloadReply->isFinished()) |
3176 | + return; |
3177 | + |
3178 | + qDebug() << "Aborting download..."; |
3179 | + |
3180 | + disconnect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadComplete(QNetworkReply*))); |
3181 | + deleteDownloadProgressBar(); |
3182 | + |
3183 | + downloadReply->abort(); |
3184 | + downloadReply->deleteLater(); |
3185 | + downloadReply = NULL; |
3186 | + |
3187 | + enableInterface(true); |
3188 | + ui->pushButtonAbortDownload->setVisible(false); |
3189 | +} |
3190 | + |
3191 | +void MpcImportWindow::downloadComplete(QNetworkReply *reply) |
3192 | +{ |
3193 | + disconnect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(downloadComplete(QNetworkReply*))); |
3194 | + deleteDownloadProgressBar(); |
3195 | + ui->pushButtonAbortDownload->setVisible(false); |
3196 | + |
3197 | + /* |
3198 | + qDebug() << "reply->isOpen():" << reply->isOpen() |
3199 | + << "reply->isReadable():" << reply->isReadable() |
3200 | + << "reply->isFinished():" << reply->isFinished(); |
3201 | + */ |
3202 | + |
3203 | + if(reply->error()) |
3204 | + { |
3205 | + qWarning() << "Download error: While downloading" |
3206 | + << reply->url().toString() |
3207 | + << "the following error occured:" |
3208 | + << reply->errorString(); |
3209 | + enableInterface(true); |
3210 | + reply->deleteLater(); |
3211 | + downloadReply = NULL; |
3212 | + return; |
3213 | + } |
3214 | + |
3215 | + QList<SsoElements> objects; |
3216 | + QTemporaryFile file; |
3217 | + if (file.open()) |
3218 | + { |
3219 | + file.write(reply->readAll()); |
3220 | + file.close(); |
3221 | + objects = readElementsFromFile(importType, file.fileName()); |
3222 | + } |
3223 | + else |
3224 | + { |
3225 | + qWarning() << "Unable to open a temporary file. Aborting operation."; |
3226 | + } |
3227 | + |
3228 | + if (objects.isEmpty()) |
3229 | + { |
3230 | + qWarning() << "No objects found in the file downloaded from" |
3231 | + << reply->url().toString(); |
3232 | + } |
3233 | + else |
3234 | + { |
3235 | + //The request has been successful: add the URL to bookmarks? |
3236 | + if (ui->checkBoxAddBookmark->isChecked()) |
3237 | + { |
3238 | + QString url = reply->url().toString(); |
3239 | + QString title = ui->lineEditBookmarkTitle->text().trimmed(); |
3240 | + //If no title has been entered, use the URL as a title |
3241 | + if (title.isEmpty()) |
3242 | + title = url; |
3243 | + if (!bookmarks.value(importType).values().contains(url)) |
3244 | + { |
3245 | + bookmarks[importType].insert(title, url); |
3246 | + populateBookmarksList(); |
3247 | + saveBookmarks(); |
3248 | + } |
3249 | + } |
3250 | + } |
3251 | + |
3252 | + reply->deleteLater(); |
3253 | + downloadReply = NULL; |
3254 | + |
3255 | + //Temporary, until the slot/socket mechanism is ready |
3256 | + populateCandidateObjects(objects); |
3257 | + ui->stackedWidget->setCurrentIndex(1); |
3258 | + //As this window is persistent, if the Solar System is changed |
3259 | + //while there is a list, it should be reset. |
3260 | + connect(ssoManager, SIGNAL(solarSystemChanged()), this, SLOT(resetDialog())); |
3261 | +} |
3262 | + |
3263 | +void MpcImportWindow::deleteDownloadProgressBar() |
3264 | +{ |
3265 | + disconnect(this, SLOT(updateDownloadProgress(qint64,qint64))); |
3266 | + |
3267 | + if (downloadProgressBar) |
3268 | + { |
3269 | + downloadProgressBar->setVisible(false); |
3270 | + downloadProgressBar->deleteLater(); |
3271 | + downloadProgressBar = NULL; |
3272 | + } |
3273 | +} |
3274 | + |
3275 | +void MpcImportWindow::sendQuery() |
3276 | +{ |
3277 | + if (queryReply != NULL) |
3278 | + return; |
3279 | + |
3280 | + QString query = ui->lineEditQuery->text().trimmed(); |
3281 | + if (query.isEmpty()) |
3282 | + return; |
3283 | + |
3284 | + //Progress bar |
3285 | + queryProgressBar = StelApp::getInstance().getGui()->addProgressBar(); |
3286 | + queryProgressBar->setValue(0); |
3287 | + queryProgressBar->setMaximum(0); |
3288 | + queryProgressBar->setFormat("Searching..."); |
3289 | + queryProgressBar->setVisible(true); |
3290 | + |
3291 | + //TODO: Better handling of the interface |
3292 | + enableInterface(false); |
3293 | + ui->labelQueryMessage->setVisible(false); |
3294 | + |
3295 | + QUrl url; |
3296 | + url.addQueryItem("ty","e");//Type: ephemerides |
3297 | + url.addQueryItem("TextArea", query);//Object name query |
3298 | + //url.addQueryItem("e", "-1");//Elements format: MPC 1-line |
3299 | + url.addQueryItem("e", "3");//Elements format: XEphem |
3300 | + //Yes, all of the rest are necessary |
3301 | + url.addQueryItem("d",""); |
3302 | + url.addQueryItem("l",""); |
3303 | + url.addQueryItem("i",""); |
3304 | + url.addQueryItem("u","d"); |
3305 | + url.addQueryItem("uto", "0"); |
3306 | + url.addQueryItem("c", ""); |
3307 | + url.addQueryItem("long", ""); |
3308 | + url.addQueryItem("lat", ""); |
3309 | + url.addQueryItem("alt", ""); |
3310 | + url.addQueryItem("raty", "a"); |
3311 | + url.addQueryItem("s", "t"); |
3312 | + url.addQueryItem("m", "m"); |
3313 | + url.addQueryItem("adir", "S"); |
3314 | + url.addQueryItem("oed", ""); |
3315 | + url.addQueryItem("resoc", ""); |
3316 | + url.addQueryItem("tit", ""); |
3317 | + url.addQueryItem("bu", ""); |
3318 | + url.addQueryItem("ch", "c"); |
3319 | + url.addQueryItem("ce", "f"); |
3320 | + url.addQueryItem("js", "f"); |
3321 | + |
3322 | + QNetworkRequest request(QUrl("http://scully.cfa.harvard.edu/~cgi/MPEph2")); |
3323 | + request.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded");//Is this really necessary? |
3324 | + request.setHeader(QNetworkRequest::ContentLengthHeader, url.encodedQuery().length()); |
3325 | + |
3326 | + startCountdown(); |
3327 | + ui->pushButtonAbortQuery->setVisible(true); |
3328 | + connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(queryComplete(QNetworkReply*))); |
3329 | + queryReply = networkManager->post(request, url.encodedQuery()); |
3330 | + connect(queryReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateQueryProgress(qint64,qint64))); |
3331 | +} |
3332 | + |
3333 | +void MpcImportWindow::abortQuery() |
3334 | +{ |
3335 | + if (queryReply == NULL) |
3336 | + return; |
3337 | + |
3338 | + disconnect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(queryComplete(QNetworkReply*))); |
3339 | + deleteQueryProgressBar(); |
3340 | + |
3341 | + queryReply->abort(); |
3342 | + queryReply->deleteLater(); |
3343 | + queryReply = NULL; |
3344 | + |
3345 | + //resetCountdown(); |
3346 | + enableInterface(true); |
3347 | + ui->pushButtonAbortQuery->setVisible(false); |
3348 | +} |
3349 | + |
3350 | +void MpcImportWindow::queryComplete(QNetworkReply *reply) |
3351 | +{ |
3352 | + disconnect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(queryComplete(QNetworkReply*))); |
3353 | + deleteQueryProgressBar(); |
3354 | + |
3355 | + //Hide the abort button - a reply has been received |
3356 | + ui->pushButtonAbortQuery->setVisible(false); |
3357 | + |
3358 | + if (reply->error()) |
3359 | + { |
3360 | + qWarning() << "Download error: While trying to access" |
3361 | + << reply->url().toString() |
3362 | + << "the following error occured:" |
3363 | + << reply->errorString(); |
3364 | + ui->labelQueryMessage->setText(reply->errorString());//TODO: Decide if this is a good idea |
3365 | + ui->labelQueryMessage->setVisible(true); |
3366 | + enableInterface(true); |
3367 | + |
3368 | + reply->deleteLater(); |
3369 | + queryReply = NULL; |
3370 | + return; |
3371 | + } |
3372 | + |
3373 | + if (reply->header(QNetworkRequest::ContentTypeHeader) != "text/ascii" || |
3374 | + reply->rawHeader(QByteArray("Content-disposition")) != "attachment; filename=elements.txt") |
3375 | + { |
3376 | + ui->labelQueryMessage->setText("Object not found."); |
3377 | + ui->labelQueryMessage->setVisible(true); |
3378 | + enableInterface(true); |
3379 | + } |
3380 | + else |
3381 | + { |
3382 | + QList<SsoElements> objects; |
3383 | + QTemporaryFile file; |
3384 | + if (file.open()) |
3385 | + { |
3386 | + file.write(reply->readAll()); |
3387 | + file.close(); |
3388 | + |
3389 | + /* |
3390 | + //Try to read it as a comet first? |
3391 | + objects = readElementsFromFile(MpcComets, file.fileName()); |
3392 | + if (objects.isEmpty()) |
3393 | + objects = readElementsFromFile(MpcMinorPlanets, file.fileName()); |
3394 | + */ |
3395 | + objects = ssoManager->readXEphemOneLineElementsFromFile(file.fileName()); |
3396 | + } |
3397 | + else |
3398 | + { |
3399 | + qWarning() << "Unable to open a temporary file. Aborting operation."; |
3400 | + } |
3401 | + |
3402 | + if (objects.isEmpty()) |
3403 | + { |
3404 | + qWarning() << "No objects found in the file downloaded from" |
3405 | + << reply->url().toString(); |
3406 | + } |
3407 | + else |
3408 | + { |
3409 | + //The request has been successful: add the URL to bookmarks? |
3410 | + if (ui->checkBoxAddBookmark->isChecked()) |
3411 | + { |
3412 | + QString url = reply->url().toString(); |
3413 | + if (!bookmarks.value(importType).values().contains(url)) |
3414 | + { |
3415 | + //Use the URL as a title for now |
3416 | + bookmarks[importType].insert(url, url); |
3417 | + } |
3418 | + } |
3419 | + |
3420 | + //Temporary, until the slot/socket mechanism is ready |
3421 | + populateCandidateObjects(objects); |
3422 | + ui->stackedWidget->setCurrentIndex(1); |
3423 | + } |
3424 | + } |
3425 | + |
3426 | + reply->deleteLater(); |
3427 | + queryReply = NULL; |
3428 | +} |
3429 | + |
3430 | +void MpcImportWindow::deleteQueryProgressBar() |
3431 | +{ |
3432 | + disconnect(this, SLOT(updateQueryProgress(qint64,qint64))); |
3433 | + if (queryProgressBar) |
3434 | + { |
3435 | + queryProgressBar->setVisible(false); |
3436 | + queryProgressBar->deleteLater(); |
3437 | + queryProgressBar = NULL; |
3438 | + } |
3439 | +} |
3440 | + |
3441 | +void MpcImportWindow::startCountdown() |
3442 | +{ |
3443 | + if (!countdownTimer->isActive()) |
3444 | + countdownTimer->start(1000);//1 second |
3445 | + |
3446 | + //Disable the interface |
3447 | + ui->lineEditQuery->setEnabled(false); |
3448 | + ui->pushButtonSendQuery->setEnabled(false); |
3449 | +} |
3450 | + |
3451 | +void MpcImportWindow::resetCountdown() |
3452 | +{ |
3453 | + //Stop the timer |
3454 | + if (countdownTimer->isActive()) |
3455 | + { |
3456 | + countdownTimer->stop(); |
3457 | + |
3458 | + //If the query is still active, kill it |
3459 | + if (queryReply != NULL && queryReply->isRunning()) |
3460 | + { |
3461 | + abortQuery(); |
3462 | + ui->labelQueryMessage->setText("The query timed out. You can try again, now or later."); |
3463 | + ui->labelQueryMessage->setVisible(true); |
3464 | + } |
3465 | + } |
3466 | + |
3467 | + //Reset the counter |
3468 | + countdown = 60; |
3469 | + |
3470 | + //Enable the interface |
3471 | + ui->lineEditQuery->setEnabled(true); |
3472 | + ui->pushButtonSendQuery->setEnabled(true); |
3473 | +} |
3474 | + |
3475 | +void MpcImportWindow::updateCountdown() |
3476 | +{ |
3477 | + --countdown; |
3478 | + if (countdown < 0) |
3479 | + { |
3480 | + resetCountdown(); |
3481 | + } |
3482 | + //If there has been an answer |
3483 | + else if (countdown > 50 && queryReply == NULL) |
3484 | + { |
3485 | + resetCountdown(); |
3486 | + } |
3487 | +} |
3488 | + |
3489 | +void MpcImportWindow::resetNotFound() |
3490 | +{ |
3491 | + ui->labelQueryMessage->setVisible(false); |
3492 | +} |
3493 | + |
3494 | +void MpcImportWindow::loadBookmarks() |
3495 | +{ |
3496 | + bookmarks[MpcComets].clear(); |
3497 | + bookmarks[MpcMinorPlanets].clear(); |
3498 | + |
3499 | + QString bookmarksFilePath(StelFileMgr::getUserDir() + "/modules/SolarSystemEditor/bookmarks.json"); |
3500 | + if (StelFileMgr::isReadable(bookmarksFilePath)) |
3501 | + { |
3502 | + QFile bookmarksFile(bookmarksFilePath); |
3503 | + if (bookmarksFile.open(QFile::ReadOnly | QFile::Text)) |
3504 | + { |
3505 | + QVariantMap jsonRoot = StelJsonParser::parse(bookmarksFile.readAll()).toMap(); |
3506 | + |
3507 | + loadBookmarksGroup(jsonRoot.value("mpcMinorPlanets").toMap(), bookmarks[MpcMinorPlanets]); |
3508 | + loadBookmarksGroup(jsonRoot.value("mpcComets").toMap(), bookmarks[MpcComets]); |
3509 | + |
3510 | + bookmarksFile.close(); |
3511 | + |
3512 | + //If nothing was read, continue |
3513 | + if (!bookmarks.value(MpcComets).isEmpty() && !bookmarks[MpcMinorPlanets].isEmpty()) |
3514 | + return; |
3515 | + } |
3516 | + } |
3517 | + |
3518 | + qDebug() << "Bookmarks file can't be read. Hard-coded bookmarks will be used."; |
3519 | + |
3520 | + //Initialize with hard-coded values |
3521 | + bookmarks[MpcMinorPlanets].insert("MPC's list of bright minor planets at opposition", "http://www.minorplanetcenter.org/iau/Ephemerides/Bright/2010/Soft00Bright.txt"); |
3522 | + bookmarks[MpcMinorPlanets].insert("MPCORB: near-Earth asteroids (NEAs)", "http://www.minorplanetcenter.org/iau/MPCORB/NEA.txt"); |
3523 | + bookmarks[MpcMinorPlanets].insert("MPCORB: potentially hazardous asteroids (PHAs)", "http://www.minorplanetcenter.org/iau/MPCORB/PHA.txt"); |
3524 | + bookmarks[MpcComets].insert("MPC's list of observable comets", "http://www.minorplanetcenter.org/iau/Ephemerides/Comets/Soft00Cmt.txt"); |
3525 | + |
3526 | + //Try to save them to a file |
3527 | + saveBookmarks(); |
3528 | +} |
3529 | + |
3530 | +void MpcImportWindow::loadBookmarksGroup(QVariantMap source, Bookmarks & bookmarkGroup) |
3531 | +{ |
3532 | + if (source.isEmpty()) |
3533 | + return; |
3534 | + |
3535 | + foreach (QString title, source.keys()) |
3536 | + { |
3537 | + QString url = source.value(title).toString(); |
3538 | + if (!url.isEmpty()) |
3539 | + bookmarkGroup.insert(title, url); |
3540 | + } |
3541 | +} |
3542 | + |
3543 | +void MpcImportWindow::saveBookmarks() |
3544 | +{ |
3545 | + try |
3546 | + { |
3547 | + StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir() + "/modules/SolarSystemEditor"); |
3548 | + |
3549 | + QVariantMap jsonRoot; |
3550 | + |
3551 | + QString bookmarksFilePath(StelFileMgr::getUserDir() + "/modules/SolarSystemEditor/bookmarks.json"); |
3552 | + |
3553 | + //If the file exists, load it first |
3554 | + if (StelFileMgr::isReadable(bookmarksFilePath)) |
3555 | + { |
3556 | + QFile bookmarksFile(bookmarksFilePath); |
3557 | + if (bookmarksFile.open(QFile::ReadOnly | QFile::Text)) |
3558 | + { |
3559 | + jsonRoot = StelJsonParser::parse(bookmarksFile.readAll()).toMap(); |
3560 | + bookmarksFile.close(); |
3561 | + } |
3562 | + } |
3563 | + |
3564 | + QFile bookmarksFile(bookmarksFilePath); |
3565 | + if (bookmarksFile.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) |
3566 | + { |
3567 | + QVariantMap minorPlanetsObject; |
3568 | + saveBookmarksGroup(bookmarks[MpcMinorPlanets], minorPlanetsObject); |
3569 | + //qDebug() << minorPlanetsObject.keys(); |
3570 | + jsonRoot.insert("mpcMinorPlanets", minorPlanetsObject); |
3571 | + |
3572 | + QVariantMap cometsObject; |
3573 | + saveBookmarksGroup(bookmarks[MpcComets], cometsObject); |
3574 | + jsonRoot.insert("mpcComets", cometsObject); |
3575 | + |
3576 | + StelJsonParser::write(jsonRoot, &bookmarksFile); |
3577 | + bookmarksFile.close(); |
3578 | + |
3579 | + qDebug() << "Bookmarks file saved to" << bookmarksFilePath; |
3580 | + return; |
3581 | + } |
3582 | + else |
3583 | + { |
3584 | + qDebug() << "Unable to write bookmarks file to" << bookmarksFilePath; |
3585 | + } |
3586 | + } |
3587 | + catch (std::exception & e) |
3588 | + { |
3589 | + qDebug() << "Unable to save bookmarks file:" << e.what(); |
3590 | + } |
3591 | +} |
3592 | + |
3593 | +void MpcImportWindow::saveBookmarksGroup(Bookmarks & bookmarkGroup, QVariantMap & output) |
3594 | +{ |
3595 | + foreach (QString title, bookmarkGroup.keys()) |
3596 | + { |
3597 | + output.insert(title, bookmarkGroup.value(title)); |
3598 | + } |
3599 | +} |
3600 | |
3601 | === added file 'plugins/SolarSystemEditor/src/gui/MpcImportWindow.hpp' |
3602 | --- plugins/SolarSystemEditor/src/gui/MpcImportWindow.hpp 1970-01-01 00:00:00 +0000 |
3603 | +++ plugins/SolarSystemEditor/src/gui/MpcImportWindow.hpp 2010-11-16 20:00:15 +0000 |
3604 | @@ -0,0 +1,135 @@ |
3605 | +/* |
3606 | + * Solar System editor plug-in for Stellarium |
3607 | + * |
3608 | + * Copyright (C) 2010 Bogdan Marinov |
3609 | + * |
3610 | + * This program is free software; you can redistribute it and/or |
3611 | + * modify it under the terms of the GNU General Public License |
3612 | + * as published by the Free Software Foundation; either version 2 |
3613 | + * of the License, or (at your option) any later version. |
3614 | + * |
3615 | + * This program is distributed in the hope that it will be useful, |
3616 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3617 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3618 | + * GNU General Public License for more details. |
3619 | + * |
3620 | + * You should have received a copy of the GNU General Public License |
3621 | + * along with this program; if not, write to the Free Software |
3622 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
3623 | + */ |
3624 | + |
3625 | +#ifndef _MPC_IMPORT_WINDOW_ |
3626 | +#define _MPC_IMPORT_WINDOW_ |
3627 | + |
3628 | +#include <QObject> |
3629 | +#include "StelDialog.hpp" |
3630 | + |
3631 | +#include "SolarSystemEditor.hpp" |
3632 | + |
3633 | +class Ui_mpcImportWindow; |
3634 | +class QNetworkAccessManager; |
3635 | +class QNetworkReply; |
3636 | +class QProgressBar; |
3637 | + |
3638 | +/*! \brief Window for importing orbital elements from various sources. |
3639 | + \author Bogdan Marinov |
3640 | +*/ |
3641 | +class MpcImportWindow : public StelDialog |
3642 | +{ |
3643 | + Q_OBJECT |
3644 | +public: |
3645 | + enum ImportType { |
3646 | + MpcComets, |
3647 | + MpcMinorPlanets |
3648 | + }; |
3649 | + |
3650 | + MpcImportWindow(); |
3651 | + virtual ~MpcImportWindow(); |
3652 | + void languageChanged(); |
3653 | + |
3654 | +signals: |
3655 | + void objectsImported(); |
3656 | + |
3657 | +private slots: |
3658 | + //Radio buttons for type |
3659 | + void switchImportType(bool checked); |
3660 | + |
3661 | + //File |
3662 | + void selectFile(); |
3663 | + |
3664 | + //Download |
3665 | + void pasteClipboardURL(); |
3666 | + void bookmarkSelected(QString); |
3667 | + |
3668 | + //Buttons for the list tab |
3669 | + void acquireObjectData(); |
3670 | + void abortDownload(); |
3671 | + |
3672 | + //Online search |
3673 | + void sendQuery(); |
3674 | + void abortQuery(); |
3675 | + void updateCountdown(); |
3676 | + void resetNotFound(); |
3677 | + |
3678 | + //Network |
3679 | + void updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); |
3680 | + void updateQueryProgress(qint64 bytesReceived, qint64 bytesTotal); |
3681 | + void downloadComplete(QNetworkReply * reply); |
3682 | + void queryComplete(QNetworkReply * reply); |
3683 | + |
3684 | + //! Marks (checks) all items in the results lists |
3685 | + void markAll(); |
3686 | + //! Unmarks (unchecks) all items in the results lists |
3687 | + void unmarkAll(); |
3688 | + void addObjects(); |
3689 | + void discardObjects(); |
3690 | + |
3691 | + //! resets the dialog to the state it should be in immediately after createDialogContent();. |
3692 | + void resetDialog(); |
3693 | + |
3694 | +private: |
3695 | + SolarSystemEditor * ssoManager; |
3696 | + QList<SsoElements> candidatesForAddition; |
3697 | + QList<SsoElements> candidatesForUpdate; |
3698 | + |
3699 | + ImportType importType; |
3700 | + |
3701 | + //! wrapper for the single object function to allow multiple formats. |
3702 | + SsoElements readElementsFromString(QString elements); |
3703 | + //! wrapper for the file function to allow multiple formats |
3704 | + QList<SsoElements> readElementsFromFile(ImportType type, QString filePath); |
3705 | + |
3706 | + void populateBookmarksList(); |
3707 | + //void populateCandidateObjects(); |
3708 | + void populateCandidateObjects(QList<SsoElements>); |
3709 | + void enableInterface(bool enable); |
3710 | + |
3711 | + //Downloading |
3712 | + QNetworkAccessManager * networkManager; |
3713 | + QNetworkReply * downloadReply; |
3714 | + QNetworkReply * queryReply; |
3715 | + QProgressBar * downloadProgressBar; |
3716 | + QProgressBar * queryProgressBar; |
3717 | + void startDownload(QString url); |
3718 | + void deleteDownloadProgressBar(); |
3719 | + void deleteQueryProgressBar(); |
3720 | + |
3721 | + typedef QHash<QString,QString> Bookmarks; |
3722 | + QHash<ImportType, Bookmarks> bookmarks; |
3723 | + void loadBookmarks(); |
3724 | + void loadBookmarksGroup(QVariantMap source, Bookmarks & bookmarkGroup); |
3725 | + void saveBookmarks(); |
3726 | + void saveBookmarksGroup(Bookmarks & bookmarkGroup, QVariantMap & output); |
3727 | + |
3728 | + //Online search |
3729 | + int countdown; |
3730 | + QTimer * countdownTimer; |
3731 | + void startCountdown(); |
3732 | + void resetCountdown(); |
3733 | + |
3734 | +protected: |
3735 | + virtual void createDialogContent(); |
3736 | + Ui_mpcImportWindow * ui; |
3737 | +}; |
3738 | + |
3739 | +#endif //_MPC_IMPORT_WINDOW_ |
3740 | |
3741 | === added file 'plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.cpp' |
3742 | --- plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.cpp 1970-01-01 00:00:00 +0000 |
3743 | +++ plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.cpp 2010-11-16 20:00:15 +0000 |
3744 | @@ -0,0 +1,170 @@ |
3745 | +/* |
3746 | + * Solar System editor plug-in for Stellarium |
3747 | + * |
3748 | + * Copyright (C) 2010 Bogdan Marinov |
3749 | + * |
3750 | + * This program is free software; you can redistribute it and/or |
3751 | + * modify it under the terms of the GNU General Public License |
3752 | + * as published by the Free Software Foundation; either version 2 |
3753 | + * of the License, or (at your option) any later version. |
3754 | + * |
3755 | + * This program is distributed in the hope that it will be useful, |
3756 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3757 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3758 | + * GNU General Public License for more details. |
3759 | + * |
3760 | + * You should have received a copy of the GNU General Public License |
3761 | + * along with this program; if not, write to the Free Software |
3762 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
3763 | + */ |
3764 | + |
3765 | +#include "SolarSystemEditor.hpp" |
3766 | + |
3767 | +#include "SolarSystemManagerWindow.hpp" |
3768 | +#include "ui_solarSystemManagerWindow.h" |
3769 | + |
3770 | +#include "MpcImportWindow.hpp" |
3771 | +#include "ManualImportWindow.hpp" |
3772 | + |
3773 | +#include "StelApp.hpp" |
3774 | +#include "StelFileMgr.hpp" |
3775 | +#include "StelModuleMgr.hpp" |
3776 | +#include "Planet.hpp" |
3777 | +#include "SolarSystem.hpp" |
3778 | + |
3779 | +#include <QFileDialog> |
3780 | + |
3781 | +SolarSystemManagerWindow::SolarSystemManagerWindow() |
3782 | +{ |
3783 | + ui = new Ui_solarSystemManagerWindow(); |
3784 | + mpcImportWindow = new MpcImportWindow(); |
3785 | + manualImportWindow = NULL; |
3786 | + |
3787 | + ssoManager = GETSTELMODULE(SolarSystemEditor); |
3788 | +} |
3789 | + |
3790 | +SolarSystemManagerWindow::~SolarSystemManagerWindow() |
3791 | +{ |
3792 | + delete ui; |
3793 | + |
3794 | + if (mpcImportWindow) |
3795 | + delete mpcImportWindow; |
3796 | + if (manualImportWindow) |
3797 | + delete manualImportWindow; |
3798 | +} |
3799 | + |
3800 | +void SolarSystemManagerWindow::createDialogContent() |
3801 | +{ |
3802 | + ui->setupUi(dialog); |
3803 | + |
3804 | + //Signals |
3805 | + connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close())); |
3806 | + connect(ui->pushButtonCopyFile, SIGNAL(clicked()), this, SLOT(copyConfiguration())); |
3807 | + connect(ui->pushButtonReplaceFile, SIGNAL(clicked()), this, SLOT(replaceConfiguration())); |
3808 | + connect(ui->pushButtonRemove, SIGNAL(clicked()), this, SLOT(removeObject())); |
3809 | + connect(ui->pushButtonImportMPC, SIGNAL(clicked()), this, SLOT(newImportMPC())); |
3810 | + connect(ui->pushButtonManual, SIGNAL(clicked()), this, SLOT(newImportManual())); |
3811 | + |
3812 | + connect(ssoManager, SIGNAL(solarSystemChanged()), this, SLOT(populateSolarSystemList())); |
3813 | + connect(ui->pushButtonReset, SIGNAL(clicked()), ssoManager, SLOT(resetSolarSystemToDefault())); |
3814 | + |
3815 | + ui->labelVersion->setText(QString("Version %1").arg(PLUGIN_VERSION)); |
3816 | + //Remove the "Data Import" tab |
3817 | + //TODO: (temporary, until the ManualImportWindow is finished) |
3818 | + ui->tabWidget->removeTab(2); |
3819 | + |
3820 | + Q_ASSERT(mpcImportWindow); |
3821 | + //Rebuild the list if any planets have been imported |
3822 | + connect(mpcImportWindow, SIGNAL(objectsImported()), this, SLOT(populateSolarSystemList())); |
3823 | + |
3824 | + ui->lineEditUserFilePath->setText(ssoManager->getCustomSolarSystemFilePath()); |
3825 | + populateSolarSystemList(); |
3826 | +} |
3827 | + |
3828 | +void SolarSystemManagerWindow::languageChanged() |
3829 | +{ |
3830 | + if (dialog) |
3831 | + { |
3832 | + ui->retranslateUi(dialog); |
3833 | + populateSolarSystemList(); |
3834 | + ui->labelVersion->setText(QString("Version %1").arg(PLUGIN_VERSION)); |
3835 | + } |
3836 | + |
3837 | + if (mpcImportWindow) |
3838 | + mpcImportWindow->languageChanged(); |
3839 | +} |
3840 | + |
3841 | +void SolarSystemManagerWindow::newImportMPC() |
3842 | +{ |
3843 | + Q_ASSERT(mpcImportWindow); |
3844 | + |
3845 | + mpcImportWindow->setVisible(true); |
3846 | +} |
3847 | + |
3848 | +void SolarSystemManagerWindow::newImportManual() |
3849 | +{ |
3850 | + if (manualImportWindow == NULL) |
3851 | + { |
3852 | + manualImportWindow = new ManualImportWindow(); |
3853 | + connect(manualImportWindow, SIGNAL(visibleChanged(bool)), this, SLOT(resetImportManual(bool))); |
3854 | + } |
3855 | + |
3856 | + manualImportWindow->setVisible(true); |
3857 | +} |
3858 | + |
3859 | +void SolarSystemManagerWindow::resetImportManual(bool show) |
3860 | +{ |
3861 | + //If the window is being displayed, do nothing |
3862 | + if (show) |
3863 | + return; |
3864 | + |
3865 | + if (manualImportWindow) |
3866 | + { |
3867 | + //TODO:Move this out of here! |
3868 | + //Reload the list, in case there are new objects |
3869 | + populateSolarSystemList(); |
3870 | + |
3871 | + delete manualImportWindow; |
3872 | + manualImportWindow = NULL; |
3873 | + |
3874 | + //This window is in the background, bring it to the foreground |
3875 | + dialog->setVisible(true); |
3876 | + } |
3877 | +} |
3878 | + |
3879 | +void SolarSystemManagerWindow::populateSolarSystemList() |
3880 | +{ |
3881 | + unlocalizedNames.clear(); |
3882 | + foreach (const PlanetP & object, GETSTELMODULE(SolarSystem)->getAllPlanets()) |
3883 | + { |
3884 | + unlocalizedNames.insert(object->getNameI18n(), object->getEnglishName()); |
3885 | + } |
3886 | + |
3887 | + ui->listWidgetObjects->clear(); |
3888 | + ui->listWidgetObjects->addItems(unlocalizedNames.keys()); |
3889 | + //No explicit sorting is necessary: sortingEnabled is set in the .ui |
3890 | +} |
3891 | + |
3892 | +void SolarSystemManagerWindow::removeObject() |
3893 | +{ |
3894 | + if(ui->listWidgetObjects->currentItem()) |
3895 | + { |
3896 | + QString ssoI18nName = ui->listWidgetObjects->currentItem()->text(); |
3897 | + QString ssoEnglishName = unlocalizedNames.value(ssoI18nName); |
3898 | + //qDebug() << ssoId; |
3899 | + //TODO: Ask for confirmation first? |
3900 | + ssoManager->removeSsoWithName(ssoEnglishName); |
3901 | + } |
3902 | +} |
3903 | + |
3904 | +void SolarSystemManagerWindow::copyConfiguration() |
3905 | +{ |
3906 | + QString filePath = QFileDialog::getSaveFileName(0, "Save the Solar System configuration file as...", StelFileMgr::getDesktopDir()); |
3907 | + ssoManager->copySolarSystemConfigurationFileTo(filePath); |
3908 | +} |
3909 | + |
3910 | +void SolarSystemManagerWindow::replaceConfiguration() |
3911 | +{ |
3912 | + QString filePath = QFileDialog::getOpenFileName(0, "Select a file to replace the Solar System configuration file", StelFileMgr::getDesktopDir(), QString("Configration files (*.ini)")); |
3913 | + ssoManager->replaceSolarSystemConfigurationFileWith(filePath); |
3914 | +} |
3915 | |
3916 | === added file 'plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.hpp' |
3917 | --- plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.hpp 1970-01-01 00:00:00 +0000 |
3918 | +++ plugins/SolarSystemEditor/src/gui/SolarSystemManagerWindow.hpp 2010-11-16 20:00:15 +0000 |
3919 | @@ -0,0 +1,73 @@ |
3920 | +/* |
3921 | + * Solar System editor plug-in for Stellarium |
3922 | + * |
3923 | + * Copyright (C) 2010 Bogdan Marinov |
3924 | + * |
3925 | + * This program is free software; you can redistribute it and/or |
3926 | + * modify it under the terms of the GNU General Public License |
3927 | + * as published by the Free Software Foundation; either version 2 |
3928 | + * of the License, or (at your option) any later version. |
3929 | + * |
3930 | + * This program is distributed in the hope that it will be useful, |
3931 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3932 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3933 | + * GNU General Public License for more details. |
3934 | + * |
3935 | + * You should have received a copy of the GNU General Public License |
3936 | + * along with this program; if not, write to the Free Software |
3937 | + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
3938 | + */ |
3939 | + |
3940 | +#ifndef _SOLAR_SYSTEM_MANAGER_WINDOW_ |
3941 | +#define _SOLAR_SYSTEM_MANAGER_WINDOW_ |
3942 | + |
3943 | +#include <QObject> |
3944 | +#include "StelDialog.hpp" |
3945 | + |
3946 | +#include <QHash> |
3947 | +#include <QString> |
3948 | + |
3949 | +class SolarSystemEditor; |
3950 | + |
3951 | +class Ui_solarSystemManagerWindow; |
3952 | +class MpcImportWindow; |
3953 | +class ManualImportWindow; |
3954 | + |
3955 | +/*! \brief Main window for handling Solar System objects. |
3956 | + \author Bogdan Marinov |
3957 | +*/ |
3958 | +class SolarSystemManagerWindow : public StelDialog |
3959 | +{ |
3960 | + Q_OBJECT |
3961 | +public: |
3962 | + SolarSystemManagerWindow(); |
3963 | + virtual ~SolarSystemManagerWindow(); |
3964 | + void languageChanged(); |
3965 | + |
3966 | +protected: |
3967 | + virtual void createDialogContent(); |
3968 | + Ui_solarSystemManagerWindow * ui; |
3969 | + |
3970 | +private slots: |
3971 | + //! \todo Find a way to suggest a default file name (select directory instead of file?) |
3972 | + void copyConfiguration(); |
3973 | + void replaceConfiguration(); |
3974 | + |
3975 | + void populateSolarSystemList(); |
3976 | + void removeObject(); |
3977 | + |
3978 | + void newImportMPC(); |
3979 | + |
3980 | + void newImportManual(); |
3981 | + void resetImportManual(bool); |
3982 | + |
3983 | +private: |
3984 | + MpcImportWindow* mpcImportWindow; |
3985 | + ManualImportWindow * manualImportWindow; |
3986 | + |
3987 | + SolarSystemEditor * ssoManager; |
3988 | + |
3989 | + QHash<QString,QString> unlocalizedNames; |
3990 | +}; |
3991 | + |
3992 | +#endif //_SOLAR_SYSTEM_MANAGER_WINDOW_ |
3993 | |
3994 | === added file 'plugins/SolarSystemEditor/src/gui/manualImportWindow.ui' |
3995 | --- plugins/SolarSystemEditor/src/gui/manualImportWindow.ui 1970-01-01 00:00:00 +0000 |
3996 | +++ plugins/SolarSystemEditor/src/gui/manualImportWindow.ui 2010-11-16 20:00:15 +0000 |
3997 | @@ -0,0 +1,890 @@ |
3998 | +<?xml version="1.0" encoding="UTF-8"?> |
3999 | +<ui version="4.0"> |
4000 | + <class>manualImportWindow</class> |
4001 | + <widget class="QWidget" name="manualImportWindow"> |
4002 | + <property name="geometry"> |
4003 | + <rect> |
4004 | + <x>0</x> |
4005 | + <y>0</y> |
4006 | + <width>600</width> |
4007 | + <height>500</height> |
4008 | + </rect> |
4009 | + </property> |
4010 | + <layout class="QGridLayout" name="gridLayoutWindow"> |
4011 | + <property name="margin"> |
4012 | + <number>0</number> |
4013 | + </property> |
4014 | + <property name="spacing"> |
4015 | + <number>0</number> |
4016 | + </property> |
4017 | + <item row="0" column="0" colspan="2"> |
4018 | + <widget class="BarFrame" name="LocationBar"> |
4019 | + <property name="sizePolicy"> |
4020 | + <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> |
4021 | + <horstretch>0</horstretch> |
4022 | + <verstretch>0</verstretch> |
4023 | + </sizepolicy> |
4024 | + </property> |
4025 | + <property name="minimumSize"> |
4026 | + <size> |
4027 | + <width>0</width> |
4028 | + <height>25</height> |
4029 | + </size> |
4030 | + </property> |
4031 | + <property name="maximumSize"> |
4032 | + <size> |
4033 | + <width>16777215</width> |
4034 | + <height>30</height> |
4035 | + </size> |
4036 | + </property> |
4037 | + <property name="focusPolicy"> |
4038 | + <enum>Qt::NoFocus</enum> |
4039 | + </property> |
4040 | + <property name="autoFillBackground"> |
4041 | + <bool>false</bool> |
4042 | + </property> |
4043 | + <property name="frameShape"> |
4044 | + <enum>QFrame::StyledPanel</enum> |
4045 | + </property> |
4046 | + <layout class="QHBoxLayout" name="_2"> |
4047 | + <property name="spacing"> |
4048 | + <number>6</number> |
4049 | + </property> |
4050 | + <property name="leftMargin"> |
4051 | + <number>0</number> |
4052 | + </property> |
4053 | + <property name="topMargin"> |
4054 | + <number>0</number> |
4055 | + </property> |
4056 | + <property name="rightMargin"> |
4057 | + <number>4</number> |
4058 | + </property> |
4059 | + <property name="bottomMargin"> |
4060 | + <number>0</number> |
4061 | + </property> |
4062 | + <item> |
4063 | + <spacer name="leftSpacer"> |
4064 | + <property name="orientation"> |
4065 | + <enum>Qt::Horizontal</enum> |
4066 | + </property> |
4067 | + <property name="sizeHint" stdset="0"> |
4068 | + <size> |
4069 | + <width>40</width> |
4070 | + <height>20</height> |
4071 | + </size> |
4072 | + </property> |
4073 | + </spacer> |
4074 | + </item> |
4075 | + <item> |
4076 | + <widget class="QLabel" name="stelWindowTitle"> |
4077 | + <property name="text"> |
4078 | + <string notr="true" extracomment="The title of the window will be set during runtime">Define an object</string> |
4079 | + </property> |
4080 | + </widget> |
4081 | + </item> |
4082 | + <item> |
4083 | + <spacer name="rightSpacer"> |
4084 | + <property name="orientation"> |
4085 | + <enum>Qt::Horizontal</enum> |
4086 | + </property> |
4087 | + <property name="sizeHint" stdset="0"> |
4088 | + <size> |
4089 | + <width>40</width> |
4090 | + <height>20</height> |
4091 | + </size> |
4092 | + </property> |
4093 | + </spacer> |
4094 | + </item> |
4095 | + <item> |
4096 | + <widget class="QPushButton" name="closeStelWindow"> |
4097 | + <property name="minimumSize"> |
4098 | + <size> |
4099 | + <width>16</width> |
4100 | + <height>16</height> |
4101 | + </size> |
4102 | + </property> |
4103 | + <property name="maximumSize"> |
4104 | + <size> |
4105 | + <width>16</width> |
4106 | + <height>16</height> |
4107 | + </size> |
4108 | + </property> |
4109 | + <property name="focusPolicy"> |
4110 | + <enum>Qt::NoFocus</enum> |
4111 | + </property> |
4112 | + <property name="text"> |
4113 | + <string/> |
4114 | + </property> |
4115 | + </widget> |
4116 | + </item> |
4117 | + </layout> |
4118 | + </widget> |
4119 | + </item> |
4120 | + <item row="1" column="1"> |
4121 | + <widget class="QGroupBox" name="groupBoxObjectType"> |
4122 | + <property name="title"> |
4123 | + <string>Object type</string> |
4124 | + </property> |
4125 | + <property name="alignment"> |
4126 | + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
4127 | + </property> |
4128 | + <layout class="QVBoxLayout" name="verticalLayoutObjectType"> |
4129 | + <property name="margin"> |
4130 | + <number>0</number> |
4131 | + </property> |
4132 | + <item> |
4133 | + <widget class="QRadioButton" name="radioButtonSolarSystemObject"> |
4134 | + <property name="text"> |
4135 | + <string>Solar System object</string> |
4136 | + </property> |
4137 | + </widget> |
4138 | + </item> |
4139 | + <item> |
4140 | + <widget class="QRadioButton" name="radioButtonMinorPlanet"> |
4141 | + <property name="text"> |
4142 | + <string>Minor planet (asteroid)</string> |
4143 | + </property> |
4144 | + </widget> |
4145 | + </item> |
4146 | + <item> |
4147 | + <widget class="QRadioButton" name="radioButtonComet"> |
4148 | + <property name="text"> |
4149 | + <string>Comet</string> |
4150 | + </property> |
4151 | + </widget> |
4152 | + </item> |
4153 | + <item> |
4154 | + <widget class="QRadioButton" name="radioButtonSatellite"> |
4155 | + <property name="text"> |
4156 | + <string>Satellite</string> |
4157 | + </property> |
4158 | + </widget> |
4159 | + </item> |
4160 | + </layout> |
4161 | + </widget> |
4162 | + </item> |
4163 | + <item row="1" column="0"> |
4164 | + <widget class="QGroupBox" name="groupBoxName"> |
4165 | + <property name="title"> |
4166 | + <string>Name</string> |
4167 | + </property> |
4168 | + <property name="alignment"> |
4169 | + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
4170 | + </property> |
4171 | + <layout class="QGridLayout" name="gridLayoutName"> |
4172 | + <property name="margin"> |
4173 | + <number>0</number> |
4174 | + </property> |
4175 | + <item row="0" column="0"> |
4176 | + <widget class="QLabel" name="labelName"> |
4177 | + <property name="text"> |
4178 | + <string>Name</string> |
4179 | + </property> |
4180 | + </widget> |
4181 | + </item> |
4182 | + <item row="0" column="1"> |
4183 | + <widget class="QLineEdit" name="lineEditName"/> |
4184 | + </item> |
4185 | + <item row="1" column="0"> |
4186 | + <widget class="QLabel" name="labelIdentifier"> |
4187 | + <property name="text"> |
4188 | + <string>Identifier</string> |
4189 | + </property> |
4190 | + </widget> |
4191 | + </item> |
4192 | + <item row="1" column="1"> |
4193 | + <widget class="QLineEdit" name="lineEditIdentifier"/> |
4194 | + </item> |
4195 | + <item row="2" column="0"> |
4196 | + <widget class="QCheckBox" name="checkBoxMinorPlanetNumber"> |
4197 | + <property name="text"> |
4198 | + <string>Minor planet number</string> |
4199 | + </property> |
4200 | + </widget> |
4201 | + </item> |
4202 | + <item row="2" column="1"> |
4203 | + <widget class="QLineEdit" name="lineEditMinorPlanetNumber"/> |
4204 | + </item> |
4205 | + </layout> |
4206 | + </widget> |
4207 | + </item> |
4208 | + <item row="2" column="0" colspan="2"> |
4209 | + <widget class="QScrollArea" name="scrollArea"> |
4210 | + <property name="widgetResizable"> |
4211 | + <bool>true</bool> |
4212 | + </property> |
4213 | + <property name="alignment"> |
4214 | + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> |
4215 | + </property> |
4216 | + <widget class="QWidget" name="scrollAreaWidgetContents"> |
4217 | + <property name="geometry"> |
4218 | + <rect> |
4219 | + <x>0</x> |
4220 | + <y>0</y> |
4221 | + <width>582</width> |
4222 | + <height>1436</height> |
4223 | + </rect> |
4224 | + </property> |
4225 | + <layout class="QVBoxLayout" name="verticalLayoutScroll"> |
4226 | + <property name="margin"> |
4227 | + <number>0</number> |
4228 | + </property> |
4229 | + <item> |
4230 | + <widget class="QGroupBox" name="groupBoxProperties"> |
4231 | + <property name="title"> |
4232 | + <string>Properties</string> |
4233 | + </property> |
4234 | + <layout class="QGridLayout" name="gridLayout_4"> |
4235 | + <item row="0" column="0"> |
4236 | + <widget class="QLabel" name="labelParent"> |
4237 | + <property name="text"> |
4238 | + <string>Parent:</string> |
4239 | + </property> |
4240 | + </widget> |
4241 | + </item> |
4242 | + <item row="0" column="2" colspan="2"> |
4243 | + <widget class="QComboBox" name="comboBoxParent"/> |
4244 | + </item> |
4245 | + <item row="1" column="0"> |
4246 | + <widget class="QLabel" name="labelRadius"> |
4247 | + <property name="text"> |
4248 | + <string>Radius:</string> |
4249 | + </property> |
4250 | + </widget> |
4251 | + </item> |
4252 | + <item row="1" column="2" colspan="2"> |
4253 | + <widget class="QLineEdit" name="lineEditRadius"/> |
4254 | + </item> |
4255 | + <item row="2" column="0"> |
4256 | + <widget class="QLabel" name="labelOblateness"> |
4257 | + <property name="text"> |
4258 | + <string>Oblateness:</string> |
4259 | + </property> |
4260 | + </widget> |
4261 | + </item> |
4262 | + <item row="2" column="2" colspan="2"> |
4263 | + <widget class="QLineEdit" name="lineEditOblateness"/> |
4264 | + </item> |
4265 | + <item row="3" column="0"> |
4266 | + <widget class="QLabel" name="labelAlbedo"> |
4267 | + <property name="text"> |
4268 | + <string>Albedo:</string> |
4269 | + </property> |
4270 | + </widget> |
4271 | + </item> |
4272 | + <item row="3" column="2" colspan="2"> |
4273 | + <widget class="QLineEdit" name="lineEditAlbedo"/> |
4274 | + </item> |
4275 | + <item row="4" column="0"> |
4276 | + <widget class="QLabel" name="labelColor"> |
4277 | + <property name="text"> |
4278 | + <string>Color:</string> |
4279 | + </property> |
4280 | + </widget> |
4281 | + </item> |
4282 | + <item row="4" column="3"> |
4283 | + <widget class="QPushButton" name="pushButtonSelectColor"/> |
4284 | + </item> |
4285 | + <item row="5" column="0" colspan="4"> |
4286 | + <widget class="QCheckBox" name="checkBoxLighting"> |
4287 | + <property name="text"> |
4288 | + <string>Lighting (TODO: More clear name)</string> |
4289 | + </property> |
4290 | + </widget> |
4291 | + </item> |
4292 | + <item row="6" column="0" colspan="4"> |
4293 | + <widget class="QCheckBox" name="checkBoxAtmosphere"> |
4294 | + <property name="text"> |
4295 | + <string>Atmosphere</string> |
4296 | + </property> |
4297 | + </widget> |
4298 | + </item> |
4299 | + <item row="7" column="0" colspan="4"> |
4300 | + <widget class="QCheckBox" name="checkBoxHidden"> |
4301 | + <property name="text"> |
4302 | + <string>Hidden</string> |
4303 | + </property> |
4304 | + </widget> |
4305 | + </item> |
4306 | + <item row="8" column="0"> |
4307 | + <widget class="QLabel" name="labelTexture"> |
4308 | + <property name="text"> |
4309 | + <string>Texture:</string> |
4310 | + </property> |
4311 | + </widget> |
4312 | + </item> |
4313 | + <item row="8" column="2"> |
4314 | + <widget class="QLineEdit" name="lineEditTexture"> |
4315 | + <property name="readOnly"> |
4316 | + <bool>true</bool> |
4317 | + </property> |
4318 | + </widget> |
4319 | + </item> |
4320 | + <item row="8" column="3"> |
4321 | + <widget class="QPushButton" name="pushButtonSelectTexture"> |
4322 | + <property name="text"> |
4323 | + <string>...</string> |
4324 | + </property> |
4325 | + </widget> |
4326 | + </item> |
4327 | + <item row="9" column="0" colspan="4"> |
4328 | + <widget class="QFrame" name="frameMagnitude"> |
4329 | + <layout class="QGridLayout" name="gridLayoutMagnitude"> |
4330 | + <property name="margin"> |
4331 | + <number>0</number> |
4332 | + </property> |
4333 | + <item row="1" column="0"> |
4334 | + <widget class="QLabel" name="labelAbsoluteMagnitude"> |
4335 | + <property name="text"> |
4336 | + <string>Absolute magnitude:</string> |
4337 | + </property> |
4338 | + </widget> |
4339 | + </item> |
4340 | + <item row="1" column="1"> |
4341 | + <widget class="QLineEdit" name="lineEditAbsoluteMagnitude"/> |
4342 | + </item> |
4343 | + <item row="1" column="2"> |
4344 | + <widget class="QLabel" name="labelSlopeParameter"> |
4345 | + <property name="text"> |
4346 | + <string>Slope parameter:</string> |
4347 | + </property> |
4348 | + </widget> |
4349 | + </item> |
4350 | + <item row="1" column="3"> |
4351 | + <widget class="QLineEdit" name="lineEditSlopeParameter"/> |
4352 | + </item> |
4353 | + <item row="2" column="0" colspan="4"> |
4354 | + <widget class="QPushButton" name="pushButtonCalculateRadius"> |
4355 | + <property name="text"> |
4356 | + <string>Calculate the object's radius from the absolute magnitude and the current albedo</string> |
4357 | + </property> |
4358 | + </widget> |
4359 | + </item> |
4360 | + <item row="0" column="0" colspan="4"> |
4361 | + <widget class="QLabel" name="labelMagnitudeSystem"> |
4362 | + <property name="text"> |
4363 | + <string>H-G two parameter magnitude system for minor planets:</string> |
4364 | + </property> |
4365 | + </widget> |
4366 | + </item> |
4367 | + </layout> |
4368 | + </widget> |
4369 | + </item> |
4370 | + <item row="4" column="2"> |
4371 | + <widget class="QLineEdit" name="lineEditColor"/> |
4372 | + </item> |
4373 | + </layout> |
4374 | + </widget> |
4375 | + </item> |
4376 | + <item> |
4377 | + <widget class="QGroupBox" name="groupBoxOrbitalElements"> |
4378 | + <property name="title"> |
4379 | + <string>Orbital elements</string> |
4380 | + </property> |
4381 | + <layout class="QGridLayout" name="gridLayoutOrbitalElements"> |
4382 | + <property name="margin"> |
4383 | + <number>0</number> |
4384 | + </property> |
4385 | + <item row="0" column="0" colspan="2"> |
4386 | + <widget class="QLabel" name="labelOrbitType"> |
4387 | + <property name="text"> |
4388 | + <string>Orbital function type:</string> |
4389 | + </property> |
4390 | + </widget> |
4391 | + </item> |
4392 | + <item row="1" column="0" colspan="2"> |
4393 | + <widget class="QRadioButton" name="radioButtonCometaryOrbit"> |
4394 | + <property name="text"> |
4395 | + <string>Cometary orbit</string> |
4396 | + </property> |
4397 | + </widget> |
4398 | + </item> |
4399 | + <item row="2" column="0" colspan="2"> |
4400 | + <widget class="QRadioButton" name="radioButtonEllipticOrbit"> |
4401 | + <property name="text"> |
4402 | + <string>Elliptic orbit</string> |
4403 | + </property> |
4404 | + </widget> |
4405 | + </item> |
4406 | + <item row="4" column="0"> |
4407 | + <widget class="QLabel" name="labelEccentricity"> |
4408 | + <property name="text"> |
4409 | + <string>Eccentricity (%1):</string> |
4410 | + </property> |
4411 | + </widget> |
4412 | + </item> |
4413 | + <item row="4" column="1"> |
4414 | + <widget class="QLineEdit" name="lineEditEccentricity"> |
4415 | + <property name="text"> |
4416 | + <string>0</string> |
4417 | + </property> |
4418 | + </widget> |
4419 | + </item> |
4420 | + <item row="5" column="0"> |
4421 | + <widget class="QLabel" name="labelInclination"> |
4422 | + <property name="text"> |
4423 | + <string>Inclination (degrees):</string> |
4424 | + </property> |
4425 | + </widget> |
4426 | + </item> |
4427 | + <item row="5" column="1"> |
4428 | + <widget class="QLineEdit" name="lineEditInclination"/> |
4429 | + </item> |
4430 | + <item row="6" column="0"> |
4431 | + <widget class="QLabel" name="labelLongitudeOfTheAscendingNode"> |
4432 | + <property name="text"> |
4433 | + <string>Longitude of the ascending node %1:</string> |
4434 | + </property> |
4435 | + </widget> |
4436 | + </item> |
4437 | + <item row="6" column="1"> |
4438 | + <widget class="QLineEdit" name="lineEditLongitudeOfTheAscendingNode"/> |
4439 | + </item> |
4440 | + <item row="7" column="0" colspan="2"> |
4441 | + <widget class="QFrame" name="framePeriapsis"> |
4442 | + <layout class="QGridLayout" name="gridLayoutPeriapsis"> |
4443 | + <property name="margin"> |
4444 | + <number>0</number> |
4445 | + </property> |
4446 | + <item row="0" column="0"> |
4447 | + <widget class="QRadioButton" name="radioButtonArgumentOfPeriapsis"> |
4448 | + <property name="text"> |
4449 | + <string>Argument of the periapsis %1:</string> |
4450 | + </property> |
4451 | + </widget> |
4452 | + </item> |
4453 | + <item row="0" column="1"> |
4454 | + <widget class="QLineEdit" name="lineEditArgumentOfPeriapsis"/> |
4455 | + </item> |
4456 | + <item row="1" column="0"> |
4457 | + <widget class="QRadioButton" name="radioButtonLongitudeOfPeriapsis"> |
4458 | + <property name="text"> |
4459 | + <string>Longitude of the periapsis %1:</string> |
4460 | + </property> |
4461 | + </widget> |
4462 | + </item> |
4463 | + <item row="1" column="1"> |
4464 | + <widget class="QLineEdit" name="lineEditLongitudeOfPeriapsis"/> |
4465 | + </item> |
4466 | + </layout> |
4467 | + </widget> |
4468 | + </item> |
4469 | + <item row="8" column="0" colspan="2"> |
4470 | + <widget class="QFrame" name="frameSemiMajorAxis"> |
4471 | + <layout class="QGridLayout" name="gridLayoutSemiMajorAxis"> |
4472 | + <property name="margin"> |
4473 | + <number>0</number> |
4474 | + </property> |
4475 | + <item row="0" column="1"> |
4476 | + <widget class="QLineEdit" name="lineEditSemiMajorAxis"/> |
4477 | + </item> |
4478 | + <item row="1" column="1"> |
4479 | + <widget class="QLineEdit" name="lineEditPeriapsisDistance"/> |
4480 | + </item> |
4481 | + <item row="0" column="0"> |
4482 | + <widget class="QRadioButton" name="radioButtonSemiMajorAxis"> |
4483 | + <property name="text"> |
4484 | + <string>Semi-major axis %1:</string> |
4485 | + </property> |
4486 | + </widget> |
4487 | + </item> |
4488 | + <item row="1" column="0"> |
4489 | + <widget class="QRadioButton" name="radioButtonPeriapsisDistance"> |
4490 | + <property name="text"> |
4491 | + <string>Periapsis distance %1:</string> |
4492 | + </property> |
4493 | + </widget> |
4494 | + </item> |
4495 | + </layout> |
4496 | + </widget> |
4497 | + </item> |
4498 | + <item row="9" column="0" colspan="2"> |
4499 | + <widget class="QFrame" name="framePeriod"> |
4500 | + <layout class="QGridLayout" name="gridLayoutPeriod"> |
4501 | + <property name="margin"> |
4502 | + <number>0</number> |
4503 | + </property> |
4504 | + <item row="0" column="0"> |
4505 | + <widget class="QCheckBox" name="checkBoxPeriod"> |
4506 | + <property name="text"> |
4507 | + <string>Period:</string> |
4508 | + </property> |
4509 | + </widget> |
4510 | + </item> |
4511 | + <item row="0" column="1"> |
4512 | + <widget class="QLineEdit" name="lineEditPeriod"/> |
4513 | + </item> |
4514 | + <item row="1" column="0"> |
4515 | + <widget class="QCheckBox" name="checkBoxMeanMotion"> |
4516 | + <property name="text"> |
4517 | + <string>Mean motion:</string> |
4518 | + </property> |
4519 | + </widget> |
4520 | + </item> |
4521 | + <item row="1" column="1"> |
4522 | + <widget class="QLineEdit" name="lineEditMeanMotion"/> |
4523 | + </item> |
4524 | + </layout> |
4525 | + </widget> |
4526 | + </item> |
4527 | + <item row="10" column="0" colspan="2"> |
4528 | + <widget class="QFrame" name="frameEpoch"> |
4529 | + <layout class="QGridLayout" name="gridLayoutEpoch"> |
4530 | + <property name="margin"> |
4531 | + <number>0</number> |
4532 | + </property> |
4533 | + <item row="0" column="1"> |
4534 | + <widget class="QLineEdit" name="lineEditEpoch"/> |
4535 | + </item> |
4536 | + <item row="1" column="1" colspan="2"> |
4537 | + <widget class="QLineEdit" name="lineEditTimeOfPeriapsis"/> |
4538 | + </item> |
4539 | + <item row="0" column="0"> |
4540 | + <widget class="QRadioButton" name="radioButtonEpoch"> |
4541 | + <property name="text"> |
4542 | + <string>Epoch:</string> |
4543 | + </property> |
4544 | + </widget> |
4545 | + </item> |
4546 | + <item row="1" column="0"> |
4547 | + <widget class="QRadioButton" name="radioButtonTimeOfPeriapsis"> |
4548 | + <property name="text"> |
4549 | + <string>Time of periapsis passage:</string> |
4550 | + </property> |
4551 | + </widget> |
4552 | + </item> |
4553 | + <item row="0" column="2"> |
4554 | + <widget class="QPushButton" name="pushButtonEpochJ2000"> |
4555 | + <property name="text"> |
4556 | + <string>J2000.0</string> |
4557 | + </property> |
4558 | + </widget> |
4559 | + </item> |
4560 | + </layout> |
4561 | + </widget> |
4562 | + </item> |
4563 | + <item row="11" column="0" colspan="2"> |
4564 | + <widget class="QFrame" name="frameMeanAnomaly"> |
4565 | + <layout class="QGridLayout" name="gridLayout_2"> |
4566 | + <property name="margin"> |
4567 | + <number>0</number> |
4568 | + </property> |
4569 | + <item row="1" column="1"> |
4570 | + <widget class="QLineEdit" name="lineEditMeanAnomaly"/> |
4571 | + </item> |
4572 | + <item row="2" column="1"> |
4573 | + <widget class="QLineEdit" name="lineEditMeanLongitude"/> |
4574 | + </item> |
4575 | + <item row="1" column="0"> |
4576 | + <widget class="QRadioButton" name="radioButtonMeanAnomaly"> |
4577 | + <property name="text"> |
4578 | + <string>Mean anomaly:</string> |
4579 | + </property> |
4580 | + </widget> |
4581 | + </item> |
4582 | + <item row="2" column="0"> |
4583 | + <widget class="QRadioButton" name="radioButtonMeanLongitude"> |
4584 | + <property name="text"> |
4585 | + <string>Mean longitude:</string> |
4586 | + </property> |
4587 | + </widget> |
4588 | + </item> |
4589 | + </layout> |
4590 | + </widget> |
4591 | + </item> |
4592 | + <item row="3" column="0"> |
4593 | + <widget class="QRadioButton" name="radioButtonOrbitFunction"> |
4594 | + <property name="text"> |
4595 | + <string>Object-specific:</string> |
4596 | + </property> |
4597 | + </widget> |
4598 | + </item> |
4599 | + <item row="3" column="1"> |
4600 | + <widget class="QComboBox" name="comboBoxOrbitFunction"/> |
4601 | + </item> |
4602 | + <item row="12" column="0"> |
4603 | + <widget class="QCheckBox" name="checkBoxOrbitVisualizationPeriod"> |
4604 | + <property name="text"> |
4605 | + <string>Orbit visualization period:</string> |
4606 | + </property> |
4607 | + </widget> |
4608 | + </item> |
4609 | + <item row="12" column="1"> |
4610 | + <widget class="QLineEdit" name="lineEditOrbitVisualizationPeriod"/> |
4611 | + </item> |
4612 | + </layout> |
4613 | + </widget> |
4614 | + </item> |
4615 | + <item> |
4616 | + <widget class="QGroupBox" name="groupBoxRotationalElements"> |
4617 | + <property name="title"> |
4618 | + <string>Rotational elements</string> |
4619 | + </property> |
4620 | + <layout class="QGridLayout" name="gridLayout"> |
4621 | + <item row="0" column="0"> |
4622 | + <widget class="QCheckBox" name="checkBoxObliquity"> |
4623 | + <property name="text"> |
4624 | + <string>Obliquity:</string> |
4625 | + </property> |
4626 | + </widget> |
4627 | + </item> |
4628 | + <item row="0" column="1" colspan="3"> |
4629 | + <widget class="QLineEdit" name="lineEditObliquity"/> |
4630 | + </item> |
4631 | + <item row="2" column="0"> |
4632 | + <widget class="QCheckBox" name="checkBoxNorthPoleRA"> |
4633 | + <property name="text"> |
4634 | + <string>North pole right ascension:</string> |
4635 | + </property> |
4636 | + </widget> |
4637 | + </item> |
4638 | + <item row="2" column="1" colspan="3"> |
4639 | + <widget class="QLineEdit" name="lineEditNorthPoleRA"/> |
4640 | + </item> |
4641 | + <item row="3" column="0"> |
4642 | + <widget class="QCheckBox" name="checkBoxNorthPoleDec"> |
4643 | + <property name="text"> |
4644 | + <string>North pole declination:</string> |
4645 | + </property> |
4646 | + </widget> |
4647 | + </item> |
4648 | + <item row="3" column="1" colspan="3"> |
4649 | + <widget class="QLineEdit" name="lineEditNorthPoleDec"/> |
4650 | + </item> |
4651 | + <item row="4" column="0"> |
4652 | + <widget class="QCheckBox" name="checkBoxRotationalPeriod"> |
4653 | + <property name="text"> |
4654 | + <string>Period (hours):</string> |
4655 | + </property> |
4656 | + </widget> |
4657 | + </item> |
4658 | + <item row="4" column="1" colspan="3"> |
4659 | + <widget class="QLineEdit" name="lineEditRotationalPeriod"/> |
4660 | + </item> |
4661 | + <item row="5" column="0"> |
4662 | + <widget class="QCheckBox" name="checkBoxPrecessionRate"> |
4663 | + <property name="text"> |
4664 | + <string>Precession rate:</string> |
4665 | + </property> |
4666 | + </widget> |
4667 | + </item> |
4668 | + <item row="5" column="1" colspan="3"> |
4669 | + <widget class="QLineEdit" name="lineEditPrecessionRate"/> |
4670 | + </item> |
4671 | + <item row="6" column="0"> |
4672 | + <widget class="QCheckBox" name="checkBoxRotationalEpoch"> |
4673 | + <property name="text"> |
4674 | + <string>Epoch:</string> |
4675 | + </property> |
4676 | + </widget> |
4677 | + </item> |
4678 | + <item row="6" column="1"> |
4679 | + <widget class="QLineEdit" name="lineEditRotationalEpoch"/> |
4680 | + </item> |
4681 | + <item row="7" column="0"> |
4682 | + <widget class="QCheckBox" name="checkBoxOffset"> |
4683 | + <property name="text"> |
4684 | + <string>Offset:</string> |
4685 | + </property> |
4686 | + </widget> |
4687 | + </item> |
4688 | + <item row="7" column="1" colspan="3"> |
4689 | + <widget class="QLineEdit" name="lineEditOffset"/> |
4690 | + </item> |
4691 | + <item row="1" column="0" colspan="3"> |
4692 | + <widget class="QCheckBox" name="checkBoxEquatorAscendingNode"> |
4693 | + <property name="text"> |
4694 | + <string>Longitude of the ascending node of the ecliptic on the equator:</string> |
4695 | + </property> |
4696 | + </widget> |
4697 | + </item> |
4698 | + <item row="6" column="3"> |
4699 | + <widget class="QPushButton" name="pushButtonRotationalEpochJ2000"> |
4700 | + <property name="text"> |
4701 | + <string>J2000.0</string> |
4702 | + </property> |
4703 | + </widget> |
4704 | + </item> |
4705 | + <item row="1" column="3"> |
4706 | + <widget class="QLineEdit" name="lineEditEquatorAscendingNode"/> |
4707 | + </item> |
4708 | + </layout> |
4709 | + </widget> |
4710 | + </item> |
4711 | + <item> |
4712 | + <widget class="QGroupBox" name="groupBoxRings"> |
4713 | + <property name="title"> |
4714 | + <string>Rings</string> |
4715 | + </property> |
4716 | + <property name="checkable"> |
4717 | + <bool>true</bool> |
4718 | + </property> |
4719 | + <property name="checked"> |
4720 | + <bool>false</bool> |
4721 | + </property> |
4722 | + <layout class="QGridLayout" name="gridLayout_3"> |
4723 | + <item row="0" column="0"> |
4724 | + <widget class="QLabel" name="labelInnerSize"> |
4725 | + <property name="text"> |
4726 | + <string>Inner size:</string> |
4727 | + </property> |
4728 | + </widget> |
4729 | + </item> |
4730 | + <item row="1" column="0"> |
4731 | + <widget class="QLabel" name="labelOuterSize"> |
4732 | + <property name="text"> |
4733 | + <string>Outer size:</string> |
4734 | + </property> |
4735 | + </widget> |
4736 | + </item> |
4737 | + <item row="2" column="0"> |
4738 | + <widget class="QLabel" name="labelRingTexture"> |
4739 | + <property name="text"> |
4740 | + <string>Texture:</string> |
4741 | + </property> |
4742 | + </widget> |
4743 | + </item> |
4744 | + <item row="2" column="1"> |
4745 | + <widget class="QLineEdit" name="lineEditRingTexture"> |
4746 | + <property name="readOnly"> |
4747 | + <bool>true</bool> |
4748 | + </property> |
4749 | + </widget> |
4750 | + </item> |
4751 | + <item row="2" column="2"> |
4752 | + <widget class="QPushButton" name="pushButtonSelectRingTexture"> |
4753 | + <property name="text"> |
4754 | + <string>...</string> |
4755 | + </property> |
4756 | + </widget> |
4757 | + </item> |
4758 | + <item row="0" column="1" colspan="2"> |
4759 | + <widget class="QLineEdit" name="lineEditRingInnerSize"/> |
4760 | + </item> |
4761 | + <item row="1" column="1" colspan="2"> |
4762 | + <widget class="QLineEdit" name="lineEditRingOuterSize"/> |
4763 | + </item> |
4764 | + </layout> |
4765 | + </widget> |
4766 | + </item> |
4767 | + </layout> |
4768 | + </widget> |
4769 | + </widget> |
4770 | + </item> |
4771 | + <item row="3" column="0" colspan="2"> |
4772 | + <widget class="QFrame" name="frameButton"> |
4773 | + <layout class="QHBoxLayout" name="horizontalLayoutButton"> |
4774 | + <item> |
4775 | + <widget class="QLabel" name="labelErrorMessage"> |
4776 | + <property name="sizePolicy"> |
4777 | + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> |
4778 | + <horstretch>0</horstretch> |
4779 | + <verstretch>0</verstretch> |
4780 | + </sizepolicy> |
4781 | + </property> |
4782 | + <property name="text"> |
4783 | + <string/> |
4784 | + </property> |
4785 | + </widget> |
4786 | + </item> |
4787 | + <item> |
4788 | + <widget class="QPushButton" name="pushButtonSave"> |
4789 | + <property name="text"> |
4790 | + <string>Save</string> |
4791 | + </property> |
4792 | + </widget> |
4793 | + </item> |
4794 | + </layout> |
4795 | + </widget> |
4796 | + </item> |
4797 | + </layout> |
4798 | + </widget> |
4799 | + <customwidgets> |
4800 | + <customwidget> |
4801 | + <class>BarFrame</class> |
4802 | + <extends>QFrame</extends> |
4803 | + <header>Dialog.hpp</header> |
4804 | + <container>1</container> |
4805 | + </customwidget> |
4806 | + </customwidgets> |
4807 | + <tabstops> |
4808 | + <tabstop>lineEditName</tabstop> |
4809 | + <tabstop>lineEditIdentifier</tabstop> |
4810 | + <tabstop>checkBoxMinorPlanetNumber</tabstop> |
4811 | + <tabstop>lineEditMinorPlanetNumber</tabstop> |
4812 | + <tabstop>radioButtonSolarSystemObject</tabstop> |
4813 | + <tabstop>radioButtonMinorPlanet</tabstop> |
4814 | + <tabstop>radioButtonComet</tabstop> |
4815 | + <tabstop>radioButtonSatellite</tabstop> |
4816 | + <tabstop>scrollArea</tabstop> |
4817 | + <tabstop>comboBoxParent</tabstop> |
4818 | + <tabstop>lineEditRadius</tabstop> |
4819 | + <tabstop>lineEditOblateness</tabstop> |
4820 | + <tabstop>lineEditAlbedo</tabstop> |
4821 | + <tabstop>lineEditColor</tabstop> |
4822 | + <tabstop>pushButtonSelectColor</tabstop> |
4823 | + <tabstop>checkBoxLighting</tabstop> |
4824 | + <tabstop>checkBoxAtmosphere</tabstop> |
4825 | + <tabstop>checkBoxHidden</tabstop> |
4826 | + <tabstop>lineEditTexture</tabstop> |
4827 | + <tabstop>pushButtonSelectTexture</tabstop> |
4828 | + <tabstop>lineEditAbsoluteMagnitude</tabstop> |
4829 | + <tabstop>lineEditSlopeParameter</tabstop> |
4830 | + <tabstop>pushButtonCalculateRadius</tabstop> |
4831 | + <tabstop>radioButtonCometaryOrbit</tabstop> |
4832 | + <tabstop>radioButtonEllipticOrbit</tabstop> |
4833 | + <tabstop>radioButtonOrbitFunction</tabstop> |
4834 | + <tabstop>comboBoxOrbitFunction</tabstop> |
4835 | + <tabstop>lineEditEccentricity</tabstop> |
4836 | + <tabstop>lineEditInclination</tabstop> |
4837 | + <tabstop>lineEditLongitudeOfTheAscendingNode</tabstop> |
4838 | + <tabstop>radioButtonArgumentOfPeriapsis</tabstop> |
4839 | + <tabstop>lineEditArgumentOfPeriapsis</tabstop> |
4840 | + <tabstop>radioButtonLongitudeOfPeriapsis</tabstop> |
4841 | + <tabstop>lineEditLongitudeOfPeriapsis</tabstop> |
4842 | + <tabstop>radioButtonSemiMajorAxis</tabstop> |
4843 | + <tabstop>lineEditSemiMajorAxis</tabstop> |
4844 | + <tabstop>radioButtonPeriapsisDistance</tabstop> |
4845 | + <tabstop>lineEditPeriapsisDistance</tabstop> |
4846 | + <tabstop>checkBoxPeriod</tabstop> |
4847 | + <tabstop>lineEditPeriod</tabstop> |
4848 | + <tabstop>checkBoxMeanMotion</tabstop> |
4849 | + <tabstop>lineEditMeanMotion</tabstop> |
4850 | + <tabstop>radioButtonEpoch</tabstop> |
4851 | + <tabstop>lineEditEpoch</tabstop> |
4852 | + <tabstop>pushButtonEpochJ2000</tabstop> |
4853 | + <tabstop>radioButtonTimeOfPeriapsis</tabstop> |
4854 | + <tabstop>lineEditTimeOfPeriapsis</tabstop> |
4855 | + <tabstop>radioButtonMeanAnomaly</tabstop> |
4856 | + <tabstop>lineEditMeanAnomaly</tabstop> |
4857 | + <tabstop>radioButtonMeanLongitude</tabstop> |
4858 | + <tabstop>lineEditMeanLongitude</tabstop> |
4859 | + <tabstop>checkBoxOrbitVisualizationPeriod</tabstop> |
4860 | + <tabstop>lineEditOrbitVisualizationPeriod</tabstop> |
4861 | + <tabstop>checkBoxObliquity</tabstop> |
4862 | + <tabstop>lineEditObliquity</tabstop> |
4863 | + <tabstop>checkBoxEquatorAscendingNode</tabstop> |
4864 | + <tabstop>lineEditEquatorAscendingNode</tabstop> |
4865 | + <tabstop>checkBoxNorthPoleRA</tabstop> |
4866 | + <tabstop>lineEditNorthPoleRA</tabstop> |
4867 | + <tabstop>checkBoxNorthPoleDec</tabstop> |
4868 | + <tabstop>lineEditNorthPoleDec</tabstop> |
4869 | + <tabstop>checkBoxRotationalPeriod</tabstop> |
4870 | + <tabstop>lineEditRotationalPeriod</tabstop> |
4871 | + <tabstop>checkBoxPrecessionRate</tabstop> |
4872 | + <tabstop>lineEditPrecessionRate</tabstop> |
4873 | + <tabstop>checkBoxRotationalEpoch</tabstop> |
4874 | + <tabstop>lineEditRotationalEpoch</tabstop> |
4875 | + <tabstop>pushButtonRotationalEpochJ2000</tabstop> |
4876 | + <tabstop>checkBoxOffset</tabstop> |
4877 | + <tabstop>lineEditOffset</tabstop> |
4878 | + <tabstop>groupBoxRings</tabstop> |
4879 | + <tabstop>lineEditRingInnerSize</tabstop> |
4880 | + <tabstop>lineEditRingOuterSize</tabstop> |
4881 | + <tabstop>lineEditRingTexture</tabstop> |
4882 | + <tabstop>pushButtonSelectRingTexture</tabstop> |
4883 | + <tabstop>pushButtonSave</tabstop> |
4884 | + </tabstops> |
4885 | + <resources/> |
4886 | + <connections/> |
4887 | +</ui> |
4888 | |
4889 | === added file 'plugins/SolarSystemEditor/src/gui/mpcImportWindow.ui' |
4890 | --- plugins/SolarSystemEditor/src/gui/mpcImportWindow.ui 1970-01-01 00:00:00 +0000 |
4891 | +++ plugins/SolarSystemEditor/src/gui/mpcImportWindow.ui 2010-11-16 20:00:15 +0000 |
4892 | @@ -0,0 +1,679 @@ |
4893 | +<?xml version="1.0" encoding="UTF-8"?> |
4894 | +<ui version="4.0"> |
4895 | + <author>Bogdan Marinov</author> |
4896 | + <class>mpcImportWindow</class> |
4897 | + <widget class="QWidget" name="mpcImportWindow"> |
4898 | + <property name="geometry"> |
4899 | + <rect> |
4900 | + <x>0</x> |
4901 | + <y>0</y> |
4902 | + <width>480</width> |
4903 | + <height>475</height> |
4904 | + </rect> |
4905 | + </property> |
4906 | + <layout class="QVBoxLayout" name="verticalLayout_2"> |
4907 | + <property name="spacing"> |
4908 | + <number>0</number> |
4909 | + </property> |
4910 | + <property name="margin"> |
4911 | + <number>0</number> |
4912 | + </property> |
4913 | + <item> |
4914 | + <widget class="BarFrame" name="TitleBar"> |
4915 | + <property name="sizePolicy"> |
4916 | + <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> |
4917 | + <horstretch>0</horstretch> |
4918 | + <verstretch>0</verstretch> |
4919 | + </sizepolicy> |
4920 | + </property> |
4921 | + <property name="minimumSize"> |
4922 | + <size> |
4923 | + <width>0</width> |
4924 | + <height>25</height> |
4925 | + </size> |
4926 | + </property> |
4927 | + <property name="maximumSize"> |
4928 | + <size> |
4929 | + <width>16777215</width> |
4930 | + <height>30</height> |
4931 | + </size> |
4932 | + </property> |
4933 | + <property name="focusPolicy"> |
4934 | + <enum>Qt::NoFocus</enum> |
4935 | + </property> |
4936 | + <property name="autoFillBackground"> |
4937 | + <bool>false</bool> |
4938 | + </property> |
4939 | + <property name="frameShape"> |
4940 | + <enum>QFrame::StyledPanel</enum> |
4941 | + </property> |
4942 | + <layout class="QHBoxLayout" name="_2"> |
4943 | + <property name="spacing"> |
4944 | + <number>6</number> |
4945 | + </property> |
4946 | + <property name="leftMargin"> |
4947 | + <number>0</number> |
4948 | + </property> |
4949 | + <property name="topMargin"> |
4950 | + <number>0</number> |
4951 | + </property> |
4952 | + <property name="rightMargin"> |
4953 | + <number>4</number> |
4954 | + </property> |
4955 | + <property name="bottomMargin"> |
4956 | + <number>0</number> |
4957 | + </property> |
4958 | + <item> |
4959 | + <spacer name="leftSpacer"> |
4960 | + <property name="orientation"> |
4961 | + <enum>Qt::Horizontal</enum> |
4962 | + </property> |
4963 | + <property name="sizeHint" stdset="0"> |
4964 | + <size> |
4965 | + <width>40</width> |
4966 | + <height>20</height> |
4967 | + </size> |
4968 | + </property> |
4969 | + </spacer> |
4970 | + </item> |
4971 | + <item> |
4972 | + <widget class="QLabel" name="stelWindowTitle"> |
4973 | + <property name="text"> |
4974 | + <string notr="true" extracomment="The title of the window will be set during runtime">Import data</string> |
4975 | + </property> |
4976 | + </widget> |
4977 | + </item> |
4978 | + <item> |
4979 | + <spacer name="rightSpacer"> |
4980 | + <property name="orientation"> |
4981 | + <enum>Qt::Horizontal</enum> |
4982 | + </property> |
4983 | + <property name="sizeHint" stdset="0"> |
4984 | + <size> |
4985 | + <width>40</width> |
4986 | + <height>20</height> |
4987 | + </size> |
4988 | + </property> |
4989 | + </spacer> |
4990 | + </item> |
4991 | + <item> |
4992 | + <widget class="QPushButton" name="closeStelWindow"> |
4993 | + <property name="minimumSize"> |
4994 | + <size> |
4995 | + <width>16</width> |
4996 | + <height>16</height> |
4997 | + </size> |
4998 | + </property> |
4999 | + <property name="maximumSize"> |
5000 | + <size> |
At some point Mike Storm worked on an experimental JSON format for solar system objects. I think this was never merged, but it was superior to the old .ini format in that it could reflect natively nesting of objects.
See the mailing list archive thread:
http:// sourceforge. net/mailarchive /forum. php?thread_ name=c3fc7ff081 2080257we37817f q7bb5e9f874c3a7 ba%40mail. gmail.com& forum_name= stellarium- pubdevel