~ubuntu-branches/debian/experimental/stellarium/experimental

1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
1
/*
2
 * Copyright (C) 2011 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
#include "StelProjector.hpp"
20
#include "StelPainter.hpp"
21
#include "StelApp.hpp"
22
#include "StelCore.hpp"
23
#include "StelGui.hpp"
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
24
#include "StelGuiItems.hpp"
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
25
#include "StelLocaleMgr.hpp"
26
#include "StelModuleMgr.hpp"
27
#include "StelObjectMgr.hpp"
28
#include "StelTextureMgr.hpp"
29
#include "StelJsonParser.hpp"
30
#include "StelFileMgr.hpp"
31
#include "StelUtils.hpp"
32
#include "StelTranslator.hpp"
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
33
#include "LabelMgr.hpp"
34
#include "Supernova.hpp"
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
35
#include "Supernovae.hpp"
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
36
#include "SupernovaeDialog.hpp"
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
37
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
38
#include <QNetworkAccessManager>
39
#include <QNetworkReply>
40
#include <QKeyEvent>
41
#include <QAction>
42
#include <QProgressBar>
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
43
#include <QDebug>
44
#include <QFileInfo>
45
#include <QFile>
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
46
#include <QTimer>
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
47
#include <QVariantMap>
48
#include <QVariant>
49
#include <QList>
50
#include <QSharedPointer>
51
#include <QStringList>
52
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
53
#define CATALOG_FORMAT_VERSION 1 /* Version of format of catalog */
54
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
55
/*
56
 This method is the one called automatically by the StelModuleMgr just 
57
 after loading the dynamic library
58
*/
59
StelModule* SupernovaeStelPluginInterface::getStelModule() const
60
{
61
	return new Supernovae();
62
}
63
64
StelPluginInfo SupernovaeStelPluginInterface::getPluginInfo() const
65
{
66
	Q_INIT_RESOURCE(Supernovae);
67
68
	StelPluginInfo info;
69
	info.id = "Supernovae";
70
	info.displayedName = N_("Historical Supernovae");
71
	info.authors = "Alexander Wolf";
72
	info.contact = "alex.v.wolf@gmail.com";
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
73
	info.description = N_("A plugin that shows some historical supernovae brighter than 10 visual magnitude.");
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
74
	return info;
75
}
76
77
Q_EXPORT_PLUGIN2(Supernovae, SupernovaeStelPluginInterface)
78
79
80
/*
81
 Constructor
82
*/
83
Supernovae::Supernovae()
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
84
	: progressBar(NULL)
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
85
{
86
	setObjectName("Supernovae");
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
87
	configDialog = new SupernovaeDialog();
88
	conf = StelApp::getInstance().getSettings();
89
	font.setPixelSize(conf->value("gui/base_font_size", 13).toInt());
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
90
}
91
92
/*
93
 Destructor
94
*/
95
Supernovae::~Supernovae()
96
{
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
97
	delete configDialog;
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
98
}
99
100
void Supernovae::deinit()
101
{
102
	texPointer.clear();
103
}
104
105
/*
106
 Reimplementation of the getCallOrder method
107
*/
108
double Supernovae::getCallOrder(StelModuleActionName actionName) const
109
{
110
	if (actionName==StelModule::ActionDraw)
111
		return StelApp::getInstance().getModuleMgr().getModule("ConstellationMgr")->getCallOrder(actionName)+10.;
112
	return 0;
113
}
114
115
116
/*
117
 Init our module
118
*/
119
void Supernovae::init()
120
{
121
	try
122
	{
123
		StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir()+"/modules/Supernovae");
124
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
125
		// If no settings in the main config file, create with defaults
126
		if (!conf->childGroups().contains("Supernovae"))
127
		{
128
			qDebug() << "Supernovae::init no Supernovae section exists in main config file - creating with defaults";
129
			restoreDefaultConfigIni();
130
		}
131
132
		// populate settings from main config file.
133
		readSettingsFromConfig();
134
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
135
		sneJsonPath = StelFileMgr::findFile("modules/Supernovae", (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/supernovae.json";
136
137
		texPointer = StelApp::getInstance().getTextureManager().createTexture("textures/pointeur2.png");
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
138
139
		// key bindings and other actions
140
		// TRANSLATORS: Title of a group of key bindings in the Help window
141
		QString groupName = N_("Plugin Key Bindings");
142
		StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
143
		gui->addGuiActions("actionShow_Supernovae_ConfigDialog", N_("Historical Supernovae configuration window"), "", groupName, true);
144
145
		connect(gui->getGuiActions("actionShow_Supernovae_ConfigDialog"), SIGNAL(toggled(bool)), configDialog, SLOT(setVisible(bool)));
146
		connect(configDialog, SIGNAL(visibleChanged(bool)), gui->getGuiActions("actionShow_Supernovae_ConfigDialog"), SLOT(setChecked(bool)));
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
147
	}
148
	catch (std::runtime_error &e)
149
	{
150
		qWarning() << "Supernovas::init error: " << e.what();
151
		return;
152
	}
153
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
154
	// A timer for hiding alert messages
155
	messageTimer = new QTimer(this);
156
	messageTimer->setSingleShot(true);   // recurring check for update
157
	messageTimer->setInterval(9000);      // 6 seconds should be enough time
158
	messageTimer->stop();
159
	connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));
