LandscapeMgr.cpp   LandscapeMgr.cpp 
skipping to change at line 23 skipping to change at line 23
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* 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 <QDebug> #include "StelActionMgr.hpp"
#include <QSettings>
#include <QString>
#include <QDir>
#include <QFile>
#include <QTemporaryFile>
#include <stdexcept>
#include "LandscapeMgr.hpp" #include "LandscapeMgr.hpp"
#include "Landscape.hpp" #include "Landscape.hpp"
#include "Atmosphere.hpp" #include "Atmosphere.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "SolarSystem.hpp" #include "SolarSystem.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "StelLocaleMgr.hpp" #include "StelLocaleMgr.hpp"
#include "StelModuleMgr.hpp" #include "StelModuleMgr.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "Planet.hpp" #include "Planet.hpp"
#include "StelIniParser.hpp" #include "StelIniParser.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "renderer/StelRenderer.hpp" #include "StelPainter.hpp"
#include "karchive.h" #include "qzipreader.h"
#include "kzip.h"
#include <QDebug>
#include <QSettings>
#include <QString>
#include <QDir>
#include <QDirIterator>
#include <QFile>
#include <QTemporaryFile>
#include <QMouseEvent>
#include <stdexcept>
// Class which manages the cardinal points displaying // Class which manages the cardinal points displaying
class Cardinals class Cardinals
{ {
public: public:
Cardinals(float _radius = 1.); Cardinals(float _radius = 1.);
virtual ~Cardinals(); virtual ~Cardinals();
void draw(const StelCore* core, StelRenderer* renderer, double latit ude) const; void draw(const StelCore* core, double latitude) const;
void setColor(const Vec3f& c) {color = c;} void setColor(const Vec3f& c) {color = c;}
Vec3f get_color() {return color;} Vec3f get_color() {return color;}
void updateI18n(); void updateI18n();
void update(double deltaTime) {fader.update((int)(deltaTime*1000));} void update(double deltaTime) {fader.update((int)(deltaTime*1000));}
void set_fade_duration(float duration) {fader.setDuration((int)(dura tion*1000.f));} void set_fade_duration(float duration) {fader.setDuration((int)(dura tion*1000.f));}
void setFlagShow(bool b){fader = b;} void setFlagShow(bool b){fader = b;}
bool getFlagShow() const {return fader;} bool getFlagShow() const {return fader;}
private: private:
float radius; float radius;
QFont font; QFont font;
skipping to change at line 87 skipping to change at line 89
sEast = "E"; sEast = "E";
sWest = "W"; sWest = "W";
} }
Cardinals::~Cardinals() Cardinals::~Cardinals()
{ {
} }
// Draw the cardinals points : N S E W // Draw the cardinals points : N S E W
// handles special cases at poles // handles special cases at poles
void Cardinals::draw(const StelCore* core, StelRenderer* renderer, double l atitude) const void Cardinals::draw(const StelCore* core, double latitude) const
{ {
const StelProjectorP prj = core->getProjection(StelCore::FrameAltAz, StelCore::RefractionOff); const StelProjectorP prj = core->getProjection(StelCore::FrameAltAz, StelCore::RefractionOff);
renderer->setFont(font); StelPainter sPainter(prj);
sPainter.setFont(font);
if (!fader.getInterstate()) return; if (!fader.getInterstate()) return;
// direction text // direction text
QString d[4]; QString d[4];
d[0] = sNorth; d[0] = sNorth;
d[1] = sSouth; d[1] = sSouth;
d[2] = sEast; d[2] = sEast;
d[3] = sWest; d[3] = sWest;
// fun polar special cases // fun polar special cases
if (latitude == 90.0 ) d[0] = d[1] = d[2] = d[3] = sSouth; if (latitude == 90.0 ) d[0] = d[1] = d[2] = d[3] = sSouth;
if (latitude == -90.0 ) d[0] = d[1] = d[2] = d[3] = sNorth; if (latitude == -90.0 ) d[0] = d[1] = d[2] = d[3] = sNorth;
renderer->setGlobalColor(color[0], color[1], color[2], fader.getInte sPainter.setColor(color[0],color[1],color[2],fader.getInterstate());
rstate()); glEnable(GL_BLEND);
renderer->setBlendMode(BlendMode_Alpha); sPainter.enableTexture2d(true);
// Normal transparency mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Vec3f pos; Vec3f pos;
Vec3f xy; Vec3f xy;
float shift = QFontMetrics(font).width(sNorth)/2; float shift = sPainter.getFontMetrics().width(sNorth)/2;
if (core->getProjection(StelCore::FrameJ2000)->getMaskType() == Stel Projector::MaskDisk) if (core->getProjection(StelCore::FrameJ2000)->getMaskType() == Stel Projector::MaskDisk)
shift = 0; shift = 0;
// N for North // N for North
pos.set(-1.f, 0.f, 0.f); pos.set(-1.f, 0.f, 0.f);
if (prj->project(pos, xy)) if (prj->project(pos,xy)) sPainter.drawText(xy[0], xy[1], d[0], 0.,
{ -shift, -shift, false);
renderer->drawText(TextParams(xy[0], xy[1], d[0])
.shift(-shift, -shift).useGravity());
}
// S for South // S for South
pos.set(1.f, 0.f, 0.f); pos.set(1.f, 0.f, 0.f);
if (prj->project(pos, xy)) if (prj->project(pos,xy)) sPainter.drawText(xy[0], xy[1], d[1], 0.,
{ -shift, -shift, false);
renderer->drawText(TextParams(xy[0], xy[1], d[1])
.shift(-shift, -shift).useGravity());
}
// E for East // E for East
pos.set(0.f, 1.f, 0.f); pos.set(0.f, 1.f, 0.f);
if (prj->project(pos, xy)) if (prj->project(pos,xy)) sPainter.drawText(xy[0], xy[1], d[2], 0.,
{ -shift, -shift, false);
renderer->drawText(TextParams(xy[0], xy[1], d[2])
.shift(-shift, -shift).useGravity());
}
// W for West // W for West
pos.set(0.f, -1.f, 0.f); pos.set(0.f, -1.f, 0.f);
if (prj->project(pos, xy)) if (prj->project(pos,xy)) sPainter.drawText(xy[0], xy[1], d[3], 0.,
{ -shift, -shift, false);
renderer->drawText(TextParams(xy[0], xy[1], d[3])
.shift(-shift, -shift).useGravity());
}
} }
// Translate cardinal labels with gettext to current sky language and updat e font for the language // Translate cardinal labels with gettext to current sky language and updat e font for the language
void Cardinals::updateI18n() void Cardinals::updateI18n()
{ {
StelTranslator& trans = StelApp::getInstance().getLocaleMgr().getApp StelTranslator(); const StelTranslator& trans = StelApp::getInstance().getLocaleMgr(). getAppStelTranslator();
sNorth = trans.qtranslate("N"); sNorth = trans.qtranslate("N");
sSouth = trans.qtranslate("S"); sSouth = trans.qtranslate("S");
sEast = trans.qtranslate("E"); sEast = trans.qtranslate("E");
sWest = trans.qtranslate("W"); sWest = trans.qtranslate("W");
} }
LandscapeMgr::LandscapeMgr() : atmosphere(NULL), cardinalsPoints(NULL), lan LandscapeMgr::LandscapeMgr()
dscape(NULL), flagLandscapeSetsLocation(false) : atmosphere(NULL)
, cardinalsPoints(NULL)
, landscape(NULL)
, flagLandscapeSetsLocation(false)
, flagLandscapeAutoSelection(false)
, flagLightPollutionFromDatabase(false)
, flagLandscapeUseMinimalBrightness(false)
, defaultMinimalBrightness(0.01)
, flagLandscapeSetsMinimalBrightness(false)
, flagAtmosphereAutoEnabling(false)
{ {
setObjectName("LandscapeMgr"); setObjectName("LandscapeMgr");
//TODO: Find a way to obtain this list automatically.
//Note: The first entry in the list is used as the default 'default landscape' in removeLandscape(). //Note: The first entry in the list is used as the default 'default landscape' in removeLandscape().
packagedLandscapeIDs = (QStringList() << "guereins" << "trees" << "m packagedLandscapeIDs = (QStringList() << "guereins");
oon" << "hurricane" << "ocean" << "garching" << "mars" << "saturn"); QDirIterator directories(StelFileMgr::getInstallationDir()+"/landsca
pes/", QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::
Subdirectories);
while(directories.hasNext())
{
directories.next();
packagedLandscapeIDs << directories.fileName();
}
packagedLandscapeIDs.removeDuplicates();
} }
LandscapeMgr::~LandscapeMgr() LandscapeMgr::~LandscapeMgr()
{ {
delete atmosphere; delete atmosphere;
delete cardinalsPoints; delete cardinalsPoints;
delete landscape; delete landscape;
landscape = NULL; landscape = NULL;
} }
/************************************************************************* /*************************************************************************
Reimplementation of the getCallOrder method Reimplementation of the getCallOrder method
*************************************************************************/ *************************************************************************/
double LandscapeMgr::getCallOrder(StelModuleActionName actionName) const double LandscapeMgr::getCallOrder(StelModuleActionName actionName) const
{ {
if (actionName==StelModule::ActionDraw) if (actionName==StelModule::ActionDraw)
return StelApp::getInstance().getModuleMgr().getModule("Mete orMgr")->getCallOrder(actionName)+20; return StelApp::getInstance().getModuleMgr().getModule("Mete orMgr")->getCallOrder(actionName)+20;
if (actionName==StelModule::ActionUpdate) if (actionName==StelModule::ActionUpdate)
return StelApp::getInstance().getModuleMgr().getModule("Sola rSystem")->getCallOrder(actionName)+10; return StelApp::getInstance().getModuleMgr().getModule("Sola rSystem")->getCallOrder(actionName)+10;
// GZ The next 2 lines are only required to test landscape transpare
ncy. They should be commented away for releases.
if (actionName==StelModule::ActionHandleMouseClicks)
return StelApp::getInstance().getModuleMgr().getModule("Stel
MovementMgr")->getCallOrder(actionName)-1;
return 0; return 0;
} }
void LandscapeMgr::update(double deltaTime) void LandscapeMgr::update(double deltaTime)
{ {
atmosphere->update(deltaTime); atmosphere->update(deltaTime);
landscape->update(deltaTime); landscape->update(deltaTime);
cardinalsPoints->update(deltaTime); cardinalsPoints->update(deltaTime);
// Compute the atmosphere color and intensity // Compute the atmosphere color and intensity
// Compute the sun position in local coordinate // Compute the sun position in local coordinate
SolarSystem* ssystem = (SolarSystem*)StelApp::getInstance().getModul eMgr().getModule("SolarSystem"); SolarSystem* ssystem = (SolarSystem*)StelApp::getInstance().getModul eMgr().getModule("SolarSystem");
StelCore* core = StelApp::getInstance().getCore(); StelCore* core = StelApp::getInstance().getCore();
Vec3d sunPos = ssystem->getSun()->getAltAzPosApparent(core); Vec3d sunPos = ssystem->getSun()->getAltAzPosApparent(core);
// Compute the moon position in local coordinate // Compute the moon position in local coordinate
Vec3d moonPos = ssystem->getMoon()->getAltAzPosApparent(core); Vec3d moonPos = ssystem->getMoon()->getAltAzPosApparent(core);
atmosphere->computeColor(core->getJDay(), sunPos, moonPos, atmosphere->computeColor(core->getJDay(), sunPos, moonPos,
ssystem->getMoon()->getPhaseAngle(ssystem->getEarth()->getHe liocentricEclipticPos()), ssystem->getMoon()->getPhaseAngle(ssystem->getEarth()->getHe liocentricEclipticPos()),
core, ssystem->getEclipseFactor(core), core->getCurrentLocat ion().latitude, core->getCurrentLocation().altitude, core, core->getCurrentLocation().latitude, core->getCurrentL ocation().altitude,
15.f, 40.f); // Temperature = 15c, relative humidity = 40 % 15.f, 40.f); // Temperature = 15c, relative humidity = 40 %
core->getSkyDrawer()->reportLuminanceInFov(3.75+atmosphere->getAvera geLuminance()*3.5, true); core->getSkyDrawer()->reportLuminanceInFov(3.75+atmosphere->getAvera geLuminance()*3.5, true);
// Compute the ground luminance based on every planets around // Compute the ground luminance based on every planets around
// TBD: Reactivate and verify this code!? Source, reference?
// float groundLuminance = 0; // float groundLuminance = 0;
// const vector<Planet*>& allPlanets = ssystem->getAllPlanets(); // const vector<Planet*>& allPlanets = ssystem->getAllPlanets();
// for (vector<Planet*>::const_iterator i=allPlanets.begin();i!=allPlan ets.end();++i) // for (vector<Planet*>::const_iterator i=allPlanets.begin();i!=allPlan ets.end();++i)
// { // {
// Vec3d pos = (*i)->getAltAzPos(core); // Vec3d pos = (*i)->getAltAzPos(core);
// pos.normalize(); // pos.normalize();
// if (pos[2] <= 0) // if (pos[2] <= 0)
// { // {
// // No need to take this body into the landscape illu mination computation // // No need to take this body into the landscape illu mination computation
// // because it is under the horizon // // because it is under the horizon
skipping to change at line 236 skipping to change at line 247
// // Luminance in cd/m^2 // // Luminance in cd/m^2
// groundLuminance += E/0.44*pos[2]*pos[2]; // 1m^2 fro m 1.5 m above the ground is 0.44 sr. // groundLuminance += E/0.44*pos[2]*pos[2]; // 1m^2 fro m 1.5 m above the ground is 0.44 sr.
// } // }
// } // }
// groundLuminance*=atmosphere->getFadeIntensity(); // groundLuminance*=atmosphere->getFadeIntensity();
// groundLuminance=atmosphere->getAverageLuminance()/50; // groundLuminance=atmosphere->getAverageLuminance()/50;
// qDebug() << "Atmosphere lum=" << atmosphere->getAverageLuminance() < < " ground lum=" << groundLuminance; // qDebug() << "Atmosphere lum=" << atmosphere->getAverageLuminance() < < " ground lum=" << groundLuminance;
// qDebug() << "Adapted Atmosphere lum=" << eye->adaptLuminance(atmosph ere->getAverageLuminance()) << " Adapted ground lum=" << eye->adaptLuminanc e(groundLuminance); // qDebug() << "Adapted Atmosphere lum=" << eye->adaptLuminance(atmosph ere->getAverageLuminance()) << " Adapted ground lum=" << eye->adaptLuminanc e(groundLuminance);
// compute global ground brightness in a simplistic way, directly in RGB // compute global ground brightness in a simplistic way, directly in RGB
float landscapeBrightness = 0;
sunPos.normalize(); sunPos.normalize();
moonPos.normalize(); moonPos.normalize();
// We define the brigthness zero when the sun is 8 degrees below the float landscapeBrightness=0.0f;
horizon. if (getFlagLandscapeUseMinimalBrightness())
float sinSunAngleRad = sin(qMin(M_PI_2, asin(sunPos[2])+8.*M_PI/180. {
)); // Setting from landscape.ini has priority if enabled
float initBrightness = getInitialLandscapeBrightness(); if (getFlagLandscapeSetsMinimalBrightness() && landscape->ge
// Setting for landscapes has priority if it enabled tLandscapeMinimalBrightness()>=0)
if (landscape->getLandscapeNightBrightness()>0 && getFlagLandscapeNi landscapeBrightness = landscape->getLandscapeMinimal
ghtBrightness()) Brightness();
initBrightness = landscape->getLandscapeNightBrightness(); else
landscapeBrightness = getDefaultMinimalBrightness();
if(sinSunAngleRad < -0.1/1.5 ) }
landscapeBrightness = initBrightness;
else // We define the solar brightness contribution zero when the sun is
landscapeBrightness = (initBrightness + 1.5*(sinSunAngleRad+ 8 degrees below the horizon.
0.1/1.5)); float sinSunAngle = sin(qMin(M_PI_2, asin(sunPos[2])+8.*M_PI/180.));
if(sinSunAngle > -0.1/1.5 )
landscapeBrightness += 1.5*(sinSunAngle+0.1/1.5);
// GZ: 2013-09-25 Take light pollution into account!
StelSkyDrawer* drawer=StelApp::getInstance().getCore()->getSkyDrawer
();
float pollutionAddonBrightness=(drawer->getBortleScaleIndex()-1.0f)*
0.025f; // 0..8, so we assume empirical linear brightening 0..0.02
float lunarAddonBrightness=0.f;
if (moonPos[2] > -0.1/1.5) if (moonPos[2] > -0.1/1.5)
landscapeBrightness += qMax(0.2/-12.*ssystem->getMoon()->get lunarAddonBrightness = qMax(0.2/-12.*ssystem->getMoon()->get
VMagnitude(core, true),0.)*moonPos[2]; VMagnitudeWithExtinction(core),0.)*moonPos[2];
landscapeBrightness += qMax(lunarAddonBrightness, pollutionAddonBrig
htness);
// TODO make this more generic for non-atmosphere planets // TODO make this more generic for non-atmosphere planets
if(atmosphere->getFadeIntensity() == 1) if(atmosphere->getFadeIntensity() == 1)
{ {
// If the atmosphere is on, a solar eclipse might darken the sky // If the atmosphere is on, a solar eclipse might darken the sky
// otherwise we just use the sun position calculation above // otherwise we just use the sun position calculation above
landscapeBrightness *= (atmosphere->getRealDisplayIntensityF actor()+0.1); landscapeBrightness *= (atmosphere->getRealDisplayIntensityF actor()+0.1);
} }
// TODO: should calculate dimming with solar eclipse even without at mosphere on
// Brightness can't be over 1.f (see https://bugs.launchpad.net/stel larium/+bug/1115364) // Brightness can't be over 1.f (see https://bugs.launchpad.net/stel larium/+bug/1115364)
if (landscapeBrightness>0.95) if (landscapeBrightness>0.95)
landscapeBrightness = 0.95; landscapeBrightness = 0.95;
// TODO: should calculate dimming with solar eclipse even without at mosphere on
if (core->getCurrentLocation().planetName.contains("Sun")) if (core->getCurrentLocation().planetName.contains("Sun"))
{ {
// NOTE: Simple workaround for brightness of landscape when observing from the Sun. // NOTE: Simple workaround for brightness of landscape when observing from the Sun.
landscape->setBrightness(1.f); landscape->setBrightness(1.f, 0.0f);
} }
else else
landscape->setBrightness(landscapeBrightness+0.05); { float lightscapeBrightness=0.0f;
// night pollution brightness is mixed in at -3...-8 degrees
.
if (sunPos[2]<-0.14f) lightscapeBrightness=1.0f;
else if (sunPos[2]<-0.05f) lightscapeBrightness = 1.0f-(sunP
os[2]+0.14)/(-0.05+0.14);
landscape->setBrightness(landscapeBrightness, lightscapeBrig
htness);
}
} }
void LandscapeMgr::draw(StelCore* core, class StelRenderer* renderer) void LandscapeMgr::draw(StelCore* core)
{ {
// Draw the atmosphere // Draw the atmosphere
atmosphere->draw(core, renderer); atmosphere->draw(core);
// Draw the landscape // Draw the landscape
landscape->draw(core, renderer); landscape->draw(core);
// Draw the cardinal points // Draw the cardinal points
cardinalsPoints->draw(core, renderer, StelApp::getInstance().getCore ()->getCurrentLocation().latitude); cardinalsPoints->draw(core, StelApp::getInstance().getCore()->getCur rentLocation().latitude);
} }
void LandscapeMgr::init() void LandscapeMgr::init()
{ {
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
Q_ASSERT(conf); Q_ASSERT(conf);
atmosphere = new Atmosphere(); atmosphere = new Atmosphere();
landscape = new LandscapeOldStyle(); landscape = new LandscapeOldStyle();
defaultLandscapeID = conf->value("init_location/landscape_name").toS tring(); defaultLandscapeID = conf->value("init_location/landscape_name").toS tring();
setCurrentLandscapeID(defaultLandscapeID); setCurrentLandscapeID(defaultLandscapeID);
setFlagLandscape(conf->value("landscape/flag_landscape", conf->value ("landscape/flag_ground", true).toBool()).toBool()); setFlagLandscape(conf->value("landscape/flag_landscape", conf->value ("landscape/flag_ground", true).toBool()).toBool());
setFlagFog(conf->value("landscape/flag_fog",true).toBool()); setFlagFog(conf->value("landscape/flag_fog",true).toBool());
setFlagAtmosphere(conf->value("landscape/flag_atmosphere", true).toB ool()); setFlagAtmosphere(conf->value("landscape/flag_atmosphere", true).toB ool());
setAtmosphereFadeDuration(conf->value("landscape/atmosphere_fade_dur ation",0.5).toFloat()); setAtmosphereFadeDuration(conf->value("landscape/atmosphere_fade_dur ation",0.5).toFloat());
setAtmosphereLightPollutionLuminance(conf->value("viewing/light_poll ution_luminance",0.0).toFloat()); setAtmosphereLightPollutionLuminance(conf->value("viewing/light_poll ution_luminance",0.0).toFloat());
setFlagUseLightPollutionFromDatabase(conf->value("viewing/flag_light _pollution_database", false).toBool());
cardinalsPoints = new Cardinals(); cardinalsPoints = new Cardinals();
cardinalsPoints->setFlagShow(conf->value("viewing/flag_cardinal_poin ts",true).toBool()); cardinalsPoints->setFlagShow(conf->value("viewing/flag_cardinal_poin ts",true).toBool());
setFlagLandscapeSetsLocation(conf->value("landscape/flag_landscape_s ets_location",false).toBool()); setFlagLandscapeSetsLocation(conf->value("landscape/flag_landscape_s ets_location",false).toBool());
setFlagLandscapeAutoSelection(conf->value("viewing/flag_landscape_au toselection", false).toBool()); setFlagLandscapeAutoSelection(conf->value("viewing/flag_landscape_au toselection", false).toBool());
// Set initial brightness for landscape. This feature has been added // Set minimal brightness for landscape. This feature has been added
for folks which say "landscape is super dark, please add light". --AW for folks which say "landscape is super dark, please add light". --AW
setInitialLandscapeBrightness(conf->value("landscape/initial_brightn setDefaultMinimalBrightness(conf->value("landscape/minimal_brightnes
ess", 0.01).toFloat()); s", 0.01).toFloat());
setFlagLandscapeNightBrightness(conf->value("landscape/flag_brightne setFlagLandscapeUseMinimalBrightness(conf->value("landscape/flag_min
ss",false).toBool()); imal_brightness", false).toBool());
setFlagLandscapeSetsMinimalBrightness(conf->value("landscape/flag_la
ndscape_sets_minimal_brightness",false).toBool());
setFlagAtmosphereAutoEnable(conf->value("viewing/flag_atmopshere_aut
o_enable",true).toBool());
bool ok =true; bool ok =true;
setAtmosphereBortleLightPollution(conf->value("stars/init_bortle_sca le",3).toInt(&ok)); setAtmosphereBortleLightPollution(conf->value("stars/init_bortle_sca le",3).toInt(&ok));
if (!ok) if (!ok)
{ {
conf->setValue("stars/init_bortle_scale",3); conf->setValue("stars/init_bortle_scale",3);
setAtmosphereBortleLightPollution(3); setAtmosphereBortleLightPollution(3);
ok = true; ok = true;
} }
StelApp *app = &StelApp::getInstance(); StelApp *app = &StelApp::getInstance();
connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n())); connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n()));
connect(app, SIGNAL(colorSchemeChanged(const QString&)), this, SLOT( setStelStyle(const QString&))); connect(app, SIGNAL(colorSchemeChanged(const QString&)), this, SLOT( setStelStyle(const QString&)));
QString displayGroup = N_("Display Options");
addAction("actionShow_Atmosphere", displayGroup, N_("Atmosphere"), "
atmosphereDisplayed", "A");
addAction("actionShow_Fog", displayGroup, N_("Fog"), "fogDisplayed",
"F");
addAction("actionShow_Cardinal_Points", displayGroup, N_("Cardinal p
oints"), "cardinalsPointsDisplayed", "Q");
addAction("actionShow_Ground", displayGroup, N_("Ground"), "landscap
eDisplayed", "G");
} }
void LandscapeMgr::setStelStyle(const QString& section) void LandscapeMgr::setStelStyle(const QString& section)
{ {
// Load colors from config file // Load colors from config file
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
QString defaultColor = conf->value(section+"/default_color").toStrin g(); QString defaultColor = conf->value(section+"/default_color").toStrin g();
setColorCardinalPoints(StelUtils::strToVec3f(conf->value(section+"/c ardinal_color", defaultColor).toString())); setColorCardinalPoints(StelUtils::strToVec3f(conf->value(section+"/c ardinal_color", defaultColor).toString()));
} }
bool LandscapeMgr::setCurrentLandscapeID(const QString& id) bool LandscapeMgr::setCurrentLandscapeID(const QString& id)
{ {
if (id.isEmpty()) if (id.isEmpty())
return false; return false;
// We want to lookup the landscape ID (dir) from the name. // We want to lookup the landscape ID (dir) from the name.
Landscape* newLandscape = NULL; Landscape* newLandscape = createFromFile(StelFileMgr::findFile("land
try scapes/" + id + "/landscape.ini"), id);
{
newLandscape = createFromFile(StelFileMgr::findFile("landsca
pes/" + id + "/landscape.ini"), id);
}
catch (std::runtime_error& e)
{
qWarning() << "ERROR while loading default landscape " << "l
andscapes/" + id + "/landscape.ini" << ", (" << e.what() << ")";
}
if (!newLandscape) if (!newLandscape)
{
qWarning() << "ERROR while loading default landscape " << "l
andscapes/" + id + "/landscape.ini";
return false; return false;
}
if (landscape) if (landscape)
{ {
// Copy display parameters from previous landscape to new on e // Copy display parameters from previous landscape to new on e
newLandscape->setFlagShow(landscape->getFlagShow()); newLandscape->setFlagShow(landscape->getFlagShow());
newLandscape->setFlagShowFog(landscape->getFlagShowFog()); newLandscape->setFlagShowFog(landscape->getFlagShowFog());
delete landscape; delete landscape;
landscape = newLandscape; landscape = newLandscape;
} }
currentLandscapeID = id; currentLandscapeID = id;
if (getFlagLandscapeSetsLocation()) if (getFlagLandscapeSetsLocation() && landscape->hasLocation())
{ {
StelApp::getInstance().getCore()->moveObserverTo(landscape-> getLocation()); StelApp::getInstance().getCore()->moveObserverTo(landscape-> getLocation());
// GZ Patch: allow change in fog, extinction, refraction par
ameters and light pollution
//QSettings* conf = StelApp::getInstance().getSettings();
//Q_ASSERT(conf);
StelSkyDrawer* drawer=StelApp::getInstance().getCore()->getS kyDrawer(); StelSkyDrawer* drawer=StelApp::getInstance().getCore()->getS kyDrawer();
if (landscape->getDefaultFogSetting() >-1) if (landscape->getDefaultFogSetting() >-1)
{ {
setFlagFog((bool) landscape->getDefaultFogSetting()) ; setFlagFog((bool) landscape->getDefaultFogSetting()) ;
landscape->setFlagShowFog((bool) landscape->getDefau ltFogSetting()); landscape->setFlagShowFog((bool) landscape->getDefau ltFogSetting());
} }
if (landscape->getDefaultBortleIndex() > 0) if (landscape->getDefaultBortleIndex() > 0)
{ {
setAtmosphereBortleLightPollution(landscape->getDefa ultBortleIndex()); setAtmosphereBortleLightPollution(landscape->getDefa ultBortleIndex());
drawer->setBortleScale(landscape->getDefaultBortleIn dex()); drawer->setBortleScaleIndex(landscape->getDefaultBor tleIndex());
} }
if (landscape->getDefaultAtmosphericExtinction() >= 0.0) if (landscape->getDefaultAtmosphericExtinction() >= 0.0)
{ {
drawer->setExtinctionCoefficient(landscape->getDefau ltAtmosphericExtinction()); drawer->setExtinctionCoefficient(landscape->getDefau ltAtmosphericExtinction());
} }
if (landscape->getDefaultAtmosphericTemperature() > -273.15) if (landscape->getDefaultAtmosphericTemperature() > -273.15)
{ {
drawer->setAtmosphereTemperature(landscape->getDefau ltAtmosphericTemperature()); drawer->setAtmosphereTemperature(landscape->getDefau ltAtmosphericTemperature());
} }
if (landscape->getDefaultAtmosphericPressure() >= 0.0) if (landscape->getDefaultAtmosphericPressure() >= 0.0)
skipping to change at line 400 skipping to change at line 426
} }
else if (landscape->getDefaultAtmosphericPressure() == -1.0) else if (landscape->getDefaultAtmosphericPressure() == -1.0)
{ {
// compute standard pressure for standard atmosphere in given altitude if landscape.ini coded as atmospheric_pressure=-1 // compute standard pressure for standard atmosphere in given altitude if landscape.ini coded as atmospheric_pressure=-1
// International altitude formula found in Wikipedia . // International altitude formula found in Wikipedia .
double alt=landscape->getLocation().altitude; double alt=landscape->getLocation().altitude;
double p=1013.25*std::pow(1-(0.0065*alt)/288.15, 5.2 55); double p=1013.25*std::pow(1-(0.0065*alt)/288.15, 5.2 55);
drawer->setAtmospherePressure(p); drawer->setAtmospherePressure(p);
} }
} }
// else qDebug() << "Will not set new location; Landscape location: planet: " << landscape->getLocation().planetName << "name: " << landscape-> getLocation().name;
return true; return true;
} }
bool LandscapeMgr::setCurrentLandscapeName(const QString& name) bool LandscapeMgr::setCurrentLandscapeName(const QString& name)
{ {
if (name.isEmpty()) if (name.isEmpty())
return false; return false;
QMap<QString,QString> nameToDirMap = getNameToDirMap(); QMap<QString,QString> nameToDirMap = getNameToDirMap();
if (nameToDirMap.find(name)!=nameToDirMap.end()) if (nameToDirMap.find(name)!=nameToDirMap.end())
skipping to change at line 450 skipping to change at line 477
landscape->setFlagShow(displayed); landscape->setFlagShow(displayed);
emit landscapeDisplayedChanged(displayed); emit landscapeDisplayedChanged(displayed);
} }
} }
bool LandscapeMgr::getFlagLandscape() const bool LandscapeMgr::getFlagLandscape() const
{ {
return landscape->getFlagShow(); return landscape->getFlagShow();
} }
bool LandscapeMgr::getIsLandscapeFullyVisible() const
{
return landscape->getIsFullyVisible();
}
bool LandscapeMgr::getFlagUseLightPollutionFromDatabase() const
{
return flagLightPollutionFromDatabase;
}
void LandscapeMgr::setFlagUseLightPollutionFromDatabase(const bool usage)
{
if (flagLightPollutionFromDatabase != usage)
{
flagLightPollutionFromDatabase = usage;
emit lightPollutionUsageChanged(usage);
}
}
void LandscapeMgr::setFlagFog(const bool displayed) void LandscapeMgr::setFlagFog(const bool displayed)
{ {
if (landscape->getFlagShowFog() != displayed) { if (landscape->getFlagShowFog() != displayed) {
landscape->setFlagShowFog(displayed); landscape->setFlagShowFog(displayed);
emit fogDisplayedChanged(displayed); emit fogDisplayedChanged(displayed);
} }
} }
bool LandscapeMgr::getFlagFog() const bool LandscapeMgr::getFlagFog() const
{ {
skipping to change at line 473 skipping to change at line 519
void LandscapeMgr::setFlagLandscapeAutoSelection(bool enableAutoSelect) void LandscapeMgr::setFlagLandscapeAutoSelection(bool enableAutoSelect)
{ {
flagLandscapeAutoSelection = enableAutoSelect; flagLandscapeAutoSelection = enableAutoSelect;
} }
bool LandscapeMgr::getFlagLandscapeAutoSelection() const bool LandscapeMgr::getFlagLandscapeAutoSelection() const
{ {
return flagLandscapeAutoSelection; return flagLandscapeAutoSelection;
} }
void LandscapeMgr::setFlagAtmosphereAutoEnable(bool b)
{
flagAtmosphereAutoEnabling = b;
}
bool LandscapeMgr::getFlagAtmosphereAutoEnable() const
{
return flagAtmosphereAutoEnabling;
}
/********************************************************************* /*********************************************************************
Retrieve list of the names of all the available landscapes Retrieve list of the names of all the available landscapes
*********************************************************************/ *********************************************************************/
QStringList LandscapeMgr::getAllLandscapeNames() const QStringList LandscapeMgr::getAllLandscapeNames() const
{ {
QMap<QString,QString> nameToDirMap = getNameToDirMap(); QMap<QString,QString> nameToDirMap = getNameToDirMap();
QStringList result; QStringList result;
// We just look over the map of names to IDs and extract the keys // We just look over the map of names to IDs and extract the keys
foreach (QString i, nameToDirMap.keys()) foreach (QString i, nameToDirMap.keys())
skipping to change at line 580 skipping to change at line 636
/////////////////////////////////////////////////////////////////////////// //////////// /////////////////////////////////////////////////////////////////////////// ////////////
// Atmosphere // Atmosphere
//! Set flag for displaying Atmosphere //! Set flag for displaying Atmosphere
void LandscapeMgr::setFlagAtmosphere(const bool displayed) void LandscapeMgr::setFlagAtmosphere(const bool displayed)
{ {
if (atmosphere->getFlagShow() != displayed) { if (atmosphere->getFlagShow() != displayed) {
atmosphere->setFlagShow(displayed); atmosphere->setFlagShow(displayed);
StelApp::getInstance().getCore()->getSkyDrawer()->setFlagHas Atmosphere(displayed); StelApp::getInstance().getCore()->getSkyDrawer()->setFlagHas Atmosphere(displayed);
emit atmosphereDisplayedChanged(displayed); emit atmosphereDisplayedChanged(displayed);
if (StelApp::getInstance().getSettings()->value("landscape/f
lag_fog", true).toBool())
setFlagFog(displayed); // sync of visibility of fog
because this is atmospheric phenomena
} }
} }
//! Get flag for displaying Atmosphere //! Get flag for displaying Atmosphere
bool LandscapeMgr::getFlagAtmosphere() const bool LandscapeMgr::getFlagAtmosphere() const
{ {
return atmosphere->getFlagShow(); return atmosphere->getFlagShow();
} }
//! Set atmosphere fade duration in s //! Set atmosphere fade duration in s
void LandscapeMgr::setAtmosphereFadeDuration(float f) void LandscapeMgr::setAtmosphereFadeDuration(const float f)
{ {
atmosphere->setFadeDuration(f); atmosphere->setFadeDuration(f);
} }
//! Get atmosphere fade duration in s //! Get atmosphere fade duration in s
float LandscapeMgr::getAtmosphereFadeDuration() const float LandscapeMgr::getAtmosphereFadeDuration() const
{ {
return atmosphere->getFadeDuration(); return atmosphere->getFadeDuration();
} }
//! Set light pollution luminance level //! Set light pollution luminance level
void LandscapeMgr::setAtmosphereLightPollutionLuminance(float f) void LandscapeMgr::setAtmosphereLightPollutionLuminance(const float f)
{ {
atmosphere->setLightPollutionLuminance(f); atmosphere->setLightPollutionLuminance(f);
} }
//! Get light pollution luminance level //! Get light pollution luminance level
float LandscapeMgr::getAtmosphereLightPollutionLuminance() const float LandscapeMgr::getAtmosphereLightPollutionLuminance() const
{ {
return atmosphere->getLightPollutionLuminance(); return atmosphere->getLightPollutionLuminance();
} }
//! Set the light pollution following the Bortle Scale //! Set the light pollution following the Bortle Scale
void LandscapeMgr::setAtmosphereBortleLightPollution(int bIndex) void LandscapeMgr::setAtmosphereBortleLightPollution(const int bIndex)
{ {
// This is an empirical formula // This is an empirical formula
setAtmosphereLightPollutionLuminance(qMax(0.,0.0020*std::pow(bIndex- setAtmosphereLightPollutionLuminance(qMax(0.,0.0004*std::pow(bIndex-
1, 2.1))); 1, 2.1)));
emit lightPollutionChanged();
} }
//! Get the light pollution following the Bortle Scale //! Get the light pollution following the Bortle Scale
int LandscapeMgr::getAtmosphereBortleLightPollution() int LandscapeMgr::getAtmosphereBortleLightPollution() const
{ {
return (int)std::pow(getAtmosphereLightPollutionLuminance()/0.0020, 1./2.1) + 1; return (int)std::pow(getAtmosphereLightPollutionLuminance()/0.0004, 1./2.1) + 1;
} }
void LandscapeMgr::setZRotation(float d) void LandscapeMgr::setZRotation(const float d)
{ {
if (landscape) if (landscape)
landscape->setZRotation(d); landscape->setZRotation(d);
} }
float LandscapeMgr::getLuminance() float LandscapeMgr::getLuminance() const
{ {
return atmosphere->getRealDisplayIntensityFactor(); return atmosphere->getRealDisplayIntensityFactor();
} }
float LandscapeMgr::getAtmosphereAverageLuminance() const
{
return atmosphere->getAverageLuminance();
}
Landscape* LandscapeMgr::createFromFile(const QString& landscapeFile, const QString& landscapeId) Landscape* LandscapeMgr::createFromFile(const QString& landscapeFile, const QString& landscapeId)
{ {
QSettings landscapeIni(landscapeFile, StelIniFormat); QSettings landscapeIni(landscapeFile, StelIniFormat);
QString s; QString s;
if (landscapeIni.status() != QSettings::NoError) if (landscapeIni.status() != QSettings::NoError)
{ {
qWarning() << "ERROR parsing landscape.ini file: " << QDir:: toNativeSeparators(landscapeFile); qWarning() << "ERROR parsing landscape.ini file: " << QDir:: toNativeSeparators(landscapeFile);
s = ""; s = "";
} }
else else
s = landscapeIni.value("landscape/type").toString(); s = landscapeIni.value("landscape/type").toString();
Landscape* ldscp = NULL; Landscape* ldscp = NULL;
if (s=="old_style") if (s=="old_style")
ldscp = new LandscapeOldStyle(); ldscp = new LandscapeOldStyle();
else if (s=="spherical") else if (s=="spherical")
ldscp = new LandscapeSpherical(); ldscp = new LandscapeSpherical();
else if (s=="fisheye") else if (s=="fisheye")
ldscp = new LandscapeFisheye(); ldscp = new LandscapeFisheye();
else if (s=="polygonal")
ldscp = new LandscapePolygonal();
else else
{ {
qDebug() << "Unknown landscape type: \"" << s << "\""; qDebug() << "Unknown landscape type: \"" << s << "\"";
// to avoid making this a fatal error, will load as a fishey e // to avoid making this a fatal error, will load as a fishey e
// if this fails, it just won't draw // if this fails, it just won't draw
ldscp = new LandscapeFisheye(); ldscp = new LandscapeFisheye();
} }
ldscp->load(landscapeIni, landscapeId); ldscp->load(landscapeIni, landscapeId);
return ldscp; return ldscp;
} }
QString LandscapeMgr::nameToID(const QString& name) QString LandscapeMgr::nameToID(const QString& name) const
{ {
QMap<QString,QString> nameToDirMap = getNameToDirMap(); QMap<QString,QString> nameToDirMap = getNameToDirMap();
if (nameToDirMap.find(name)!=nameToDirMap.end()) if (nameToDirMap.find(name)!=nameToDirMap.end())
{ {
Q_ASSERT(0); Q_ASSERT(0);
return "error"; return "error";
} }
else else
{ {
return nameToDirMap[name]; return nameToDirMap[name];
} }
} }
/************************************************************************** ** /************************************************************************** **
get a map of landscape name (from landscape.ini name field) to ID (dir nam e) get a map of landscape name (from landscape.ini name field) to ID (dir nam e)
************************************************************************** **/ ************************************************************************** **/
QMap<QString,QString> LandscapeMgr::getNameToDirMap() const QMap<QString,QString> LandscapeMgr::getNameToDirMap() const
{ {
QSet<QString> landscapeDirs;
QMap<QString,QString> result; QMap<QString,QString> result;
try QSet<QString> landscapeDirs = StelFileMgr::listContents("landscapes"
{ ,StelFileMgr::Directory);
landscapeDirs = StelFileMgr::listContents("landscapes",StelF
ileMgr::Directory);
}
catch (std::runtime_error& e)
{
qDebug() << "ERROR while trying list landscapes:" << e.what(
);
}
foreach (const QString& dir, landscapeDirs) foreach (const QString& dir, landscapeDirs)
{ {
try QString fName = StelFileMgr::findFile("landscapes/" + dir +
"/landscape.ini");
if (!fName.isEmpty())
{ {
QSettings landscapeIni(StelFileMgr::findFile("landsc apes/" + dir + "/landscape.ini"), StelIniFormat); QSettings landscapeIni(fName, StelIniFormat);
QString k = landscapeIni.value("landscape/name").toS tring(); QString k = landscapeIni.value("landscape/name").toS tring();
result[k] = dir; result[k] = dir;
} }
catch (std::runtime_error& e)
{
//qDebug << "WARNING: unable to successfully read la
ndscape.ini file from landscape " << dir;
}
} }
return result; return result;
} }
QString LandscapeMgr::installLandscapeFromArchive(QString sourceFilePath, b ool display, bool toMainDirectory) QString LandscapeMgr::installLandscapeFromArchive(QString sourceFilePath, c onst bool display, const bool toMainDirectory)
{ {
Q_UNUSED(toMainDirectory); Q_UNUSED(toMainDirectory);
if (!QFile::exists(sourceFilePath)) if (!QFile::exists(sourceFilePath))
{ {
qDebug() << "LandscapeMgr: File does not exist:" << QDir::to NativeSeparators(sourceFilePath); qDebug() << "LandscapeMgr: File does not exist:" << QDir::to NativeSeparators(sourceFilePath);
emit errorUnableToOpen(sourceFilePath); emit errorUnableToOpen(sourceFilePath);
return QString(); return QString();
} }
QDir parentDestinationDir; QDir parentDestinationDir;
//TODO: Fix the "for all users" option
parentDestinationDir.setPath(StelFileMgr::getUserDir()); parentDestinationDir.setPath(StelFileMgr::getUserDir());
if (!parentDestinationDir.exists("landscapes")) if (!parentDestinationDir.exists("landscapes"))
{ {
//qDebug() << "LandscapeMgr: No 'landscapes' subdirectory ex ists in" << parentDestinationDir.absolutePath(); //qDebug() << "LandscapeMgr: No 'landscapes' subdirectory ex ists in" << parentDestinationDir.absolutePath();
if (!parentDestinationDir.mkdir("landscapes")) if (!parentDestinationDir.mkdir("landscapes"))
{ {
qWarning() << "LandscapeMgr: Unable to install lands cape: Unable to create sub-directory 'landscapes' in" << QDir::toNativeSepa rators(parentDestinationDir.absolutePath()); qWarning() << "LandscapeMgr: Unable to install lands cape: Unable to create sub-directory 'landscapes' in" << QDir::toNativeSepa rators(parentDestinationDir.absolutePath());
emit errorUnableToOpen(QDir::cleanPath(parentDestina tionDir.filePath("landscapes")));//parentDestinationDir.absolutePath() emit errorUnableToOpen(QDir::cleanPath(parentDestina tionDir.filePath("landscapes")));//parentDestinationDir.absolutePath()
return QString(); return QString();
} }
} }
QDir destinationDir (parentDestinationDir.absoluteFilePath("landscap es")); QDir destinationDir (parentDestinationDir.absoluteFilePath("landscap es"));
KZip sourceArchive(sourceFilePath); QZipReader reader(sourceFilePath);
if(!sourceArchive.open(QIODevice::ReadOnly)) if (reader.status() != QZipReader::NoError)
{ {
qWarning() << "LandscapeMgr: Unable to open as a ZIP archive :" << QDir::toNativeSeparators(sourceFilePath); qWarning() << "LandscapeMgr: Unable to open as a ZIP archive :" << QDir::toNativeSeparators(sourceFilePath);
emit errorNotArchive(); emit errorNotArchive();
return QString(); return QString();
} }
//Detect top directory //Detect top directory
const KArchiveDirectory * archiveTopDirectory = NULL; QString topDir, iniPath;
QStringList topLevelContents = sourceArchive.directory()->entries(); QList<QZipReader::FileInfo> infoList = reader.fileInfoList();
if(topLevelContents.contains("landscape.ini")) foreach(QZipReader::FileInfo info, infoList)
{
//If the landscape archive has no top level directory...
//(test case is "tulipfield" from the Stellarium Wiki)
archiveTopDirectory = sourceArchive.directory();
}
else
{ {
foreach (QString entryPath, topLevelContents) QFileInfo fileInfo(info.filePath);
if (fileInfo.fileName() == "landscape.ini")
{ {
if (sourceArchive.directory()->entry(entryPath)->isD iniPath = info.filePath;
irectory()) topDir = fileInfo.dir().path();
{ break;
if((dynamic_cast<const KArchiveDirectory*>(s
ourceArchive.directory()->entry(entryPath)))->entries().contains("landscape
.ini"))
{
archiveTopDirectory = dynamic_cast<c
onst KArchiveDirectory*>(sourceArchive.directory()->entry(entryPath));
break;
}
}
} }
} }
if (archiveTopDirectory == NULL) if (topDir.isEmpty())
{ {
qWarning() << "LandscapeMgr: Unable to install landscape. Th ere is no directory that contains a 'landscape.ini' file in the source arch ive."; qWarning() << "LandscapeMgr: Unable to install landscape. Th ere is no directory that contains a 'landscape.ini' file in the source arch ive.";
emit errorNotArchive(); emit errorNotArchive();
return QString(); return QString();
} }
/*
qDebug() << "LandscapeMgr: Contents of the source archive:" << endl
<< "- top level direcotory:" << archiveTopDirectory
->name() << endl
<< "- contents:" << archiveTopDirectory->entries();
*/
//Check if the top directory name is unique
//TODO: Prompt rename? Rename silently?
/*
if (destinationDir.exists(archiveTopDirectory->name()))
{
qWarning() << "LandscapeMgr: Unable to install landscape. A
directory named" << archiveTopDirectory->name() << "already exists in" << d
estinationDir.absolutePath();
return QString();
}
*/
//Determine the landscape's identifier //Determine the landscape's identifier
QString landscapeID = archiveTopDirectory->name(); QString landscapeID = QFileInfo(topDir).fileName();
if (landscapeID.length() < 2) if (landscapeID.length() < 2)
{ {
//If the archive has no top level directory (landscapeID is // If the archive has no top level directory
"/"), // use the first 65 characters of its file name for an ident
//use the first 65 characters of its file name for an identi ifier
fier
QFileInfo sourceFileInfo(sourceFilePath); QFileInfo sourceFileInfo(sourceFilePath);
landscapeID = sourceFileInfo.baseName().left(65); landscapeID = sourceFileInfo.baseName().left(65);
} }
//Check for duplicate IDs //Check for duplicate IDs
if (getAllLandscapeIDs().contains(landscapeID)) if (getAllLandscapeIDs().contains(landscapeID))
{ {
qWarning() << "LandscapeMgr: Unable to install landscape. A landscape with the ID" << landscapeID << "already exists."; qWarning() << "LandscapeMgr: Unable to install landscape. A landscape with the ID" << landscapeID << "already exists.";
emit errorNotUnique(landscapeID); emit errorNotUnique(landscapeID);
return QString(); return QString();
} }
//Read the .ini file and check if the landscape name is unique //Read the .ini file and check if the landscape name is unique
QTemporaryFile tempLandscapeIni("landscapeXXXXXX.ini"); QTemporaryFile tempLandscapeIni("landscapeXXXXXX.ini");
if (tempLandscapeIni.open()) if (tempLandscapeIni.open())
{ {
const KZipFileEntry * archLandscapeIni = static_cast<const K QByteArray iniData = reader.fileData(iniPath);
ZipFileEntry*>(archiveTopDirectory->entry("landscape.ini")); tempLandscapeIni.write(iniData);
tempLandscapeIni.write(archLandscapeIni->createDevice()->rea
dAll());
tempLandscapeIni.close(); tempLandscapeIni.close();
QSettings confLandscapeIni(tempLandscapeIni.fileName(), Stel IniFormat); QSettings confLandscapeIni(tempLandscapeIni.fileName(), Stel IniFormat);
QString landscapeName = confLandscapeIni.value("landscape/na me").toString(); QString landscapeName = confLandscapeIni.value("landscape/na me").toString();
if (getAllLandscapeNames().contains(landscapeName)) if (getAllLandscapeNames().contains(landscapeName))
{ {
qWarning() << "LandscapeMgr: Unable to install lands cape. There is already a landscape named" << landscapeName; qWarning() << "LandscapeMgr: Unable to install lands cape. There is already a landscape named" << landscapeName;
emit errorNotUnique(landscapeName); emit errorNotUnique(landscapeName);
return QString(); return QString();
} }
} }
//Copy the landscape directory to the target //Copy the landscape directory to the target
//sourceArchive.directory()->copyTo(destinationDir.absolutePath());
//This case already has been handled - and commented out - above. :) //This case already has been handled - and commented out - above. :)
if(destinationDir.exists(landscapeID)) if(destinationDir.exists(landscapeID))
{ {
qWarning() << "LandscapeMgr: A subdirectory" << landscapeID << "already exists in" << QDir::toNativeSeparators(destinationDir.absoluteP ath()) << "Its contents may be overwritten."; qWarning() << "LandscapeMgr: A subdirectory" << landscapeID << "already exists in" << QDir::toNativeSeparators(destinationDir.absoluteP ath()) << "Its contents may be overwritten.";
} }
else if(!destinationDir.mkdir(landscapeID)) else if(!destinationDir.mkdir(landscapeID))
{ {
qWarning() << "LandscapeMgr: Unable to install landscape. Un able to create" << landscapeID << "directory in" << QDir::toNativeSeparator s(destinationDir.absolutePath()); qWarning() << "LandscapeMgr: Unable to install landscape. Un able to create" << landscapeID << "directory in" << QDir::toNativeSeparator s(destinationDir.absolutePath());
emit errorUnableToOpen(QDir::cleanPath(destinationDir.filePa th(landscapeID))); emit errorUnableToOpen(QDir::cleanPath(destinationDir.filePa th(landscapeID)));
return QString(); return QString();
} }
destinationDir.cd(landscapeID); destinationDir.cd(landscapeID);
QString destinationDirPath = destinationDir.absolutePath(); foreach(QZipReader::FileInfo info, infoList)
QStringList landscapeFileEntries = archiveTopDirectory->entries();
foreach (QString entry, landscapeFileEntries)
{ {
const KArchiveEntry * archEntry = archiveTopDirectory->entry QFileInfo fileInfo(info.filePath);
(entry); if (info.isFile && fileInfo.dir().path() == topDir)
if(archEntry->isFile())
{ {
static_cast<const KZipFileEntry*>(archEntry)->copyTo QByteArray data = reader.fileData(info.filePath);
(destinationDirPath); QFile out(destinationDir.filePath(fileInfo.fileName(
)));
if (out.open(QIODevice::WriteOnly))
{
out.write(data);
out.close();
}
else
{
qWarning() << "LandscapeMgr: cannot open " <
< QDir::toNativeSeparators(fileInfo.absoluteFilePath());
}
} }
} }
reader.close();
sourceArchive.close();
//If necessary, make the new landscape the current landscape //If necessary, make the new landscape the current landscape
if (display) if (display)
{ {
setCurrentLandscapeID(landscapeID); setCurrentLandscapeID(landscapeID);
} }
//Make sure that everyone knows that the list of available landscape s has changed //Make sure that everyone knows that the list of available landscape s has changed
emit landscapesChanged(); emit landscapesChanged();
qDebug() << "LandscapeMgr: Successfully installed landscape director y" << landscapeID << "to" << QDir::toNativeSeparators(destinationDir.absolu tePath()); qDebug() << "LandscapeMgr: Successfully installed landscape director y" << landscapeID << "to" << QDir::toNativeSeparators(destinationDir.absolu tePath());
return landscapeID; return landscapeID;
} }
bool LandscapeMgr::removeLandscape(QString landscapeID) bool LandscapeMgr::removeLandscape(const QString landscapeID)
{ {
if (landscapeID.isEmpty()) if (landscapeID.isEmpty())
{ {
qWarning() << "LandscapeMgr: Error! No landscape ID passed t o removeLandscape()."; qWarning() << "LandscapeMgr: Error! No landscape ID passed t o removeLandscape().";
return false; return false;
} }
if (packagedLandscapeIDs.contains(landscapeID)) if (packagedLandscapeIDs.contains(landscapeID))
{ {
qWarning() << "LandscapeMgr: Landscapes that are part of the default installation cannot be removed."; qWarning() << "LandscapeMgr: Landscapes that are part of the default installation cannot be removed.";
skipping to change at line 935 skipping to change at line 966
setCurrentLandscapeID(getDefaultLandscapeID()); setCurrentLandscapeID(getDefaultLandscapeID());
} }
//Make sure that everyone knows that the list of available landscape s has changed //Make sure that everyone knows that the list of available landscape s has changed
emit landscapesChanged(); emit landscapesChanged();
return true; return true;
} }
QString LandscapeMgr::getLandscapePath(QString landscapeID) QString LandscapeMgr::getLandscapePath(const QString landscapeID) const
{ {
QString result; QString result;
//Is this necessary? This function is private. //Is this necessary? This function is private.
if (landscapeID.isEmpty()) if (landscapeID.isEmpty())
return result; return result;
try result = StelFileMgr::findFile("landscapes/" + landscapeID, StelFile
{ Mgr::Directory);
result = StelFileMgr::findFile("landscapes/" + landscapeID, if (result.isEmpty())
StelFileMgr::Directory);
}
catch (std::runtime_error &e)
{ {
qWarning() << "LandscapeMgr: Error! Unable to find" << lands capeID << ":" << e.what(); qWarning() << "LandscapeMgr: Error! Unable to find" << lands capeID;
return result; return result;
} }
return result; return result;
} }
QString LandscapeMgr::loadLandscapeName(QString landscapeID) QString LandscapeMgr::loadLandscapeName(const QString landscapeID)
{ {
QString landscapeName; QString landscapeName;
if (landscapeID.isEmpty()) if (landscapeID.isEmpty())
{ {
qWarning() << "LandscapeMgr: Error! No landscape ID passed t o loadLandscapeName()."; qWarning() << "LandscapeMgr: Error! No landscape ID passed t o loadLandscapeName().";
return landscapeName; return landscapeName;
} }
QString landscapePath = getLandscapePath(landscapeID); QString landscapePath = getLandscapePath(landscapeID);
if (landscapePath.isEmpty()) if (landscapePath.isEmpty())
skipping to change at line 983 skipping to change at line 1011
landscapeName = landscapeSettings.value("landscape/name").to String(); landscapeName = landscapeSettings.value("landscape/name").to String();
} }
else else
{ {
qWarning() << "LandscapeMgr: Error! Landscape directory" << QDir::toNativeSeparators(landscapePath) << "does not contain a 'landscape.i ni' file"; qWarning() << "LandscapeMgr: Error! Landscape directory" << QDir::toNativeSeparators(landscapePath) << "does not contain a 'landscape.i ni' file";
} }
return landscapeName; return landscapeName;
} }
quint64 LandscapeMgr::loadLandscapeSize(QString landscapeID) quint64 LandscapeMgr::loadLandscapeSize(const QString landscapeID) const
{ {
quint64 landscapeSize = 0; quint64 landscapeSize = 0;
if (landscapeID.isEmpty()) if (landscapeID.isEmpty())
{ {
qWarning() << "LandscapeMgr: Error! No landscape ID passed t o loadLandscapeSize()."; qWarning() << "LandscapeMgr: Error! No landscape ID passed t o loadLandscapeSize().";
return landscapeSize; return landscapeSize;
} }
QString landscapePath = getLandscapePath(landscapeID); QString landscapePath = getLandscapePath(landscapeID);
if (landscapePath.isEmpty()) if (landscapePath.isEmpty())
skipping to change at line 1008 skipping to change at line 1036
{ {
//qDebug() << "name:" << file.baseName() << "size:" << file. size(); //qDebug() << "name:" << file.baseName() << "size:" << file. size();
landscapeSize += file.size(); landscapeSize += file.size();
} }
return landscapeSize; return landscapeSize;
} }
QString LandscapeMgr::getDescription() const QString LandscapeMgr::getDescription() const
{ {
QString lang = StelApp::getInstance().getLocaleMgr().getAppLanguage QString lang, desc, descFile, locDescriptionFile, engDescriptionFile
(); ;
if (!QString("pt_BR zh_CN zh_HK zh_TW").contains(lang)) bool hasFile = true;
{
lang = lang.split("_").at(0); lang = StelApp::getInstance().getLocaleMgr().getAppLanguage();
} locDescriptionFile = StelFileMgr::findFile("landscapes/" + getCurren
QString descriptionFile = StelFileMgr::findFile("landscapes/" + getC tLandscapeID(), StelFileMgr::Directory) + "/description." + lang + ".utf8";
urrentLandscapeID(), StelFileMgr::Directory) + "/description." + lang + ".u engDescriptionFile = StelFileMgr::findFile("landscapes/" + getCurren
tf8"; tLandscapeID(), StelFileMgr::Directory) + "/description.en.utf8";
QString desc;
// OK. Check the file with full name of locale
if(QFileInfo(descriptionFile).exists()) if (!QFileInfo(locDescriptionFile).exists())
{ {
QFile file(descriptionFile); // Oops... File not exists! What about short name of locale
file.open(QIODevice::ReadOnly | QIODevice::Text); ?
QTextStream in(&file); lang = lang.split("_").at(0);
in.setCodec("UTF-8"); locDescriptionFile = StelFileMgr::findFile("landscapes/" + g
desc = in.readAll(); etCurrentLandscapeID(), StelFileMgr::Directory) + "/description." + lang +
file.close(); ".utf8";
}
// Check localized description for landscape
if (!locDescriptionFile.isEmpty() && QFileInfo(locDescriptionFile).e
xists())
{
descFile = locDescriptionFile;
}
// OK. Localized description of landscape not exists. What about eng
lish description of its?
else if (!engDescriptionFile.isEmpty() && QFileInfo(engDescriptionFi
le).exists())
{
descFile = engDescriptionFile;
}
// That file not exists too? OK. Will be used description from lands
cape.ini file.
else
{
hasFile = false;
}
if (hasFile)
{
QFile file(descFile);
if(file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file);
in.setCodec("UTF-8");
desc = in.readAll();
file.close();
}
} }
else else
{ {
desc = QString("<h2>%1</h2>").arg(q_(landscape->getName())); desc = QString("<h2>%1</h2>").arg(q_(landscape->getName()));
desc += landscape->getDescription(); desc += landscape->getDescription();
} }
return desc; return desc;
} }
/*
// GZ: Addition to identify landscape transparency. Used for development an
d debugging only, should be commented out in release builds.
// Also, StelMovementMgr l.382 event->accept() must be commented out for th
is here to work!
void LandscapeMgr::handleMouseClicks(QMouseEvent *event)
{
switch (event->button())
{
case Qt::LeftButton :
if (event->type()==QEvent::MouseButtonRelease)
{
Vec3d v;
StelApp::getInstance().getCore()->getProjection(Stel
Core::FrameAltAz, StelCore::RefractionOff)->unProject(event->x(),event->y()
,v);
v.normalize();
float trans=landscape->getOpacity(v);
qDebug() << "Landscape opacity at screen X=" << even
t->x() << ", Y=" << event->y() << ": " << trans;
}
break;
default: break;
}
// do not event->accept(), so that it is forwarded to other modules.
return;
}
*/
 End of changes. 83 change blocks. 
221 lines changed or deleted 287 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/