1 /*
2  * Copyright (C) 2012 Alexander Wolf
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
17  */
18 
19 #ifndef PULSARS_HPP
20 #define PULSARS_HPP
21 
22 #include "StelObjectModule.hpp"
23 #include "StelObject.hpp"
24 #include "StelFader.hpp"
25 #include "StelTextureTypes.hpp"
26 #include "Pulsar.hpp"
27 #include <QFont>
28 #include <QVariantMap>
29 #include <QDateTime>
30 #include <QList>
31 #include <QSharedPointer>
32 #include <QNetworkAccessManager>
33 #include <QNetworkReply>
34 
35 class QSettings;
36 class QTimer;
37 class QPixmap;
38 class StelButton;
39 class PulsarsDialog;
40 
41 class StelPainter;
42 
43 /*! @defgroup pulsars Pulsars Plug-in
44 @{
45 The %Pulsars plugin plots the position of various pulsars, with object information
46 about each one. Pulsar data is derived from Catalog of Pulsars
47 ([Taylor+ 1995](http://cdsads.u-strasbg.fr/cgi-bin/nph-bib_query?1993ApJS...88..529T&db_key=AST&nosetcookie=1))
48 for 0.1.x series and derived from The ATNF Pulsar Catalogue (Manchester, R. N.,
49 Hobbs, G. B., Teoh, A. & Hobbs, M., Astron. J., 129, 1993-2006 (2005)
50 ([astro-ph/0412641](http://arxiv.org/abs/astro-ph/0412641))) for series 0.2.x.
51 
52 <b>Pulsars Catalog</b>
53 
54 The pulsars catalog is stored on the disk in [JSON](http://www.json.org/)
55 format, in a file named "pulsars.json". A default copy is embedded in the
56 plug-in at compile time. A working copy is kept in the user data directory.
57 
58 <b>Configuration</b>
59 
60 The plug-ins' configuration data is stored in Stellarium's main configuration
61 file (section [Pulsars]).
62 
63 @}
64 */
65 
66 //! @ingroup pulsars
67 typedef QSharedPointer<Pulsar> PulsarP;
68 
69 //! @class Pulsars
70 //! Main class of the %Pulsars plugin.
71 //! @author Alexander Wolf
72 //! @ingroup pulsars
73 class Pulsars : public StelObjectModule
74 {
75 	Q_OBJECT
76 	Q_PROPERTY(bool pulsarsVisible
77 		   READ getFlagShowPulsars
78 		   WRITE setFlagShowPulsars
79 		   NOTIFY flagPulsarsVisibilityChanged
80 		   )
81 	Q_PROPERTY(Vec3f markerColor
82 		   READ getMarkerColor
83 		   WRITE setMarkerColor
84 		   NOTIFY markerColorChanged
85 		   )
86 	Q_PROPERTY(Vec3f glitchColor
87 		   READ getGlitchColor
88 		   WRITE setGlitchColor
89 		   NOTIFY glitchColorChanged
90 		   )
91 public:
92 	//! @enum UpdateState
93 	//! Used for keeping for track of the download/update status
94 	enum UpdateState {
95 		Updating,		//!< Update in progress
96 		CompleteNoUpdates,	//!< Update completed, there we no updates
97 		CompleteUpdates,	//!< Update completed, there were updates
98 		DownloadError,		//!< Error during download phase
99 		OtherError		//!< Other error
100 	};
101 
102 	Pulsars();
103 	virtual ~Pulsars() Q_DECL_OVERRIDE;
104 
105 	///////////////////////////////////////////////////////////////////////////
106 	// Methods defined in the StelModule class
107 	virtual void init() Q_DECL_OVERRIDE;
108 	virtual void deinit() Q_DECL_OVERRIDE;
update(double)109 	virtual void update(double) Q_DECL_OVERRIDE {;}
110 	virtual void draw(StelCore* core) Q_DECL_OVERRIDE;
111 	virtual void drawPointer(StelCore* core, StelPainter& painter);
112 	virtual double getCallOrder(StelModuleActionName actionName) const Q_DECL_OVERRIDE;
113 
114 	///////////////////////////////////////////////////////////////////////////
115 	// Methods defined in StelObjectModule class
116 	//! Used to get a list of objects which are near to some position.
117 	//! @param v a vector representing the position in th sky around which to search for pulsars.
118 	//! @param limitFov the field of view around the position v in which to search for pulsars.
119 	//! @param core the StelCore to use for computations.
120 	//! @return a list containing the pulsars located inside the limitFov circle around position v.
121 	virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const Q_DECL_OVERRIDE;
122 
123 	//! Return the matching Pulsar object's pointer if exists or Q_NULLPTR.
124 	//! @param nameI18n The case in-sensitive localized Pulsar name
125 	virtual StelObjectP searchByNameI18n(const QString& nameI18n) const Q_DECL_OVERRIDE;
126 
127 	//! Return the matching Pulsar if exists or Q_NULLPTR.
128 	//! @param name The case in-sensitive english Pulsar name
129 	virtual StelObjectP searchByName(const QString& name) const Q_DECL_OVERRIDE;
130 
131 	//! Return the matching Pulsar if exists or Q_NULLPTR.
132 	//! @param id The Pulsar id
searchByID(const QString & id) const133 	virtual StelObjectP searchByID(const QString &id) const Q_DECL_OVERRIDE
134 	{
135 		return qSharedPointerCast<StelObject>(getByID(id));
136 	}
137 
138 	//! Find and return the list of at most maxNbItem objects auto-completing the passed object name.
139 	//! @param objPrefix the case insensitive first letters of the searched object
140 	//! @param maxNbItem the maximum number of returned object names
141 	//! @param useStartOfWords the autofill mode for returned objects names
142 	//! @return a list of matching object name by order of relevance, or an empty list if nothing match
143 	virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const Q_DECL_OVERRIDE;
144 	virtual QStringList listAllObjects(bool inEnglish) const Q_DECL_OVERRIDE;
getName() const145 	virtual QString getName() const Q_DECL_OVERRIDE { return "Pulsars"; }
getStelObjectType() const146 	virtual QString getStelObjectType() const Q_DECL_OVERRIDE { return Pulsar::PULSAR_TYPE; }
147 
148 	//! get a Pulsar object by identifier
149 	PulsarP getByID(const QString& id) const;
150 
151 	//! Implement this to tell the main Stellarium GUI that there is a GUI element to configure this
152 	//! plugin.
153 	virtual bool configureGui(bool show=true) Q_DECL_OVERRIDE;
154 
155 	//! Set up the plugin with default values.  This means clearing out the Pulsars section in the
156 	//! main config.ini (if one already exists), and populating it with default values.  It also
157 	//! creates the default pulsars.json file from the resource embedded in the plugin lib/dll file.
158 	void restoreDefaults(void);
159 
160 	//! Read (or re-read) settings from the main config file.  This will be called from init and also
161 	//! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
162 	void readSettingsFromConfig(void);
163 
164 	//! Save the settings to the main configuration file.
165 	void saveSettingsToConfig(void);
166 
167 	//! get whether or not the plugin will try to update catalog data from the internet
168 	//! @return true if updates are set to be done, false otherwise
getUpdatesEnabled(void)169 	bool getUpdatesEnabled(void) {return updatesEnabled;}
170 	//! set whether or not the plugin will try to update catalog data from the internet
171 	//! @param b if true, updates will be enabled, else they will be disabled
setUpdatesEnabled(bool b)172 	void setUpdatesEnabled(bool b) {updatesEnabled=b;}
173 
setEnableAtStartup(bool b)174 	void setEnableAtStartup(bool b) { enableAtStartup=b; }
getEnableAtStartup(void)175 	bool getEnableAtStartup(void) { return enableAtStartup; }
176 
177 	//! get the date and time the pulsars were updated
getLastUpdate(void)178 	QDateTime getLastUpdate(void) {return lastUpdate;}
179 
180 	//! get the update frequency in days
getUpdateFrequencyDays(void)181 	int getUpdateFrequencyDays(void) {return updateFrequencyDays;}
setUpdateFrequencyDays(int days)182 	void setUpdateFrequencyDays(int days) {updateFrequencyDays = days;}
183 
184 	//! get the number of seconds till the next update
185 	int getSecondsToUpdate(void);
186 
187 	//! Get the current updateState
getUpdateState(void)188 	UpdateState getUpdateState(void) {return updateState;}
189 
190 	//! Get the list of all pulsars.
getAllPulsars() const191 	const QList<PulsarP>& getAllPulsars() const {return psr;}
192 
193 signals:
194 	//! @param state the new update state.
195 	void updateStateChanged(Pulsars::UpdateState state);
196 
197 	//! emitted after a JSON update has run.
198 	void jsonUpdateComplete(void);
199 
200 	void flagPulsarsVisibilityChanged(bool b);
201 	void flagUsingFilterChanged(bool b);
202 	void markerColorChanged(Vec3f);
203 	void glitchColorChanged(Vec3f);
204 
205 public slots:
206 	//! Define whether the button toggling pulsars should be visible
207 	void setFlagShowPulsarsButton(bool b);
getFlagShowPulsarsButton(void)208 	bool getFlagShowPulsarsButton(void) { return flagShowPulsarsButton; }
209 
210 	//! Enable/disable display of markers of pulsars
211 	//! @param b boolean flag
212 	void setFlagShowPulsars(bool b);
213 	//! Get status to display of markers of pulsars
214 	//! @return true if it's visible
getFlagShowPulsars(void)215 	bool getFlagShowPulsars(void) { return flagShowPulsars; }
216 
217 	//! Enable/disable display filter of pulsars
218 	//! @param b boolean flag
219 	void setFilteredMode(bool b);
220 	//! Get status to usage display filter of pulsars
221 	//! @return true if it's visible
222 	bool getFilteredMode(void) const;
223 
224 	//! Set value for filter
225 	//! @param v float value
226 	void setFilterValue(float v);
227 	//! Get value for filter
228 	//! @return value
229 	float getFilterValue(void) const;
230 
231 	//! Get status to display of distribution of pulsars
232 	//! @return true if distribution of pulsars is enabled
233 	bool getDisplayMode(void) const;
234 	//! Enable/disable display of distribution of pulsars
235 	//! @param b
236 	void setDisplayMode(bool b);
237 
238 	//! Get status for usage of separate color for pulsars with glitches
239 	//! @return true if separate color is used for pulsars with glitches
240 	bool getGlitchFlag(void) const;
241 	//! Enable/disable the use of a separate color for pulsars with glitches
242 	//! @param boolean flag
243 	void setGlitchFlag(bool b);
244 
245 	//! Get color for pulsars markers
246 	//! @param mtype set false if you want get color of pulsars with glitches
247 	//! @return color
248 	Vec3f getMarkerColor() const;
249 	//! Set color for pulsars markers
250 	//! @param c color
251 	//! @param mtype set false if you want set color for pulsars with glitches
252 	//! @code
253 	//! // example of usage in scripts
254 	//! Pulsars.setMarkerColor(Vec3f(1.0,0.0,0.0), true);
255 	//! @endcode
256 	void setMarkerColor(const Vec3f& c);
257 
258 	//! Get marker color for pulsars with glitches
259 	//! @param mtype set false if you want get color of pulsars with glitches
260 	//! @return color
261 	Vec3f getGlitchColor() const;
262 	//! Set markers color for pulsars with glitches
263 	//! @param c color
264 	//! @code
265 	//! // example of usage in scripts
266 	//! Pulsars.setGlitchColor(Vec3f(1.0,0.0,0.0));
267 	//! @endcode
268 	void setGlitchColor(const Vec3f& c);
269 
270 	//! Get count of pulsars from catalog
271 	//! @return count of pulsars
getCountPulsars(void) const272 	int getCountPulsars(void) const {return PsrCount;}
273 
274 	//! Download JSON from web recources described in the module section of the
275 	//! module.ini file and update the local JSON file.
276 	void updateJSON(void);
277 
278 	//! Connect this to StelApp font size.
setFontSize(int s)279 	void setFontSize(int s){font.setPixelSize(s);}
280 private:
281 	// Font used for displaying our text
282 	QFont font;
283 
284 	// if existing, delete Satellites section in main config.ini, then create with default values
285 	void restoreDefaultConfigIni(void);
286 
287 	// Upgrade config.ini: rename old key settings to new
288 	void upgradeConfigIni(void);
289 
290 	//! replace the json file with the default from the compiled-in resource
291 	void restoreDefaultJsonFile(void);
292 
293 	//! read the json file and create list of Pulsars.
294 	void readJsonFile(void);
295 
296 	//! Creates a backup of the pulsars.json file called pulsars.json.old
297 	//! @param deleteOriginal if true, the original file is removed, else not
298 	//! @return true on OK, false on failure
299 	bool backupJsonFile(bool deleteOriginal=false);
300 
301 	//! Get the version from the "version of the format" value in the pulsars.json file
302 	//! @return version string, e.g. "2"
303 	int getJsonFileFormatVersion(void);
304 
305 	//! Check format of the catalog of pulsars
306 	//! @return valid boolean, e.g. "true"
307 	bool checkJsonFileFormat(void);
308 
309 	//! parse JSON file and load pulsars to map
310 	QVariantMap loadPSRMap(QString path=QString());
311 
312 	//! set items for list of struct from data map
313 	void setPSRMap(const QVariantMap& map);
314 
315 	QString jsonCatalogPath;
316 
317 	StelTextureSP texPointer;
318 	QList<PulsarP> psr;
319 
320 	int PsrCount;
321 
322 	// variables and functions for the updater
323 	UpdateState updateState;
324 	QNetworkAccessManager * networkManager;
325 	QNetworkReply * downloadReply;
326 	QString updateUrl;
327 	QTimer* updateTimer;
328 	QList<int> messageIDs;
329 	bool updatesEnabled;
330 	QDateTime lastUpdate;
331 	int updateFrequencyDays;
332 	bool enableAtStartup;
333 
334 	void startDownload(QString url);
335 	void deleteDownloadProgressBar();
336 
337 	QSettings* conf;
338 
339 	// GUI
340 	PulsarsDialog* configDialog;
341 	bool flagShowPulsars;
342 	bool flagShowPulsarsButton;
343 	QPixmap* OnIcon;
344 	QPixmap* OffIcon;
345 	QPixmap* GlowIcon;
346 	StelButton* toolbarButton;
347 	class StelProgressController* progressBar;
348 
349 
350 private slots:
351 	//! check to see if an update is required.  This is called periodically by a timer
352 	//! if the last update was longer than updateFrequencyHours ago then the update is
353 	//! done.
354 	void checkForUpdate(void);
355 
356 	void updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
357 	void downloadComplete(QNetworkReply * reply);
358 
359 	void reloadCatalog(void);
360 	//! Call when button "Save settings" in main GUI are pressed
saveSettings()361 	void 	saveSettings() { saveSettingsToConfig(); }
362 
363 	//! Display a message. This is used for plugin-specific warnings and such
364 	void displayMessage(const QString& message, const QString hexColor="#999999");
365 };
366 
367 
368 
369 #include <QObject>
370 #include "StelPluginInterface.hpp"
371 
372 //! This class is used by Qt to manage a plug-in interface
373 class PulsarsStelPluginInterface : public QObject, public StelPluginInterface
374 {
375 	Q_OBJECT
376 	Q_PLUGIN_METADATA(IID StelPluginInterface_iid)
377 	Q_INTERFACES(StelPluginInterface)
378 public:
379 	virtual StelModule* getStelModule() const Q_DECL_OVERRIDE;
380 	virtual StelPluginInfo getPluginInfo() const Q_DECL_OVERRIDE;
getExtensionList() const381 	virtual QObjectList getExtensionList() const Q_DECL_OVERRIDE { return QObjectList(); }
382 };
383 
384 #endif /* PULSARS_HPP */
385