160
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
161
	// If the json file does not already exist, create it from the resource in the Qt resource
162
	if(QFileInfo(sneJsonPath).exists())
163
	{
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
164
		if (getJsonFileVersion() < CATALOG_FORMAT_VERSION)
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
165
		{
166
			restoreDefaultJsonFile();
167
		}
168
	}
169
	else
170
	{
171
		qDebug() << "Supernovae::init supernovae.json does not exist - copying default file to " << sneJsonPath;
172
		restoreDefaultJsonFile();
173
	}
174
175
	qDebug() << "Supernovae::init using supernovae.json file: " << sneJsonPath;
176
177
	readJsonFile();
178
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
179
	// Set up download manager and the update schedule
180
	downloadMgr = new QNetworkAccessManager(this);
181
	connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(updateDownloadComplete(QNetworkReply*)));
182
	updateState = CompleteNoUpdates;
183
	updateTimer = new QTimer(this);
184
	updateTimer->setSingleShot(false);   // recurring check for update
185
	updateTimer->setInterval(13000);     // check once every 13 seconds to see if it is time for an update
186
	connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()));
187
	updateTimer->start();
188
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
189
	GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
190
}
191
192
/*
193
 Draw our module. This should print name of first SNe in the main window
194
*/
195
void Supernovae::draw(StelCore* core)
196
{
197
	StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
198
	StelPainter painter(prj);
199
	painter.setFont(font);
200
	
201
	foreach (const SupernovaP& sn, snstar)
202
	{
203
		if (sn && sn->initialized)
204
			sn->draw(core, painter);
205
	}
206
207
	if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
208
		drawPointer(core, painter);
209
210
}
211
212
void Supernovae::drawPointer(StelCore* core, StelPainter& painter)
213
{
214
	const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
215
216
	const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("Supernova");
217
	if (!newSelected.empty())
218
	{
219
		const StelObjectP obj = newSelected[0];
220
		Vec3d pos=obj->getJ2000EquatorialPos(core);
221
222
		Vec3d screenpos;
223
		// Compute 2D pos and return if outside screen
224
		if (!painter.getProjector()->project(pos, screenpos))
225
			return;
226
227
		const Vec3f& c(obj->getInfoColor());
228
		painter.setColor(c[0],c[1],c[2]);
229
		texPointer->bind();
230
		painter.enableTexture2d(true);
231
		glEnable(GL_BLEND);
232
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
233
		painter.drawSprite2dMode(screenpos[0], screenpos[1], 13.f, StelApp::getInstance().getTotalRunTime()*40.);
234
	}
235
}
236
237
QList<StelObjectP> Supernovae::searchAround(const Vec3d& av, double limitFov, const StelCore*) const
238
{
239
	QList<StelObjectP> result;
240
241
	Vec3d v(av);
242
	v.normalize();
243
	double cosLimFov = cos(limitFov * M_PI/180.);
244
	Vec3d equPos;
245
246
	foreach(const SupernovaP& sn, snstar)
247
	{
248
		if (sn->initialized)
249
		{
250
			equPos = sn->XYZ;
251
			equPos.normalize();
252
			if (equPos[0]*v[0] + equPos[1]*v[1] + equPos[2]*v[2]>=cosLimFov)
253
			{
254
				result.append(qSharedPointerCast<StelObject>(sn));
255
			}
256
		}
257
	}
258
259
	return result;
260
}
261
262
StelObjectP Supernovae::searchByName(const QString& englishName) const
263
{
264
	QString objw = englishName.toUpper();
265
	foreach(const SupernovaP& sn, snstar)
266
	{
267
		if (sn->getEnglishName().toUpper() == englishName)
268
			return qSharedPointerCast<StelObject>(sn);
269
	}
270
271
	return NULL;
272
}
273
274
StelObjectP Supernovae::searchByNameI18n(const QString& nameI18n) const
275
{
276
	QString objw = nameI18n.toUpper();
277
278
	foreach(const SupernovaP& sn, snstar)
279
	{
280
		if (sn->getNameI18n().toUpper() == nameI18n)
281
			return qSharedPointerCast<StelObject>(sn);
282
	}
283
284
	return NULL;
285
}
286
287
QStringList Supernovae::listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem) const
288
{
289
	QStringList result;
290
	if (maxNbItem==0) return result;
291
292
	QString objw = objPrefix.toUpper();
293
294
	foreach(const SupernovaP& sn, snstar)
295
	{
296
		if (sn->getNameI18n().toUpper().left(objw.length()) == objw)
297
		{
298
				result << sn->getNameI18n().toUpper();
299
		}
300
	}
301
302
	result.sort();
303
	if (result.size()>maxNbItem) result.erase(result.begin()+maxNbItem, result.end());
304
305
	return result;
306
}
307
308
/*
309
  Replace the JSON file with the default from the compiled-in resource
310
*/
311
void Supernovae::restoreDefaultJsonFile(void)
312
{
313
	if (QFileInfo(sneJsonPath).exists())
314
		backupJsonFile(true);
315
316
	QFile src(":/Supernovae/supernovae.json");
317
	if (!src.copy(sneJsonPath))
318
	{
319
		qWarning() << "Supernovae::restoreDefaultJsonFile cannot copy json resource to " + sneJsonPath;
320
	}
321
	else
322
	{
323
		qDebug() << "Supernovae::init copied default supernovae.json to " << sneJsonPath;
324
		// The resource is read only, and the new file inherits this...  make sure the new file
325
		// is writable by the Stellarium process so that updates can be done.
326
		QFile dest(sneJsonPath);
327
		dest.setPermissions(dest.permissions() | QFile::WriteOwner);
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
328
329
		// Make sure that in the case where an online update has previously been done, but
330
		// the json file has been manually removed, that an update is schreduled in a timely
331
		// manner
332
		conf->remove("Supernovae/last_update");
333
		lastUpdate = QDateTime::fromString("2012-05-24T12:00:00", Qt::ISODate);
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
334
	}
335
}
336
337
/*
338
  Creates a backup of the supernovae.json file called supernovae.json.old
339
*/
340
bool Supernovae::backupJsonFile(bool deleteOriginal)
341
{
342
	QFile old(sneJsonPath);
343
	if (!old.exists())
344
	{
345
		qWarning() << "Supernovae::backupJsonFile no file to backup";
346
		return false;
347
	}
348
349
	QString backupPath = sneJsonPath + ".old";
350
	if (QFileInfo(backupPath).exists())
351
		QFile(backupPath).remove();
352
353
	if (old.copy(backupPath))
354
	{
355
		if (deleteOriginal)
356
		{
357
			if (!old.remove())
358
			{
359
				qWarning() << "Supernovae::backupJsonFile WARNING - could not remove old supernovas.json file";
360
				return false;
361
			}
362
		}
363
	}
364
	else
365
	{
366
		qWarning() << "Supernovae::backupJsonFile WARNING - failed to copy supernovae.json to supernovae.json.old";
367
		return false;
368
	}
369
370
	return true;
371
}
372
373
/*
374
  Read the JSON file and create list of supernovaes.
375
*/
376
void Supernovae::readJsonFile(void)
377
{
378
	setSNeMap(loadSNeMap());
379
}
380
381
/*
382
  Parse JSON file and load supernovaes to map
383
*/
384
QVariantMap Supernovae::loadSNeMap(QString path)
385
{
386
	if (path.isEmpty())
387
	    path = sneJsonPath;
388
389
	QVariantMap map;
390
	QFile jsonFile(path);
391
	if (!jsonFile.open(QIODevice::ReadOnly))
392
	    qWarning() << "Supernovae::loadSNeMap cannot open " << path;
393
	else
394
	    map = StelJsonParser::parse(jsonFile.readAll()).toMap();
395
396
	jsonFile.close();
397
	return map;
398
}
399
400
/*
401
  Set items for list of struct from data map
402
*/
403
void Supernovae::setSNeMap(const QVariantMap& map)
404
{
405
	snstar.clear();
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
406
	snlist.clear();
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
407
	QVariantMap sneMap = map.value("supernova").toMap();
408
	foreach(QString sneKey, sneMap.keys())
409
	{
410
		QVariantMap sneData = sneMap.value(sneKey).toMap();
411
		sneData["designation"] = QString("SN %1").arg(sneKey);
412
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
413
		snlist.insert(sneData.value("designation").toString(), sneData.value("peakJD").toDouble());
414
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
415
		SupernovaP sn(new Supernova(sneData));
416
		if (sn->initialized)
417
			snstar.append(sn);
418
419
	}
420
}
421
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
422
int Supernovae::getJsonFileVersion(void)
423
{	
424
	int jsonVersion = -1;
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
425
	QFile sneJsonFile(sneJsonPath);
426
	if (!sneJsonFile.open(QIODevice::ReadOnly))
427
	{
428
		qWarning() << "Supernovae::init cannot open " << sneJsonPath;
429
		return jsonVersion;
430
	}
431
432
	QVariantMap map;
433
	map = StelJsonParser::parse(&sneJsonFile).toMap();
434
	if (map.contains("version"))
435
	{
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
436
		jsonVersion = map.value("version").toInt();
1.2.7 by Tomasz Buchert
Import upstream version 0.11.2
437
	}
438
439
	sneJsonFile.close();
440
	qDebug() << "Supernovae::getJsonFileVersion() version from file:" << jsonVersion;
441
	return jsonVersion;
442
}
443
444
SupernovaP Supernovae::getByID(const QString& id)
445
{
446
	foreach(const SupernovaP& sn, snstar)
447
	{
448
		if (sn->initialized && sn->designation == id)
449
			return sn;
450
	}
451
	return SupernovaP();
452
}
1.2.9 by Tomasz Buchert
Import upstream version 0.11.4a
453
454
bool Supernovae::configureGui(bool show)
455
{
456
	if (show)
457
	{
458
		StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
459
		gui->getGuiActions("actionShow_Supernovae_ConfigDialog")->setChecked(true);
460
	}
461
462
	return true;
463
}
464
465
void Supernovae::restoreDefaults(void)
466
{
467
	restoreDefaultConfigIni();
468
	restoreDefaultJsonFile();
469
	readJsonFile();
470
	readSettingsFromConfig();
471
}
472
473
void Supernovae::restoreDefaultConfigIni(void)
474
{
475
	conf->beginGroup("Supernovae");
476
477
	// delete all existing Supernovae settings...
478
	conf->remove("");
479
480
	conf->setValue("updates_enabled", true);
481
	conf->setValue("url", "http://stellarium.org/json/supernovae.json");
482
	conf->setValue("update_frequency_days", 100);
483
	conf->endGroup();
484
}
485
486
void Supernovae::readSettingsFromConfig(void)
487
{
488
	conf->beginGroup("Supernovae");
489
490
	updateUrl = conf->value("url", "http://stellarium.org/json/supernovae.json").toString();
491
	updateFrequencyDays = conf->value("update_frequency_days", 100).toInt();
492
	lastUpdate = QDateTime::fromString(conf->value("last_update", "2012-06-11T12:00:00").toString(), Qt::ISODate);
493
	updatesEnabled = conf->value("updates_enabled", true).toBool();
494
495
	conf->endGroup();
496
}
497
498
void Supernovae::saveSettingsToConfig(void)
499
{
500
	conf->beginGroup("Supernovae");
501
502
	conf->setValue("url", updateUrl);
503
	conf->setValue("update_frequency_days", updateFrequencyDays);
504
	conf->setValue("updates_enabled", updatesEnabled );
505
506
	conf->endGroup();
507
}
508
509
int Supernovae::getSecondsToUpdate(void)
510
{
511
	QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyDays * 3600 * 24);
