diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index 41ce16c229..d178397fc2 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -11,6 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include #include @@ -31,18 +32,30 @@ static const QString IS_TRUNCATED_NAME = "IsTruncated"; static const QString CONTAINER_NAME = "Contents"; static const QString KEY_NAME = "Key"; -ScriptItem::ScriptItem(const QString& filename, const QString& fullPath) : +TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type) : + _parent(parent), + _type(type) { +}; + +TreeNodeScript::TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin) : + TreeNodeBase(NULL, TREE_NODE_TYPE_SCRIPT), _filename(filename), - _fullPath(fullPath) { + _fullPath(fullPath), + _origin(origin) +{ +}; + +TreeNodeFolder::TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent) : + TreeNodeBase(parent, TREE_NODE_TYPE_FOLDER), + _foldername(foldername) { }; ScriptsModel::ScriptsModel(QObject* parent) : - QAbstractListModel(parent), + QAbstractItemModel(parent), _loadingScripts(false), _localDirectory(), _fsWatcher(), - _localFiles(), - _remoteFiles() + _treeNodes() { _localDirectory.setFilter(QDir::Files | QDir::Readable); @@ -57,23 +70,31 @@ ScriptsModel::ScriptsModel(QObject* parent) : reloadRemoteFiles(); } +QModelIndex ScriptsModel::index(int row, int column, const QModelIndex& parent) const { + return QModelIndex(); +} + +QModelIndex ScriptsModel::parent(const QModelIndex& child) const { + return QModelIndex(); +} + QVariant ScriptsModel::data(const QModelIndex& index, int role) const { - const QList* files = NULL; + /*const QList* files = NULL; int row = 0; bool isLocal = index.row() < _localFiles.size(); - if (isLocal) { - files = &_localFiles; - row = index.row(); - } else { - files = &_remoteFiles; - row = index.row() - _localFiles.size(); - } + if (isLocal) { + files = &_localFiles; + row = index.row(); + } else { + files = &_remoteFiles; + row = index.row() - _localFiles.size(); + } if (role == Qt::DisplayRole) { return QVariant((*files)[row]->getFilename() + (isLocal ? " (local)" : "")); } else if (role == ScriptPath) { return QVariant((*files)[row]->getFullPath()); - } + }*/ return QVariant(); } @@ -81,9 +102,14 @@ int ScriptsModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } - return _localFiles.length() + _remoteFiles.length(); + return 0;// _localFiles.length() + _remoteFiles.length(); } +int ScriptsModel::columnCount(const QModelIndex& parent) const { + return 1; +} + + void ScriptsModel::updateScriptsLocation(const QString& newPath) { _fsWatcher.removePath(_localDirectory.absolutePath()); @@ -93,7 +119,7 @@ void ScriptsModel::updateScriptsLocation(const QString& newPath) { if (!_localDirectory.absolutePath().isEmpty()) { _fsWatcher.addPath(_localDirectory.absolutePath()); } - } + } reloadLocalFiles(); } @@ -101,8 +127,12 @@ void ScriptsModel::updateScriptsLocation(const QString& newPath) { void ScriptsModel::reloadRemoteFiles() { if (!_loadingScripts) { _loadingScripts = true; - while (!_remoteFiles.isEmpty()) { - delete _remoteFiles.takeFirst(); + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + TreeNodeBase* node = _treeNodes.at(i); + if (typeid(*node) == typeid(TreeNodeScript) && static_cast(node)->getOrigin() == SCRIPT_ORIGIN_REMOTE) { + delete node; + _treeNodes.removeAt(i); + } } requestRemoteFiles(); } @@ -121,7 +151,6 @@ void ScriptsModel::requestRemoteFiles(QString marker) { QNetworkRequest request(url); QNetworkReply* reply = networkAccessManager.get(request); connect(reply, SIGNAL(finished()), SLOT(downloadFinished())); - } void ScriptsModel::downloadFinished() { @@ -170,7 +199,7 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { xml.readNext(); lastKey = xml.text().toString(); if (jsRegex.exactMatch(xml.text().toString())) { - _remoteFiles.append(new ScriptItem(lastKey.mid(MODELS_LOCATION.length()), S3_URL + "/" + lastKey)); + _treeNodes.append(new TreeNodeScript(lastKey.mid(MODELS_LOCATION.length()), S3_URL + "/" + lastKey, SCRIPT_ORIGIN_REMOTE)); } } xml.readNext(); @@ -178,7 +207,7 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { } xml.readNext(); } - + rebuildTree(); endResetModel(); // Error handling @@ -198,8 +227,15 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { void ScriptsModel::reloadLocalFiles() { beginResetModel(); - while (!_localFiles.isEmpty()) { - delete _localFiles.takeFirst(); + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + TreeNodeBase* node = _treeNodes.at(i); + qDebug() << "deleting local " << i << " " << typeid(*node).name(); + if (node->getType() == TREE_NODE_TYPE_SCRIPT && + static_cast(node)->getOrigin() == SCRIPT_ORIGIN_LOCAL) + { + delete node; + _treeNodes.removeAt(i); + } } _localDirectory.refresh(); @@ -207,8 +243,35 @@ void ScriptsModel::reloadLocalFiles() { const QFileInfoList localFiles = _localDirectory.entryInfoList(); for (int i = 0; i < localFiles.size(); i++) { QFileInfo file = localFiles[i]; - _localFiles.append(new ScriptItem(file.fileName(), file.absoluteFilePath())); + _treeNodes.append(new TreeNodeScript(file.fileName(), file.absoluteFilePath(), SCRIPT_ORIGIN_LOCAL)); } - + rebuildTree(); endResetModel(); } + +void ScriptsModel::rebuildTree() { + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + + if (_treeNodes.at(i)->getType() == TREE_NODE_TYPE_FOLDER) { + delete _treeNodes.at(i); + _treeNodes.removeAt(i); + } + } + QHash folders; + for (int i = 0; i < _treeNodes.size(); i++) { + TreeNodeBase* node = _treeNodes.at(i); + qDebug() << "blup" << i << typeid(*node).name(); + if (typeid(*node) == typeid(TreeNodeScript)) { + TreeNodeScript* script = static_cast(node); + TreeNodeFolder* parent = NULL; + QString hash; + QStringList pathList = script->getFilename().split(tr("/")); + QStringList::const_iterator pathIterator; + for (pathIterator = pathList.constBegin(); pathIterator != pathList.constEnd(); ++pathIterator) { + hash.append("/" + *pathIterator); + qDebug() << hash; + } + } + } + folders.clear(); +} diff --git a/interface/src/ScriptsModel.h b/interface/src/ScriptsModel.h index ca72a8d8f4..bb4883e399 100644 --- a/interface/src/ScriptsModel.h +++ b/interface/src/ScriptsModel.h @@ -12,30 +12,67 @@ #ifndef hifi_ScriptsModel_h #define hifi_ScriptsModel_h -#include +#include #include #include #include -class ScriptItem { +class TreeNodeFolder; + +enum ScriptOrigin { + SCRIPT_ORIGIN_LOCAL, + SCRIPT_ORIGIN_REMOTE +}; + +enum TreeNodeType { + TREE_NODE_TYPE_SCRIPT, + TREE_NODE_TYPE_FOLDER +}; + +class TreeNodeBase { public: - ScriptItem(const QString& filename, const QString& fullPath); + const TreeNodeFolder* getParent() { return _parent; } + void setParent(TreeNodeFolder* parent) { _parent = parent; } + TreeNodeType getType() { return _type; } + +private: + TreeNodeFolder* _parent; + TreeNodeType _type; + +protected: + TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type); +}; + +class TreeNodeScript : public TreeNodeBase { +public: + TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin); const QString& getFilename() { return _filename; }; const QString& getFullPath() { return _fullPath; }; + const ScriptOrigin getOrigin() { return _origin; }; private: QString _filename; QString _fullPath; + ScriptOrigin _origin; }; -class ScriptsModel : public QAbstractListModel { +class TreeNodeFolder : public TreeNodeBase { +public: + TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent); +private: + QString _foldername; +}; + +class ScriptsModel : public QAbstractItemModel { Q_OBJECT public: ScriptsModel(QObject* parent = NULL); - + QModelIndex index(int row, int column, const QModelIndex& parent) const; + QModelIndex parent(const QModelIndex& child) const; virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; enum Role { ScriptPath = Qt::UserRole, @@ -50,13 +87,13 @@ protected slots: protected: void requestRemoteFiles(QString marker = QString()); bool parseXML(QByteArray xmlFile); + void rebuildTree(); private: bool _loadingScripts; QDir _localDirectory; QFileSystemWatcher _fsWatcher; - QList _localFiles; - QList _remoteFiles; + QList _treeNodes; }; #endif // hifi_ScriptsModel_h diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 57c0532777..f56c6e32af 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -50,10 +50,10 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : _proxyModel.setSourceModel(&_scriptsModel); _proxyModel.sort(0, Qt::AscendingOrder); _proxyModel.setDynamicSortFilter(true); - ui->scriptListView->setModel(&_proxyModel); + ui->scriptTreeView->setModel(&_proxyModel); connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter); - connect(ui->scriptListView, &QListView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); + connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); connect(ui->reloadAllButton, &QPushButton::clicked, Application::getInstance(), &Application::reloadAllScripts); @@ -80,7 +80,7 @@ void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) { } void RunningScriptsWidget::loadSelectedScript() { - QModelIndex selectedIndex = ui->scriptListView->currentIndex(); + QModelIndex selectedIndex = ui->scriptTreeView->currentIndex(); if (selectedIndex.isValid()) { loadScriptFromList(selectedIndex); } @@ -166,7 +166,7 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) { void RunningScriptsWidget::selectFirstInList() { if (_proxyModel.rowCount() > 0) { - ui->scriptListView->setCurrentIndex(_proxyModel.index(0, 0)); + ui->scriptTreeView->setCurrentIndex(_proxyModel.index(0, 0)); } } @@ -177,7 +177,7 @@ bool RunningScriptsWidget::eventFilter(QObject* sender, QEvent* event) { } QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { - QModelIndex selectedIndex = ui->scriptListView->currentIndex(); + QModelIndex selectedIndex = ui->scriptTreeView->currentIndex(); if (selectedIndex.isValid()) { loadScriptFromList(selectedIndex); } diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index b70200e9f2..203db35d2d 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -245,8 +245,8 @@ font: bold 16px; 0 0 - 328 - 18 + 334 + 20 @@ -390,10 +390,27 @@ font: bold 16px; + + + + color: #0e7077; font: bold 14px; + + + Load script + + + + + + + from URL + + + - Load script + from Disk @@ -429,7 +446,7 @@ font: bold 16px; - + 0 @@ -442,6 +459,12 @@ font: bold 16px; Qt::ScrollBarAlwaysOff + + true + + + true +