Satellites.cpp   Satellites.cpp 
skipping to change at line 80 skipping to change at line 80
info.contact = "http://stellarium.org/"; info.contact = "http://stellarium.org/";
info.description = N_("Prediction of artificial satellite positions in Earth orbit based on NORAD TLE data"); info.description = N_("Prediction of artificial satellite positions in Earth orbit based on NORAD TLE data");
info.version = SATELLITES_PLUGIN_VERSION; info.version = SATELLITES_PLUGIN_VERSION;
return info; return info;
} }
Satellites::Satellites() Satellites::Satellites()
: satelliteListModel(NULL) : satelliteListModel(NULL)
, toolbarButton(NULL) , toolbarButton(NULL)
, earth(NULL) , earth(NULL)
, defaultHintColor(0.0, 0.4, 0.6) , defaultHintColor(0.0f, 0.4f, 0.6f)
, defaultOrbitColor(0.0, 0.3, 0.6) , defaultOrbitColor(0.0f, 0.3f, 0.6f)
, updateState(CompleteNoUpdates) , updateState(CompleteNoUpdates)
, downloadMgr(NULL) , downloadMgr(NULL)
, progressBar(NULL) , progressBar(NULL)
, numberDownloadsComplete(0) , numberDownloadsComplete(0)
, updateTimer(0) , updateTimer(0)
, updatesEnabled(false) , updatesEnabled(false)
, autoAddEnabled(false) , autoAddEnabled(false)
, autoRemoveEnabled(false) , autoRemoveEnabled(false)
, updateFrequencyHours(0) , updateFrequencyHours(0)
, messageTimer(0) , messageTimer(0)
skipping to change at line 160 skipping to change at line 160
toolbarButton = new StelButton(NULL, toolbarButton = new StelButton(NULL,
QPixmap(":/satellites /bt_satellites_on.png"), QPixmap(":/satellites /bt_satellites_on.png"),
QPixmap(":/satellites /bt_satellites_off.png"), QPixmap(":/satellites /bt_satellites_off.png"),
QPixmap(":/graphicGui /glow32x32.png"), QPixmap(":/graphicGui /glow32x32.png"),
"actionShow_Satellite _Hints"); "actionShow_Satellite _Hints");
gui->getButtonBar()->addButton(toolbarButton, "065-p luginsGroup"); gui->getButtonBar()->addButton(toolbarButton, "065-p luginsGroup");
} }
} }
catch (std::runtime_error &e) catch (std::runtime_error &e)
{ {
qWarning() << "Satellites::init error: " << e.what(); qWarning() << "[Satellites] init error: " << e.what();
return; return;
} }
// A timer for hiding alert messages // A timer for hiding alert messages
messageTimer = new QTimer(this); messageTimer = new QTimer(this);
messageTimer->setSingleShot(true); // recurring check for update messageTimer->setSingleShot(true); // recurring check for update
messageTimer->setInterval(9000); // 6 seconds should be enough time messageTimer->setInterval(9000); // 6 seconds should be enough time
messageTimer->stop(); messageTimer->stop();
connect(messageTimer, SIGNAL(timeout()), this, SLOT(hideMessages())) ; connect(messageTimer, SIGNAL(timeout()), this, SLOT(hideMessages())) ;
skipping to change at line 182 skipping to change at line 182
if(QFileInfo(catalogPath).exists()) if(QFileInfo(catalogPath).exists())
{ {
if (!checkJsonFileFormat() || readCatalogVersion() != SATELL ITES_PLUGIN_VERSION) if (!checkJsonFileFormat() || readCatalogVersion() != SATELL ITES_PLUGIN_VERSION)
{ {
displayMessage(q_("The old satellites.json file is n o longer compatible - using default file"), "#bb0000"); displayMessage(q_("The old satellites.json file is n o longer compatible - using default file"), "#bb0000");
restoreDefaultCatalog(); restoreDefaultCatalog();
} }
} }
else else
{ {
qDebug() << "Satellites::init satellites.json does not exist - copying default file to " << QDir::toNativeSeparators(catalogPath); qDebug() << "[Satellites] satellites.json does not exist - c opying default file to " << QDir::toNativeSeparators(catalogPath);
restoreDefaultCatalog(); restoreDefaultCatalog();
} }
if(!QFileInfo(qsMagFilePath).exists()) if(!QFileInfo(qsMagFilePath).exists())
{ {
restoreDefaultQSMagFile(); restoreDefaultQSMagFile();
} }
qDebug() << "Satellites: loading catalog file:" << QDir::toNativeSep arators(catalogPath); qDebug() << "[Satellites] loading catalog file:" << QDir::toNativeSe parators(catalogPath);
// create satellites according to content os satellites.json file // create satellites according to content os satellites.json file
loadCatalog(); loadCatalog();
// Set up download manager and the update schedule // Set up download manager and the update schedule
downloadMgr = new QNetworkAccessManager(this); downloadMgr = new QNetworkAccessManager(this);
connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), connect(downloadMgr, SIGNAL(finished(QNetworkReply*)),
this, SLOT(saveDownloadedUpdate(QNetworkReply*))); this, SLOT(saveDownloadedUpdate(QNetworkReply*)));
updateState = CompleteNoUpdates; updateState = CompleteNoUpdates;
updateTimer = new QTimer(this); updateTimer = new QTimer(this);
updateTimer->setSingleShot(false); // recurring check for update updateTimer->setSingleShot(false); // recurring check for update
updateTimer->setInterval(13000); // check once every 13 seconds to see if it is time for an update updateTimer->setInterval(13000); // check once every 13 seconds to see if it is time for an update
connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()) ); connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()) );
updateTimer->start(); updateTimer->start();
earth = GETSTELMODULE(SolarSystem)->getEarth(); earth = GETSTELMODULE(SolarSystem)->getEarth();
GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this); GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
// Handle changes to the observer location: // Handle changes to the observer location:
connect(StelApp::getInstance().getCore(), connect(StelApp::getInstance().getCore(), SIGNAL(locationChanged(Ste
SIGNAL(locationChanged(StelLocation)), lLocation)), this, SLOT(updateObserverLocation(StelLocation)));
this,
SLOT(updateObserverLocation(StelLocation)));
} }
bool Satellites::backupCatalog(bool deleteOriginal) bool Satellites::backupCatalog(bool deleteOriginal)
{ {
QFile old(catalogPath); QFile old(catalogPath);
if (!old.exists()) if (!old.exists())
{ {
qWarning() << "Satellites::backupJsonFile no file to backup" ; qWarning() << "[Satellites] no file to backup";
return false; return false;
} }
QString backupPath = catalogPath + ".old"; QString backupPath = catalogPath + ".old";
if (QFileInfo(backupPath).exists()) if (QFileInfo(backupPath).exists())
QFile(backupPath).remove(); QFile(backupPath).remove();
if (old.copy(backupPath)) if (old.copy(backupPath))
{ {
if (deleteOriginal) if (deleteOriginal)
{ {
if (!old.remove()) if (!old.remove())
{ {
qWarning() << "Satellites: WARNING: unable t o remove old catalog file!"; qWarning() << "[Satellites] WARNING: unable to remove old catalog file!";
return false; return false;
} }
} }
} }
else else
{ {
qWarning() << "Satellites: WARNING: failed to back up catalo g file as" qWarning() << "[Satellites] WARNING: failed to back up catal og file as"
<< QDir::toNativeSeparators(backupPath); << QDir::toNativeSeparators(backupPath);
return false; return false;
} }
return true; return true;
} }
double Satellites::getCallOrder(StelModuleActionName actionName) const double Satellites::getCallOrder(StelModuleActionName actionName) const
{ {
if (actionName==StelModule::ActionDraw) if (actionName==StelModule::ActionDraw)
skipping to change at line 299 skipping to change at line 296
QString objw = nameI18n.toUpper(); QString objw = nameI18n.toUpper();
StelObjectP result = searchByNoradNumber(objw); StelObjectP result = searchByNoradNumber(objw);
if (result) if (result)
return result; return result;
foreach(const SatelliteP& sat, satellites) foreach(const SatelliteP& sat, satellites)
{ {
if (sat->initialized && sat->displayed) if (sat->initialized && sat->displayed)
{ {
if (sat->getNameI18n().toUpper() == nameI18n) if (sat->getNameI18n().toUpper() == objw)
return qSharedPointerCast<StelObject>(sat); return qSharedPointerCast<StelObject>(sat);
} }
} }
return NULL; return NULL;
} }
StelObjectP Satellites::searchByName(const QString& englishName) const StelObjectP Satellites::searchByName(const QString& englishName) const
{ {
if (!hintFader || StelApp::getInstance().getCore()->getCurrentLocati on().planetName != earth->getEnglishName() || !isValidRangeDates()) if (!hintFader || StelApp::getInstance().getCore()->getCurrentLocati on().planetName != earth->getEnglishName() || !isValidRangeDates())
skipping to change at line 322 skipping to change at line 319
QString objw = englishName.toUpper(); QString objw = englishName.toUpper();
StelObjectP result = searchByNoradNumber(objw); StelObjectP result = searchByNoradNumber(objw);
if (result) if (result)
return result; return result;
foreach(const SatelliteP& sat, satellites) foreach(const SatelliteP& sat, satellites)
{ {
if (sat->initialized && sat->displayed) if (sat->initialized && sat->displayed)
{ {
if (sat->getEnglishName().toUpper() == englishName) if (sat->getEnglishName().toUpper() == objw)
return qSharedPointerCast<StelObject>(sat); return qSharedPointerCast<StelObject>(sat);
} }
} }
return NULL; return NULL;
} }
StelObjectP Satellites::searchByNoradNumber(const QString &noradNumber) con st StelObjectP Satellites::searchByNoradNumber(const QString &noradNumber) con st
{ {
if (!hintFader || StelApp::getInstance().getCore()->getCurrentLocati on().planetName != earth->getEnglishName() || !isValidRangeDates()) if (!hintFader || StelApp::getInstance().getCore()->getCurrentLocati on().planetName != earth->getEnglishName() || !isValidRangeDates())
skipping to change at line 517 skipping to change at line 514
} }
void Satellites::restoreDefaultCatalog() void Satellites::restoreDefaultCatalog()
{ {
if (QFileInfo(catalogPath).exists()) if (QFileInfo(catalogPath).exists())
backupCatalog(true); backupCatalog(true);
QFile src(":/satellites/satellites.json"); QFile src(":/satellites/satellites.json");
if (!src.copy(catalogPath)) if (!src.copy(catalogPath))
{ {
qWarning() << "Satellites::restoreDefaultJsonFile cannot cop y json resource to " + QDir::toNativeSeparators(catalogPath); qWarning() << "[Satellites] cannot copy json resource to " + QDir::toNativeSeparators(catalogPath);
} }
else else
{ {
qDebug() << "Satellites::init copied default satellites.json to " << QDir::toNativeSeparators(catalogPath); qDebug() << "[Satellites] copied default satellites.json to " << QDir::toNativeSeparators(catalogPath);
// The resource is read only, and the new file inherits this ... make sure the new file // The resource is read only, and the new file inherits this ... make sure the new file
// is writable by the Stellarium process so that updates can be done. // is writable by the Stellarium process so that updates can be done.
QFile dest(catalogPath); QFile dest(catalogPath);
dest.setPermissions(dest.permissions() | QFile::WriteOwner); dest.setPermissions(dest.permissions() | QFile::WriteOwner);
// Make sure that in the case where an online update has pre viously been done, but // Make sure that in the case where an online update has pre viously been done, but
// the json file has been manually removed, that an update i s schreduled in a timely // the json file has been manually removed, that an update i s schreduled in a timely
// manner // manner
StelApp::getInstance().getSettings()->remove("Satellites/las t_update"); StelApp::getInstance().getSettings()->remove("Satellites/las t_update");
lastUpdate = QDateTime::fromString("2015-05-01T12:00:00", Qt ::ISODate); lastUpdate = QDateTime::fromString("2015-05-01T12:00:00", Qt ::ISODate);
} }
} }
void Satellites::restoreDefaultQSMagFile() void Satellites::restoreDefaultQSMagFile()
{ {
QFile src(":/satellites/qs.mag"); QFile src(":/satellites/qs.mag");
if (!src.copy(qsMagFilePath)) if (!src.copy(qsMagFilePath))
{ {
qWarning() << "Satellites::restoreDefaultQSMagFile cannot co py qs.mag resource to " + QDir::toNativeSeparators(qsMagFilePath); qWarning() << "[Satellites] cannot copy qs.mag resource to " + QDir::toNativeSeparators(qsMagFilePath);
} }
else else
{ {
qDebug() << "Satellites::init copied default qs.mag to " << QDir::toNativeSeparators(qsMagFilePath); qDebug() << "[Satellites] copied default qs.mag to " << QDir ::toNativeSeparators(qsMagFilePath);
// The resource is read only, and the new file inherits this ... make sure the new file // The resource is read only, and the new file inherits this ... make sure the new file
// is writable by the Stellarium process so that updates can be done. // is writable by the Stellarium process so that updates can be done.
QFile dest(qsMagFilePath); QFile dest(qsMagFilePath);
dest.setPermissions(dest.permissions() | QFile::WriteOwner); dest.setPermissions(dest.permissions() | QFile::WriteOwner);
} }
} }
void Satellites::loadSettings() void Satellites::loadSettings()
{ {
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
skipping to change at line 675 skipping to change at line 672
{ {
setDataMap(loadDataMap()); setDataMap(loadDataMap());
} }
const QString Satellites::readCatalogVersion() const QString Satellites::readCatalogVersion()
{ {
QString jsonVersion("unknown"); QString jsonVersion("unknown");
QFile satelliteJsonFile(catalogPath); QFile satelliteJsonFile(catalogPath);
if (!satelliteJsonFile.open(QIODevice::ReadOnly)) if (!satelliteJsonFile.open(QIODevice::ReadOnly))
{ {
qWarning() << "Satellites::init cannot open " << QDir::toNat iveSeparators(catalogPath); qWarning() << "[Satellites] cannot open " << QDir::toNativeS eparators(catalogPath);
return jsonVersion; return jsonVersion;
} }
QVariantMap map; QVariantMap map;
map = StelJsonParser::parse(&satelliteJsonFile).toMap(); map = StelJsonParser::parse(&satelliteJsonFile).toMap();
if (map.contains("creator")) if (map.contains("creator"))
{ {
QString creator = map.value("creator").toString(); QString creator = map.value("creator").toString();
QRegExp vRx(".*(\\d+\\.\\d+\\.\\d+).*"); QRegExp vRx(".*(\\d+\\.\\d+\\.\\d+).*");
if (vRx.exactMatch(creator)) if (vRx.exactMatch(creator))
{ {
jsonVersion = vRx.capturedTexts().at(1); jsonVersion = vRx.capturedTexts().at(1);
} }
} }
satelliteJsonFile.close(); satelliteJsonFile.close();
//qDebug() << "Satellites: catalog version from file:" << jsonVersio n; //qDebug() << "[Satellites] catalog version from file:" << jsonVersi on;
return jsonVersion; return jsonVersion;
} }
bool Satellites::saveDataMap(const QVariantMap& map, QString path) bool Satellites::saveDataMap(const QVariantMap& map, QString path)
{ {
if (path.isEmpty()) if (path.isEmpty())
path = catalogPath; path = catalogPath;
QFile jsonFile(path); QFile jsonFile(path);
StelJsonParser parser; StelJsonParser parser;
if (jsonFile.exists()) if (jsonFile.exists())
jsonFile.remove(); jsonFile.remove();
if (!jsonFile.open(QIODevice::WriteOnly)) if (!jsonFile.open(QIODevice::WriteOnly))
{ {
qWarning() << "Satellites::saveTleMap() cannot open for writ ing:" << QDir::toNativeSeparators(path); qWarning() << "[Satellites] cannot open for writing:" << QDi r::toNativeSeparators(path);
return false; return false;
} }
else else
{ {
qDebug() << "Satellites::saveTleMap() writing to:" << QDir:: toNativeSeparators(path); qDebug() << "[Satellites] writing to:" << QDir::toNativeSepa rators(path);
parser.write(map, &jsonFile); parser.write(map, &jsonFile);
jsonFile.close(); jsonFile.close();
return true; return true;
} }
} }
QVariantMap Satellites::loadDataMap(QString path) QVariantMap Satellites::loadDataMap(QString path)
{ {
if (path.isEmpty()) if (path.isEmpty())
path = catalogPath; path = catalogPath;
QVariantMap map; QVariantMap map;
QFile jsonFile(path); QFile jsonFile(path);
if (!jsonFile.open(QIODevice::ReadOnly)) if (!jsonFile.open(QIODevice::ReadOnly))
qWarning() << "Satellites::loadTleMap cannot open " << QDir: :toNativeSeparators(path); qWarning() << "[Satellites] cannot open " << QDir::toNativeS eparators(path);
else else
{ {
map = StelJsonParser::parse(&jsonFile).toMap(); map = StelJsonParser::parse(&jsonFile).toMap();
jsonFile.close(); jsonFile.close();
} }
return map; return map;
} }
void Satellites::setDataMap(const QVariantMap& map) void Satellites::setDataMap(const QVariantMap& map)
{ {
skipping to change at line 808 skipping to change at line 805
if (satMap["orbitColor"] == satMap["hintColor"]) if (satMap["orbitColor"] == satMap["hintColor"])
satMap.remove("orbitColor"); satMap.remove("orbitColor");
if (satMap["hintColor"].toList() == defHintCol) if (satMap["hintColor"].toList() == defHintCol)
satMap.remove("hintColor"); satMap.remove("hintColor");
if (satMap["stdMag"].toFloat() == 99.f) if (satMap["stdMag"].toFloat() == 99.f)
satMap.remove("stdMag"); satMap.remove("stdMag");
if (satMap["status"].toInt() == Satellite::StatusUnknown)
satMap.remove("status");
sats[sat->id] = satMap; sats[sat->id] = satMap;
} }
map["satellites"] = sats; map["satellites"] = sats;
return map; return map;
} }
void Satellites::markLastUpdate() void Satellites::markLastUpdate()
{ {
lastUpdate = QDateTime::currentDateTime(); lastUpdate = QDateTime::currentDateTime();
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
skipping to change at line 916 skipping to change at line 916
QVariantMap satProperties; QVariantMap satProperties;
satProperties.insert("name", tleData.name); satProperties.insert("name", tleData.name);
satProperties.insert("tle1", tleData.first); satProperties.insert("tle1", tleData.first);
satProperties.insert("tle2", tleData.second); satProperties.insert("tle2", tleData.second);
satProperties.insert("hintColor", hintColor); satProperties.insert("hintColor", hintColor);
//TODO: Decide if newly added satellites are visible by default --BM //TODO: Decide if newly added satellites are visible by default --BM
satProperties.insert("visible", true); satProperties.insert("visible", true);
satProperties.insert("orbitVisible", false); satProperties.insert("orbitVisible", false);
if (qsMagList.contains(tleData.id)) if (qsMagList.contains(tleData.id))
satProperties.insert("stdMag", qsMagList[tleData.id]); satProperties.insert("stdMag", qsMagList[tleData.id]);
if (tleData.status != Satellite::StatusUnknown)
satProperties.insert("status", tleData.status);
SatelliteP sat(new Satellite(tleData.id, satProperties)); SatelliteP sat(new Satellite(tleData.id, satProperties));
if (sat->initialized) if (sat->initialized)
{ {
qDebug() << "Satellite added:" << tleData.id << tleData.name ; qDebug() << "[Satellites] satellite added:" << tleData.id << tleData.name;
satellites.append(sat); satellites.append(sat);
sat->setNew(); sat->setNew();
return true; return true;
} }
return false; return false;
} }
void Satellites::add(const TleDataList& newSatellites) void Satellites::add(const TleDataList& newSatellites)
{ {
if (satelliteListModel) if (satelliteListModel)
skipping to change at line 947 skipping to change at line 949
{ {
numAdded++; numAdded++;
} }
} }
if (numAdded > 0) if (numAdded > 0)
qSort(satellites); qSort(satellites);
if (satelliteListModel) if (satelliteListModel)
satelliteListModel->endSatellitesChange(); satelliteListModel->endSatellitesChange();
qDebug() << "Satellites: " qDebug() << "[Satellites] "
<< newSatellites.count() << "satell << newSatellites.count() << "satellites proposed for additi
ites proposed for addition, " on, "
<< numAdded << " added, " << numAdded << " added, "
<< satellites.count() << " total af << satellites.count() << " total after the operation.";
ter the operation.";
} }
void Satellites::remove(const QStringList& idList) void Satellites::remove(const QStringList& idList)
{ {
if (satelliteListModel) if (satelliteListModel)
satelliteListModel->beginSatellitesChange(); satelliteListModel->beginSatellitesChange();
StelObjectMgr* objMgr = GETSTELMODULE(StelObjectMgr); StelObjectMgr* objMgr = GETSTELMODULE(StelObjectMgr);
int numRemoved = 0; int numRemoved = 0;
for (int i = 0; i < satellites.size(); i++) for (int i = 0; i < satellites.size(); i++)
skipping to change at line 980 skipping to change at line 982
satellites.removeAt(i); satellites.removeAt(i);
i--; //Compensate for the change in the array's inde xing i--; //Compensate for the change in the array's inde xing
numRemoved++; numRemoved++;
} }
} }
// As the satellite list is kept sorted, no need for re-sorting. // As the satellite list is kept sorted, no need for re-sorting.
if (satelliteListModel) if (satelliteListModel)
satelliteListModel->endSatellitesChange(); satelliteListModel->endSatellitesChange();
qDebug() << "Satellites: " qDebug() << "[Satellites] "
<< idList.count() << "satellites pr << idList.count() << "satellites proposed for removal, "
oposed for removal, " << numRemoved << " removed, "
<< numRemoved << " removed, " << satellites.count() << " remain.";
<< satellites.count() << " remain."
;
} }
int Satellites::getSecondsToUpdate(void) int Satellites::getSecondsToUpdate(void)
{ {
QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 360 0); QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 360 0);
return QDateTime::currentDateTime().secsTo(nextUpdate); return QDateTime::currentDateTime().secsTo(nextUpdate);
} }
void Satellites::setTleSources(QStringList tleSources) void Satellites::setTleSources(QStringList tleSources)
{ {
skipping to change at line 1120 skipping to change at line 1122
{ {
if (updatesEnabled && updateState != Updating if (updatesEnabled && updateState != Updating
&& lastUpdate.addSecs(updateFrequencyHours * 3600) <= QDateTime: :currentDateTime()) && lastUpdate.addSecs(updateFrequencyHours * 3600) <= QDateTime: :currentDateTime())
updateFromOnlineSources(); updateFromOnlineSources();
} }
void Satellites::updateFromOnlineSources() void Satellites::updateFromOnlineSources()
{ {
if (updateState==Satellites::Updating) if (updateState==Satellites::Updating)
{ {
qWarning() << "Satellites: Internet update already in progre ss!"; qWarning() << "[Satellites] Internet update already in progr ess!";
return; return;
} }
else else
{ {
qDebug() << "Satellites: starting Internet update..."; qDebug() << "[Satellites] starting Internet update...";
} }
// Setting lastUpdate should be done only when the update is finishe d. -BM // Setting lastUpdate should be done only when the update is finishe d. -BM
// TODO: Perhaps tie the emptyness of updateUrls to updatesEnabled.. . --BM // TODO: Perhaps tie the emptyness of updateUrls to updatesEnabled.. . --BM
if (updateUrls.isEmpty()) if (updateUrls.isEmpty())
{ {
qWarning() << "Satellites: update failed." qWarning() << "[Satellites] update failed."
<< "No update sources are defined!"; << "No update sources are defined!";
// Prevent from re-entering this method on the next check: // Prevent from re-entering this method on the next check:
markLastUpdate(); markLastUpdate();
// TODO: Do something saner, such as disabling internet upda tes, // TODO: Do something saner, such as disabling internet upda tes,
// or stopping the timer. --BM // or stopping the timer. --BM
emit updateStateChanged(OtherError); emit updateStateChanged(OtherError);
emit tleUpdateComplete(0, satellites.count(), 0, 0); emit tleUpdateComplete(0, satellites.count(), 0, 0);
return; return;
} }
skipping to change at line 1186 skipping to change at line 1188
downloadMgr->get(QNetworkRequest(source.url)); downloadMgr->get(QNetworkRequest(source.url));
} }
} }
} }
void Satellites::saveDownloadedUpdate(QNetworkReply* reply) void Satellites::saveDownloadedUpdate(QNetworkReply* reply)
{ {
// check the download worked, and save the data to file if this is t he case. // check the download worked, and save the data to file if this is t he case.
if (reply->error() != QNetworkReply::NoError) if (reply->error() != QNetworkReply::NoError)
{ {
qWarning() << "Satellites: FAILED to download" qWarning() << "[Satellites] FAILED to download"
<< reply->url().toString(QUrl::RemoveUserInfo) << reply->url().toString(QUrl::RemoveUserInfo)
<< "Error:" << reply->errorString(); << "Error:" << reply->errorString();
} }
else else
{ {
// download completed successfully. // download completed successfully.
QString name = QString("tle%1.txt").arg(numberDownloadsCompl ete); QString name = QString("tle%1.txt").arg(numberDownloadsCompl ete);
QString path = dataDir.absoluteFilePath(name); QString path = dataDir.absoluteFilePath(name);
// QFile as a child object to the plugin to ease memory mana gement // QFile as a child object to the plugin to ease memory mana gement
QFile* tmpFile = new QFile(path, this); QFile* tmpFile = new QFile(path, this);
skipping to change at line 1221 skipping to change at line 1223
updateSources[i].file = tmpFile; updateSources[i].file = tmpFile;
tmpFile = 0; tmpFile = 0;
break; break;
} }
} }
if (tmpFile) // Something strange just happened... if (tmpFile) // Something strange just happened...
delete tmpFile; // ...so we have to clean. delete tmpFile; // ...so we have to clean.
} }
else else
{ {
qWarning() << "Satellites: cannot save update file:" qWarning() << "[Satellites] cannot save update file: "
<< tmpFile->error() << tmpFile->error()
<< tmpFile->errorString(); << tmpFile->errorString();
} }
} }
numberDownloadsComplete++; numberDownloadsComplete++;
if (progressBar) if (progressBar)
progressBar->setValue(numberDownloadsComplete); progressBar->setValue(numberDownloadsComplete);
// Check if all files have been downloaded. // Check if all files have been downloaded.
// TODO: It's better to keep track of the network requests themselve s. --BM // TODO: It's better to keep track of the network requests themselve s. --BM
skipping to change at line 1333 skipping to change at line 1335
} }
void Satellites::updateSatellites(TleDataHash& newTleSets) void Satellites::updateSatellites(TleDataHash& newTleSets)
{ {
// Save the update time. // Save the update time.
// One of the reasons it's here is that lastUpdate is used below. // One of the reasons it's here is that lastUpdate is used below.
markLastUpdate(); markLastUpdate();
if (newTleSets.isEmpty()) if (newTleSets.isEmpty())
{ {
qWarning() << "Satellites: update files contain no TLE sets! "; qWarning() << "[Satellites] update files contain no TLE sets !";
updateState = OtherError; updateState = OtherError;
emit(updateStateChanged(updateState)); emit(updateStateChanged(updateState));
return; return;
} }
if (satelliteListModel) if (satelliteListModel)
satelliteListModel->beginSatellitesChange(); satelliteListModel->beginSatellitesChange();
// Right, we should now have a map of all the elements we downloaded . For each satellite // Right, we should now have a map of all the elements we downloaded . For each satellite
// which this module is managing, see if it exists with an updated e lement, and update it if so... // which this module is managing, see if it exists with an updated e lement, and update it if so...
skipping to change at line 1377 skipping to change at line 1379
if (sat->tleElements.first != newTle.first || if (sat->tleElements.first != newTle.first ||
sat->tleElements.second != newTle.second || sat->tleElements.second != newTle.second ||
sat->name != newTle.name) sat->name != newTle.name)
{ {
// We have updated TLE elements for this sat ellite // We have updated TLE elements for this sat ellite
sat->setNewTleElements(newTle.first, newTle. second); sat->setNewTleElements(newTle.first, newTle. second);
// Update the name if it has been changed in the source list // Update the name if it has been changed in the source list
sat->name = newTle.name; sat->name = newTle.name;
// Update operational status
sat->status = newTle.status;
// we reset this to "now" when we started th e update. // we reset this to "now" when we started th e update.
sat->lastUpdated = lastUpdate; sat->lastUpdated = lastUpdate;
updatedCount++; updatedCount++;
} }
if (qsMagList.contains(id)) if (qsMagList.contains(id))
sat->stdMag = qsMagList[id]; sat->stdMag = qsMagList[id];
} }
else else
{ {
if (autoRemoveEnabled) if (autoRemoveEnabled)
toBeRemoved.append(sat->id); toBeRemoved.append(sat->id);
else else
qWarning() << "Satellites:" << sat->id << sa t->name qWarning() << "[Satellites]" << sat->id << s at->name
<< "is missing in the update list s."; << "is missing in the update list s.";
missingCount++; missingCount++;
} }
// All satellites, who has invalid orbit should be removed. // All satellites, who has invalid orbit should be removed.
if (!sat->orbitValid) if (!sat->orbitValid)
{ {
toBeRemoved.append(sat->id); toBeRemoved.append(sat->id);
qWarning() << "Satellite" << sat->id << sat->name qWarning() << "[Satellites]" << sat->id << sat->name
<< "has invalid orbit and will be removed ."; << "has invalid orbit and will be removed .";
missingCount++; missingCount++;
} }
} }
// Only those not in the loaded collection have remained // Only those not in the loaded collection have remained
// (autoAddEnabled is not checked, because it's already in the flags ) // (autoAddEnabled is not checked, because it's already in the flags )
QHash<QString, TleData>::const_iterator i; QHash<QString, TleData>::const_iterator i;
for (i = newTleSets.begin(); i != newTleSets.end(); ++i) for (i = newTleSets.begin(); i != newTleSets.end(); ++i)
{ {
skipping to change at line 1421 skipping to change at line 1426
// Add the satellite... // Add the satellite...
if (add(i.value())) if (add(i.value()))
addedCount++; addedCount++;
} }
} }
if (addedCount) if (addedCount)
qSort(satellites); qSort(satellites);
if (autoRemoveEnabled && !toBeRemoved.isEmpty()) if (autoRemoveEnabled && !toBeRemoved.isEmpty())
{ {
qWarning() << "Satellites: purging objects that were not upd ated..."; qWarning() << "[Satellites] purging objects that were not up dated...";
remove(toBeRemoved); remove(toBeRemoved);
} }
if (updatedCount > 0 || if (updatedCount > 0 ||
(autoRemoveEnabled && missingCount > 0)) (autoRemoveEnabled && missingCount > 0))
{ {
saveDataMap(createDataMap()); saveDataMap(createDataMap());
updateState = CompleteUpdates; updateState = CompleteUpdates;
} }
else else
updateState = CompleteNoUpdates; updateState = CompleteNoUpdates;
if (satelliteListModel) if (satelliteListModel)
satelliteListModel->endSatellitesChange(); satelliteListModel->endSatellitesChange();
qDebug() << "Satellites: update finished." qDebug() << "[Satellites] update finished."
<< updatedCount << "/" << totalCount << "updated," << updatedCount << "/" << totalCount << "updated,"
<< addedCount << "added," << addedCount << "added,"
<< missingCount << "missing or removed." << missingCount << "missing or removed."
<< sourceCount << "source entries parsed."; << sourceCount << "source entries parsed.";
emit(updateStateChanged(updateState)); emit(updateStateChanged(updateState));
emit(tleUpdateComplete(updatedCount, totalCount, addedCount, missing Count)); emit(tleUpdateComplete(updatedCount, totalCount, addedCount, missing Count));
} }
void Satellites::parseTleFile(QFile& openFile, void Satellites::parseTleFile(QFile& openFile,
skipping to change at line 1468 skipping to change at line 1473
while (!openFile.atEnd()) while (!openFile.atEnd())
{ {
QString line = QString(openFile.readLine()).trimmed(); QString line = QString(openFile.readLine()).trimmed();
if (line.length() < 65) // this is title line if (line.length() < 65) // this is title line
{ {
// New entry in the list, so reset all fields // New entry in the list, so reset all fields
lastData = TleData(); lastData = TleData();
lastData.addThis = addFlagValue; lastData.addThis = addFlagValue;
// The thing in square brackets after the name is ac
tually
// Celestrak's "status code". Parse it!
QStringList codes;
codes << "+" << "-" << "P" << "B" << "S" << "X" << "
D" << "?";
QRegExp statusRx("\\s*\\[(\\D{1})\\]\\s*$");
statusRx.setMinimal(true);
if (statusRx.indexIn(line)>-1)
{
lastData.status = Satellite::StatusUnknown;
switch (codes.indexOf(statusRx.capturedTexts
().at(1).toUpper()))
{
case 0:
lastData.status = Satellite:
:StatusOperational;
break;
case 1:
lastData.status = Satellite:
:StatusNonoperational;
break;
case 2:
lastData.status = Satellite:
:StatusPartiallyOperational;
break;
case 3:
lastData.status = Satellite:
:StatusStandby;
break;
case 4:
lastData.status = Satellite:
:StatusSpare;
break;
case 5:
lastData.status = Satellite:
:StatusExtendedMission;
break;
case 6:
lastData.status = Satellite:
:StatusDecayed;
break;
default:
lastData.status = Satellite:
:StatusUnknown;
}
}
//TODO: We need to think of some kind of ecaping the se //TODO: We need to think of some kind of ecaping the se
//characters in the JSON parser. --BM //characters in the JSON parser. --BM
// The thing in square brackets after the name is ac line.replace(QRegExp("\\s*\\[([^\\]])*\\]\\s*$"),"")
tually ; // remove "status code" from name
// Celestrak's "status code". Parse automatically? -
-BM
line.replace(QRegExp("\\s*\\[([^\\]])*\\]\\s*$"),"")
; // remove things in square brackets
lastData.name = line; lastData.name = line;
} }
else else
{ {
// TODO: Yet another place suitable for a standard T LE regex. --BM // TODO: Yet another place suitable for a standard T LE regex. --BM
if (QRegExp("^1 .*").exactMatch(line)) if (QRegExp("^1 .*").exactMatch(line))
lastData.first = line; lastData.first = line;
else if (QRegExp("^2 .*").exactMatch(line)) else if (QRegExp("^2 .*").exactMatch(line))
{ {
lastData.second = line; lastData.second = line;
// The Satellite Catalog Number is the secon d number // The Satellite Catalog Number is the secon d number
// on the second line. // on the second line.
QString id = line.split(' ').at(1).trimmed() ; QString id = line.split(' ').at(1).trimmed() ;
if (id.isEmpty()) if (id.isEmpty())
continue; continue;
lastData.id = id; lastData.id = id;
// This is the second line and there will be no more, // This is the second line and there will be no more,
// so if everything is OK, save the elements . // so if everything is OK, save the elements .
if (!lastData.name.isEmpty() && if (!lastData.name.isEmpty() && !lastData.fi
!lastData.first.isEmpty()) rst.isEmpty())
{ {
// Some satellites can be listed in multiple files, // Some satellites can be listed in multiple files,
// and only some of those files may be marked for adding, // and only some of those files may be marked for adding,
// so try to preserve the flag - if it's set, // so try to preserve the flag - if it's set,
// feel free to overwrite the existi ng value. // feel free to overwrite the existi ng value.
// If not, overwrite only if it's no t in the list already. // If not, overwrite only if it's no t in the list already.
// NOTE: Second case overwrite may n eed to check which TLE set is newer. // NOTE: Second case overwrite may n eed to check which TLE set is newer.
if (lastData.addThis || !tleList.con tains(id)) if (lastData.addThis || !tleList.con tains(id))
tleList.insert(id, lastData) ; // Overwrite if necessary tleList.insert(id, lastData) ; // Overwrite if necessary
} }
//TODO: Error warnings? --BM //TODO: Error warnings? --BM
} }
else else
qDebug() << "Satellites: unprocessed line " << lineNumber << " in file " << QDir::toNativeSeparators(openFile.fileName ()); qDebug() << "[Satellites] unprocessed line " << lineNumber << " in file " << QDir::toNativeSeparators(openFile.fileNam e());
} }
} }
} }
void Satellites::parseQSMagFile(QString qsMagFile) void Satellites::parseQSMagFile(QString qsMagFile)
{ {
// Description of file and some additional information you can find here: // Description of file and some additional information you can find here:
// 1) http://www.prismnet.com/~mmccants/tles/mccdesc.html // 1) http://www.prismnet.com/~mmccants/tles/mccdesc.html
// 2) http://www.prismnet.com/~mmccants/tles/intrmagdef.html // 2) http://www.prismnet.com/~mmccants/tles/intrmagdef.html
if (qsMagFile.isEmpty()) if (qsMagFile.isEmpty())
return; return;
QFile qsmFile(qsMagFile); QFile qsmFile(qsMagFile);
if (!qsmFile.open(QIODevice::ReadOnly)) if (!qsmFile.open(QIODevice::ReadOnly))
{ {
qWarning() << "Satellites: oops... cannot open " << QDir::to NativeSeparators(qsMagFile); qWarning() << "[Satellites] oops... cannot open " << QDir::t oNativeSeparators(qsMagFile);
return; return;
} }
qsMagList.clear(); qsMagList.clear();
while (!qsmFile.atEnd()) while (!qsmFile.atEnd())
{ {
QString line = QString(qsmFile.readLine()); QString line = QString(qsmFile.readLine());
QString id = line.mid(0,5).trimmed(); QString id = line.mid(0,5).trimmed();
QString smag = line.mid(33,4).trimmed(); QString smag = line.mid(33,4).trimmed();
if (!smag.isEmpty()) if (!smag.isEmpty())
skipping to change at line 1621 skipping to change at line 1661
painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+s ize/2, 20, -90); painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+s ize/2, 20, -90);
painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-s ize/2, 20, -180); painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-s ize/2, 20, -180);
} }
} }
bool Satellites::checkJsonFileFormat() bool Satellites::checkJsonFileFormat()
{ {
QFile jsonFile(catalogPath); QFile jsonFile(catalogPath);
if (!jsonFile.open(QIODevice::ReadOnly)) if (!jsonFile.open(QIODevice::ReadOnly))
{ {
qWarning() << "Satellites::checkJsonFileFormat(): cannot ope n " << QDir::toNativeSeparators(catalogPath); qWarning() << "[Satellites] cannot open " << QDir::toNativeS eparators(catalogPath);
return false; return false;
} }
QVariantMap map; QVariantMap map;
try try
{ {
map = StelJsonParser::parse(&jsonFile).toMap(); map = StelJsonParser::parse(&jsonFile).toMap();
jsonFile.close(); jsonFile.close();
} }
catch (std::runtime_error& e) catch (std::runtime_error& e)
{ {
qDebug() << "Satellites::checkJsonFileFormat(): file format qDebug() << "[Satellites] file format is wrong!";
is wrong!"; qDebug() << "[Satellites] error:" << e.what();
qDebug() << "Satellites::checkJsonFileFormat() error:" << e.
what();
return false; return false;
} }
return true; return true;
} }
bool Satellites::isValidRangeDates() const bool Satellites::isValidRangeDates() const
{ {
bool ok; bool ok;
skipping to change at line 1694 skipping to change at line 1734
double lat = pos.latitude(); double lat = pos.latitude();
double lon = M_PI - pos.longitude(); double lon = M_PI - pos.longitude();
double v = sat.data()->getVMagnitude(pcore ); double v = sat.data()->getVMagnitude(pcore );
double angle = sat.data()->sunReflAngle; double angle = sat.data()->sunReflAngle;
if (angle>0 && angle<2) if (angle>0 && angle<2)
{ {
if (angle>angle0 && (v<1) && lat>5*M _PI/180) if (angle>angle0 && (v<1) && lat>5*M _PI/180)
{ {
IridiumFlaresPrediction flar e; IridiumFlaresPrediction flar e;
flare.datetime = StelUtils:: julianDayToISO8601String(currentJD+dt+StelUtils::getGMTShiftFromQT(currentJ D+dt)/24.f); flare.datetime = StelUtils:: julianDayToISO8601String(currentJD+dt+StelApp::getInstance().getCore()->get UTCOffset(currentJD+dt)/24.f);
flare.satellite = sat.data() ->getEnglishName(); flare.satellite = sat.data() ->getEnglishName();
flare.azimuth = lon; flare.azimuth = lon;
flare.altitude = lat; flare.altitude = lat;
flare.magnitude = v; flare.magnitude = v;
predictions.append(flare); predictions.append(flare);
dt +=0.005; dt +=0.005;
} }
angle0 = angle; angle0 = angle;
skipping to change at line 1776 skipping to change at line 1816
*/ */
// Satellite descriptions - bright and/or famous objects // Satellite descriptions - bright and/or famous objects
// Just A FEW objects please! (I'm looking at you, Alex!) // Just A FEW objects please! (I'm looking at you, Alex!)
// TRANSLATORS: Satellite description. "Hubble" is a person's name. // TRANSLATORS: Satellite description. "Hubble" is a person's name.
N_("The Hubble Space Telescope"); N_("The Hubble Space Telescope");
// TRANSLATORS: Satellite description. // TRANSLATORS: Satellite description.
N_("The International Space Station"); N_("The International Space Station");
// TRANSLATORS: Satellite description. // TRANSLATORS: Satellite description.
N_("China's first space station"); N_("China's first space station");
// TRANSLATORS: Satellite description.
N_("The russian space radio telescope RadioAstron");
// TRANSLATORS: Satellite description.
N_("International Gamma-Ray Astrophysics Laboratory");
// TRANSLATORS: Satellite description.
N_("The Gamma-Ray Observatory");
// Satellite names - a few famous objects only
// TRANSLATORS: Satellite name: International Space Station
N_("ISS (ZARYA)");
// TRANSLATORS: Satellite name: Hubble Space Telescope
N_("HST");
// TRANSLATORS: Satellite name: Spektr-R Space Observatory (or Radio
Astron)
N_("SPEKTR-R");
// TRANSLATORS: Satellite name: International Gamma-Ray Astrophysics
Laboratory (INTEGRAL)
N_("INTEGRAL");
// TRANSLATORS: China's first space station name
N_("TIANGONG 1");
#endif #endif
} }
 End of changes. 44 change blocks. 
62 lines changed or deleted 129 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/