From 388f8d480a3b59fe791c8b1abd31832ecabf0627 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 18 Mar 2014 13:58:23 -0700 Subject: [PATCH] Added the model browser --- interface/src/ModelBrowser.cpp | 127 +++++++++++++++++++++++++++++++++ interface/src/ModelBrowser.h | 59 +++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 interface/src/ModelBrowser.cpp create mode 100644 interface/src/ModelBrowser.h diff --git a/interface/src/ModelBrowser.cpp b/interface/src/ModelBrowser.cpp new file mode 100644 index 0000000000..cf401d6b75 --- /dev/null +++ b/interface/src/ModelBrowser.cpp @@ -0,0 +1,127 @@ +// +// ModelBrowser.cpp +// hifi +// +// Created by Clement on 3/17/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ModelBrowser.h" + +static const int DOWNLOAD_TIMEOUT = 1000; +static const QString CONTAINER_NAME = "Contents"; +static const QString KEY_NAME = "Key"; + +ModelBrowser::ModelBrowser(QWidget* parent) : + QWidget(parent), + _downloader(QUrl(S3_URL)) +{ +} + +QString ModelBrowser::browse(ModelType modelType) { + _models.clear(); + if (!parseXML(modelType)) { + return QString(); + } + + + QDialog dialog(this); + dialog.setWindowTitle("Browse models"); + + QGridLayout* layout = new QGridLayout(&dialog); + dialog.setLayout(layout); + + QLineEdit* searchBar = new QLineEdit(&dialog); + layout->addWidget(searchBar, 0, 0); + + ListView* listView = new ListView(&dialog); + listView->setEditTriggers(QAbstractItemView::NoEditTriggers); + layout->addWidget(listView, 1, 0); + listView->connect(searchBar, SIGNAL(textChanged(const QString&)), SLOT(keyboardSearch(const QString&))); + dialog.connect(listView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(accept())); + + QStringListModel* model = new QStringListModel(_models.keys(), listView); + model->sort(0); + listView->setModel(model); + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + layout->addWidget(buttons, 2, 0); + dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); + dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); + + if (dialog.exec() == QDialog::Rejected) { + return QString(); + } + + QString selectedKey = model->data(listView->currentIndex(), Qt::DisplayRole).toString(); + return _models[selectedKey]; +} + +void ModelBrowser::browseHead() { + QString model = browse(Head); + emit selectedHead(model); +} + +void ModelBrowser::browseSkeleton() { + QString model = browse(Skeleton); + emit selectedSkeleton(model); +} + +bool ModelBrowser::parseXML(ModelType modelType) { + _downloader.waitForFile(DOWNLOAD_TIMEOUT); + QString location; + switch (modelType) { + case Head: + location = HEAD_MODELS_LOCATION; + break; + case Skeleton: + location = SKELETON_MODELS_LOCATION; + break; + default: + return false; + } + + QXmlStreamReader xml(_downloader.getData()); + QRegExp rx(location + "[^/]*fst"); + + // Read xml until the end or an error is detected + while(!xml.atEnd() && !xml.hasError()) { + if(xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == CONTAINER_NAME) { + while(!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == CONTAINER_NAME)) { + // If a file is find, process it + if(xml.tokenType() == QXmlStreamReader::StartElement && xml.name() == KEY_NAME) { + xml.readNext(); + if (rx.exactMatch(xml.text().toString())) { + // Add the found file to the list + _models.insert(QFileInfo(xml.text().toString()).baseName(), + S3_URL + "/" + xml.text().toString()); + } + } + xml.readNext(); + } + } + xml.readNext(); + } + + // Error handling + if(xml.hasError()) { + _models.clear(); + QMessageBox::critical(this, + "ModelBrowser::ModelBrowser()", + xml.errorString(), + QMessageBox::Ok); + return false; + } + return true; +} \ No newline at end of file diff --git a/interface/src/ModelBrowser.h b/interface/src/ModelBrowser.h new file mode 100644 index 0000000000..9b7cf51ab3 --- /dev/null +++ b/interface/src/ModelBrowser.h @@ -0,0 +1,59 @@ +// +// ModelBrowser.h +// hifi +// +// Created by Clement on 3/17/14. +// Copyright (c) 2014 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__ModelBrowser__ +#define __hifi__ModelBrowser__ + +#include + +#include +#include + +static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; +static const QString HEAD_MODELS_LOCATION = "meshes/"; +static const QString SKELETON_MODELS_LOCATION = "meshes/"; + +enum ModelType { + Head, + Skeleton +}; + +class ModelBrowser : public QWidget { + Q_OBJECT + +public: + ModelBrowser(QWidget* parent = NULL); + + QString browse(ModelType modelType); + +signals: + void selectedHead(QString); + void selectedSkeleton(QString); + +public slots: + void browseHead(); + void browseSkeleton(); + +private: + FileDownloader _downloader; + QHash _models; + + bool parseXML(ModelType modelType); +}; + +class ListView : public QListView { + Q_OBJECT +public: + ListView(QWidget* parent) : QListView(parent) {} + public slots: + void keyboardSearch(const QString& text) { + QAbstractItemView::keyboardSearch(text); + } +}; + +#endif /* defined(__hifi__ModelBrowser__) */