Merge lp:~daggerstab/stellarium/satellites-import-gui into lp:stellarium
- satellites-import-gui
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~daggerstab/stellarium/satellites-import-gui |
Merge into: | lp:stellarium |
Diff against target: |
1531 lines (+1055/-102) 16 files modified
data/gui/nightStyle.css (+3/-3) data/gui/normalStyle.css (+3/-3) plugins/Satellites/CMakeLists.txt (+1/-1) plugins/Satellites/ChangeLog (+5/-0) plugins/Satellites/resources/satellites.json (+21/-1) plugins/Satellites/src/CMakeLists.txt (+4/-0) plugins/Satellites/src/Satellite.cpp (+1/-1) plugins/Satellites/src/Satellite.hpp (+4/-0) plugins/Satellites/src/Satellites.cpp (+147/-61) plugins/Satellites/src/Satellites.hpp (+34/-1) plugins/Satellites/src/gui/SatellitesDialog.cpp (+102/-27) plugins/Satellites/src/gui/SatellitesDialog.hpp (+10/-3) plugins/Satellites/src/gui/SatellitesImportDialog.cpp (+360/-0) plugins/Satellites/src/gui/SatellitesImportDialog.hpp (+73/-0) plugins/Satellites/src/gui/satellitesDialog.ui (+37/-1) plugins/Satellites/src/gui/satellitesImportDialog.ui (+250/-0) |
To merge this branch: | bzr merge lp:~daggerstab/stellarium/satellites-import-gui |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Matthew Gates | uat | Needs Fixing | |
Alexander Wolf | Approve | ||
Review via email: mp+87865@code.launchpad.net |
This proposal has been superseded by a proposal from 2012-01-10.
Commit message
Description of the change
Simple GUI for adding satellites. Supports both downloading data from the Internet and loading files from the local disk, if Internet updates are disabled.
If this is approved, I'm going to merge it myself. In case I can't, please mark the linked bug as being fixed by that revision when committing the merge.
Alexander Wolf (alexwolf) wrote : | # |
Bogdan Marinov (daggerstab) wrote : | # |
It's on my TODO list. I don't have time for it now, though. So it's either this (with important bugs fixed, if any), or nothing.
Alexander Wolf (alexwolf) : | # |
Matthew Gates (matthew-porpoisehead) wrote : | # |
This is a summary of some issues discussed in the IRC channel:
1. When a new satellite is added, the list in the main Satellites dialog should be re-loaded to the new satellite is shown.
2. The new satellite list should look like the list box in the main Satellites dialog (i.e. same font size and spacing etc.
3. Nice to have: filter-as-you-type searching of the new satellites list.
4. Nice to have: some way to select the newly added satellites in the main satellites dialog list.
- 5127. By Bogdan Marinov
-
reload satellite list after adding new satellites
- 5128. By Bogdan Marinov
-
+ select the newly added satellites after import (but it's not enough?)
- 5129. By Bogdan Marinov
-
save changes to file after adding or removing satellites
- 5130. By Bogdan Marinov
-
scroll to the first selected newly added satellite
- 5131. By Bogdan Marinov
-
+ search for the new satellites list
Bogdan Marinov (daggerstab) wrote : | # |
1. Fixed.
2. Because of 3., the QListWidget was replaced with a QListView, which has its own default style. Have a look at it.
3. Done.
4. A possible mechanism:
- add a "new" flag to the Satellite object that is not saved to JSON;
- add "new" to Satellites:
- add a "[newly added]" group to the drop-down list - it will display the satellites added since Stellarium has been started.
- 5132. By Bogdan Marinov
-
+ check box style for QListView objects
- 5133. By Bogdan Marinov
-
+ a "newly added" pseudo-group
- 5134. By Bogdan Marinov
-
+ Spektr-R and Tiangong-1; + scientific.txt to the sources
- 5135. By Bogdan Marinov
-
fixed link style in Satellites' About tab
Unmerged revisions
Preview Diff
1 | === modified file 'data/gui/nightStyle.css' |
2 | --- data/gui/nightStyle.css 2011-11-11 16:14:30 +0000 |
3 | +++ data/gui/nightStyle.css 2012-01-10 09:14:25 +0000 |
4 | @@ -524,11 +524,11 @@ |
5 | image: url(:/graphicGui/nv_checkbox-unchecked.png); |
6 | } |
7 | |
8 | -QListWidget::indicator::checked { |
9 | +QListWidget::indicator:checked, QListView::indicator:checked { |
10 | image: url(:/graphicGui/nv_checkbox-checked.png); |
11 | } |
12 | |
13 | -QListWidget::indicator:unchecked { |
14 | +QListWidget::indicator:unchecked, QListView::indicator:unchecked { |
15 | image: url(:/graphicGui/nv_checkbox-unchecked.png); |
16 | } |
17 | |
18 | @@ -791,4 +791,4 @@ |
19 | /**** The following are used for Satellites ****/ |
20 | QListWidget#satellitesList, QListWidget#sourceList { |
21 | font-size: 8pt; |
22 | -} |
23 | \ No newline at end of file |
24 | +} |
25 | |
26 | === modified file 'data/gui/normalStyle.css' |
27 | --- data/gui/normalStyle.css 2011-11-11 10:34:13 +0000 |
28 | +++ data/gui/normalStyle.css 2012-01-10 09:14:25 +0000 |
29 | @@ -523,11 +523,11 @@ |
30 | image: url(:/graphicGui/checkbox-unchecked.png); |
31 | } |
32 | |
33 | -QListWidget::indicator::checked { |
34 | +QListWidget::indicator:checked, QListView::indicator:checked { |
35 | image: url(:/graphicGui/checkbox-checked.png); |
36 | } |
37 | |
38 | -QListWidget::indicator:unchecked { |
39 | +QListWidget::indicator:unchecked, QListView::indicator:unchecked { |
40 | image: url(:/graphicGui/checkbox-unchecked.png); |
41 | } |
42 | |
43 | @@ -896,4 +896,4 @@ |
44 | /**** The following are used for Satellites ****/ |
45 | QListWidget#satellitesList, QListWidget#sourceList { |
46 | font-size: 8pt; |
47 | -} |
48 | \ No newline at end of file |
49 | +} |
50 | |
51 | === modified file 'plugins/Satellites/CMakeLists.txt' |
52 | --- plugins/Satellites/CMakeLists.txt 2011-12-13 03:53:53 +0000 |
53 | +++ plugins/Satellites/CMakeLists.txt 2012-01-10 09:14:25 +0000 |
54 | @@ -1,4 +1,4 @@ |
55 | -SET(SATELLITES_VERSION "0.7.0") |
56 | +SET(SATELLITES_VERSION "0.7.1") |
57 | |
58 | SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/.stellarium) |
59 | |
60 | |
61 | === modified file 'plugins/Satellites/ChangeLog' |
62 | --- plugins/Satellites/ChangeLog 2011-12-14 10:31:15 +0000 |
63 | +++ plugins/Satellites/ChangeLog 2012-01-10 09:14:25 +0000 |
64 | @@ -1,3 +1,8 @@ |
65 | +0.7.1 [2012-01-08] |
66 | +Added basic GUI for adding satellites from TLE lists. |
67 | +Added CelesTrak's tle-new.txt to the default sources list to make adding fresh |
68 | +satellites easier. |
69 | + |
70 | 0.7.0 [2011-12-13] |
71 | Use catalog number instead of satellite name as an identifier. |
72 | Save dates as proper JSON strings (before they broke stricter parsers). |
73 | |
74 | === modified file 'plugins/Satellites/resources/satellites.json' |
75 | --- plugins/Satellites/resources/satellites.json 2011-12-12 23:12:49 +0000 |
76 | +++ plugins/Satellites/resources/satellites.json 2012-01-10 09:14:25 +0000 |
77 | @@ -1,5 +1,5 @@ |
78 | { |
79 | - "creator": "Satellites plugin version 0.7.0 (updated)", |
80 | + "creator": "Satellites plugin version 0.7.1 (updated)", |
81 | "hintColor": [0.4, 0.4, 0.4], |
82 | "satellites": |
83 | { |
84 | @@ -7641,6 +7641,16 @@ |
85 | "tle2": "2 37753 55.0113 180.9488 0003255 61.0940 299.0042 2.00564618 2948", |
86 | "visible": false |
87 | }, |
88 | + "37755": |
89 | + { |
90 | + "comms": [], |
91 | + "groups": ["scientific"], |
92 | + "name": "SPEKTR-R", |
93 | + "orbitVisible": false, |
94 | + "tle1": "1 37755U 11037A 12004.66875000 -.00012069 00000-0 10000-3 0 228", |
95 | + "tle2": "2 37755 74.6765 307.4457 8148154 317.9596 358.4400 0.11583720 219", |
96 | + "visible": true |
97 | + }, |
98 | "37763": |
99 | { |
100 | "comms": [], |
101 | @@ -7690,6 +7700,16 @@ |
102 | "tle1": "1 37779U 11042A 11345.61344730 .00000169 00000-0 10000-3 0 736", |
103 | "tle2": "2 37779 0.0476 148.6335 0001436 93.6679 96.5562 1.00275394 1304", |
104 | "visible": false |
105 | + }, |
106 | + "37820": |
107 | + { |
108 | + "comms": [], |
109 | + "groups": ["scientific", "visual"], |
110 | + "name": "TIANGONG 1", |
111 | + "orbitVisible": false, |
112 | + "tle1": "1 37820U 11053A 12009.74723891 .00034896 00000-0 29586-3 0 3619", |
113 | + "tle2": "2 37820 42.7873 297.8111 0008641 198.6555 249.7744 15.68962907 16096", |
114 | + "visible": true |
115 | } |
116 | }, |
117 | "shortName": "satellite orbital data" |
118 | |
119 | === modified file 'plugins/Satellites/src/CMakeLists.txt' |
120 | --- plugins/Satellites/src/CMakeLists.txt 2011-02-08 17:20:14 +0000 |
121 | +++ plugins/Satellites/src/CMakeLists.txt 2012-01-10 09:14:25 +0000 |
122 | @@ -30,10 +30,13 @@ |
123 | Satellites.cpp |
124 | gui/SatellitesDialog.hpp |
125 | gui/SatellitesDialog.cpp |
126 | + gui/SatellitesImportDialog.hpp |
127 | + gui/SatellitesImportDialog.cpp |
128 | ) |
129 | |
130 | SET(SatellitesDialog_UIS |
131 | gui/satellitesDialog.ui |
132 | + gui/satellitesImportDialog.ui |
133 | ) |
134 | QT4_WRAP_UI(SatellitesDialog_UIS_H ${SatellitesDialog_UIS}) |
135 | |
136 | @@ -45,6 +48,7 @@ |
137 | SET(Satellites_MOC_HDRS |
138 | Satellites.hpp |
139 | gui/SatellitesDialog.hpp |
140 | + gui/SatellitesImportDialog.hpp |
141 | ) |
142 | |
143 | # After this call, Satellites_MOC_SRCS = moc_Satellites.cxx |
144 | |
145 | === modified file 'plugins/Satellites/src/Satellite.cpp' |
146 | --- plugins/Satellites/src/Satellite.cpp 2012-01-06 20:06:54 +0000 |
147 | +++ plugins/Satellites/src/Satellite.cpp 2012-01-10 09:14:25 +0000 |
148 | @@ -53,7 +53,7 @@ |
149 | |
150 | |
151 | Satellite::Satellite(const QString& identifier, const QVariantMap& map) |
152 | - : initialized(false), visible(true), hintColor(0.0,0.0,0.0), lastUpdated(), pSatWrapper(NULL) |
153 | + : initialized(false), visible(true), newlyAdded(false), hintColor(0.0,0.0,0.0), lastUpdated(), pSatWrapper(NULL) |
154 | { |
155 | // return initialized if the mandatory fields are not present |
156 | if (identifier.isEmpty()) |
157 | |
158 | === modified file 'plugins/Satellites/src/Satellite.hpp' |
159 | --- plugins/Satellites/src/Satellite.hpp 2011-12-28 00:18:26 +0000 |
160 | +++ plugins/Satellites/src/Satellite.hpp 2012-01-10 09:14:25 +0000 |
161 | @@ -109,6 +109,9 @@ |
162 | // when the observer location changes we need to |
163 | void recalculateOrbitLines(void); |
164 | |
165 | + void setNew() {newlyAdded = true;} |
166 | + bool isNew() const {return newlyAdded;} |
167 | + |
168 | static QString extractInternationalDesignator(const QString& tle1); |
169 | |
170 | public: |
171 | @@ -127,6 +130,7 @@ |
172 | bool initialized; |
173 | bool visible; |
174 | bool orbitVisible; //draw orbit enabled/disabled |
175 | + bool newlyAdded; |
176 | |
177 | //! Identifier of the satellite, must be unique within the list. |
178 | //! Currently, the Satellite Catalog Number is used. It is contained in both |
179 | |
180 | === modified file 'plugins/Satellites/src/Satellites.cpp' |
181 | --- plugins/Satellites/src/Satellites.cpp 2011-12-13 03:53:53 +0000 |
182 | +++ plugins/Satellites/src/Satellites.cpp 2012-01-10 09:14:25 +0000 |
183 | @@ -409,6 +409,9 @@ |
184 | conf->setValue("tle_url5", "http://celestrak.com/NORAD/elements/amateur.txt"); |
185 | conf->setValue("tle_url6", "http://celestrak.com/NORAD/elements/iridium.txt"); |
186 | conf->setValue("tle_url7", "http://celestrak.com/NORAD/elements/geo.txt"); |
187 | + conf->setValue("tle_url8", "http://celestrak.com/NORAD/elements/tle-new.txt"); |
188 | + conf->setValue("tle_url9", "http://celestrak.com/NORAD/elements/science.txt"); |
189 | + //TODO: Better? See http://doc.qt.nokia.com/4.7/qsettings.html#beginWriteArray --BM |
190 | conf->setValue("update_frequency_hours", 72); |
191 | conf->setValue("orbit_line_flag", true); |
192 | conf->setValue("orbit_line_segments", 90); |
193 | @@ -683,7 +686,10 @@ |
194 | { |
195 | if ((group.isEmpty() || sat->groupIDs.contains(group)) && ! result.contains(sat->id)) |
196 | { |
197 | - if (vis==Both || (vis==Visible && sat->visible) || (vis==NotVisible && !sat->visible)) |
198 | + if (vis==Both || |
199 | + (vis==Visible && sat->visible) || |
200 | + (vis==NotVisible && !sat->visible) || |
201 | + (vis==NewlyAdded && sat->isNew())) |
202 | result.insert(sat->id, sat->name); |
203 | } |
204 | } |
205 | @@ -701,6 +707,83 @@ |
206 | return SatelliteP(); |
207 | } |
208 | |
209 | +QStringList Satellites::getAllIDs() |
210 | +{ |
211 | + QStringList result; |
212 | + foreach(const SatelliteP& sat, satellites) |
213 | + { |
214 | + if (sat->initialized) |
215 | + result.append(sat->id); |
216 | + } |
217 | + return result; |
218 | +} |
219 | + |
220 | +void Satellites::add(const TleDataList& newSatellites) |
221 | +{ |
222 | + int numAdded = 0; |
223 | + QVariantList defaultHintColorMap; |
224 | + defaultHintColorMap << defaultHintColor[0] << defaultHintColor[1] |
225 | + << defaultHintColor[2]; |
226 | + |
227 | + foreach (const TleData& tleSet, newSatellites) |
228 | + { |
229 | + //TODO: Duplicates check? --BM |
230 | + |
231 | + if (tleSet.id.isEmpty() || |
232 | + tleSet.name.isEmpty() || |
233 | + tleSet.first.isEmpty() || |
234 | + tleSet.second.isEmpty()) |
235 | + continue; |
236 | + |
237 | + QVariantMap satProperties; |
238 | + satProperties.insert("name", tleSet.name); |
239 | + satProperties.insert("tle1", tleSet.first); |
240 | + satProperties.insert("tle2", tleSet.second); |
241 | + satProperties.insert("hintColor", defaultHintColorMap); |
242 | + //TODO: Decide if newly added satellites are visible by default --BM |
243 | + satProperties.insert("visible", true); |
244 | + satProperties.insert("orbitVisible", false); |
245 | + |
246 | + SatelliteP sat(new Satellite(tleSet.id, satProperties)); |
247 | + if (sat->initialized) |
248 | + { |
249 | + qDebug() << "Satellites: added" << tleSet.id << tleSet.name; |
250 | + satellites.append(sat); |
251 | + sat->setNew(); |
252 | + numAdded++; |
253 | + } |
254 | + } |
255 | + qDebug() << "Satellites: " |
256 | + << newSatellites.count() << "satellites proposed for addition, " |
257 | + << numAdded << " added, " |
258 | + << satellites.count() << " total after the operation."; |
259 | +} |
260 | + |
261 | +void Satellites::remove(const QStringList& idList) |
262 | +{ |
263 | + StelObjectMgr* objMgr = GETSTELMODULE(StelObjectMgr); |
264 | + int numRemoved = 0; |
265 | + for (int i = 0; i < satellites.size(); i++) |
266 | + { |
267 | + const SatelliteP& sat = satellites.at(i); |
268 | + if (idList.contains(sat->id)) |
269 | + { |
270 | + QList<StelObjectP> selected = objMgr->getSelectedObject("Satellite"); |
271 | + if (selected.contains(sat.staticCast<StelObject>())) |
272 | + objMgr->unSelect(); |
273 | + |
274 | + qDebug() << "Satellite removed:" << sat->id << sat->name; |
275 | + satellites.removeAt(i); |
276 | + i--; //Compensate for the change in the array's indexing |
277 | + numRemoved++; |
278 | + } |
279 | + } |
280 | + qDebug() << "Satellites: " |
281 | + << idList.count() << "satellites proposed for removal, " |
282 | + << numRemoved << " removed, " |
283 | + << satellites.count() << " remain."; |
284 | +} |
285 | + |
286 | int Satellites::getSecondsToUpdate(void) |
287 | { |
288 | QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 3600); |
289 | @@ -874,10 +957,8 @@ |
290 | |
291 | void Satellites::updateFromFiles(QStringList paths, bool deleteFiles) |
292 | { |
293 | - // define a map of new TLE data - the key is the satellite designation |
294 | - QMap< QString, QPair<QString, QString> > newTLE; |
295 | - //TODO: Ugly hack, think of something better: --BM |
296 | - QHash<QString, QString> nameFromId; |
297 | + // Container for the new data. |
298 | + TleDataHash newTleSets; |
299 | |
300 | if (progressBar) |
301 | { |
302 | @@ -891,52 +972,7 @@ |
303 | QFile tleFile(tleFilePath); |
304 | if (tleFile.open(QIODevice::ReadOnly|QIODevice::Text)) |
305 | { |
306 | - int lineNumber = 0; |
307 | - QString lastId, lastName; |
308 | - QPair<QString, QString> tleLines; |
309 | - |
310 | - while (!tleFile.atEnd()) |
311 | - { |
312 | - QString line = QString(tleFile.readLine()).trimmed(); |
313 | - if (line.length() < 65) // this is title line |
314 | - { |
315 | - // New entry in the list, so prepare all fields |
316 | - lastId.clear(); |
317 | - lastName = line; |
318 | - lastName.replace(QRegExp("\\s*\\[([^\\]])*\\]\\s*$"),""); // remove things in square brackets |
319 | - //TODO: We need to think of some kind of ecaping these |
320 | - //characters in the JSON parser. --BM |
321 | - |
322 | - tleLines.first = QString(); |
323 | - tleLines.second = QString(); |
324 | - } |
325 | - else |
326 | - { |
327 | - if (QRegExp("^1 .*").exactMatch(line)) |
328 | - tleLines.first = line; |
329 | - else if (QRegExp("^2 .*").exactMatch(line)) |
330 | - { |
331 | - tleLines.second = line; |
332 | - // The Satellite Catalog Number is the second number |
333 | - // on the second line. |
334 | - lastId = line.split(' ').at(1).trimmed(); |
335 | - if (lastId.isEmpty()) |
336 | - continue; |
337 | - |
338 | - // This is the second line and there will be no more, |
339 | - // so if everything is OK, save the elements. |
340 | - if (!lastName.isEmpty() && |
341 | - !tleLines.first.isEmpty()) |
342 | - { |
343 | - newTLE[lastId] = tleLines; |
344 | - nameFromId[lastId] = lastName; |
345 | - } |
346 | - //TODO: Error warnings? --BM |
347 | - } |
348 | - else |
349 | - qDebug() << "Satellites::updateFromFiles(): unprocessed line " << lineNumber << " in file " << tleFilePath; |
350 | - } |
351 | - } |
352 | + parseTleFile(tleFile, newTleSets); |
353 | tleFile.close(); |
354 | |
355 | if (deleteFiles) |
356 | @@ -956,20 +992,18 @@ |
357 | { |
358 | totalSats++; |
359 | QString id = sat->id; |
360 | - if (newTLE.contains(id)) |
361 | + if (newTleSets.contains(id)) |
362 | { |
363 | - // If it's in the new list, the name should also be there. |
364 | - QString name = nameFromId.value(id); |
365 | - |
366 | - if (sat->tleElements.first != newTLE[id].first || |
367 | - sat->tleElements.second != newTLE[id].second || |
368 | - sat->name != name) |
369 | + TleData newTle = newTleSets.value(id); |
370 | + if (sat->tleElements.first != newTle.first || |
371 | + sat->tleElements.second != newTle.second || |
372 | + sat->name != newTle.name) |
373 | { |
374 | // We have updated TLE elements for this satellite |
375 | - sat->setNewTleElements(newTLE[id].first, newTLE[id].second); |
376 | + sat->setNewTleElements(newTle.first, newTle.second); |
377 | |
378 | // Update the name if it has been changed in the source list |
379 | - sat->name = name; |
380 | + sat->name = newTle.name; |
381 | |
382 | // we reset this to "now" when we started the update. |
383 | sat->lastUpdated = lastUpdate; |
384 | @@ -995,7 +1029,7 @@ |
385 | progressBar = NULL; |
386 | |
387 | qDebug() << "Satellites: updated" << numUpdated << "/" << totalSats |
388 | - << "satellites. Update URLs contained" << newTLE.size() << "objects. " |
389 | + << "satellites. Update URLs contained" << newTleSets.size() << "objects. " |
390 | << "There were" << numMissing << "satellies missing from the update URLs"; |
391 | |
392 | if (numUpdated==0) |
393 | @@ -1007,6 +1041,58 @@ |
394 | emit(tleUpdateComplete(numUpdated, totalSats, numMissing)); |
395 | } |
396 | |
397 | +void Satellites::parseTleFile(QFile& openFile, TleDataHash& tleList) |
398 | +{ |
399 | + if (!openFile.isOpen() || !openFile.isReadable()) |
400 | + return; |
401 | + |
402 | + // Code mostly re-used from updateFromFiles() |
403 | + int lineNumber = 0; |
404 | + TleData lastData; |
405 | + |
406 | + while (!openFile.atEnd()) |
407 | + { |
408 | + QString line = QString(openFile.readLine()).trimmed(); |
409 | + if (line.length() < 65) // this is title line |
410 | + { |
411 | + // New entry in the list, so reset all fields |
412 | + lastData = TleData(); |
413 | + |
414 | + //TODO: We need to think of some kind of ecaping these |
415 | + //characters in the JSON parser. --BM |
416 | + line.replace(QRegExp("\\s*\\[([^\\]])*\\]\\s*$"),""); // remove things in square brackets |
417 | + lastData.name = line; |
418 | + } |
419 | + else |
420 | + { |
421 | + if (QRegExp("^1 .*").exactMatch(line)) |
422 | + lastData.first = line; |
423 | + else if (QRegExp("^2 .*").exactMatch(line)) |
424 | + { |
425 | + lastData.second = line; |
426 | + // The Satellite Catalog Number is the second number |
427 | + // on the second line. |
428 | + QString id = line.split(' ').at(1).trimmed(); |
429 | + if (id.isEmpty()) |
430 | + continue; |
431 | + lastData.id = id; |
432 | + |
433 | + // This is the second line and there will be no more, |
434 | + // so if everything is OK, save the elements. |
435 | + if (!lastData.name.isEmpty() && |
436 | + !lastData.first.isEmpty()) |
437 | + { |
438 | + //TODO: This overwrites duplicates. Display warning? --BM |
439 | + tleList.insert(id, lastData); |
440 | + } |
441 | + //TODO: Error warnings? --BM |
442 | + } |
443 | + else |
444 | + qDebug() << "Satellites: unprocessed line " << lineNumber << " in file " << openFile.fileName(); |
445 | + } |
446 | + } |
447 | +} |
448 | + |
449 | void Satellites::update(double deltaTime) |
450 | { |
451 | if (StelApp::getInstance().getCore()->getCurrentLocation().planetName != earth->getEnglishName() || (!hintFader && hintFader.getInterstate() <= 0.)) |
452 | |
453 | === modified file 'plugins/Satellites/src/Satellites.hpp' |
454 | --- plugins/Satellites/src/Satellites.hpp 2011-12-12 23:12:49 +0000 |
455 | +++ plugins/Satellites/src/Satellites.hpp 2012-01-10 09:14:25 +0000 |
456 | @@ -42,6 +42,20 @@ |
457 | |
458 | typedef QSharedPointer<Satellite> SatelliteP; |
459 | |
460 | +//! Data structure containing unvalidated TLE set as read from a TLE list file. |
461 | +struct TleData |
462 | +{ |
463 | + //! NORAD catalog number, as extracted from the TLE set. |
464 | + QString id; |
465 | + //! Human readable name, as extracted from the TLE title line. |
466 | + QString name; |
467 | + QString first; |
468 | + QString second; |
469 | +}; |
470 | + |
471 | +typedef QList<TleData> TleDataList; |
472 | +typedef QHash<QString, TleData> TleDataHash ; |
473 | + |
474 | //! @class Satellites |
475 | //! Satellites in low Earth orbit require different orbital calculations from planets, the moon |
476 | //! and so on. This plugin implements the SGP4/SDP4 algorithms in Stellarium, allowing accurate |
477 | @@ -65,7 +79,8 @@ |
478 | { |
479 | Visible, |
480 | NotVisible, |
481 | - Both |
482 | + Both, |
483 | + NewlyAdded |
484 | }; |
485 | |
486 | Satellites(); |
487 | @@ -130,6 +145,17 @@ |
488 | |
489 | //! get a satellite object by identifier |
490 | SatelliteP getByID(const QString& id); |
491 | + |
492 | + //! Returns a list of all satellite IDs. |
493 | + QStringList getAllIDs(); |
494 | + |
495 | + //! Add the given satellites. |
496 | + //! The changes are not saved to file. |
497 | + void add(const TleDataList& newSatellites); |
498 | + |
499 | + //! Remove the selected satellites. |
500 | + //! The changes are not saved to file. |
501 | + void remove(const QStringList& idList); |
502 | |
503 | //! get whether or not the plugin will try to update TLE data from the internet |
504 | //! @return true if updates are set to be done, false otherwise |
505 | @@ -171,6 +197,13 @@ |
506 | //! @param deleteFiles if set, the update files are deleted after |
507 | //! they are used, else they are left alone |
508 | void updateFromFiles(QStringList paths, bool deleteFiles=false); |
509 | + |
510 | + //! Reads a TLE list from a file to the supplied hash. |
511 | + //! If an entry with the same ID exists in the given hash, its contents |
512 | + //! are overwritten with the new values. |
513 | + //! \param openFile a reference to an \b open file. |
514 | + //! \param tleList a hash with satellite IDs (catalog numbers) as keys. |
515 | + static void parseTleFile(QFile& openFile, TleDataHash& tleList); |
516 | |
517 | signals: |
518 | //! emitted when the update status changes, e.g. when |
519 | |
520 | === modified file 'plugins/Satellites/src/gui/SatellitesDialog.cpp' |
521 | --- plugins/Satellites/src/gui/SatellitesDialog.cpp 2011-12-13 03:53:53 +0000 |
522 | +++ plugins/Satellites/src/gui/SatellitesDialog.cpp 2012-01-10 09:14:25 +0000 |
523 | @@ -27,6 +27,7 @@ |
524 | #include "StelApp.hpp" |
525 | #include "ui_satellitesDialog.h" |
526 | #include "SatellitesDialog.hpp" |
527 | +#include "SatellitesImportDialog.hpp" |
528 | #include "Satellites.hpp" |
529 | #include "StelModuleMgr.hpp" |
530 | #include "StelObjectMgr.hpp" |
531 | @@ -37,7 +38,7 @@ |
532 | #include "StelFileMgr.hpp" |
533 | #include "StelTranslator.hpp" |
534 | |
535 | -SatellitesDialog::SatellitesDialog() : updateTimer(NULL) |
536 | +SatellitesDialog::SatellitesDialog() : updateTimer(NULL), importWindow(0) |
537 | { |
538 | ui = new Ui_satellitesDialog; |
539 | } |
540 | @@ -50,6 +51,13 @@ |
541 | delete updateTimer; |
542 | updateTimer = NULL; |
543 | } |
544 | + |
545 | + if (importWindow) |
546 | + { |
547 | + delete importWindow; |
548 | + importWindow = 0; |
549 | + } |
550 | + |
551 | delete ui; |
552 | } |
553 | |
554 | @@ -115,9 +123,16 @@ |
555 | this, |
556 | SLOT(updateSelectedSatelliteInfo(QListWidgetItem*,QListWidgetItem*))); |
557 | connect(ui->satellitesList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(satelliteDoubleClick(QListWidgetItem*))); |
558 | - connect(ui->groupsCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(groupFilterChanged(int))); |
559 | + connect(ui->groupsCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(listSatelliteGroup(int))); |
560 | connect(ui->saveSatellitesButton, SIGNAL(clicked()), this, SLOT(saveSatellites())); |
561 | + connect(ui->removeSatellitesButton, SIGNAL(clicked()), this, SLOT(removeSatellites())); |
562 | connectSatelliteGuiForm(); |
563 | + |
564 | + importWindow = new SatellitesImportDialog(); |
565 | + connect(ui->addSatellitesButton, SIGNAL(clicked()), |
566 | + importWindow, SLOT(setVisible())); |
567 | + connect(importWindow, SIGNAL(satellitesAccepted(TleDataList)), |
568 | + this, SLOT(addSatellites(TleDataList))); |
569 | |
570 | // Sources tab |
571 | connect(ui->sourceList, SIGNAL(currentTextChanged(const QString&)), ui->sourceEdit, SLOT(setText(const QString&))); |
572 | @@ -135,7 +150,7 @@ |
573 | |
574 | } |
575 | |
576 | -void SatellitesDialog::groupFilterChanged(int index) |
577 | +void SatellitesDialog::listSatelliteGroup(int index) |
578 | { |
579 | QVariantList prevMultiSelection; |
580 | foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
581 | @@ -153,6 +168,8 @@ |
582 | satellites = plugin->getSatellites(QString(), Satellites::Visible); |
583 | else if (selectedGroup == "notvisible") |
584 | satellites = plugin->getSatellites(QString(), Satellites::NotVisible); |
585 | + else if (selectedGroup == "newlyadded") |
586 | + satellites = plugin->getSatellites(QString(), Satellites::NewlyAdded); |
587 | else |
588 | satellites = plugin->getSatellites(ui->groupsCombo->currentText()); |
589 | |
590 | @@ -190,6 +207,11 @@ |
591 | } |
592 | } |
593 | |
594 | +void SatellitesDialog::reloadSatellitesList() |
595 | +{ |
596 | + listSatelliteGroup(ui->groupsCombo->currentIndex()); |
597 | +} |
598 | + |
599 | void SatellitesDialog::updateSelectedSatelliteInfo(QListWidgetItem* curItem, |
600 | QListWidgetItem* prevItem) |
601 | { |
602 | @@ -430,6 +452,7 @@ |
603 | ui->groupsCombo->addItems(GETSTELMODULE(Satellites)->getGroups()); |
604 | // BM: The wording has been changed to prevent confusion with the visibility |
605 | // status of the actual satellites. I'll leave further changes to Matthew.:) |
606 | + ui->groupsCombo->insertItem(0, q_("[all newly added]"), QVariant("newlyadded")); |
607 | ui->groupsCombo->insertItem(0, q_("[all not displayed]"), QVariant("notvisible")); |
608 | ui->groupsCombo->insertItem(0, q_("[all displayed]"), QVariant("visible")); |
609 | ui->groupsCombo->insertItem(0, q_("[all]"), QVariant("all")); |
610 | @@ -440,26 +463,78 @@ |
611 | GETSTELMODULE(Satellites)->saveSettingsToConfig(); |
612 | } |
613 | |
614 | -void SatellitesDialog::visibleCheckChanged(int state) |
615 | -{ |
616 | - foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
617 | - { |
618 | - QString id = i->data(Qt::UserRole).toString(); |
619 | - SatelliteP sat = GETSTELMODULE(Satellites)->getByID(id); |
620 | - sat->visible = (state==Qt::Checked); |
621 | - } |
622 | - groupFilterChanged(ui->groupsCombo->currentIndex()); |
623 | -} |
624 | - |
625 | -void SatellitesDialog::orbitCheckChanged(int state) |
626 | -{ |
627 | - foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
628 | - { |
629 | - QString id = i->data(Qt::UserRole).toString(); |
630 | - SatelliteP sat = GETSTELMODULE(Satellites)->getByID(id); |
631 | - sat->orbitVisible = (state==Qt::Checked); |
632 | - } |
633 | - groupFilterChanged(ui->groupsCombo->currentIndex()); |
634 | +void SatellitesDialog::addSatellites(const TleDataList& newSatellites) |
635 | +{ |
636 | + GETSTELMODULE(Satellites)->add(newSatellites); |
637 | + saveSatellites(); |
638 | + |
639 | + // Trigger re-loading the list to display the new satellites |
640 | + int index = ui->groupsCombo->findData(QVariant("newlyadded")); |
641 | + if (ui->groupsCombo->currentIndex() == index) |
642 | + listSatelliteGroup(index); |
643 | + else |
644 | + ui->groupsCombo->setCurrentIndex(index); //Triggers the same operation |
645 | + |
646 | + // Select the satellites that were added just now |
647 | + QListWidget* list = ui->satellitesList; |
648 | + list->clearSelection(); |
649 | + int firstAddedIndex = -1; |
650 | + QSet<QString> newIds; |
651 | + foreach (const TleData& sat, newSatellites) |
652 | + newIds.insert(sat.id); |
653 | + for (int i = 0; i < list->count(); i++) |
654 | + { |
655 | + QString id = list->item(i)->data(Qt::UserRole).toString(); |
656 | + if (newIds.remove(id)) |
657 | + { |
658 | + list->item(i)->setSelected(true); |
659 | + if (firstAddedIndex < 0) |
660 | + firstAddedIndex = i; |
661 | + } |
662 | + } |
663 | + if (firstAddedIndex >= 0) |
664 | + list->scrollToItem(list->item(firstAddedIndex), |
665 | + QAbstractItemView::PositionAtTop); |
666 | + else |
667 | + list->setCurrentRow(0); |
668 | +} |
669 | + |
670 | +void SatellitesDialog::removeSatellites() |
671 | +{ |
672 | + QStringList idList; |
673 | + foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
674 | + { |
675 | + QString id = i->data(Qt::UserRole).toString(); |
676 | + idList.append(id); |
677 | + } |
678 | + if (!idList.isEmpty()) |
679 | + { |
680 | + GETSTELMODULE(Satellites)->remove(idList); |
681 | + reloadSatellitesList(); |
682 | + saveSatellites(); |
683 | + } |
684 | +} |
685 | + |
686 | +void SatellitesDialog::setDisplayFlag(bool display) |
687 | +{ |
688 | + foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
689 | + { |
690 | + QString id = i->data(Qt::UserRole).toString(); |
691 | + SatelliteP sat = GETSTELMODULE(Satellites)->getByID(id); |
692 | + sat->visible = display; |
693 | + } |
694 | + reloadSatellitesList(); |
695 | +} |
696 | + |
697 | +void SatellitesDialog::setOrbitFlag(bool display) |
698 | +{ |
699 | + foreach (QListWidgetItem* i, ui->satellitesList->selectedItems()) |
700 | + { |
701 | + QString id = i->data(Qt::UserRole).toString(); |
702 | + SatelliteP sat = GETSTELMODULE(Satellites)->getByID(id); |
703 | + sat->orbitVisible = display; |
704 | + } |
705 | + reloadSatellitesList(); |
706 | } |
707 | |
708 | void SatellitesDialog::satelliteDoubleClick(QListWidgetItem* item) |
709 | @@ -503,12 +578,12 @@ |
710 | { |
711 | // make sure we don't connect more than once |
712 | disconnectSatelliteGuiForm(); |
713 | - connect(ui->visibleCheckbox, SIGNAL(stateChanged(int)), this, SLOT(visibleCheckChanged(int))); |
714 | - connect(ui->orbitCheckbox, SIGNAL(stateChanged(int)), this, SLOT(orbitCheckChanged(int))); |
715 | + connect(ui->visibleCheckbox, SIGNAL(clicked(bool)), this, SLOT(setDisplayFlag(bool))); |
716 | + connect(ui->orbitCheckbox, SIGNAL(clicked(bool)), this, SLOT(setOrbitFlag(bool))); |
717 | } |
718 | |
719 | void SatellitesDialog::disconnectSatelliteGuiForm(void) |
720 | { |
721 | - disconnect(ui->visibleCheckbox, SIGNAL(stateChanged(int)), this, SLOT(visibleCheckChanged(int))); |
722 | - disconnect(ui->orbitCheckbox, SIGNAL(stateChanged(int)), this, SLOT(orbitCheckChanged(int))); |
723 | + disconnect(ui->visibleCheckbox, SIGNAL(clicked(bool)), this, SLOT(setDisplayFlag(bool))); |
724 | + disconnect(ui->orbitCheckbox, SIGNAL(clicked(bool)), this, SLOT(setOrbitFlag(bool))); |
725 | } |
726 | |
727 | === modified file 'plugins/Satellites/src/gui/SatellitesDialog.hpp' |
728 | --- plugins/Satellites/src/gui/SatellitesDialog.hpp 2011-12-12 23:12:49 +0000 |
729 | +++ plugins/Satellites/src/gui/SatellitesDialog.hpp 2012-01-10 09:14:25 +0000 |
730 | @@ -27,6 +27,7 @@ |
731 | |
732 | class Ui_satellitesDialog; |
733 | class QTimer; |
734 | +class SatellitesImportDialog; |
735 | |
736 | class SatellitesDialog : public StelDialog |
737 | { |
738 | @@ -45,7 +46,9 @@ |
739 | void refreshUpdateValues(void); |
740 | |
741 | private slots: |
742 | - void groupFilterChanged(int index); |
743 | + void listSatelliteGroup(int index); |
744 | + //! Reloads the satellites list with the currently selected group. |
745 | + void reloadSatellitesList(); |
746 | void updateSelectedSatelliteInfo(QListWidgetItem* cur, QListWidgetItem* prev); |
747 | void saveSatellites(void); |
748 | void setUpdateValues(int hours); |
749 | @@ -58,8 +61,10 @@ |
750 | void addSourceRow(void); |
751 | void restoreDefaults(void); |
752 | void saveSettings(void); |
753 | - void visibleCheckChanged(int state); |
754 | - void orbitCheckChanged(int state); |
755 | + void addSatellites(const TleDataList& newSatellites); |
756 | + void removeSatellites(); |
757 | + void setDisplayFlag(bool display); |
758 | + void setOrbitFlag(bool display); |
759 | void satelliteDoubleClick(QListWidgetItem* item); |
760 | void setOrbitParams(void); |
761 | void updateTLEs(void); |
762 | @@ -74,6 +79,8 @@ |
763 | void updateGuiFromSettings(void); |
764 | void populateGroupsList(); |
765 | QTimer* updateTimer; |
766 | + |
767 | + SatellitesImportDialog* importWindow; |
768 | }; |
769 | |
770 | #endif // _SATELLITESDIALOG_HPP_ |
771 | |
772 | === added file 'plugins/Satellites/src/gui/SatellitesImportDialog.cpp' |
773 | --- plugins/Satellites/src/gui/SatellitesImportDialog.cpp 1970-01-01 00:00:00 +0000 |
774 | +++ plugins/Satellites/src/gui/SatellitesImportDialog.cpp 2012-01-10 09:14:25 +0000 |
775 | @@ -0,0 +1,360 @@ |
776 | +/* |
777 | + * Stellarium Satellites Plug-in: satellites import feature |
778 | + * Copyright (C) 2012 Bogdan Marinov |
779 | + * |
780 | + * This program is free software; you can redistribute it and/or |
781 | + * modify it under the terms of the GNU General Public License |
782 | + * as published by the Free Software Foundation; either version 2 |
783 | + * of the License, or (at your option) any later version. |
784 | + * |
785 | + * This program is distributed in the hope that it will be useful, |
786 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
787 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
788 | + * GNU General Public License for more details. |
789 | + * |
790 | + * You should have received a copy of the GNU General Public License |
791 | + * along with this program; if not, write to the Free Software |
792 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
793 | +*/ |
794 | + |
795 | +#include "SatellitesImportDialog.hpp" |
796 | +#include "ui_satellitesImportDialog.h" |
797 | + |
798 | +#include "StelApp.hpp" |
799 | +#include "StelMainGraphicsView.hpp" //for the QFileDialog? Why? |
800 | +#include "StelModuleMgr.hpp" // for the GETSTELMODULE macro :( |
801 | + |
802 | +#include <QDesktopServices> |
803 | +#include <QFileDialog> |
804 | +#include <QFileInfo> |
805 | +#include <QNetworkReply> |
806 | +#include <QSortFilterProxyModel> |
807 | +#include <QStandardItemModel> |
808 | +#include <QTemporaryFile> |
809 | + |
810 | +SatellitesImportDialog::SatellitesImportDialog() : |
811 | + downloadMgr(0), |
812 | + progressBar(0) |
813 | +{ |
814 | + ui = new Ui_satellitesImportDialog; |
815 | + newSatellitesModel = new QStandardItemModel(this); |
816 | +} |
817 | + |
818 | +SatellitesImportDialog::~SatellitesImportDialog() |
819 | +{ |
820 | + delete ui; |
821 | + |
822 | + // Do I need to explicitly delete this? |
823 | + if (progressBar) |
824 | + { |
825 | + delete progressBar; |
826 | + progressBar = 0; |
827 | + } |
828 | + |
829 | + if (newSatellitesModel) |
830 | + { |
831 | + newSatellitesModel->clear(); |
832 | + delete newSatellitesModel; |
833 | + newSatellitesModel = 0; |
834 | + } |
835 | +} |
836 | + |
837 | +void SatellitesImportDialog::languageChanged() |
838 | +{ |
839 | + if (dialog) |
840 | + { |
841 | + ui->retranslateUi(dialog); |
842 | + } |
843 | +} |
844 | + |
845 | +void SatellitesImportDialog::setVisible(bool visible) |
846 | +{ |
847 | + StelDialog::setVisible(visible); |
848 | + if (!isGettingData) |
849 | + getData(); |
850 | +} |
851 | + |
852 | +void SatellitesImportDialog::createDialogContent() |
853 | +{ |
854 | + ui->setupUi(dialog); |
855 | + |
856 | + connect(ui->closeStelWindow, SIGNAL(clicked()), |
857 | + this, SLOT(close())); |
858 | + |
859 | + connect(ui->pushButtonGetData, SIGNAL(clicked()), |
860 | + this, SLOT(getData())); |
861 | + connect(ui->pushButtonAbort, SIGNAL(clicked()), |
862 | + this, SLOT(abortDownloads())); |
863 | + connect(ui->pushButtonAdd, SIGNAL(clicked()), |
864 | + this, SLOT(acceptNewSatellites())); |
865 | + connect(ui->pushButtonDiscard, SIGNAL(clicked()), |
866 | + this, SLOT(discardNewSatellites())); |
867 | + |
868 | + QSortFilterProxyModel * filterProxyModel = new QSortFilterProxyModel(this); |
869 | + filterProxyModel->setSourceModel(newSatellitesModel); |
870 | + filterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); |
871 | + ui->listView->setModel(filterProxyModel); |
872 | + connect(ui->lineEditSearch, SIGNAL(textChanged(const QString&)), |
873 | + filterProxyModel, SLOT(setFilterFixedString(const QString&))); |
874 | + |
875 | + reset(); |
876 | +} |
877 | + |
878 | +void SatellitesImportDialog::getData() |
879 | +{ |
880 | + if (isGettingData) |
881 | + return; |
882 | + isGettingData = true; |
883 | + |
884 | + if (!downloadMgr) |
885 | + { |
886 | + downloadMgr = StelApp::getInstance().getNetworkAccessManager(); |
887 | + connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), |
888 | + this, SLOT(receiveDownload(QNetworkReply*))); |
889 | + } |
890 | + Satellites* satMgr = GETSTELMODULE(Satellites); |
891 | + |
892 | + if (satMgr->getUpdatesEnabled()) |
893 | + { |
894 | + sourceUrls = satMgr->getTleSources(); |
895 | + qDeleteAll(sourceFiles); |
896 | + sourceFiles.clear(); |
897 | + numberDownloadsComplete = 0; |
898 | + |
899 | + // Reusing some code from Satellites::updateTLEs() |
900 | + if (progressBar == 0) |
901 | + progressBar = StelApp::getInstance().getGui()->addProgressBar(); |
902 | + progressBar->setValue(0); |
903 | + progressBar->setMaximum(sourceUrls.size()); |
904 | + progressBar->setVisible(true); |
905 | + progressBar->setFormat("TLE download %v/%m"); |
906 | + |
907 | + ui->pushButtonGetData->setVisible(false); |
908 | + ui->pushButtonAbort->setVisible(true); |
909 | + ui->groupBoxWorking->setTitle("Downloading data..."); |
910 | + displayMessage("Stellarium is downloading satellite data from the update sources. Please wait..."); |
911 | + |
912 | + for (int i = 0; i < sourceUrls.size(); i++) |
913 | + { |
914 | + QUrl url(sourceUrls.at(i)); |
915 | + QNetworkReply* reply = downloadMgr->get(QNetworkRequest(url)); |
916 | + activeDownloads.append(reply); |
917 | + } |
918 | + } |
919 | + else |
920 | + { |
921 | + QStringList sourceFilePaths; |
922 | + QString homeDirPath = QDesktopServices::storageLocation(QDesktopServices::HomeLocation); |
923 | + sourceFilePaths = QFileDialog::getOpenFileNames( |
924 | + &StelMainGraphicsView::getInstance(), |
925 | + "Select TLE source file(s)...", |
926 | + homeDirPath, "*.*"); |
927 | + if (sourceFilePaths.isEmpty()) |
928 | + return; |
929 | + foreach (QString filePath, sourceFilePaths) |
930 | + { |
931 | + QFileInfo fileInfo(filePath); |
932 | + if (fileInfo.exists() && fileInfo.isReadable()) |
933 | + { |
934 | + QFile* file = new QFile(filePath); |
935 | + sourceFiles.append(file); |
936 | + } |
937 | + } |
938 | + ui->pushButtonGetData->setVisible(false); |
939 | + ui->pushButtonAbort->setVisible(false); |
940 | + ui->groupBoxWorking->setTitle("Processing data..."); |
941 | + displayMessage("Processing data..."); |
942 | + populateList(); |
943 | + } |
944 | +} |
945 | + |
946 | +void SatellitesImportDialog::receiveDownload(QNetworkReply* networkReply) |
947 | +{ |
948 | + Q_ASSERT(networkReply); |
949 | + |
950 | + // First, check if this one is one of ours |
951 | + QString url = networkReply->request().url().toString(); |
952 | + if (!activeDownloads.contains(networkReply)) |
953 | + { |
954 | + qDebug() << "Satellites: Received URL not in the source list:" << url; |
955 | + return; |
956 | + } |
957 | + |
958 | + // An error is a completed download, isn't it? |
959 | + activeDownloads.removeAll(networkReply); |
960 | + numberDownloadsComplete++; |
961 | + if (progressBar) |
962 | + progressBar->setValue(numberDownloadsComplete); |
963 | + |
964 | + // Then, see if there was an error... |
965 | + if (networkReply->error() != QNetworkReply::NoError) |
966 | + { |
967 | + qWarning() << "Satellites: failed to download" << url |
968 | + << networkReply->errorString(); |
969 | + return; |
970 | + } |
971 | + |
972 | + QTemporaryFile* tmpFile = new QTemporaryFile(); |
973 | + if (tmpFile->open()) |
974 | + { |
975 | + tmpFile->write(networkReply->readAll()); |
976 | + tmpFile->close(); |
977 | + sourceFiles.append(tmpFile); |
978 | + } |
979 | + else |
980 | + { |
981 | + qWarning() << "Satellites: could not save to file" << url; |
982 | + } |
983 | + |
984 | + if (numberDownloadsComplete >= sourceUrls.count()) |
985 | + { |
986 | + if (progressBar) |
987 | + { |
988 | + delete progressBar; |
989 | + progressBar = 0; |
990 | + } |
991 | + |
992 | + if (sourceFiles.isEmpty()) |
993 | + { |
994 | + reset(); |
995 | + displayMessage("No data could be downloaded. Try again later."); |
996 | + } |
997 | + else |
998 | + { |
999 | + ui->pushButtonAbort->setVisible(false); |
1000 | + ui->groupBoxWorking->setTitle("Processing data..."); |
1001 | + displayMessage("Processing data..."); |
1002 | + populateList(); |
1003 | + } |
1004 | + } |
1005 | + |
1006 | + networkReply->deleteLater(); |
1007 | +} |
1008 | + |
1009 | +void SatellitesImportDialog::abortDownloads() |
1010 | +{ |
1011 | + for (int i = 0; i < activeDownloads.count(); i++) |
1012 | + { |
1013 | + activeDownloads[i]->abort(); |
1014 | + activeDownloads[i]->deleteLater(); |
1015 | + } |
1016 | + reset(); |
1017 | + displayMessage("Download aborted."); |
1018 | +} |
1019 | + |
1020 | +void SatellitesImportDialog::acceptNewSatellites() |
1021 | +{ |
1022 | + TleDataList satellitesToAdd; |
1023 | + for (int row = 0; row < newSatellitesModel->rowCount(); row++) |
1024 | + { |
1025 | + QStandardItem* item = newSatellitesModel->item(row); |
1026 | + if (item->checkState() == Qt::Checked) |
1027 | + { |
1028 | + QString id = item->data(Qt::UserRole).toString(); |
1029 | + satellitesToAdd.append(newSatellites.value(id)); |
1030 | + } |
1031 | + } |
1032 | + emit satellitesAccepted(satellitesToAdd); |
1033 | + reset(); |
1034 | + close(); |
1035 | +} |
1036 | + |
1037 | +void SatellitesImportDialog::discardNewSatellites() |
1038 | +{ |
1039 | + reset(); |
1040 | + close(); |
1041 | +} |
1042 | + |
1043 | +void SatellitesImportDialog::reset() |
1044 | +{ |
1045 | + // Assuming that everything that needs to be stopped is stopped |
1046 | + isGettingData = false; |
1047 | + ui->stackedWidget->setCurrentIndex(0); |
1048 | + ui->pushButtonGetData->setVisible(true); |
1049 | + ui->pushButtonAbort->setVisible(false); |
1050 | + ui->labelMessage->setVisible(false); |
1051 | + ui->labelMessage->clear(); |
1052 | + ui->groupBoxWorking->setTitle("Get data"); |
1053 | + newSatellitesModel->clear(); |
1054 | + ui->lineEditSearch->clear(); |
1055 | + |
1056 | + newSatellites.clear(); |
1057 | + sourceUrls.clear(); |
1058 | + |
1059 | + qDeleteAll(activeDownloads); |
1060 | + activeDownloads.clear(); |
1061 | + |
1062 | + qDeleteAll(sourceFiles); |
1063 | + sourceFiles.clear(); |
1064 | + |
1065 | + numberDownloadsComplete = 0; |
1066 | + if (progressBar) |
1067 | + { |
1068 | + delete progressBar; |
1069 | + progressBar = 0; |
1070 | + } |
1071 | +} |
1072 | + |
1073 | +void SatellitesImportDialog::populateList() |
1074 | +{ |
1075 | + newSatellites.clear(); |
1076 | + newSatellitesModel->clear(); |
1077 | + Satellites* satMgr = GETSTELMODULE(Satellites); |
1078 | + |
1079 | + // Load ALL two-line element sets... |
1080 | + for (int f = 0; f < sourceFiles.count(); f++) |
1081 | + { |
1082 | + bool open = false; |
1083 | + QTemporaryFile* tempFile = dynamic_cast<QTemporaryFile*>(sourceFiles[f]); |
1084 | + if (tempFile) |
1085 | + open = tempFile->open(); |
1086 | + else |
1087 | + open = sourceFiles[f]->open(QFile::ReadOnly); |
1088 | + if (open) |
1089 | + { |
1090 | + satMgr->parseTleFile(*sourceFiles[f], newSatellites); |
1091 | + sourceFiles[f]->close(); |
1092 | + } |
1093 | + else |
1094 | + { |
1095 | + qDebug() << "Satellites: cannot open file" |
1096 | + << sourceFiles[f]->fileName(); |
1097 | + } |
1098 | + } |
1099 | + // Clear the disk... |
1100 | + qDeleteAll(sourceFiles); |
1101 | + sourceFiles.clear(); |
1102 | + |
1103 | + QStringList existingIDs = satMgr->getAllIDs(); |
1104 | + QHashIterator<QString,TleData> i(newSatellites); |
1105 | + while (i.hasNext()) |
1106 | + { |
1107 | + i.next(); |
1108 | + |
1109 | + // Skip duplicates |
1110 | + if (existingIDs.contains(i.key())) |
1111 | + continue; |
1112 | + |
1113 | + TleData tle = i.value(); |
1114 | + QStandardItem* newItem = new QStandardItem(tle.name); |
1115 | + newItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsUserCheckable); |
1116 | + newItem->setCheckState(Qt::Unchecked); |
1117 | + newItem->setData(tle.id, Qt::UserRole); |
1118 | + QString text = QString("Catalog Number: %1").arg(tle.id); |
1119 | + newItem->setToolTip(text); |
1120 | + newSatellitesModel->appendRow(newItem); |
1121 | + } |
1122 | + existingIDs.clear(); |
1123 | + newSatellitesModel->sort(0); |
1124 | + ui->listView->scrollToTop(); |
1125 | + ui->stackedWidget->setCurrentIndex(1); |
1126 | +} |
1127 | + |
1128 | +void SatellitesImportDialog::displayMessage(const QString& message) |
1129 | +{ |
1130 | + if (message.isEmpty()) |
1131 | + return; |
1132 | + |
1133 | + ui->labelMessage->setText(message); |
1134 | + ui->labelMessage->setVisible(true); |
1135 | +} |
1136 | |
1137 | === added file 'plugins/Satellites/src/gui/SatellitesImportDialog.hpp' |
1138 | --- plugins/Satellites/src/gui/SatellitesImportDialog.hpp 1970-01-01 00:00:00 +0000 |
1139 | +++ plugins/Satellites/src/gui/SatellitesImportDialog.hpp 2012-01-10 09:14:25 +0000 |
1140 | @@ -0,0 +1,73 @@ |
1141 | +/* |
1142 | + * Stellarium Satellites Plug-in: satellites import feature |
1143 | + * Copyright (C) 2012 Bogdan Marinov |
1144 | + * |
1145 | + * This program is free software; you can redistribute it and/or |
1146 | + * modify it under the terms of the GNU General Public License |
1147 | + * as published by the Free Software Foundation; either version 2 |
1148 | + * of the License, or (at your option) any later version. |
1149 | + * |
1150 | + * This program is distributed in the hope that it will be useful, |
1151 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1152 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1153 | + * GNU General Public License for more details. |
1154 | + * |
1155 | + * You should have received a copy of the GNU General Public License |
1156 | + * along with this program; if not, write to the Free Software |
1157 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
1158 | +*/ |
1159 | + |
1160 | +#ifndef IMPORTSATELLITESWINDOW_HPP |
1161 | +#define IMPORTSATELLITESWINDOW_HPP |
1162 | + |
1163 | +#include "StelDialog.hpp" |
1164 | +#include "Satellites.hpp" |
1165 | + |
1166 | +class Ui_satellitesImportDialog; |
1167 | +class QStandardItemModel; |
1168 | +class QTemporaryFile; |
1169 | +class QNetworkReply; |
1170 | + |
1171 | +class SatellitesImportDialog : public StelDialog |
1172 | +{ |
1173 | + Q_OBJECT |
1174 | + |
1175 | +public: |
1176 | + SatellitesImportDialog(); |
1177 | + ~SatellitesImportDialog(); |
1178 | + |
1179 | +signals: |
1180 | + void satellitesAccepted(const TleDataList& newSatellites); |
1181 | + |
1182 | +public slots: |
1183 | + void languageChanged(); |
1184 | + void setVisible(bool visible = true); |
1185 | + |
1186 | +private slots: |
1187 | + void getData(); |
1188 | + void receiveDownload(QNetworkReply* networkReply); |
1189 | + void abortDownloads(); |
1190 | + void acceptNewSatellites(); |
1191 | + void discardNewSatellites(); |
1192 | + |
1193 | +private: |
1194 | + void createDialogContent(); |
1195 | + Ui_satellitesImportDialog* ui; |
1196 | + |
1197 | + void reset(); |
1198 | + void populateList(); |
1199 | + void displayMessage(const QString& message); |
1200 | + |
1201 | + TleDataHash newSatellites; |
1202 | + bool isGettingData; |
1203 | + int numberDownloadsComplete; |
1204 | + QNetworkAccessManager* downloadMgr; |
1205 | + QList<QNetworkReply*> activeDownloads; |
1206 | + QStringList sourceUrls; |
1207 | + QList<QFile*> sourceFiles; |
1208 | + QProgressBar* progressBar; |
1209 | + |
1210 | + QStandardItemModel* newSatellitesModel; |
1211 | +}; |
1212 | + |
1213 | +#endif // IMPORTSATELLITESWINDOW_HPP |
1214 | |
1215 | === modified file 'plugins/Satellites/src/gui/satellitesDialog.ui' |
1216 | --- plugins/Satellites/src/gui/satellitesDialog.ui 2012-01-07 09:15:06 +0000 |
1217 | +++ plugins/Satellites/src/gui/satellitesDialog.ui 2012-01-10 09:14:25 +0000 |
1218 | @@ -383,7 +383,7 @@ |
1219 | </spacer> |
1220 | </item> |
1221 | <item> |
1222 | - <widget class="QFrame" name=""> |
1223 | + <widget class="QFrame" name="frame"> |
1224 | <layout class="QHBoxLayout" name="horizontalLayout_7"> |
1225 | <property name="leftMargin"> |
1226 | <number>9</number> |
1227 | @@ -641,6 +641,40 @@ |
1228 | </spacer> |
1229 | </item> |
1230 | <item> |
1231 | + <widget class="QPushButton" name="removeSatellitesButton"> |
1232 | + <property name="sizePolicy"> |
1233 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1234 | + <horstretch>0</horstretch> |
1235 | + <verstretch>0</verstretch> |
1236 | + </sizepolicy> |
1237 | + </property> |
1238 | + <property name="toolTip"> |
1239 | + <string>Remove the selected satellites</string> |
1240 | + </property> |
1241 | + <property name="icon"> |
1242 | + <iconset resource="../../resources/Satellites.qrc"> |
1243 | + <normaloff>:/satellites/bt_delete.png</normaloff>:/satellites/bt_delete.png</iconset> |
1244 | + </property> |
1245 | + </widget> |
1246 | + </item> |
1247 | + <item> |
1248 | + <widget class="QPushButton" name="addSatellitesButton"> |
1249 | + <property name="sizePolicy"> |
1250 | + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> |
1251 | + <horstretch>0</horstretch> |
1252 | + <verstretch>0</verstretch> |
1253 | + </sizepolicy> |
1254 | + </property> |
1255 | + <property name="toolTip"> |
1256 | + <string>Add more satellites</string> |
1257 | + </property> |
1258 | + <property name="icon"> |
1259 | + <iconset resource="../../resources/Satellites.qrc"> |
1260 | + <normaloff>:/satellites/bt_add.png</normaloff>:/satellites/bt_add.png</iconset> |
1261 | + </property> |
1262 | + </widget> |
1263 | + </item> |
1264 | + <item> |
1265 | <widget class="QPushButton" name="commsButton"> |
1266 | <property name="enabled"> |
1267 | <bool>false</bool> |
1268 | @@ -807,6 +841,8 @@ |
1269 | <tabstop>descriptionTextEdit</tabstop> |
1270 | <tabstop>groupsTextEdit</tabstop> |
1271 | <tabstop>tleTextEdit</tabstop> |
1272 | + <tabstop>removeSatellitesButton</tabstop> |
1273 | + <tabstop>addSatellitesButton</tabstop> |
1274 | <tabstop>commsButton</tabstop> |
1275 | <tabstop>saveSatellitesButton</tabstop> |
1276 | <tabstop>sourceList</tabstop> |
1277 | |
1278 | === added file 'plugins/Satellites/src/gui/satellitesImportDialog.ui' |
1279 | --- plugins/Satellites/src/gui/satellitesImportDialog.ui 1970-01-01 00:00:00 +0000 |
1280 | +++ plugins/Satellites/src/gui/satellitesImportDialog.ui 2012-01-10 09:14:25 +0000 |
1281 | @@ -0,0 +1,250 @@ |
1282 | +<?xml version="1.0" encoding="UTF-8"?> |
1283 | +<ui version="4.0"> |
1284 | + <class>satellitesImportDialog</class> |
1285 | + <widget class="QWidget" name="satellitesImportDialog"> |
1286 | + <property name="geometry"> |
1287 | + <rect> |
1288 | + <x>0</x> |
1289 | + <y>0</y> |
1290 | + <width>400</width> |
1291 | + <height>300</height> |
1292 | + </rect> |
1293 | + </property> |
1294 | + <layout class="QVBoxLayout" name="verticalLayoutMain"> |
1295 | + <property name="spacing"> |
1296 | + <number>0</number> |
1297 | + </property> |
1298 | + <property name="margin"> |
1299 | + <number>0</number> |
1300 | + </property> |
1301 | + <item> |
1302 | + <widget class="BarFrame" name="TitleBar"> |
1303 | + <property name="sizePolicy"> |
1304 | + <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> |
1305 | + <horstretch>0</horstretch> |
1306 | + <verstretch>0</verstretch> |
1307 | + </sizepolicy> |
1308 | + </property> |
1309 | + <property name="minimumSize"> |
1310 | + <size> |
1311 | + <width>0</width> |
1312 | + <height>25</height> |
1313 | + </size> |
1314 | + </property> |
1315 | + <property name="maximumSize"> |
1316 | + <size> |
1317 | + <width>16777215</width> |
1318 | + <height>30</height> |
1319 | + </size> |
1320 | + </property> |
1321 | + <property name="focusPolicy"> |
1322 | + <enum>Qt::NoFocus</enum> |
1323 | + </property> |
1324 | + <property name="autoFillBackground"> |
1325 | + <bool>false</bool> |
1326 | + </property> |
1327 | + <property name="frameShape"> |
1328 | + <enum>QFrame::StyledPanel</enum> |
1329 | + </property> |
1330 | + <layout class="QHBoxLayout" name="_2"> |
1331 | + <property name="spacing"> |
1332 | + <number>6</number> |
1333 | + </property> |
1334 | + <property name="leftMargin"> |
1335 | + <number>0</number> |
1336 | + </property> |
1337 | + <property name="topMargin"> |
1338 | + <number>0</number> |
1339 | + </property> |
1340 | + <property name="rightMargin"> |
1341 | + <number>4</number> |
1342 | + </property> |
1343 | + <property name="bottomMargin"> |
1344 | + <number>0</number> |
1345 | + </property> |
1346 | + <item> |
1347 | + <spacer name="leftSpacer"> |
1348 | + <property name="orientation"> |
1349 | + <enum>Qt::Horizontal</enum> |
1350 | + </property> |
1351 | + <property name="sizeHint" stdset="0"> |
1352 | + <size> |
1353 | + <width>40</width> |
1354 | + <height>20</height> |
1355 | + </size> |
1356 | + </property> |
1357 | + </spacer> |
1358 | + </item> |
1359 | + <item> |
1360 | + <widget class="QLabel" name="stelWindowTitle"> |
1361 | + <property name="text"> |
1362 | + <string notr="true" extracomment="The title of the window will be set during runtime">More Satellites</string> |
1363 | + </property> |
1364 | + </widget> |
1365 | + </item> |
1366 | + <item> |
1367 | + <spacer name="rightSpacer"> |
1368 | + <property name="orientation"> |
1369 | + <enum>Qt::Horizontal</enum> |
1370 | + </property> |
1371 | + <property name="sizeHint" stdset="0"> |
1372 | + <size> |
1373 | + <width>40</width> |
1374 | + <height>20</height> |
1375 | + </size> |
1376 | + </property> |
1377 | + </spacer> |
1378 | + </item> |
1379 | + <item> |
1380 | + <widget class="QPushButton" name="closeStelWindow"> |
1381 | + <property name="minimumSize"> |
1382 | + <size> |
1383 | + <width>16</width> |
1384 | + <height>16</height> |
1385 | + </size> |
1386 | + </property> |
1387 | + <property name="maximumSize"> |
1388 | + <size> |
1389 | + <width>16</width> |
1390 | + <height>16</height> |
1391 | + </size> |
1392 | + </property> |
1393 | + <property name="focusPolicy"> |
1394 | + <enum>Qt::NoFocus</enum> |
1395 | + </property> |
1396 | + <property name="text"> |
1397 | + <string/> |
1398 | + </property> |
1399 | + </widget> |
1400 | + </item> |
1401 | + </layout> |
1402 | + </widget> |
1403 | + </item> |
1404 | + <item> |
1405 | + <widget class="QStackedWidget" name="stackedWidget"> |
1406 | + <property name="currentIndex"> |
1407 | + <number>0</number> |
1408 | + </property> |
1409 | + <widget class="QWidget" name="pageStart"> |
1410 | + <layout class="QVBoxLayout" name="verticalLayout"> |
1411 | + <property name="spacing"> |
1412 | + <number>0</number> |
1413 | + </property> |
1414 | + <property name="margin"> |
1415 | + <number>0</number> |
1416 | + </property> |
1417 | + <item> |
1418 | + <widget class="QGroupBox" name="groupBoxWorking"> |
1419 | + <layout class="QVBoxLayout" name="verticalLayout_3"> |
1420 | + <property name="margin"> |
1421 | + <number>0</number> |
1422 | + </property> |
1423 | + <item> |
1424 | + <widget class="QLabel" name="labelMessage"> |
1425 | + <property name="alignment"> |
1426 | + <set>Qt::AlignCenter</set> |
1427 | + </property> |
1428 | + <property name="wordWrap"> |
1429 | + <bool>true</bool> |
1430 | + </property> |
1431 | + </widget> |
1432 | + </item> |
1433 | + <item> |
1434 | + <widget class="QPushButton" name="pushButtonGetData"> |
1435 | + <property name="text"> |
1436 | + <string>Get data from update sources</string> |
1437 | + </property> |
1438 | + </widget> |
1439 | + </item> |
1440 | + <item> |
1441 | + <widget class="QPushButton" name="pushButtonAbort"> |
1442 | + <property name="text"> |
1443 | + <string>Abort download</string> |
1444 | + </property> |
1445 | + </widget> |
1446 | + </item> |
1447 | + </layout> |
1448 | + </widget> |
1449 | + </item> |
1450 | + </layout> |
1451 | + </widget> |
1452 | + <widget class="QWidget" name="pageResults"> |
1453 | + <layout class="QVBoxLayout" name="verticalLayout_2"> |
1454 | + <property name="spacing"> |
1455 | + <number>0</number> |
1456 | + </property> |
1457 | + <property name="margin"> |
1458 | + <number>0</number> |
1459 | + </property> |
1460 | + <item> |
1461 | + <widget class="QGroupBox" name="groupBoxResults"> |
1462 | + <property name="title"> |
1463 | + <string>New satellites</string> |
1464 | + </property> |
1465 | + <layout class="QGridLayout" name="gridLayout"> |
1466 | + <property name="margin"> |
1467 | + <number>0</number> |
1468 | + </property> |
1469 | + <item row="2" column="0"> |
1470 | + <widget class="QPushButton" name="pushButtonAdd"> |
1471 | + <property name="text"> |
1472 | + <string>Add</string> |
1473 | + </property> |
1474 | + </widget> |
1475 | + </item> |
1476 | + <item row="2" column="1"> |
1477 | + <widget class="QPushButton" name="pushButtonDiscard"> |
1478 | + <property name="text"> |
1479 | + <string>Discard</string> |
1480 | + </property> |
1481 | + </widget> |
1482 | + </item> |
1483 | + <item row="1" column="0" colspan="2"> |
1484 | + <widget class="QListView" name="listView"> |
1485 | + <property name="uniformItemSizes"> |
1486 | + <bool>true</bool> |
1487 | + </property> |
1488 | + </widget> |
1489 | + </item> |
1490 | + <item row="0" column="0" colspan="2"> |
1491 | + <widget class="QLineEdit" name="lineEditSearch"> |
1492 | + <property name="styleSheet"> |
1493 | + <string notr="true">QLineEdit { |
1494 | + margin: 0px 0px 4px 0px; |
1495 | + padding: 4px; |
1496 | + padding-left: 32px; |
1497 | + background-image: url(:/graphicGui/searchBoxBackground.png); |
1498 | + background-repeat: none; |
1499 | + background-position: center left; |
1500 | + border: none; |
1501 | +}/* Stolen from the #citySearchLineEdit widget. */</string> |
1502 | + </property> |
1503 | + </widget> |
1504 | + </item> |
1505 | + </layout> |
1506 | + </widget> |
1507 | + </item> |
1508 | + </layout> |
1509 | + </widget> |
1510 | + </widget> |
1511 | + </item> |
1512 | + </layout> |
1513 | + </widget> |
1514 | + <customwidgets> |
1515 | + <customwidget> |
1516 | + <class>BarFrame</class> |
1517 | + <extends>QFrame</extends> |
1518 | + <header>Dialog.hpp</header> |
1519 | + <container>1</container> |
1520 | + </customwidget> |
1521 | + </customwidgets> |
1522 | + <tabstops> |
1523 | + <tabstop>pushButtonGetData</tabstop> |
1524 | + <tabstop>pushButtonAbort</tabstop> |
1525 | + <tabstop>listView</tabstop> |
1526 | + <tabstop>pushButtonAdd</tabstop> |
1527 | + <tabstop>pushButtonDiscard</tabstop> |
1528 | + </tabstops> |
1529 | + <resources/> |
1530 | + <connections/> |
1531 | +</ui> |
I think we need add editable blocks for description and groups.