Merge lp:~daggerstab/stellarium/satellites-import-gui into lp:stellarium

Proposed by Bogdan Marinov
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
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.

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.

To post a comment you must log in.
Revision history for this message
Alexander Wolf (alexwolf) wrote :

I think we need add editable blocks for description and groups.

Revision history for this message
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.

Revision history for this message
Alexander Wolf (alexwolf) :
review: Approve
Revision history for this message
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.

review: Needs Fixing (uat)
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

Revision history for this message
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::Visibility and use getSatellites() to get all with that flag;
- 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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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>