Pulsars.cpp   Pulsars.cpp 
skipping to change at line 151 skipping to change at line 151
{ {
upgradeConfigIni(); upgradeConfigIni();
try try
{ {
StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::get UserDir()+"/modules/Pulsars"); StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::get UserDir()+"/modules/Pulsars");
// If no settings in the main config file, create with defau lts // If no settings in the main config file, create with defau lts
if (!conf->childGroups().contains("Pulsars")) if (!conf->childGroups().contains("Pulsars"))
{ {
qDebug() << "Pulsars: no Pulsars section exists in m ain config file - creating with defaults"; qDebug() << "[Pulsars] No Pulsars section exists in main config file - creating with defaults";
restoreDefaultConfigIni(); restoreDefaultConfigIni();
} }
// populate settings from main config file. // populate settings from main config file.
readSettingsFromConfig(); readSettingsFromConfig();
jsonCatalogPath = StelFileMgr::findFile("modules/Pulsars", ( StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/puls ars.json"; jsonCatalogPath = StelFileMgr::findFile("modules/Pulsars", ( StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/puls ars.json";
if (jsonCatalogPath.isEmpty()) if (jsonCatalogPath.isEmpty())
return; return;
skipping to change at line 178 skipping to change at line 178
GlowIcon = new QPixmap(":/graphicGui/glow32x32.png"); GlowIcon = new QPixmap(":/graphicGui/glow32x32.png");
OnIcon = new QPixmap(":/Pulsars/btPulsars-on.png"); OnIcon = new QPixmap(":/Pulsars/btPulsars-on.png");
OffIcon = new QPixmap(":/Pulsars/btPulsars-off.png"); OffIcon = new QPixmap(":/Pulsars/btPulsars-off.png");
setFlagShowPulsars(getEnableAtStartup()); setFlagShowPulsars(getEnableAtStartup());
setFlagShowPulsarsButton(flagShowPulsarsButton); setFlagShowPulsarsButton(flagShowPulsarsButton);
} }
catch (std::runtime_error &e) catch (std::runtime_error &e)
{ {
qWarning() << "Pulsars: init error:" << e.what(); qWarning() << "[Pulsars] 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(messageTimeout() )); connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout() ));
// If the json file does not already exist, create it from the resou rce in the Qt resource // If the json file does not already exist, create it from the resou rce in the Qt resource
if(QFileInfo(jsonCatalogPath).exists()) if(QFileInfo(jsonCatalogPath).exists())
{ {
if (!checkJsonFileFormat() || getJsonFileFormatVersion()<CAT ALOG_FORMAT_VERSION) if (!checkJsonFileFormat() || getJsonFileFormatVersion()<CAT ALOG_FORMAT_VERSION)
{ {
restoreDefaultJsonFile(); restoreDefaultJsonFile();
} }
} }
else else
{ {
qDebug() << "Pulsars: pulsars.json does not exist - copying default file to" << QDir::toNativeSeparators(jsonCatalogPath); qDebug() << "[Pulsars] pulsars.json does not exist - copying default file to" << QDir::toNativeSeparators(jsonCatalogPath);
restoreDefaultJsonFile(); restoreDefaultJsonFile();
} }
qDebug() << "Pulsars: loading catalog file:" << QDir::toNativeSepara tors(jsonCatalogPath); qDebug() << "[Pulsars] Loading catalog file:" << QDir::toNativeSepar ators(jsonCatalogPath);
readJsonFile(); readJsonFile();
// 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*)), this, SLOT(up dateDownloadComplete(QNetworkReply*))); connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(up dateDownloadComplete(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
skipping to change at line 324 skipping to change at line 324
foreach(const PulsarP& pulsar, psr) foreach(const PulsarP& pulsar, psr)
{ {
if (pulsar->getNameI18n().toUpper() == nameI18n.toUpper()) if (pulsar->getNameI18n().toUpper() == nameI18n.toUpper())
return qSharedPointerCast<StelObject>(pulsar); return qSharedPointerCast<StelObject>(pulsar);
} }
return NULL; return NULL;
} }
QStringList Pulsars::listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const QStringList Pulsars::listMatchingObjects(const QString& objPrefix, int maxN bItem, bool useStartOfWords, bool inEnglish) const
{ {
QStringList result; QStringList result;
if (!flagShowPulsars) if (flagShowPulsars)
return result;
if (maxNbItem==0)
return result;
QString psrn;
bool find;
foreach(const PulsarP& pulsar, psr)
{
psrn = pulsar->getNameI18n();
find = false;
if (useStartOfWords)
{
if (psrn.toUpper().left(objPrefix.length()) == objPr
efix.toUpper())
find = true;
}
else
{
if (psrn.contains(objPrefix, Qt::CaseInsensitive))
find = true;
}
if (find)
{
result << psrn;
}
}
result.sort();
if (result.size()>maxNbItem)
result.erase(result.begin()+maxNbItem, result.end());
return result;
}
QStringList Pulsars::listMatchingObjects(const QString& objPrefix, int maxN
bItem, bool useStartOfWords) const
{
QStringList result;
if (!flagShowPulsars)
return result;
if (maxNbItem==0)
return result;
QString psrn;
bool find;
foreach(const PulsarP& pulsar, psr)
{ {
psrn = pulsar->getEnglishName(); result = StelObjectModule::listMatchingObjects(objPrefix, ma
find = false; xNbItem, useStartOfWords, inEnglish);
if (useStartOfWords)
{
if (psrn.toUpper().left(objPrefix.length()) == objPr
efix.toUpper())
find = true;
}
else
{
if (psrn.contains(objPrefix, Qt::CaseInsensitive))
find = true;
}
if (find)
{
result << psrn;
}
} }
result.sort();
if (result.size()>maxNbItem)
result.erase(result.begin()+maxNbItem, result.end());
return result; return result;
} }
QStringList Pulsars::listAllObjects(bool inEnglish) const QStringList Pulsars::listAllObjects(bool inEnglish) const
{ {
QStringList result; QStringList result;
if (!flagShowPulsars) if (!flagShowPulsars)
return result; return result;
if (inEnglish) if (inEnglish)
skipping to change at line 434 skipping to change at line 368
Replace the JSON file with the default from the compiled-in resource Replace the JSON file with the default from the compiled-in resource
*/ */
void Pulsars::restoreDefaultJsonFile(void) void Pulsars::restoreDefaultJsonFile(void)
{ {
if (QFileInfo(jsonCatalogPath).exists()) if (QFileInfo(jsonCatalogPath).exists())
backupJsonFile(true); backupJsonFile(true);
QFile src(":/Pulsars/pulsars.json"); QFile src(":/Pulsars/pulsars.json");
if (!src.copy(jsonCatalogPath)) if (!src.copy(jsonCatalogPath))
{ {
qWarning() << "Pulsars: cannot copy JSON resource to" + QDir ::toNativeSeparators(jsonCatalogPath); qWarning() << "[Pulsars] Cannot copy JSON resource to" + QDi r::toNativeSeparators(jsonCatalogPath);
} }
else else
{ {
qDebug() << "Pulsars: copied default pulsars.json to" << QDi r::toNativeSeparators(jsonCatalogPath); qDebug() << "[Pulsars] Copied default pulsars.json to" << QD ir::toNativeSeparators(jsonCatalogPath);
// 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(jsonCatalogPath); QFile dest(jsonCatalogPath);
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
conf->remove("Pulsars/last_update"); conf->remove("Pulsars/last_update");
lastUpdate = QDateTime::fromString("2012-05-24T12:00:00", Qt ::ISODate); lastUpdate = QDateTime::fromString("2012-05-24T12:00:00", Qt ::ISODate);
skipping to change at line 460 skipping to change at line 394
} }
/* /*
Creates a backup of the pulsars.json file called pulsars.json.old Creates a backup of the pulsars.json file called pulsars.json.old
*/ */
bool Pulsars::backupJsonFile(bool deleteOriginal) bool Pulsars::backupJsonFile(bool deleteOriginal)
{ {
QFile old(jsonCatalogPath); QFile old(jsonCatalogPath);
if (!old.exists()) if (!old.exists())
{ {
qWarning() << "Pulsars: no file to backup"; qWarning() << "[Pulsars] No file to backup";
return false; return false;
} }
QString backupPath = jsonCatalogPath + ".old"; QString backupPath = jsonCatalogPath + ".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() << "Pulsars: WARNING - could not remove old pulsars.json file"; qWarning() << "[Pulsars] WARNING - could not remove old pulsars.json file";
return false; return false;
} }
} }
} }
else else
{ {
qWarning() << "Pulsars: WARNING - failed to copy pulsars.jso n to pulsars.json.old"; qWarning() << "[Pulsars] WARNING - failed to copy pulsars.js on to pulsars.json.old";
return false; return false;
} }
return true; return true;
} }
/* /*
Read the JSON file and create list of pulsars. Read the JSON file and create list of pulsars.
*/ */
void Pulsars::readJsonFile(void) void Pulsars::readJsonFile(void)
skipping to change at line 507 skipping to change at line 441
Parse JSON file and load pulsars to map Parse JSON file and load pulsars to map
*/ */
QVariantMap Pulsars::loadPSRMap(QString path) QVariantMap Pulsars::loadPSRMap(QString path)
{ {
if (path.isEmpty()) if (path.isEmpty())
path = jsonCatalogPath; path = jsonCatalogPath;
QVariantMap map; QVariantMap map;
QFile jsonFile(path); QFile jsonFile(path);
if (!jsonFile.open(QIODevice::ReadOnly)) if (!jsonFile.open(QIODevice::ReadOnly))
qWarning() << "Pulsars: cannot open" << QDir::toNativeSepara tors(path); qWarning() << "[Pulsars] Cannot open" << QDir::toNativeSepar ators(path);
else else
{ {
map = StelJsonParser::parse(jsonFile.readAll()).toMap(); map = StelJsonParser::parse(jsonFile.readAll()).toMap();
jsonFile.close(); jsonFile.close();
} }
return map; return map;
} }
/* /*
Set items for list of struct from data map Set items for list of struct from data map
skipping to change at line 544 skipping to change at line 478
} }
} }
int Pulsars::getJsonFileFormatVersion(void) int Pulsars::getJsonFileFormatVersion(void)
{ {
int jsonVersion = -1; int jsonVersion = -1;
QFile jsonPSRCatalogFile(jsonCatalogPath); QFile jsonPSRCatalogFile(jsonCatalogPath);
if (!jsonPSRCatalogFile.open(QIODevice::ReadOnly)) if (!jsonPSRCatalogFile.open(QIODevice::ReadOnly))
{ {
qWarning() << "Pulsars: cannot open" << QDir::toNativeSepara tors(jsonCatalogPath); qWarning() << "[Pulsars] Cannot open" << QDir::toNativeSepar ators(jsonCatalogPath);
return jsonVersion; return jsonVersion;
} }
QVariantMap map; QVariantMap map;
map = StelJsonParser::parse(&jsonPSRCatalogFile).toMap(); map = StelJsonParser::parse(&jsonPSRCatalogFile).toMap();
if (map.contains("version")) if (map.contains("version"))
{ {
jsonVersion = map.value("version").toInt(); jsonVersion = map.value("version").toInt();
} }
jsonPSRCatalogFile.close(); jsonPSRCatalogFile.close();
qDebug() << "Pulsars: version of the format of the catalog:" << json Version; qDebug() << "[Pulsars] Version of the format of the catalog:" << jso nVersion;
return jsonVersion; return jsonVersion;
} }
bool Pulsars::checkJsonFileFormat() bool Pulsars::checkJsonFileFormat()
{ {
QFile jsonPSRCatalogFile(jsonCatalogPath); QFile jsonPSRCatalogFile(jsonCatalogPath);
if (!jsonPSRCatalogFile.open(QIODevice::ReadOnly)) if (!jsonPSRCatalogFile.open(QIODevice::ReadOnly))
{ {
qWarning() << "Pulsars: cannot open" << QDir::toNativeSepara tors(jsonCatalogPath); qWarning() << "[Pulsars] Cannot open" << QDir::toNativeSepar ators(jsonCatalogPath);
return false; return false;
} }
QVariantMap map; QVariantMap map;
try try
{ {
map = StelJsonParser::parse(&jsonPSRCatalogFile).toMap(); map = StelJsonParser::parse(&jsonPSRCatalogFile).toMap();
jsonPSRCatalogFile.close(); jsonPSRCatalogFile.close();
} }
catch (std::runtime_error& e) catch (std::runtime_error& e)
{ {
qDebug() << "Pulsars: file format is wrong! Error:" << e.wha t(); qDebug() << "[Pulsars] File format is wrong! Error:" << e.wh at();
return false; return false;
} }
return true; return true;
} }
PulsarP Pulsars::getByID(const QString& id) PulsarP Pulsars::getByID(const QString& id)
{ {
foreach(const PulsarP& pulsar, psr) foreach(const PulsarP& pulsar, psr)
{ {
skipping to change at line 638 skipping to change at line 572
void Pulsars::readSettingsFromConfig(void) void Pulsars::readSettingsFromConfig(void)
{ {
conf->beginGroup("Pulsars"); conf->beginGroup("Pulsars");
updateUrl = conf->value("url", "http://stellarium.org/json/pulsars.j son").toString(); updateUrl = conf->value("url", "http://stellarium.org/json/pulsars.j son").toString();
updateFrequencyDays = conf->value("update_frequency_days", 100).toIn t(); updateFrequencyDays = conf->value("update_frequency_days", 100).toIn t();
lastUpdate = QDateTime::fromString(conf->value("last_update", "2012- 05-24T12:00:00").toString(), Qt::ISODate); lastUpdate = QDateTime::fromString(conf->value("last_update", "2012- 05-24T12:00:00").toString(), Qt::ISODate);
updatesEnabled = conf->value("updates_enabled", true).toBool(); updatesEnabled = conf->value("updates_enabled", true).toBool();
setDisplayMode(conf->value("distribution_enabled", false).toBool()); setDisplayMode(conf->value("distribution_enabled", false).toBool());
setGlitchFlag(conf->value("use_separate_colors", false).toBool()); setGlitchFlag(conf->value("use_separate_colors", false).toBool());
setMarkerColor(conf->value("marker_color", "0.4,0.5,1.0").toString() setMarkerColor(StelUtils::strToVec3f(conf->value("marker_color", "0.
, true); 4,0.5,1.0").toString()), true);
setMarkerColor(conf->value("glitch_color", "0.2,0.3,1.0").toString() setMarkerColor(StelUtils::strToVec3f(conf->value("glitch_color", "0.
, false); 2,0.3,1.0").toString()), false);
enableAtStartup = conf->value("enable_at_startup", false).toBool(); enableAtStartup = conf->value("enable_at_startup", false).toBool();
flagShowPulsarsButton = conf->value("flag_show_pulsars_button", true ).toBool(); flagShowPulsarsButton = conf->value("flag_show_pulsars_button", true ).toBool();
conf->endGroup(); conf->endGroup();
} }
void Pulsars::saveSettingsToConfig(void) void Pulsars::saveSettingsToConfig(void)
{ {
conf->beginGroup("Pulsars"); conf->beginGroup("Pulsars");
conf->setValue("url", updateUrl); conf->setValue("url", updateUrl);
conf->setValue("update_frequency_days", updateFrequencyDays); conf->setValue("update_frequency_days", updateFrequencyDays);
conf->setValue("updates_enabled", updatesEnabled ); conf->setValue("updates_enabled", updatesEnabled );
conf->setValue("distribution_enabled", getDisplayMode()); conf->setValue("distribution_enabled", getDisplayMode());
conf->setValue("use_separate_colors", getGlitchFlag()); conf->setValue("use_separate_colors", getGlitchFlag());
conf->setValue("enable_at_startup", enableAtStartup); conf->setValue("enable_at_startup", enableAtStartup);
conf->setValue("flag_show_pulsars_button", flagShowPulsarsButton); conf->setValue("flag_show_pulsars_button", flagShowPulsarsButton);
conf->setValue("marker_color", getMarkerColor(true)); conf->setValue("marker_color", StelUtils::vec3fToStr(getMarkerColor(
conf->setValue("glitch_color", getMarkerColor(false)); true)));
conf->setValue("glitch_color", StelUtils::vec3fToStr(getMarkerColor(
false)));
conf->endGroup(); conf->endGroup();
} }
int Pulsars::getSecondsToUpdate(void) int Pulsars::getSecondsToUpdate(void)
{ {
QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyDays * 3600 * 24); QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyDays * 3600 * 24);
return QDateTime::currentDateTime().secsTo(nextUpdate); return QDateTime::currentDateTime().secsTo(nextUpdate);
} }
void Pulsars::checkForUpdate(void) void Pulsars::checkForUpdate(void)
{ {
if (updatesEnabled && lastUpdate.addSecs(updateFrequencyDays * 3600 * 24) <= QDateTime::currentDateTime()) if (updatesEnabled && lastUpdate.addSecs(updateFrequencyDays * 3600 * 24) <= QDateTime::currentDateTime())
updateJSON(); updateJSON();
} }
void Pulsars::updateJSON(void) void Pulsars::updateJSON(void)
{ {
if (updateState==Pulsars::Updating) if (updateState==Pulsars::Updating)
{ {
qWarning() << "Pulsars: already updating... will not start again current update is complete."; qWarning() << "[Pulsars] Already updating... will not start again current update is complete.";
return; return;
} }
else else
{ {
qDebug() << "Pulsars: starting update..."; qDebug() << "[Pulsars] Starting update...";
} }
lastUpdate = QDateTime::currentDateTime(); lastUpdate = QDateTime::currentDateTime();
conf->setValue("Pulsars/last_update", lastUpdate.toString(Qt::ISODat e)); conf->setValue("Pulsars/last_update", lastUpdate.toString(Qt::ISODat e));
updateState = Pulsars::Updating; updateState = Pulsars::Updating;
emit(updateStateChanged(updateState)); emit(updateStateChanged(updateState));
if (progressBar==NULL) if (progressBar==NULL)
progressBar = StelApp::getInstance().addProgressBar(); progressBar = StelApp::getInstance().addProgressBar();
skipping to change at line 715 skipping to change at line 649
updateState = Pulsars::CompleteUpdates; updateState = Pulsars::CompleteUpdates;
emit(updateStateChanged(updateState)); emit(updateStateChanged(updateState));
emit(jsonUpdateComplete()); emit(jsonUpdateComplete());
} }
void Pulsars::updateDownloadComplete(QNetworkReply* reply) void Pulsars::updateDownloadComplete(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() << "Pulsars: FAILED to download" << reply->url() << " Error: " << reply->errorString(); qWarning() << "[Pulsars] FAILED to download" << reply->url() << " Error: " << reply->errorString();
} }
else else
{ {
// download completed successfully. // download completed successfully.
QString jsonFilePath = StelFileMgr::findFile("modules/Pulsar s", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/p ulsars.json"; QString jsonFilePath = StelFileMgr::findFile("modules/Pulsar s", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/p ulsars.json";
if (jsonFilePath.isEmpty()) if (jsonFilePath.isEmpty())
{ {
qWarning() << "Pulsars: cannot write JSON data to fi le:" << QDir::toNativeSeparators(jsonCatalogPath); qWarning() << "[Pulsars] Cannot write JSON data to f ile:" << QDir::toNativeSeparators(jsonCatalogPath);
return; return;
} }
QFile jsonFile(jsonFilePath); QFile jsonFile(jsonFilePath);
if (jsonFile.exists()) if (jsonFile.exists())
jsonFile.remove(); jsonFile.remove();
if(jsonFile.open(QIODevice::WriteOnly | QIODevice::Text)) if(jsonFile.open(QIODevice::WriteOnly | QIODevice::Text))
{ {
jsonFile.write(reply->readAll()); jsonFile.write(reply->readAll());
jsonFile.close(); jsonFile.close();
skipping to change at line 810 skipping to change at line 744
bool Pulsars::getGlitchFlag() bool Pulsars::getGlitchFlag()
{ {
return Pulsar::glitchFlag; return Pulsar::glitchFlag;
} }
void Pulsars::setGlitchFlag(bool b) void Pulsars::setGlitchFlag(bool b)
{ {
Pulsar::glitchFlag=b; Pulsar::glitchFlag=b;
} }
QString Pulsars::getMarkerColor(bool mtype) Vec3f Pulsars::getMarkerColor(bool mtype)
{ {
Vec3f c; Vec3f c = Pulsar::glitchColor;
if (mtype) if (mtype)
c = Pulsar::markerColor; c = Pulsar::markerColor;
else
c = Pulsar::glitchColor; return c;
return QString("%1,%2,%3").arg(c[0]).arg(c[1]).arg(c[2]);
} }
void Pulsars::setMarkerColor(QString c, bool mtype) void Pulsars::setMarkerColor(const Vec3f &c, bool mtype)
{ {
if (mtype) if (mtype)
Pulsar::markerColor = StelUtils::strToVec3f(c); Pulsar::markerColor = c;
else else
Pulsar::glitchColor = StelUtils::strToVec3f(c); Pulsar::glitchColor = c;
}
void Pulsars::reloadCatalog(void)
{
bool hasSelection = false;
StelObjectMgr* objMgr = GETSTELMODULE(StelObjectMgr);
// Whether any pulsar are selected? Save the current selection...
const QList<StelObjectP> selectedObject = objMgr->getSelectedObject(
"Pulsar");
if (!selectedObject.isEmpty())
{
// ... unselect current pulsar.
hasSelection = true;
objMgr->unSelect();
}
readJsonFile();
if (hasSelection)
{
// Restore selection...
objMgr->setSelectedObject(selectedObject);
}
}
void Pulsars::setFlagShowPulsars(bool b)
{
if (b!=flagShowPulsars)
{
flagShowPulsars=b;
emit flagPulsarsVisibilityChanged(b);
}
} }
 End of changes. 30 change blocks. 
104 lines changed or deleted 69 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/