StelLocationMgr.cpp   StelLocationMgr.cpp 
skipping to change at line 23 skipping to change at line 23
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelLocationMgr.hpp" #include "StelLocationMgr.hpp"
#include "StelUtils.hpp" #include "StelUtils.hpp"
#include "kfilterdev.h"
#include <QStringListModel> #include <QStringListModel>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
StelLocationMgr::StelLocationMgr() StelLocationMgr::StelLocationMgr()
{ {
// The line below allows to re-generate the location file, you still need to gunzip it manually afterward. // The line below allows to re-generate the location file, you still need to gunzip it manually afterward.
// generateBinaryLocationFile("data/base_locations.txt", false, "dat a/base_locations.bin"); // generateBinaryLocationFile("data/base_locations.txt", false, "dat a/base_locations.bin");
locations = loadCitiesBin("data/base_locations.bin.gz"); locations = loadCitiesBin("data/base_locations.bin.gz");
locations.unite(loadCities("data/user_locations.txt", true)); locations.unite(loadCities("data/user_locations.txt", true));
modelAllLocation = new QStringListModel(this); modelAllLocation = new QStringListModel(this);
modelAllLocation->setStringList(locations.keys()); modelAllLocation->setStringList(locations.keys());
// Init to Paris France because it's the center of the world. // Init to Paris France because it's the center of the world.
lastResortLocation = locationForSmallString("Paris, France"); lastResortLocation = locationForString("Paris, France");
} }
void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, b ool isUserLocation, const QString& binFilePath) const void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, b ool isUserLocation, const QString& binFilePath) const
{ {
const QMap<QString, StelLocation>& cities = loadCities(fileName, isU serLocation); const QMap<QString, StelLocation>& cities = loadCities(fileName, isU serLocation);
QFile binfile(binFilePath); QFile binfile(binFilePath);
binfile.open(QIODevice::WriteOnly); if(binfile.open(QIODevice::WriteOnly))
QDataStream out(&binfile); {
out.setVersion(QDataStream::Qt_4_6); QDataStream out(&binfile);
out << cities; out.setVersion(QDataStream::Qt_4_6);
binfile.close(); out << cities;
binfile.close();
}
} }
QMap<QString, StelLocation> StelLocationMgr::loadCitiesBin(const QString& f ileName) const QMap<QString, StelLocation> StelLocationMgr::loadCitiesBin(const QString& f ileName) const
{ {
QMap<QString, StelLocation> res; QMap<QString, StelLocation> res;
QString cityDataPath; QString cityDataPath = StelFileMgr::findFile(fileName);
try if (cityDataPath.isEmpty())
{
cityDataPath = StelFileMgr::findFile(fileName);
}
catch (std::runtime_error& e)
{
return res; return res;
}
QFile sourcefile(cityDataPath); QFile sourcefile(cityDataPath);
if (!sourcefile.open(QIODevice::ReadOnly)) if (!sourcefile.open(QIODevice::ReadOnly))
{ {
qWarning() << "ERROR: Could not open location data file: " < < QDir::toNativeSeparators(cityDataPath); qWarning() << "ERROR: Could not open location data file: " < < QDir::toNativeSeparators(cityDataPath);
return res; return res;
} }
if (fileName.endsWith(".gz")) if (fileName.endsWith(".gz"))
{ {
QIODevice* d = KFilterDev::device(&sourcefile, "application/ // FIXME: This code doesn't work with MSVC2012 -- need fix!
x-gzip", false); --AW
d->open(QIODevice::ReadOnly); QDataStream in(StelUtils::uncompress(sourcefile.readAll()));
QDataStream in(d);
in.setVersion(QDataStream::Qt_4_6); in.setVersion(QDataStream::Qt_4_6);
in >> res; in >> res;
d->close();
delete d;
return res; return res;
} }
else else
{ {
QDataStream in(&sourcefile); QDataStream in(&sourcefile);
in.setVersion(QDataStream::Qt_4_6); in.setVersion(QDataStream::Qt_4_6);
in >> res; in >> res;
return res; return res;
} }
} }
QMap<QString, StelLocation> StelLocationMgr::loadCities(const QString& file Name, bool isUserLocation) const QMap<QString, StelLocation> StelLocationMgr::loadCities(const QString& file Name, bool isUserLocation) const
{ {
// Load the cities from data file // Load the cities from data file
QMap<QString, StelLocation> locations; QMap<QString, StelLocation> locations;
QString cityDataPath; QString cityDataPath = StelFileMgr::findFile(fileName);
try if (cityDataPath.isEmpty())
{ {
cityDataPath = StelFileMgr::findFile(fileName); // Note it is quite normal not to have a user locations file
} (e.g. first run)
catch (std::runtime_error& e)
{
// Note it is quite normal to nor have a user locations file
(e.g. first run)
if (!isUserLocation) if (!isUserLocation)
qWarning() << "WARNING: Failed to locate location da ta file: " << QDir::toNativeSeparators(fileName) << e.what(); qWarning() << "WARNING: Failed to locate location da ta file: " << QDir::toNativeSeparators(fileName);
return locations; return locations;
} }
QFile sourcefile(cityDataPath); QFile sourcefile(cityDataPath);
if (!sourcefile.open(QIODevice::ReadOnly | QIODevice::Text)) if (!sourcefile.open(QIODevice::ReadOnly | QIODevice::Text))
{ {
qWarning() << "ERROR: Could not open location data file: " < < QDir::toNativeSeparators(cityDataPath); qWarning() << "ERROR: Could not open location data file: " < < QDir::toNativeSeparators(cityDataPath);
return locations; return locations;
} }
skipping to change at line 161 skipping to change at line 149
} }
} }
sourcefile.close(); sourcefile.close();
return locations; return locations;
} }
StelLocationMgr::~StelLocationMgr() StelLocationMgr::~StelLocationMgr()
{ {
} }
const StelLocation StelLocationMgr::locationForSmallString(const QString& s , bool* ok) const static float parseAngle(const QString& s, bool* ok)
{ {
QMap<QString, StelLocation>::const_iterator iter = locations.find(s) float ret;
; // First try normal decimal value.
if (iter==locations.end()) ret = s.toFloat(ok);
{ if (*ok) return ret;
if (ok) // Try GPS coordinate like +121°33'38.28"
*ok=false; QRegExp reg("([+-]?[\\d.]+)°(?:([\\d.]+)')?(?:([\\d.]+)\")?");
return lastResortLocation; if (reg.exactMatch(s))
} {
else float deg = reg.capturedTexts()[1].toFloat(ok);
{ if (!*ok) return 0;
if (ok) float min = reg.capturedTexts()[2].isEmpty()? 0 : reg.captur
*ok = true; edTexts()[2].toFloat(ok);
return locations.value(s); if (!*ok) return 0;
float sec = reg.capturedTexts()[3].isEmpty()? 0 : reg.captur
edTexts()[3].toFloat(ok);
if (!*ok) return 0;
return deg + min / 60 + sec / 3600;
} }
return 0;
} }
const StelLocation StelLocationMgr::locationForString(const QString& s, boo l* ok) const const StelLocation StelLocationMgr::locationForString(const QString& s) con st
{ {
bool myOk; QMap<QString, StelLocation>::const_iterator iter = locations.find(s)
StelLocation ret = locationForSmallString(s, &myOk); ;
if (myOk) if (iter!=locations.end())
{ {
if (ok) return iter.value();
*ok=true;
return ret;
} }
// Maybe it is a coordinate set ? (e.g. GPS +41d51'00" -51d00'00" ) StelLocation ret;
QRegExp reg("(.*)([\\+\\-](?:\\d+)d(?:\\d+)'(?:\\d+)\") ([\\+\\-](?: // Maybe it is a coordinate set ? (e.g. GPS 25.107363,121.558807 )
\\d+)d(?:\\d+)'(?:\\d+)\")"); QRegExp reg("(?:(.+)\\s+)?(.+),(.+)");
reg.setMinimal(true); if (reg.exactMatch(s))
if (!reg.exactMatch(s)) {
{ bool ok;
if (ok) // We have a set of coordinates
*ok=false; ret.latitude = parseAngle(reg.capturedTexts()[2].trimmed(),
&ok);
if (!ok) ret.role = '!';
ret.longitude = parseAngle(reg.capturedTexts()[3].trimmed(),
&ok);
if (!ok) ret.role = '!';
ret.name = reg.capturedTexts()[1].trimmed();
ret.planetName = "Earth";
return ret; return ret;
} }
// We have a set of coordinates ret.role = '!';
ret.name = reg.capturedTexts()[1].trimmed();
ret.latitude = StelUtils::dmsStrToRad(reg.capturedTexts()[2]) * 180
/ M_PI;
ret.longitude = StelUtils::dmsStrToRad(reg.capturedTexts()[3]) * 180
/ M_PI;
if (ok)
*ok=true;
return ret; return ret;
} }
// Get whether a location can be permanently added to the list of user loca tions // Get whether a location can be permanently added to the list of user loca tions
bool StelLocationMgr::canSaveUserLocation(const StelLocation& loc) const bool StelLocationMgr::canSaveUserLocation(const StelLocation& loc) const
{ {
return locations.find(loc.getID())==locations.end(); return loc.isValid() && locations.find(loc.getID())==locations.end() ;
} }
// Add permanently a location to the list of user locations // Add permanently a location to the list of user locations
bool StelLocationMgr::saveUserLocation(const StelLocation& loc) bool StelLocationMgr::saveUserLocation(const StelLocation& loc)
{ {
if (!canSaveUserLocation(loc)) if (!canSaveUserLocation(loc))
return false; return false;
// Add in the program // Add in the program
locations[loc.getID()]=loc; locations[loc.getID()]=loc;
// Append in the Qt model // Append in the Qt model
modelAllLocation->setStringList(locations.keys()); modelAllLocation->setStringList(locations.keys());
// Append to the user location file // Append to the user location file
QString cityDataPath; QString cityDataPath = StelFileMgr::findFile("data/user_locations.tx
try t", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::File));
{ if (cityDataPath.isEmpty())
cityDataPath = StelFileMgr::findFile("data/user_locations.tx
t", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::File));
}
catch (std::runtime_error& e)
{ {
if (!StelFileMgr::exists(StelFileMgr::getUserDir()+"/data")) if (!StelFileMgr::exists(StelFileMgr::getUserDir()+"/data"))
{ {
if (!StelFileMgr::mkDir(StelFileMgr::getUserDir()+"/ data")) if (!StelFileMgr::mkDir(StelFileMgr::getUserDir()+"/ data"))
{ {
qWarning() << "ERROR - cannot create non-exi stent data directory" << QDir::toNativeSeparators(StelFileMgr::getUserDir() +"/data"); qWarning() << "ERROR - cannot create non-exi stent data directory" << QDir::toNativeSeparators(StelFileMgr::getUserDir() +"/data");
qWarning() << "Location cannot be saved"; qWarning() << "Location cannot be saved";
return false; return false;
} }
} }
skipping to change at line 286 skipping to change at line 272
bool StelLocationMgr::deleteUserLocation(const QString& id) bool StelLocationMgr::deleteUserLocation(const QString& id)
{ {
if (!canDeleteUserLocation(id)) if (!canDeleteUserLocation(id))
return false; return false;
locations.remove(id); locations.remove(id);
// Remove in the Qt model file // Remove in the Qt model file
modelAllLocation->setStringList(locations.keys()); modelAllLocation->setStringList(locations.keys());
// Resave the whole remaining user locations file // Resave the whole remaining user locations file
QString cityDataPath; QString cityDataPath = StelFileMgr::findFile("data/user_locations.tx
try t", StelFileMgr::Writable);
{ if (cityDataPath.isEmpty())
cityDataPath = StelFileMgr::findFile("data/user_locations.tx
t", StelFileMgr::Writable);
}
catch (std::runtime_error& e)
{ {
if (!StelFileMgr::exists(StelFileMgr::getUserDir()+"/data")) if (!StelFileMgr::exists(StelFileMgr::getUserDir()+"/data"))
{ {
if (!StelFileMgr::mkDir(StelFileMgr::getUserDir()+"/ data")) if (!StelFileMgr::mkDir(StelFileMgr::getUserDir()+"/ data"))
{ {
qWarning() << "ERROR - cannot create non-exi stent data directory" << QDir::toNativeSeparators(StelFileMgr::getUserDir() +"/data"); qWarning() << "ERROR - cannot create non-exi stent data directory" << QDir::toNativeSeparators(StelFileMgr::getUserDir() +"/data");
qWarning() << "Location cannot be saved"; qWarning() << "Location cannot be saved";
return false; return false;
} }
} }
 End of changes. 21 change blocks. 
82 lines changed or deleted 65 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/