MultiLevelJsonBase.cpp   MultiLevelJsonBase.cpp 
skipping to change at line 26 skipping to change at line 26
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, U SA.
*/ */
#include "MultiLevelJsonBase.hpp" #include "MultiLevelJsonBase.hpp"
#include "StelJsonParser.hpp" #include "StelJsonParser.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
#include "StelProjector.hpp" #include "StelProjector.hpp"
#include "StelCore.hpp" #include "StelCore.hpp"
#include "kfilterdev.h" #include "kfilterdev.h"
#include "StelUtils.hpp"
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QHttp> #include <QHttp>
#include <QUrl> #include <QUrl>
#include <QBuffer> #include <QBuffer>
#include <QThread> #include <QThread>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
#include <stdexcept> #include <stdexcept>
// #if QT_VERSION >= 0x040500
// #include <QNetworkDiskCache> // #include <QNetworkDiskCache>
// #include <QDesktopServices>
// #endif
// Init statics // Init statics
QNetworkAccessManager* MultiLevelJsonBase::networkAccessManager = NULL; QNetworkAccessManager* MultiLevelJsonBase::networkAccessManager = NULL;
QNetworkAccessManager& MultiLevelJsonBase::getNetworkAccessManager() QNetworkAccessManager& MultiLevelJsonBase::getNetworkAccessManager()
{ {
if (networkAccessManager==NULL) if (networkAccessManager==NULL)
{ {
networkAccessManager = new QNetworkAccessManager(&StelApp::g etInstance()); networkAccessManager = new QNetworkAccessManager(&StelApp::g etInstance());
// #if QT_VERSION >= 0x040500 // Cache on JSON files doesn't work, and I don't know why.
// There may be a problem in Qt for text objects caching (compression is ac
tivated in cache)
// QNetworkDiskCache* cache = new QNetworkDiskCache(networkAcce ssManager); // QNetworkDiskCache* cache = new QNetworkDiskCache(networkAcce ssManager);
// QString cachePath = QDesktopServices::storageLocation(QDeskt // QString cachePath = StelApp::getInstance().getCacheDir();
opServices::CacheLocation);
// if (cachePath.isEmpty())
// {
// cachePath = StelApp::getInstance().getFileMgr().getU
serDir()+"/cache";
// }
// cache->setCacheDirectory(cachePath+"/JSONCache"); // cache->setCacheDirectory(cachePath+"/JSONCache");
// networkAccessManager->setCache(cache); // networkAccessManager->setCache(cache);
// #endif
connect(networkAccessManager, SIGNAL(finished(QNetworkReply* )), &StelApp::getInstance(), SLOT(reportFileDownloadFinished(QNetworkReply* ))); connect(networkAccessManager, SIGNAL(finished(QNetworkReply* )), &StelApp::getInstance(), SLOT(reportFileDownloadFinished(QNetworkReply* )));
} }
return *networkAccessManager; return *networkAccessManager;
} }
/************************************************************************* /*************************************************************************
Class used to load a JSON file in a thread Class used to load a JSON file in a thread
*************************************************************************/ *************************************************************************/
class JsonLoadThread : public QThread class JsonLoadThread : public QThread
{ {
skipping to change at line 98 skipping to change at line 92
buf.open(QIODevice::ReadOnly); buf.open(QIODevice::ReadOnly);
tile->temporaryResultMap = MultiLevelJsonBase::loadFromJSON( buf, qZcompressed, gzCompressed); tile->temporaryResultMap = MultiLevelJsonBase::loadFromJSON( buf, qZcompressed, gzCompressed);
} }
catch (std::runtime_error e) catch (std::runtime_error e)
{ {
qWarning() << "WARNING : Can't parse loaded JSON description : " << e.what(); qWarning() << "WARNING : Can't parse loaded JSON description : " << e.what();
tile->errorOccured = true; tile->errorOccured = true;
} }
} }
MultiLevelJsonBase::MultiLevelJsonBase(MultiLevelJsonBase* parent) : QObjec t(parent) MultiLevelJsonBase::MultiLevelJsonBase(MultiLevelJsonBase* parent) : StelSk yLayer(parent)
{ {
errorOccured = false; errorOccured = false;
httpReply = NULL; httpReply = NULL;
downloading = false; downloading = false;
loadThread = NULL; loadThread = NULL;
loadingState = false; loadingState = false;
lastPercent = 0; lastPercent = 0;
// Avoid tiles to be deleted just after constructed // Avoid tiles to be deleted just after constructed
timeWhenDeletionScheduled = -1.; timeWhenDeletionScheduled = -1.;
deletionDelay = 2.; deletionDelay = 2.;
skipping to change at line 126 skipping to change at line 120
void MultiLevelJsonBase::initFromUrl(const QString& url) void MultiLevelJsonBase::initFromUrl(const QString& url)
{ {
const MultiLevelJsonBase* parent = qobject_cast<MultiLevelJsonBase*> (QObject::parent()); const MultiLevelJsonBase* parent = qobject_cast<MultiLevelJsonBase*> (QObject::parent());
contructorUrl = url; contructorUrl = url;
if (!url.startsWith("http://") && (parent==NULL || !parent->getBaseU rl().startsWith("http://"))) if (!url.startsWith("http://") && (parent==NULL || !parent->getBaseU rl().startsWith("http://")))
{ {
// Assume a local file // Assume a local file
QString fileName; QString fileName;
try try
{ {
fileName = StelApp::getInstance().getFileMgr().findF ile(url); fileName = StelFileMgr::findFile(url);
} }
catch (std::runtime_error e) catch (std::runtime_error e)
{ {
try try
{ {
if (parent==NULL) if (parent==NULL)
throw std::runtime_error("NULL paren t"); throw std::runtime_error("NULL paren t");
fileName = StelApp::getInstance().getFileMgr ().findFile(parent->getBaseUrl()+url); fileName = StelFileMgr::findFile(parent->get BaseUrl()+url);
} }
catch (std::runtime_error e) catch (std::runtime_error e)
{ {
qWarning() << "WARNING : Can't find JSON des cription: " << url << ": " << e.what(); qWarning() << "WARNING : Can't find JSON des cription: " << url << ": " << e.what();
errorOccured = true; errorOccured = true;
return; return;
} }
} }
QFileInfo finf(fileName); QFileInfo finf(fileName);
baseUrl = finf.absolutePath()+'/'; baseUrl = finf.absolutePath()+'/';
skipping to change at line 179 skipping to change at line 173
{ {
qurl.setUrl(url); qurl.setUrl(url);
} }
else else
{ {
Q_ASSERT(parent->getBaseUrl().startsWith("http://")) ; Q_ASSERT(parent->getBaseUrl().startsWith("http://")) ;
qurl.setUrl(parent->getBaseUrl()+url); qurl.setUrl(parent->getBaseUrl()+url);
} }
Q_ASSERT(httpReply==NULL); Q_ASSERT(httpReply==NULL);
QNetworkRequest req(qurl); QNetworkRequest req(qurl);
req.setRawHeader("User-Agent", StelApp::getApplicationName() .toAscii()); req.setRawHeader("User-Agent", StelUtils::getApplicationName ().toAscii());
httpReply = getNetworkAccessManager().get(req); httpReply = getNetworkAccessManager().get(req);
//qDebug() << "Started downloading " << httpReply->request() .url().path(); //qDebug() << "Started downloading " << httpReply->request() .url().path();
Q_ASSERT(httpReply->error()==QNetworkReply::NoError); Q_ASSERT(httpReply->error()==QNetworkReply::NoError);
//qDebug() << httpReply->attribute(QNetworkRequest::SourceIs FromCacheAttribute).toBool(); //qDebug() << httpReply->attribute(QNetworkRequest::SourceIs FromCacheAttribute).toBool();
connect(httpReply, SIGNAL(finished()), this, SLOT(downloadFi nished())); connect(httpReply, SIGNAL(finished()), this, SLOT(downloadFi nished()));
//connect(httpReply, SIGNAL(error(QNetworkReply::NetworkErro r)), this, SLOT(downloadError(QNetworkReply::NetworkError))); //connect(httpReply, SIGNAL(error(QNetworkReply::NetworkErro r)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
//connect(httpReply, SIGNAL(destroyed()), this, SLOT(replyDe stroyed())); //connect(httpReply, SIGNAL(destroyed()), this, SLOT(replyDe stroyed()));
downloading = true; downloading = true;
QString turl = qurl.toString(); QString turl = qurl.toString();
baseUrl = turl.left(turl.lastIndexOf('/')+1); baseUrl = turl.left(turl.lastIndexOf('/')+1);
skipping to change at line 202 skipping to change at line 196
// Constructor from a map used for JSON files with more than 1 level // Constructor from a map used for JSON files with more than 1 level
void MultiLevelJsonBase::initFromQVariantMap(const QVariantMap& map) void MultiLevelJsonBase::initFromQVariantMap(const QVariantMap& map)
{ {
const MultiLevelJsonBase* parent = qobject_cast<MultiLevelJsonBase*> (QObject::parent()); const MultiLevelJsonBase* parent = qobject_cast<MultiLevelJsonBase*> (QObject::parent());
if (parent!=NULL) if (parent!=NULL)
{ {
baseUrl = parent->getBaseUrl(); baseUrl = parent->getBaseUrl();
contructorUrl = parent->contructorUrl + "/?"; contructorUrl = parent->contructorUrl + "/?";
} }
loadFromQVariantMap(map); try
{
loadFromQVariantMap(map);
}
catch (std::runtime_error e)
{
qWarning() << "WARNING: invalid variant map: " << e.what();
errorOccured = true;
return;
}
downloading = false; downloading = false;
} }
// Destructor // Destructor
MultiLevelJsonBase::~MultiLevelJsonBase() MultiLevelJsonBase::~MultiLevelJsonBase()
{ {
if (httpReply) if (httpReply)
{ {
//qDebug() << "Abort: " << httpReply->request().url().path() ; //qDebug() << "Abort: " << httpReply->request().url().path() ;
//httpReply->abort(); //httpReply->abort();
// This line should not be commented, but I have to keep it // TODO: This line should not be commented, but I have to ke
because of a Qt bug. ep it because of a Qt bug.
// It cause a nasty memory leak, but prevents an even more n // It should be fixed with Qt 4.5.1
asty // It causes a nasty memory leak, but prevents an even more
nasty
//httpReply->deleteLater(); //httpReply->deleteLater();
httpReply = NULL; httpReply = NULL;
} }
if (loadThread && loadThread->isRunning()) if (loadThread && loadThread->isRunning())
{ {
//qDebug() << "--> Abort thread " << contructorUrl; //qDebug() << "--> Abort thread " << contructorUrl;
disconnect(loadThread, SIGNAL(finished()), this, SLOT(jsonLo adFinished())); disconnect(loadThread, SIGNAL(finished()), this, SLOT(jsonLo adFinished()));
// The thread is currently running, it needs to be properly stopped // The thread is currently running, it needs to be properly stopped
if (loadThread->wait(1)==false) if (loadThread->wait(1)==false)
{ {
skipping to change at line 267 skipping to change at line 271
QVariantMap MultiLevelJsonBase::loadFromJSON(QIODevice& input, bool qZcompr essed, bool gzCompressed) QVariantMap MultiLevelJsonBase::loadFromJSON(QIODevice& input, bool qZcompr essed, bool gzCompressed)
{ {
StelJsonParser parser; StelJsonParser parser;
QVariantMap map; QVariantMap map;
if (qZcompressed && input.size()>0) if (qZcompressed && input.size()>0)
{ {
QByteArray ar = qUncompress(input.readAll()); QByteArray ar = qUncompress(input.readAll());
input.close(); input.close();
QBuffer buf(&ar); QBuffer buf(&ar);
buf.open(QIODevice::ReadOnly); buf.open(QIODevice::ReadOnly);
map = parser.parse(buf).toMap(); map = parser.parse(&buf).toMap();
buf.close(); buf.close();
} }
else if (gzCompressed) else if (gzCompressed)
{ {
QIODevice* d = KFilterDev::device(&input, "application/x-gzi p", false); QIODevice* d = KFilterDev::device(&input, "application/x-gzi p", false);
d->open(QIODevice::ReadOnly); d->open(QIODevice::ReadOnly);
map = parser.parse(*d).toMap(); map = parser.parse(d).toMap();
d->close(); d->close();
delete d; delete d;
} }
else else
{ {
map = parser.parse(input).toMap(); map = parser.parse(&input).toMap();
} }
if (map.isEmpty()) if (map.isEmpty())
throw std::runtime_error("empty JSON file, cannot load"); throw std::runtime_error("empty JSON file, cannot load");
return map; return map;
} }
// Called when the download for the JSON file terminated // Called when the download for the JSON file terminated
void MultiLevelJsonBase::downloadFinished() void MultiLevelJsonBase::downloadFinished()
{ {
skipping to change at line 336 skipping to change at line 340
// Called when the element is fully loaded from the JSON file // Called when the element is fully loaded from the JSON file
void MultiLevelJsonBase::jsonLoadFinished() void MultiLevelJsonBase::jsonLoadFinished()
{ {
loadThread->wait(); loadThread->wait();
delete loadThread; delete loadThread;
loadThread = NULL; loadThread = NULL;
downloading = false; downloading = false;
if (errorOccured) if (errorOccured)
return; return;
loadFromQVariantMap(temporaryResultMap); try
{
loadFromQVariantMap(temporaryResultMap);
}
catch (std::runtime_error e)
{
qWarning() << "WARNING: invalid variant map: " << e.what();
errorOccured = true;
return;
}
} }
// Delete all the subtiles which were not displayed since more than lastDra wTrigger seconds // Delete all the subtiles which were not displayed since more than lastDra wTrigger seconds
void MultiLevelJsonBase::deleteUnusedSubTiles() void MultiLevelJsonBase::deleteUnusedSubTiles()
{ {
if (subTiles.isEmpty()) if (subTiles.isEmpty())
return; return;
const double now = StelApp::getInstance().getTotalRunTime(); const double now = StelApp::getInstance().getTotalRunTime();
bool deleteAll = true; bool deleteAll = true;
foreach (MultiLevelJsonBase* tile, subTiles) foreach (MultiLevelJsonBase* tile, subTiles)
 End of changes. 16 change blocks. 
25 lines changed or deleted 37 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/