Merge pull request #2593 from Atlante45/display_models_metadata

Display models metadata
This commit is contained in:
Andrzej Kapolka 2014-04-04 15:18:18 -07:00
commit 1f3a5d09d9
4 changed files with 92 additions and 129 deletions

View file

@ -8,11 +8,10 @@
#include <QDialog> #include <QDialog>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QEventLoop>
#include <QGridLayout> #include <QGridLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QMessageBox> #include <QMessageBox>
#include <QStringListModel> #include <QNetworkAccessManager>
#include <QUrl> #include <QUrl>
#include <QXmlStreamReader> #include <QXmlStreamReader>
@ -33,27 +32,42 @@ static const QString KEY_NAME = "Key";
static const QString LOADING_MSG = "Loading..."; static const QString LOADING_MSG = "Loading...";
static const QString ERROR_MSG = "Error loading files"; static const QString ERROR_MSG = "Error loading files";
static const QString DO_NOT_MODIFY_TAG = "DoNotModify";
enum ModelMetaData { enum ModelMetaData {
NAME, NAME,
CREATOR, CREATOR,
UPLOAD_DATE, DATE_ADDED,
TYPE, TOTAL_SIZE,
GENDER, POLY_NUM,
TAGS,
MODEL_METADATA_COUNT MODEL_METADATA_COUNT
}; };
static const QString propertiesNames[MODEL_METADATA_COUNT] = { static const QString propertiesNames[MODEL_METADATA_COUNT] = {
"Name", "Name",
"Creator", "Creator",
"Upload Date", "Date Added",
"Type", "Total Size",
"Gender" "Poly#",
"Tags"
};
static const QString propertiesIds[MODEL_METADATA_COUNT] = {
DO_NOT_MODIFY_TAG,
"Creator",
"Date-Added",
"Total-Size",
"Poly-Num",
"Tags"
}; };
ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) : ModelsBrowser::ModelsBrowser(ModelType modelsType, QWidget* parent) :
QWidget(parent), QWidget(parent),
_handler(new ModelHandler(modelsType)) _handler(new ModelHandler(modelsType))
{ {
connect(_handler, SIGNAL(doneDownloading()), SLOT(resizeView()));
connect(_handler, SIGNAL(updated()), SLOT(resizeView()));
// Connect handler // Connect handler
_handler->connect(this, SIGNAL(startDownloading()), SLOT(download())); _handler->connect(this, SIGNAL(startDownloading()), SLOT(download()));
_handler->connect(_handler, SIGNAL(doneDownloading()), SLOT(update())); _handler->connect(_handler, SIGNAL(doneDownloading()), SLOT(update()));
@ -86,7 +100,7 @@ void ModelsBrowser::applyFilter(const QString &filter) {
for (int k = 0; k < filters.count(); ++k) { for (int k = 0; k < filters.count(); ++k) {
match = false; match = false;
for (int j = 0; j < MODEL_METADATA_COUNT; ++j) { for (int j = 0; j < MODEL_METADATA_COUNT; ++j) {
if (model->item(i, j)->text().contains(filters.at(k))) { if (model->item(i, j)->text().contains(filters.at(k), Qt::CaseInsensitive)) {
match = true; match = true;
break; break;
} }
@ -106,6 +120,12 @@ void ModelsBrowser::applyFilter(const QString &filter) {
_handler->unlockModel(); _handler->unlockModel();
} }
void ModelsBrowser::resizeView() {
for (int i = 0; i < MODEL_METADATA_COUNT; ++i) {
_view.resizeColumnToContents(i);
}
}
void ModelsBrowser::browse() { void ModelsBrowser::browse() {
QDialog dialog; QDialog dialog;
dialog.setWindowTitle("Browse models"); dialog.setWindowTitle("Browse models");
@ -145,8 +165,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) :
_initiateExit(false), _initiateExit(false),
_type(modelsType) _type(modelsType)
{ {
connect(&_downloader, SIGNAL(done(QNetworkReply::NetworkError)), SLOT(downloadFinished()));
// set headers data // set headers data
QStringList headerData; QStringList headerData;
for (int i = 0; i < MODEL_METADATA_COUNT; ++i) { for (int i = 0; i < MODEL_METADATA_COUNT; ++i) {
@ -156,9 +174,6 @@ ModelHandler::ModelHandler(ModelType modelsType, QWidget* parent) :
} }
void ModelHandler::download() { void ModelHandler::download() {
// Query models list
queryNewFiles();
_lock.lockForWrite(); _lock.lockForWrite();
if (_initiateExit) { if (_initiateExit) {
_lock.unlock(); _lock.unlock();
@ -169,10 +184,25 @@ void ModelHandler::download() {
loadingItem->setEnabled(false); loadingItem->setEnabled(false);
_model.appendRow(loadingItem); _model.appendRow(loadingItem);
_lock.unlock(); _lock.unlock();
// Query models list
queryNewFiles();
} }
void ModelHandler::update() { void ModelHandler::update() {
// Will be implemented in my next PR _lock.lockForWrite();
if (_initiateExit) {
_lock.unlock();
return;
}
for (int i = 0; i < _model.rowCount(); ++i) {
QUrl url(_model.item(i,0)->data(Qt::UserRole).toString());
QNetworkAccessManager* accessManager = new QNetworkAccessManager(this);
QNetworkRequest request(url);
accessManager->head(request);
connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*)));
}
_lock.unlock();
} }
void ModelHandler::exit() { void ModelHandler::exit() {
@ -180,7 +210,6 @@ void ModelHandler::exit() {
_initiateExit = true; _initiateExit = true;
// Disconnect everything // Disconnect everything
_downloader.disconnect();
disconnect(); disconnect();
thread()->disconnect(); thread()->disconnect();
@ -191,12 +220,16 @@ void ModelHandler::exit() {
_lock.unlock(); _lock.unlock();
} }
void ModelHandler::downloadFinished() { void ModelHandler::downloadFinished(QNetworkReply* reply) {
if (_downloader.getData().startsWith("<?xml")) { QByteArray data = reply->readAll();
parseXML(_downloader.getData());
if (!data.isEmpty()) {
parseXML(data);
} else { } else {
qDebug() << _downloader.getData(); parseHeaders(reply);
} }
reply->deleteLater();
sender()->deleteLater();
} }
void ModelHandler::queryNewFiles(QString marker) { void ModelHandler::queryNewFiles(QString marker) {
@ -219,7 +252,11 @@ void ModelHandler::queryNewFiles(QString marker) {
// Download // Download
url.setQuery(query); url.setQuery(query);
_downloader.download(url); QNetworkAccessManager* accessManager = new QNetworkAccessManager(this);
QNetworkRequest request(url);
accessManager->get(request);
connect(accessManager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*)));
} }
bool ModelHandler::parseXML(QByteArray xmlFile) { bool ModelHandler::parseXML(QByteArray xmlFile) {
@ -266,18 +303,9 @@ bool ModelHandler::parseXML(QByteArray xmlFile) {
QList<QStandardItem*> model; QList<QStandardItem*> model;
model << new QStandardItem(QFileInfo(xml.text().toString()).baseName()); model << new QStandardItem(QFileInfo(xml.text().toString()).baseName());
model.first()->setData(PUBLIC_URL + "/" + xml.text().toString(), Qt::UserRole); model.first()->setData(PUBLIC_URL + "/" + xml.text().toString(), Qt::UserRole);
for (int i = 1; i < MODEL_METADATA_COUNT; ++i) {
// Rand properties for now (Will be taken out in the next PR) model << new QStandardItem();
static QString creator[] = {"Ryan", "Philip", "Andzrej"}; }
static QString type[] = {"human", "beast", "pet", "elfe"};
static QString gender[] = {"male", "female", "none"};
model << new QStandardItem(creator[randIntInRange(0, 2)]);
model << new QStandardItem(QDate(randIntInRange(2013, 2014),
randIntInRange(1, 12),
randIntInRange(1, 30)).toString());
model << new QStandardItem(type[randIntInRange(0, 3)]);
model << new QStandardItem(gender[randIntInRange(0, 2)]);
////////////////////////////////////////////////////////////
_model.appendRow(model); _model.appendRow(model);
} }
@ -312,9 +340,32 @@ bool ModelHandler::parseXML(QByteArray xmlFile) {
_lock.unlock(); _lock.unlock();
if (!truncated) { if (!truncated) {
qDebug() << "Emitting...";
emit doneDownloading(); emit doneDownloading();
} }
return true; return true;
} }
bool ModelHandler::parseHeaders(QNetworkReply* reply) {
_lock.lockForWrite();
QList<QStandardItem*> items = _model.findItems(QFileInfo(reply->url().toString()).baseName());
if (items.isEmpty() || items.first()->text() == DO_NOT_MODIFY_TAG) {
return false;
}
for (int i = 0; i < MODEL_METADATA_COUNT; ++i) {
for (int k = 1; k < reply->rawHeaderPairs().count(); ++k) {
QString key = reply->rawHeaderPairs().at(k).first.data();
QString item = reply->rawHeaderPairs().at(k).second.data();
if (key == propertiesIds[i]) {
_model.item(_model.indexFromItem(items.first()).row(), i)->setText(item);
}
}
}
_lock.unlock();
emit updated();
return true;
}

View file

@ -9,13 +9,10 @@
#ifndef __hifi__ModelsBrowser__ #ifndef __hifi__ModelsBrowser__
#define __hifi__ModelsBrowser__ #define __hifi__ModelsBrowser__
#include <QAbstractTableModel>
#include <QStandardItem>
#include <QTreeView>
#include <QVector>
#include <QReadWriteLock> #include <QReadWriteLock>
#include <QStandardItemModel>
#include <QTreeView>
#include "FileDownloader.h"
enum ModelType { enum ModelType {
Head, Head,
@ -33,7 +30,7 @@ public:
signals: signals:
void doneDownloading(); void doneDownloading();
void doneUpdating(); void updated();
public slots: public slots:
void download(); void download();
@ -41,17 +38,17 @@ public slots:
void exit(); void exit();
private slots: private slots:
void downloadFinished(); void downloadFinished(QNetworkReply* reply);
private: private:
bool _initiateExit; bool _initiateExit;
ModelType _type; ModelType _type;
FileDownloader _downloader;
QReadWriteLock _lock; QReadWriteLock _lock;
QStandardItemModel _model; QStandardItemModel _model;
void queryNewFiles(QString marker = QString()); void queryNewFiles(QString marker = QString());
bool parseXML(QByteArray xmlFile); bool parseXML(QByteArray xmlFile);
bool parseHeaders(QNetworkReply* reply);
}; };
@ -71,6 +68,7 @@ public slots:
private slots: private slots:
void applyFilter(const QString& filter); void applyFilter(const QString& filter);
void resizeView();
private: private:
ModelHandler* _handler; ModelHandler* _handler;

View file

@ -1,45 +0,0 @@
//
// FileDownloader.cpp
// hifi
//
// Created by Clement Brisset on 3/14/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
//
#include <QUrl>
#include <QNetworkRequest>
#include <QEventLoop>
#include <QTimer>
#include "FileDownloader.h"
FileDownloader::FileDownloader(QObject* parent) : QObject(parent) {
connect(&_networkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(processReply(QNetworkReply*)));
}
void FileDownloader::download(const QUrl& dataURL, QNetworkAccessManager::Operation operation) {
QNetworkRequest request(dataURL);
_downloadedData.clear();
switch (operation) {
case QNetworkAccessManager::GetOperation:
_networkAccessManager.get(request);
break;
case QNetworkAccessManager::HeadOperation:
_networkAccessManager.head(request);
break;
default:
emit done(QNetworkReply::ProtocolInvalidOperationError);
break;
}
}
void FileDownloader::processReply(QNetworkReply *reply) {
if (reply->error() == QNetworkReply::NoError) {
_downloadedData = reply->readAll();
}
reply->deleteLater();
emit done(reply->error());
}

View file

@ -1,41 +0,0 @@
//
// FileDownloader.h
// hifi
//
// Created by Clement Brisset on 3/14/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
//
#ifndef __hifi__FileDownloader__
#define __hifi__FileDownloader__
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QThread>
class FileDownloader : public QObject {
Q_OBJECT
public:
FileDownloader(QObject* parent = NULL);
QByteArray getData() const { return _downloadedData; }
signals:
void done(QNetworkReply::NetworkError error);
public slots:
void download(const QUrl& dataURL, QNetworkAccessManager::Operation operation = QNetworkAccessManager::GetOperation);
private slots:
void processReply(QNetworkReply* reply);
private:
QNetworkAccessManager _networkAccessManager;
QByteArray _downloadedData;
};
#endif /* defined(__hifi__FileDownloader__) */