1 /*
2  * Copyright (C) 2009, 2012 Matthew Gates
3  * Copyright (C) 2015 Nick Fedoseev (Iridium flares)
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #ifndef SATELLITES_HPP
21 #define SATELLITES_HPP
22 
23 #include "StelObjectModule.hpp"
24 #include "Satellite.hpp"
25 #include "StelFader.hpp"
26 #include "StelGui.hpp"
27 #include "StelDialog.hpp"
28 #include "StelLocation.hpp"
29 
30 #include <QDateTime>
31 #include <QFile>
32 #include <QDir>
33 #include <QUrl>
34 #include <QVariantMap>
35 
36 class StelButton;
37 class Planet;
38 class QNetworkAccessManager;
39 class QNetworkReply;
40 class QSettings;
41 class QTimer;
42 
43 class SatellitesDialog;
44 class SatellitesListModel;
45 
46 /*! @defgroup satellites Satellites Plug-in
47 @{
48 The %Satellites plugin displays the positions of artificial satellites in Earth
49 orbit based on a catalog of orbital data.
50 
51 The Satellites class is the main class of the plug-in. It manages a collection
52 of Satellite objects and takes care of loading, saving and updating the
53 satellite catalog. It allows automatic updates from online sources and manages
54 a list of update file URLs.
55 
56 To calculate satellite positions, the plugin uses an implementation of
57 the SGP4/SDP4 algorithms (J.L. Canales' gsat library).
58 
59 <b>Satellite Properties</b>
60 
61 <i>Name and identifiers</i>
62 
63 Each satellite has a name. It's displayed as a label of the satellite hint and in the list of satellites. Names are not unique though, so they are used only
64 for presentation purposes.
65 
66 In the <b>Satellite Catalog</b> satellites are uniquely identified by their NORAD number, which is encoded in TLEs.
67 
68 <i>Grouping</i>
69 
70 A satellite can belong to one or more groups such as "amateur", "geostationary" or "navigation". They have no other function but to help the user organize the satellite collection.
71 
72 Group names are arbitrary strings defined in the <b>Satellite Catalog</b> for each satellite and are more similar to the concept of "tags" than a hierarchical grouping. A satellite may not belong to any group at all.
73 
74 By convention, group names are in lowercase. The GUI translates some of the groups used in the default catalog.
75 
76 <b>Satellite Catalog</b>
77 
78 The satellite catalog is stored on the disk in [JSON](http://www.json.org/)
79 format, in a file named "satellites.json". A default copy is embedded in the
80 plug-in at compile time. A working copy is kept in the user data directory.
81 
82 <b>Configuration</b>
83 
84 The plug-ins' configuration data is stored in Stellarium's main configuration
85 file.
86 
87 @}
88 */
89 
90 //! Data structure containing unvalidated TLE set as read from a TLE list file.
91 //! @ingroup satellites
92 struct TleData
93 {
94 	//! NORAD catalog number, as extracted from the TLE set.
95 	QString id;
96 	//! Human readable name, as extracted from the TLE title line.
97 	QString name;
98 	QString first;
99 	QString second;
100 	int status;
101 	//! Flag indicating whether this satellite should be added.
102 	//! See Satellites::autoAddEnabled.
103 	bool addThis;
104 	//! Source of TLE (URL), can be used for assign satellites group
105 	QString sourceURL;
106 };
107 
108 //! @ingroup satellites
109 typedef QList<TleData> TleDataList;
110 //! @ingroup satellites
111 typedef QHash<QString, TleData> TleDataHash ;
112 
113 //! TLE update source, used only internally for now.
114 //! @ingroup satellites
115 struct TleSource
116 {
117 	//! URL from where the source list should be downloaded.
118 	QUrl url;
119 	//! The downloaded file, location set after finishing download.
120 	//! In the future may be a QTemporaryFile object.
121 	QFile* file;
122 	//! Flag indicating whether new satellites in this list should be added.
123 	//! See Satellites::autoAddEnabled.
124 	bool addNew;
125 };
126 
127 //! @ingroup satellites
128 typedef QList<TleSource> TleSourceList;
129 
130 #if(SATELLITES_PLUGIN_IRIDIUM == 1)
131 struct IridiumFlaresPrediction
132 {
133 	QString datetime;
134 	QString satellite;
135 	float azimuth;		// radians
136 	float altitude;		// radians
137 	float magnitude;
138 };
139 
140 typedef QList<IridiumFlaresPrediction> IridiumFlaresPredictionList;
141 #endif
142 
143 //! @class Satellites
144 //! Main class of the %Satellites plugin.
145 //! @author Matthew Gates
146 //! @author Bogdan Marinov
147 //! @ingroup satellites
148 class Satellites : public StelObjectModule
149 {
150 	Q_OBJECT
151 	Q_PROPERTY(bool flagHintsVisible         READ getFlagHintsVisible         WRITE setFlagHintsVisible         NOTIFY flagHintsVisibleChanged)
152 	Q_PROPERTY(bool flagLabelsVisible        READ getFlagLabelsVisible        WRITE setFlagLabelsVisible        NOTIFY flagLabelsVisibleChanged)
153 	Q_PROPERTY(int  labelFontSize            READ getLabelFontSize            WRITE setLabelFontSize            NOTIFY labelFontSizeChanged)
154 	Q_PROPERTY(bool autoAddEnabled           READ isAutoAddEnabled            WRITE setAutoAddEnabled           NOTIFY autoAddEnabledChanged)
155 	Q_PROPERTY(bool autoRemoveEnabled        READ isAutoRemoveEnabled         WRITE setAutoRemoveEnabled        NOTIFY autoRemoveEnabledChanged)
156 	Q_PROPERTY(bool flagIconicMode           READ getFlagIconicMode           WRITE setFlagIconicMode           NOTIFY flagIconicModeChanged)
157 	Q_PROPERTY(bool flagHideInvisible        READ getFlagHideInvisible        WRITE setFlagHideInvisible        NOTIFY flagHideInvisibleChanged)
158 	Q_PROPERTY(bool flagOrbitLines           READ getFlagOrbitLines           WRITE setFlagOrbitLines           NOTIFY flagOrbitLinesChanged)
159 	Q_PROPERTY(bool updatesEnabled           READ getUpdatesEnabled           WRITE setUpdatesEnabled           NOTIFY updatesEnabledChanged)
160 	Q_PROPERTY(int  updateFrequencyHours     READ getUpdateFrequencyHours     WRITE setUpdateFrequencyHours     NOTIFY updateFrequencyHoursChanged)
161 	Q_PROPERTY(int  orbitLineSegments        READ getOrbitLineSegments        WRITE setOrbitLineSegments        NOTIFY orbitLineSegmentsChanged)
162 	Q_PROPERTY(int  orbitLineFadeSegments    READ getOrbitLineFadeSegments    WRITE setOrbitLineFadeSegments    NOTIFY orbitLineFadeSegmentsChanged)
163 	Q_PROPERTY(int  orbitLineSegmentDuration READ getOrbitLineSegmentDuration WRITE setOrbitLineSegmentDuration NOTIFY orbitLineSegmentDurationChanged)
164 	Q_PROPERTY(int  tleEpochAgeDays     READ getTleEpochAgeDays     WRITE setTleEpochAgeDays     NOTIFY tleEpochAgeDaysChanged)
165 	Q_PROPERTY(Vec3f invisibleSatelliteColor READ getInvisibleSatelliteColor  WRITE setInvisibleSatelliteColor  NOTIFY invisibleSatelliteColorChanged)
166 	Q_PROPERTY(Vec3f transitSatelliteColor   READ getTransitSatelliteColor    WRITE setTransitSatelliteColor    NOTIFY transitSatelliteColorChanged)
167 
168 public:
169 	//! @enum UpdateState
170 	//! Used for keeping track of the download/update status
171 	enum UpdateState
172 	{
173 		Updating,             //!< Update in progress
174 		CompleteNoUpdates,    //!< Update completed, there we no updates
175 		CompleteUpdates,      //!< Update completed, there were updates
176 		DownloadError,        //!< Error during download phase
177 		OtherError            //!< Other error
178 	};
179 
180 	//! Flags used to filter the satellites list according to their status.
181 	enum Status
182 	{
183 		Visible,
184 		NotVisible,
185 		Both,
186 		NewlyAdded,
187 		OrbitError
188 	};
189 
190 	Satellites();
191 	virtual ~Satellites() Q_DECL_OVERRIDE;
192 
193 	///////////////////////////////////////////////////////////////////////////
194 	// Methods defined in the StelModule class
195 	virtual void init() Q_DECL_OVERRIDE;
196 	virtual void deinit() Q_DECL_OVERRIDE;
197 	virtual void update(double deltaTime) Q_DECL_OVERRIDE;
198 	virtual void draw(StelCore* core) Q_DECL_OVERRIDE;
199 	virtual void drawPointer(StelCore* core, StelPainter& painter);
200 	virtual double getCallOrder(StelModuleActionName actionName) const Q_DECL_OVERRIDE;
201 
202 	///////////////////////////////////////////////////////////////////////////
203 	// Methods defined in StelObjectModule class
204 	//! Used to get a list of objects which are near to some position.
205 	//! @param v a vector representing the position in th sky around which to search for satellites.
206 	//! @param limitFov the field of view around the position v in which to search for satellites.
207 	//! @param core the StelCore to use for computations.
208 	//! @return a list containing the satellites located inside the limitFov circle around position v.
209 	virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const Q_DECL_OVERRIDE;
210 
211 	//! Return the matching satellite object's pointer if exists or Q_NULLPTR.
212 	//! @param nameI18n The case in-sensitive satellite name
213 	virtual StelObjectP searchByNameI18n(const QString& nameI18n) const Q_DECL_OVERRIDE;
214 
215 	//! Return the matching satellite if exists or Q_NULLPTR.
216 	//! @param name The case in-sensitive standard program name
217 	virtual StelObjectP searchByName(const QString& name) const Q_DECL_OVERRIDE;
218 
219 	//! Return the matching satellite if exists or Q_NULLPTR.
220 	//! @param id The satellite id (NORAD)
221 	virtual StelObjectP searchByID(const QString &id) const Q_DECL_OVERRIDE;
222 
223 	//! Return the satellite with the given catalog number.
224 	//! Used as a helper function by searchByName() and
225 	//! searchByNameI18n().
226 	//! @param noradNumber search string in the format "NORAD XXXX".
227 	//! @returns a null pointer if no such satellite is found.
228 	StelObjectP searchByNoradNumber(const QString& noradNumber) const;
229 
230 	//! Find and return the list of at most maxNbItem objects auto-completing the passed object name.
231 	//! @param objPrefix the case insensitive first letters of the searched object
232 	//! @param maxNbItem the maximum number of returned object names
233 	//! @param useStartOfWords the autofill mode for returned objects names
234 	//! @return a list of matching object name by order of relevance, or an empty list if nothing match
235 	virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const Q_DECL_OVERRIDE;
236 
237 	virtual QStringList listAllObjects(bool inEnglish) const Q_DECL_OVERRIDE;
238 
getName() const239 	virtual QString getName() const Q_DECL_OVERRIDE { return "Satellites"; }
getStelObjectType() const240 	virtual QString getStelObjectType() const Q_DECL_OVERRIDE { return Satellite::SATELLITE_TYPE; }
241 
242 	//! Implement this to tell the main Stellarium GUI that there is a GUI element to configure this
243 	//! plugin.
244 	virtual bool configureGui(bool show=true) Q_DECL_OVERRIDE;
245 
246 	//! Set up the plugin with default values.  This means clearing out the Satellites section in the
247 	//! main config.ini (if one already exists), and populating it with default values.  It also
248 	//! creates the default satellites.json file from the resource embedded in the plugin lib/dll file.
249 	void restoreDefaults(void);
250 
251 	//! Read (or re-read) the plugin's settings from the configuration file.
252 	//! This will be called from init() and also when restoring defaults
253 	//! (i.e. from the configuration dialog / restore defaults button).
254 	void loadSettings();
255 
256 	//! Save the plugin's settings to the main configuration file.
257 	void saveSettingsToConfig();
258 
259 	//! Get the groups used in the currently loaded satellite collection.
260 	//! See @ref groups for details. Use getGroupIdList() if you need a list.
261 	QSet<QString> getGroups() const;
262 	//! Get a sorted list of group names.
263 	//! See @ref groups for details. Use getGroups() if you don't need a list.
264 	QStringList getGroupIdList() const;
265 	//! Add this group to the global list.
266 	void addGroup(const QString& groupId);
267 
268 	//! get satellite objects filtered by group.  If an empty string is used for the
269 	//! group name, return all satallites
270 	QHash<QString,QString> getSatellites(const QString& group=QString(), Status vis=Both) const;
271 	//! Get a model representing the list of satellites.
272 	SatellitesListModel* getSatellitesListModel();
273 
274 	//! Get a satellite object by its identifier (i.e. NORAD number).
275 	SatelliteP getById(const QString& id) const;
276 
277 	//! Returns a list of all satellite IDs.
278 	QStringList listAllIds() const;
279 
280 	//! Add to the current collection the satellites described by the data list.
281 	//! The changes are not saved to file.
282 	//! Calls add(TleData).
283 	void add(const TleDataList& newSatellites);
284 
285 	//! Remove the selected satellites.
286 	//! The changes are not saved to file.
287 	void remove(const QStringList& idList);
288 
289 	//! get the date and time the TLE elements were updated
getLastUpdate(void) const290 	QDateTime getLastUpdate(void) const {return lastUpdate;}
291 
292 	//! get the update frequency in hours
getUpdateFrequencyHours(void) const293 	int getUpdateFrequencyHours(void) const {return updateFrequencyHours;}
294 
295 	//! get the number of seconds till the next update
296 	int getSecondsToUpdate(void);
297 
298 	//! get the update frequency in hours
299 	//void setUpdateFrequencyHours(int hours);
300 
301 	//! Get the current updateState
getUpdateState(void) const302 	UpdateState getUpdateState(void) const {return updateState;}
303 
304 	//! Get a list of URLs which are sources of TLE data.
305 	//! @returns a list of URL strings, some with prefixes - see #updateUrls
306 	//! for details.
getTleSources(void) const307 	QStringList getTleSources(void) const {return updateUrls;}
308 
309 	//! Set the list of URLs which are sources of TLE data.
310 	//! In addition to replacing the current list of sources, it also
311 	//! saves them to the configuration file. Allows marking sources for
312 	//! auto-addition by adding a prefix to the URL string.
313 	//! @see updateUrls
314 	//! @param tleSources a list of valid URLs (http://, ftp://, file://),
315 	//! allowed prefixes are "0,", "1," or no prefix.
316 	void setTleSources(QStringList tleSources);
317 
318 	//! Saves the current list of update URLs to the configuration file.
319 	void saveTleSources(const QStringList& urls);
320 
321 	//! Reads update file(s) in celestrak's .txt format, and updates
322 	//! the TLE elements for existing satellites from them.
323 	//! Indirectly emits signals updateStateChanged() and tleUpdateComplete(),
324 	//! as it calls updateSatellites().
325 	//! See updateFromOnlineSources() for the other kind of update operation.
326 	//! @param paths a list of paths to update files
327 	//! @param deleteFiles if set, the update files are deleted after
328 	//!        they are used, else they are left alone
329 	void updateFromFiles(QStringList paths, bool deleteFiles=false);
330 
331 	//! Updates the loaded satellite collection from the provided data.
332 	//! Worker function called by updateFromFiles() and saveDownloadedUpdate().
333 	//! (Respectively, user-initiated update from file(s) and user- or auto-
334 	//! initiated update from online source(s).)
335 	//! Emits updateStateChanged() and tleUpdateComplete().
336 	//! @note Instead of splitting this method off updateFromFiles() and passing
337 	//! the auto-add flag through data structures, another possibility was to
338 	//! modify updateFromFiles to use the same prefix trick (adding "1,"
339 	//! to file paths). I decided against it because I thought it would be more
340 	//! complex. :) --BM
341 	//! @param[in,out] newTleSets a hash with satellite IDs as keys; it's
342 	//! modified by the method!
343 	void updateSatellites(TleDataHash& newTleSets);
344 
345 	//! Reads a TLE list from a file to the supplied hash.
346 	//! If an entry with the same ID exists in the given hash, its contents
347 	//! are overwritten with the new values.
348 	//! \param openFile a reference to an \b open file.
349 	//! @param[in,out] tleList a hash with satellite IDs as keys.
350 	//! @param[in] addFlagValue value to be set to TleData::addThis for all.
351 	//! @param[in] tleURL a URL of TLE's source (e.g. Celestrak URL)
352 	//! @todo If this can accept a QIODevice, it will be able to read directly
353 	//! QNetworkReply-s... --BM
354 	static void parseTleFile(QFile& openFile, TleDataHash& tleList, bool addFlagValue = false, const QString& tleURL = "");
355 
356 	//! Insert a three line TLE into the hash array.
357 	//! @param[in] line The second line from the TLE
358 	static QString getSatIdFromLine2(const QString& line);
359 
360 	//! Reads qs.mag and rcs files and its parsing for getting id,  standard magnitude and RCS values
361 	//! for satellites.
362 	//! @note We are having permissions for use this file from Mike McCants.
363 	void loadExtraData();
364 
365 #if(SATELLITES_PLUGIN_IRIDIUM == 1)
366 	//! Get depth of prediction for Iridium flares
getIridiumFlaresPredictionDepth(void) const367 	int getIridiumFlaresPredictionDepth(void) const { return iridiumFlaresPredictionDepth; }
368 
369 	IridiumFlaresPredictionList getIridiumFlaresPrediction();
370 #endif
371 
372 signals:
373 	void flagHintsVisibleChanged(bool b);
374 	void flagLabelsVisibleChanged(bool b);
375 	void labelFontSizeChanged(int s);
376 	void flagOrbitLinesChanged(bool b);
377 	void flagIconicModeChanged(bool b);
378 	void flagHideInvisibleChanged(bool b);
379 	void updatesEnabledChanged(bool b);
380 	void updateFrequencyHoursChanged(int i);
381 	void autoAddEnabledChanged(bool b);
382 	void autoRemoveEnabledChanged(bool b);
383 	void orbitLineSegmentsChanged(int i);
384 	void orbitLineFadeSegmentsChanged(int i);
385 	void orbitLineSegmentDurationChanged(int i);
386 	void tleEpochAgeDaysChanged(int i);
387 	void invisibleSatelliteColorChanged(Vec3f);
388 	void transitSatelliteColorChanged(Vec3f);
389 
390 	//! Emitted when some of the plugin settings have been changed.
391 	//! Used to communicate with the configuration window.
392 	void settingsChanged();
393 
394 	//! emitted when the update status changes, e.g. when
395 	//! an update starts, completes and so on.  Note that
396 	//! on completion of an update, tleUpdateComplete is also
397 	//! emitted with the number of updates done.
398 	//! @param state the new update state.
399 	void updateStateChanged(Satellites::UpdateState state);
400 
401 	//! Emitted after an update has run.
402 	//! @param updated the number of updated satellites;
403 	//! @param total the total number of satellites in the catalog;
404 	//! @param added the number of newly added satellites;
405 	//! @param missing the number of satellites that were not found in the
406 	//! update source(s) (and were removed, if autoRemoveEnabled is set).
407 	void tleUpdateComplete(int updated, int total, int added, int missing);
408 
409 	void satGroupVisibleChanged();
410 
411 public slots:
412 	//! get whether or not the plugin will try to update TLE data from the internet
413 	//! @return true if updates are set to be done, false otherwise
getUpdatesEnabled(void) const414 	bool getUpdatesEnabled(void) const {return updatesEnabled;}
415 	//! Set whether the plugin will try to download updates from the Internet.
416 	//! Emits settingsChanged() if the value changes.
417 	//! @param b if true, updates will be enabled, else they will be disabled.
418 	void setUpdatesEnabled(bool enabled);
419 
isAutoAddEnabled() const420 	bool isAutoAddEnabled() const { return autoAddEnabled; }
421 	//! Emits settingsChanged() if the value changes.
422 	void setAutoAddEnabled(bool enabled);
423 
isAutoRemoveEnabled() const424 	bool isAutoRemoveEnabled() const { return autoRemoveEnabled; }
425 	//! Emits settingsChanged() if the value changes.
426 	void setAutoRemoveEnabled(bool enabled);
427 
428 	//! Set whether satellite position hints (icons or star-like dot) should be displayed.
429 	//! Note that hint visibility also applies to satellite labels.
430 	//! Emits settingsChanged() if the value changes.
431 	void setFlagHintsVisible(bool b);
getFlagHintsVisible() const432 	bool getFlagHintsVisible() const {return hintFader;}
433 
434 	//! Set whether text labels should be displayed next to satellite hints.
435 	//! Emits settingsChanged() if the value changes.
436 	//! @todo Decide how to sync with "actionShow_Satellite_Labels".
437 	void setFlagLabelsVisible(bool b);
438 	bool getFlagLabelsVisible() const;
439 
440 	//! Emits settingsChanged() if the value changes.
441 	void setFlagIconicMode(bool b);
442 	bool getFlagIconicMode() const;
443 
444 	bool getFlagHideInvisible() const;
445 	void setFlagHideInvisible(bool b);
446 
447 	//! Get color for invisible satellites
448 	//! @return color
449 	Vec3f getInvisibleSatelliteColor() const;
450 	//! Set color for invisible satellites
451 	void setInvisibleSatelliteColor(const Vec3f& c);
452 
453 	//! Get color for satellites in transit through the Sun or the Moon (color of markers)
454 	//! @return color
455 	Vec3f getTransitSatelliteColor() const;
456 	//! Set color for satellites in transit through the Sun or the Moon (color of markers)
457 	void setTransitSatelliteColor(const Vec3f& c);
458 
459 	//! get the label font size.
460 	//! @return the pixel size of the font
getLabelFontSize() const461 	int getLabelFontSize() const {return labelFont.pixelSize();}
462 	//! set the label font size.
463 	//! @param size the pixel size of the font
464 	//! Emits settingsChanged() if the value changes.
465 	void setLabelFontSize(int size);
466 
467 	//! Set the Internet update frequency.
468 	//! Emits settingsChanged() if the value changes.
469 	void setUpdateFrequencyHours(int hours);
470 
471 	//! Start an Internet update.
472 	//! This method starts the process of an Internet update: it tries to
473 	//! download TLE lists from online resources and then use them to
474 	//! update the orbital data (and names, etc.) of the included satellites.
475 	//! This only initialized the download. The rest of the work is done by
476 	//! saveDownloadedUpdate() and updateSatellites().
477 	//! Update sources are described in updateUrls (see for accessors details).
478 	//! If autoAddEnabled is true when this function is called, new satellites
479 	//! in the chosen update sources will be added during the update.
480 	//! If autoRemoveEnabled is true when this function is called, any existing
481 	//! satellite that can't be found in the downloaded update lists will be
482 	//! removed.
483 	//! See updateFromFiles() for the other type of update operation.
484 	void updateFromOnlineSources();
485 
486 	//! Choose whether or not to draw orbit lines.  Each satellite has its own setting
487 	//! as well, but this can be used to turn on/off all those satellites which elect to
488 	//! have orbit lines all in one go.
489 	//! @param b - true to turn on orbit lines, false to turn off
490 	void setFlagOrbitLines(bool b);
491 	//! Get the current status of the orbit line rendering flag.
492 	bool getFlagOrbitLines() const;
493 
494 	//! return number of segments for orbit lines
getOrbitLineSegments() const495 	int getOrbitLineSegments() const {return Satellite::orbitLineSegments;}
496 	//! set number of segments for orbit lines
497 	void setOrbitLineSegments(int s);
498 
499 	//! return number of fading segments at end of orbit
getOrbitLineFadeSegments() const500 	int getOrbitLineFadeSegments() const {return Satellite::orbitLineFadeSegments;}
501 	//! set number of fading segments at end of orbit
502 	void setOrbitLineFadeSegments(int s);
503 
504 	//! return duration of a single segments
getOrbitLineSegmentDuration() const505 	int getOrbitLineSegmentDuration() const {return Satellite::orbitLineSegmentDuration;}
506 	//! set duration of a single segments
507 	void setOrbitLineSegmentDuration(int s);
508 
509 	//! return the valid age of TLE's epoch
getTleEpochAgeDays() const510 	int getTleEpochAgeDays() const { return Satellite::tleEpochAge; }
511 	//! set the valid age of TLE's epoch
512 	void setTleEpochAgeDays(int age);
513 
514 	void recalculateOrbitLines(void);
515 
516 	//! Display a message on the screen for a few seconds.
517 	//! This is used for plugin-specific warnings and such.
518 	void displayMessage(const QString& message, const QString hexColor="#999999");
519 
520 	//! Save the current satellite catalog to disk.
521 	void saveCatalog(QString path=QString());
522 
523 #if(SATELLITES_PLUGIN_IRIDIUM == 1)
524 	//! Set depth of prediction for Iridium flares
525 	//! @param depth in days
setIridiumFlaresPredictionDepth(int depth)526 	void setIridiumFlaresPredictionDepth(int depth) { iridiumFlaresPredictionDepth=depth; }
527 #endif
528 
529 private slots:
530 	//! Update satellites visibility on wide range of dates changes - by month or year
531 	void updateSatellitesVisibility();
532 	//! Call when button "Save settings" in main GUI are pressed
saveSettings()533 	void saveSettings() { saveSettingsToConfig(); }
534 	void translateData();
535 
536 private:
537 	//! Add to the current collection the satellite described by the data.
538 	//! @warning Use only in other methods! Does not update satelliteListModel!
539 	//! @todo This probably could be done easier if Satellite had a constructor
540 	//! accepting TleData... --BM
541 	//! @returns true if the addition was successful.
542 	bool add(const TleData& tleData);
543 
544 	//! Delete Satellites section in main config.ini, then create with default values.
545 	void restoreDefaultSettings();
546 	//! Replace the catalog file with the default one.
547 	void restoreDefaultCatalog();
548 	//! Load the satellites from the catalog file.
549 	//! Removes existing satellites first if there are any.
550 	//! this will be done once at init, and also if the defaults are reset.
551 	void loadCatalog();
552 	//! Creates a backup of the satellites.json file called satellites.json.old
553 	//! @param deleteOriginal if true, the original file is removed, else not
554 	//! @return true on OK, false on failure
555 	bool backupCatalog(bool deleteOriginal=false);
556 	//! Read the version number from the "creator" value in the catalog file.
557 	//! @return version string, e.g. "0.6.1"
558 	const QString readCatalogVersion();
559 
560 	//! Checks valid range dates of life of satellites
561 	bool isValidRangeDates(const StelCore* core) const;
562 
563 	//! Save a structure representing a satellite catalog to a JSON file.
564 	//! If no path is specified, catalogPath is used.
565 	//! @see createDataMap()
566 	bool saveDataMap(const QVariantMap& map, QString path=QString());
567 	//! Load a structure representing a satellite catalog from a JSON file.
568 	//! If no path is specified, catalogPath is used.
569 	QVariantMap loadDataMap(QString path=QString());
570 	//! Parse a satellite catalog structure into internal satellite data.
571 	void setDataMap(const QVariantMap& map);
572 	//! Make a satellite catalog structure from current satellite data.
573 	//! @return a representation of a JSON file.
574 	QVariantMap createDataMap();
575 
576 	//! Sets lastUpdate to the current date/time and saves it to the settings.
577 	void markLastUpdate();
578 
579 	//! Check format of the catalog of satellites
580 	//! @return valid boolean, e.g. "true"
581 	bool checkJsonFileFormat();
582 
583 	void setSatGroupVisible(const QString& groupId, bool visible);
584 
585 	void bindingGroups();
586 	//! A fake method for strings marked for translation.
587 	//! Use it instead of translations.h for N_() strings, except perhaps for
588 	//! keyboard action descriptions. (It's better for them to be in a single
589 	//! place.)
590 	static void translations();
591 
592 	//! Path to the satellite catalog file.
593 	QString catalogPath;
594 	//! Plug-in data directory.
595 	//! Intialized by init(). Contains the catalog file (satellites.json),
596 	//! temporary TLE lists downloaded during an online update, or whatever
597 	//! other modifiable files the plug-in needs.
598 	QDir dataDir;
599 
600 	QList<SatelliteP> satellites;
601 	SatellitesListModel* satelliteListModel;
602 
603 	QHash<int, double> qsMagList, rcsList;
604 
605 	//! Union of the groups used by all loaded satellites - see @ref groups.
606 	//! For simplicity, it can only grow until the plug-in is unloaded -
607 	//! a group is not removed even if there are no more satellites tagged with
608 	//! it.
609 	QSet<QString> groups;
610 
611 	LinearFader hintFader;
612 	StelTextureSP texPointer;
613 
614 	//! @name Bottom toolbar button
615 	//@{
616 	StelButton* toolbarButton;
617 	//@}
618 	QSharedPointer<Planet> earth;
619 	Vec3f defaultHintColor;
620 	QFont labelFont;
621 
622 	//! @name Updater module
623 	//@{
624 	UpdateState updateState;
625 	QNetworkAccessManager* downloadMgr;
626 	//! List of TLE source lists for automatic updates.
627 	//! Use getTleSources() to get the value, setTleSources() to set it (and
628 	//! save it to configuration).
629 	//! URLs prefixed with "1," indicate that satellites from this source will
630 	//! be auto-added if autoAddEnabled is true. URLs prefixed with "0," or
631 	//! without a prefix are used only to update existing satellites. This
632 	//! system was introduced to avoid using a custom type as a parameter in
633 	//! setTleSources(), which in turn allows it to be used in scripts.
634 	QStringList updateUrls;
635 	//! Temporary stores update URLs and files during an online update.
636 	//! In use only between updateFromOnlineSources() and the final call to
637 	//! saveDownloadedUpdate(). @b DO @b NOT use elsewhere!
638 	//! As a side effect it prevents problems if the user calls
639 	//! setTleSources() while an update is in progress.
640 	TleSourceList updateSources;
641 	class StelProgressController* progressBar;
642 	int numberDownloadsComplete;
643 	QTimer* updateTimer;
644 	//! Flag enabling automatic Internet updates.
645 	bool updatesEnabled;
646 	//! Flag enabling the automatic addition of new satellites on update.
647 	//! This will apply only for the selected update sources.
648 	bool autoAddEnabled;
649 	//! Flag enabling the automatic removal of missing satellites on update.
650 	bool autoRemoveEnabled;
651 	QDateTime lastUpdate;
652 	int updateFrequencyHours;
653 	//@}
654 
655 	//! @name Screen message infrastructure
656 	//@{
657 	QList<int> messageIDs;
658 	//@}
659 
660 #if(SATELLITES_PLUGIN_IRIDIUM == 1)
661 	int iridiumFlaresPredictionDepth;
662 #endif
663 	// GUI
664 	SatellitesDialog* configDialog;
665 
666 	static QString SatellitesCatalogVersion;
667 
668 private slots:
669 	//! check to see if an update is required.  This is called periodically by a timer
670 	//! if the last update was longer than updateFrequencyHours ago then the update is
671 	//! done.
672 	void checkForUpdate(void);
673 	//! Save the downloaded file and finish the update if it's the last one.
674 	//! Calls updateSatellites() and indirectly emits updateStateChanged()
675 	//! and updateFinished().
676 	//! Ends the update process started with updateFromOnlineSources().
677 	//! @todo I've kept the previous behaviour, which was to save the update to
678 	//! temporary files and then read them. If we give up on the idea to
679 	//! re-use them later when adding manually satellites, parseTleFile()
680 	//! can be modified to read directly form QNetworkReply-s. --BM
681 	void saveDownloadedUpdate(QNetworkReply* reply);
682 	void updateObserverLocation(const StelLocation &loc);
683 };
684 
685 
686 
687 #include <QObject>
688 #include "StelPluginInterface.hpp"
689 
690 //! This class is used by Qt to manage a plug-in interface
691 class SatellitesStelPluginInterface : public QObject, public StelPluginInterface
692 {
693 	Q_OBJECT
694 	Q_PLUGIN_METADATA(IID StelPluginInterface_iid)
695 	Q_INTERFACES(StelPluginInterface)
696 public:
697 	virtual StelModule* getStelModule() const Q_DECL_OVERRIDE;
698 	virtual StelPluginInfo getPluginInfo() const Q_DECL_OVERRIDE;
getExtensionList() const699 	virtual QObjectList getExtensionList() const Q_DECL_OVERRIDE { return QObjectList(); }
700 };
701 
702 #endif /* SATELLITES_HPP */
703 
704