1 /*
2  * Copyright (C) 2013 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 NOVAE_HPP
20 #define NOVAE_HPP
21 
22 #include "StelObjectModule.hpp"
23 #include "StelObject.hpp"
24 #include "StelFader.hpp"
25 #include "Nova.hpp"
26 #include "StelTextureTypes.hpp"
27 #include <QFont>
28 #include <QVariantMap>
29 #include <QDateTime>
30 #include <QList>
31 #include <QSharedPointer>
32 #include <QHash>
33 #include <QNetworkAccessManager>
34 #include <QNetworkReply>
35 
36 class QSettings;
37 class QTimer;
38 class NovaeDialog;
39 class StelPainter;
40 
41 /*! @defgroup brightNovae Bright Novae Plug-in
42 @{
43 The %Bright Novae plugin displays the positions some bright
44 novae in the Milky Way galaxy.
45 
46 <b>Bright Novae Catalog</b>
47 
48 The novae catalog is stored on the disk in [JSON](http://www.json.org/)
49 format, in a file named "novae.json". A default copy is embedded in the
50 plug-in at compile time. A working copy is kept in the user data directory.
51 
52 <b>Configuration</b>
53 
54 The plug-ins' configuration data is stored in Stellarium's main configuration
55 file (section [Novae]).
56 
57 @}
58 */
59 
60 //! @ingroup brightNovae
61 typedef QSharedPointer<Nova> NovaP;
62 
63 //! @class Novae
64 //! Main class of the %Bright Novae plugin.
65 //! @author Alexander Wolf
66 //! @ingroup brightNovae
67 class Novae : public StelObjectModule
68 {
69 	Q_OBJECT
70 public:
71 	//! @enum UpdateState
72 	//! Used for keeping for track of the download/update status
73 	enum UpdateState {
74 		Updating,		//!< Update in progress
75 		CompleteNoUpdates,	//!< Update completed, there we no updates
76 		CompleteUpdates,	//!< Update completed, there were updates
77 		DownloadError,		//!< Error during download phase
78 		OtherError		//!< Other error
79 	};
80 
81 	Novae();
82 	virtual ~Novae() Q_DECL_OVERRIDE;
83 
84 	///////////////////////////////////////////////////////////////////////////
85 	// Methods defined in the StelModule class
86 	virtual void init() Q_DECL_OVERRIDE;
update(double)87 	virtual void update(double) Q_DECL_OVERRIDE {;}
88 	virtual void draw(StelCore* core) Q_DECL_OVERRIDE;
89 	virtual void drawPointer(StelCore* core, StelPainter& painter);
90 	virtual double getCallOrder(StelModuleActionName actionName) const Q_DECL_OVERRIDE;
91 
92 	///////////////////////////////////////////////////////////////////////////
93 	// Methods defined in StelObjectModule class
94 	//! Used to get a list of objects which are near to some position.
95 	//! @param v a vector representing the position in th sky around which to search for novae.
96 	//! @param limitFov the field of view around the position v in which to search for novae.
97 	//! @param core the StelCore to use for computations.
98 	//! @return a list containing the novae located inside the limitFov circle around position v.
99 	virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const Q_DECL_OVERRIDE;
100 
101 	//! Return the matching Nova object's pointer if exists or Q_NULLPTR.
102 	//! @param nameI18n The case in-sensitive localized Nova name
103 	virtual StelObjectP searchByNameI18n(const QString& nameI18n) const Q_DECL_OVERRIDE;
104 
105 	//! Return the matching Nova if exists or Q_NULLPTR.
106 	//! @param name The case in-sensitive english Nova name
107 	virtual StelObjectP searchByName(const QString& name) const Q_DECL_OVERRIDE;
108 
109 	//! Return the matching Nova if exists or Q_NULLPTR.
110 	//! @param id The Nova id
searchByID(const QString & id) const111 	virtual StelObjectP searchByID(const QString &id) const Q_DECL_OVERRIDE
112 	{
113 		return qSharedPointerCast<StelObject>(getByID(id));
114 	}
115 
116 	//! Find and return the list of at most maxNbItem objects auto-completing the passed object name.
117 	//! @param objPrefix the case insensitive first letters of the searched object
118 	//! @param maxNbItem the maximum number of returned object names
119 	//! @param useStartOfWords the autofill mode for returned objects names
120 	//! @return a list of matching object name by order of relevance, or an empty list if nothing match
121 	virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const Q_DECL_OVERRIDE;
122 	virtual QStringList listAllObjects(bool inEnglish) const Q_DECL_OVERRIDE;
getName() const123 	virtual QString getName() const  Q_DECL_OVERRIDE{ return "Bright Novae"; }
getStelObjectType() const124 	virtual QString getStelObjectType() const Q_DECL_OVERRIDE { return Nova::NOVA_TYPE; }
125 
126 	//! get a nova object by identifier
127 	NovaP getByID(const QString& id) const;
128 
129 	//! Implement this to tell the main Stellarium GUI that there is a GUI element to configure this
130 	//! plugin.
131 	virtual bool configureGui(bool show=true) Q_DECL_OVERRIDE;
132 
133 	//! Set up the plugin with default values.  This means clearing out the Novae section in the
134 	//! main config.ini (if one already exists), and populating it with default values.  It also
135 	//! creates the default novae.json file from the resource embedded in the plugin lib/dll file.
136 	void restoreDefaults(void);
137 
138 	//! Read (or re-read) settings from the main config file.  This will be called from init and also
139 	//! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
140 	void readSettingsFromConfig(void);
141 
142 	//! Save the settings to the main configuration file.
143 	void saveSettingsToConfig(void);
144 
145 	//! Get whether or not the plugin will try to update catalog data from the internet
146 	//! @return true if updates are set to be done, false otherwise
getUpdatesEnabled(void)147 	bool getUpdatesEnabled(void) {return updatesEnabled;}
148 	//! Set whether or not the plugin will try to update catalog data from the internet
149 	//! @param b if true, updates will be enabled, else they will be disabled
setUpdatesEnabled(bool b)150 	void setUpdatesEnabled(bool b) {updatesEnabled=b;}
151 
152 	//! Get the date and time the novae were updated
getLastUpdate(void) const153 	QDateTime getLastUpdate(void) const {return lastUpdate;}
154 
155 	//! Get the update frequency in days
getUpdateFrequencyDays(void) const156 	int getUpdateFrequencyDays(void) const {return updateFrequencyDays;}
setUpdateFrequencyDays(int days)157 	void setUpdateFrequencyDays(int days) {updateFrequencyDays = days;}
158 
159 	//! Get the number of seconds till the next update
160 	int getSecondsToUpdate(void);
161 
162 	//! Get the current updateState
getUpdateState(void) const163 	UpdateState getUpdateState(void) const {return updateState;}
164 
165 	//! Get list of novae
166 	QString getNovaeList();
167 
168 	//! Get lower limit of  brightness for displayed novae
169 	float getLowerLimitBrightness();
170 
171 	//! Get count of novae from catalog
getCountNovae(void) const172 	int getCountNovae(void) const {return NovaCnt;}
173 
174 	//! Get the list of all bright novae.
getAllBrightNovae() const175 	const QList<NovaP>& getAllBrightNovae() const {return nova;}
176 
177 signals:
178 	//! @param state the new update state.
179 	void updateStateChanged(Novae::UpdateState state);
180 
181 	//! Emitted after a JSON update has run.
182 	void jsonUpdateComplete(void);
183 
184 public slots:
185 	// TODO: Add functions for scripting support
186 
187 	//! Download JSON from web recources described in the module section of the
188 	//! module.ini file and update the local JSON file.
189 	void updateJSON(void);
190 
191 	//! Display a message. This is used for plugin-specific warnings and such
192 	void displayMessage(const QString& message, const QString hexColor="#999999");
193 
194 	void reloadCatalog(void);
195 
196 	//! Connect this to StelApp font size.
setFontSize(int s)197 	void setFontSize(int s){font.setPixelSize(s);}
198 private:
199 	// Font used for displaying our text
200 	QFont font;
201 
202 	// if existing, delete Novae section in main config.ini, then create with default values
203 	void restoreDefaultConfigIni(void);
204 
205 	//! Replace the JSON file with the default from the compiled-in resource
206 	void restoreDefaultJsonFile(void);
207 
208 	//! Read the JSON file and create list of novae.
209 	void readJsonFile(void);
210 
211 	//! Creates a backup of the novae.json file called novae.json.old
212 	//! @param deleteOriginal if true, the original file is removed, else not
213 	//! @return true on OK, false on failure
214 	bool backupJsonFile(bool deleteOriginal=false);
215 
216 	//! Get the version from the "version" value in the novae.json file
217 	//! @return version string, e.g. "1"
218 	int getJsonFileVersion(void) const;
219 
220 	//! Check format of the catalog of novae
221 	//! @return valid boolean, e.g. "true"
222 	bool checkJsonFileFormat(void) const;
223 
224 	//! Parse JSON file and load novae to map
225 	QVariantMap loadNovaeMap(QString path=QString());
226 
227 	//! Set items for list of struct from data map
228 	void setNovaeMap(const QVariantMap& map);
229 
230 	QString novaeJsonPath;
231 
232 	int NovaCnt;
233 
234 	StelTextureSP texPointer;
235 	QList<NovaP> nova;
236 	QHash<QString, double> novalist;
237 
238 	// variables and functions for the updater
239 	UpdateState updateState;
240 	QNetworkAccessManager * networkManager;
241 	QNetworkReply * downloadReply;
242 	QString updateUrl;
243 	class StelProgressController* progressBar;
244 	QTimer* updateTimer;
245 	QList<int> messageIDs;
246 	bool updatesEnabled;
247 	QDateTime lastUpdate;
248 	int updateFrequencyDays;
249 
250 	void startDownload(QString url);
251 	void deleteDownloadProgressBar();
252 
253 	QSettings* conf;
254 
255 	// GUI
256 	NovaeDialog* configDialog;
257 
258 private slots:
259 	//! Check to see if an update is required.  This is called periodically by a timer
260 	//! if the last update was longer than updateFrequencyHours ago then the update is
261 	//! done.
262 	void checkForUpdate(void);
263 
264 	void updateDownloadProgress(qint64 bytesReceived, qint64 bytesTotal);
265 	void downloadComplete(QNetworkReply * reply);
266 
267 	//! Call when button "Save settings" in main GUI are pressed
saveSettings()268 	void saveSettings() { saveSettingsToConfig(); }
269 };
270 
271 #include <QObject>
272 #include "StelPluginInterface.hpp"
273 
274 //! This class is used by Qt to manage a plug-in interface
275 class NovaeStelPluginInterface : public QObject, public StelPluginInterface
276 {
277 	Q_OBJECT
278 	Q_PLUGIN_METADATA(IID StelPluginInterface_iid)
279 	Q_INTERFACES(StelPluginInterface)
280 public:
281 	virtual StelModule* getStelModule() const Q_DECL_OVERRIDE;
282 	virtual StelPluginInfo getPluginInfo() const Q_DECL_OVERRIDE;
getExtensionList() const283 	virtual QObjectList getExtensionList() const Q_DECL_OVERRIDE { return QObjectList(); }
284 };
285 
286 #endif /*NOVAE_HPP*/
287