512
	return QDateTime::currentDateTime().secsTo(nextUpdate);
513
}
514
515
void Supernovae::checkForUpdate(void)
516
{
517
	if (updatesEnabled && lastUpdate.addSecs(updateFrequencyDays * 3600 * 24) <= QDateTime::currentDateTime())
518
		updateJSON();
519
}
520
521
void Supernovae::updateJSON(void)
522
{
523
	if (updateState==Supernovae::Updating)
524
	{
525
		qWarning() << "Supernovae: already updating...  will not start again current update is complete.";
526
		return;
527
	}
528
	else
529
	{
530
		qDebug() << "Supernovae: starting update...";
531
	}
532
533
	lastUpdate = QDateTime::currentDateTime();
534
	conf->setValue("Supernovae/last_update", lastUpdate.toString(Qt::ISODate));
535
536
	emit(jsonUpdateComplete());
537
538
	updateState = Supernovae::Updating;
539
540
	emit(updateStateChanged(updateState));
541
	updateFile.clear();
542
543
	if (progressBar==NULL)
544
		progressBar = StelApp::getInstance().getGui()->addProgressBar();
545
546
	progressBar->setValue(0);
547
	progressBar->setMaximum(updateUrl.size());
548
	progressBar->setVisible(true);
549
	progressBar->setFormat("Update historical supernovae");
550
551
	QNetworkRequest request;
552
	request.setUrl(QUrl(updateUrl));
553
	request.setRawHeader("User-Agent", QString("Mozilla/5.0 (Stellarium Historical Supernovae Plugin %1; http://stellarium.org/)").arg(SUPERNOVAE_PLUGIN_VERSION).toUtf8());
554
	downloadMgr->get(request);
555
556
	progressBar->setValue(100);
557
	delete progressBar;
558
	progressBar = NULL;
559
560
	updateState = CompleteUpdates;
561
562
	emit(updateStateChanged(updateState));
563
	emit(jsonUpdateComplete());
564
}
565
566
void Supernovae::updateDownloadComplete(QNetworkReply* reply)
567
{
568
	// check the download worked, and save the data to file if this is the case.
569
	if (reply->error() != QNetworkReply::NoError)
570
	{
571
		qWarning() << "Supernovae::updateDownloadComplete FAILED to download" << reply->url() << " Error: " << reply->errorString();
572
	}
573
	else
574
	{
575
		// download completed successfully.
576
		try
577
		{
578
			QString jsonFilePath = StelFileMgr::findFile("modules/Supernovae", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/supernovae.json";
579
			QFile jsonFile(jsonFilePath);
580
			if (jsonFile.exists())
581
				jsonFile.remove();
582
583
			jsonFile.open(QIODevice::WriteOnly | QIODevice::Text);
584
			jsonFile.write(reply->readAll());
585
			jsonFile.close();
586
		}
587
		catch (std::runtime_error &e)
588
		{
589
			qWarning() << "Supernovae::updateDownloadComplete: cannot write JSON data to file:" << e.what();
590
		}
591
592
	}
593
594
	if (progressBar)
595
		progressBar->setValue(100);
596
}
597
598
void Supernovae::displayMessage(const QString& message, const QString hexColor)
599
{
600
	messageIDs << GETSTELMODULE(LabelMgr)->labelScreen(message, 30, 30 + (20*messageIDs.count()), true, 16, hexColor);
601
	messageTimer->start();
602
}
603
604
void Supernovae::messageTimeout(void)
605
{
606
	foreach(int i, messageIDs)
607
	{
608
		GETSTELMODULE(LabelMgr)->deleteLabel(i);
609
	}
610
}
611
612
QString Supernovae::getSupernovaeList()
613
{
614
	QString smonth[] = {q_("January"), q_("February"), q_("March"), q_("April"), q_("May"), q_("June"), q_("July"), q_("August"), q_("September"), q_("October"), q_("November"), q_("December")};
615
	QStringList out;
616
	int year, month, day;
617
	QList<double> vals = snlist.values();
618
	qSort(vals);
619
	foreach(double val, vals)
620
	{
621
		StelUtils::getDateFromJulianDay(val, &year, &month, &day);
622
		out << QString("%1 (%2 %3)").arg(snlist.key(val)).arg(day).arg(smonth[month-1]);
623
	}
624
625
	return out.join(", ");
626
}