summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp')
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp630
1 files changed, 0 insertions, 630 deletions
diff --git a/src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp b/src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp
deleted file mode 100644
index 3a1a008b..00000000
--- a/src/Authoring/Studio/Palettes/Inspector/ChooserModelBase.cpp
+++ /dev/null
@@ -1,630 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt 3D Studio.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#include <QtCore/qset.h>
-
-#include "Qt3DSCommonPrecompile.h"
-
-#include "ChooserModelBase.h"
-#include "Core.h"
-#include "Dispatch.h"
-#include "Doc.h"
-#include "StudioUtils.h"
-#include "Qt3DSFileTools.h"
-#include "ImportUtils.h"
-#include "StudioApp.h"
-
-ChooserModelBase::ChooserModelBase(QObject *parent) : QAbstractListModel(parent)
- , m_model(new QFileSystemModel(this))
-{
- connect(m_model, &QAbstractItemModel::rowsInserted, this, &ChooserModelBase::modelRowsInserted);
- connect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved, this, &ChooserModelBase::modelRowsRemoved);
- connect(m_model, &QAbstractItemModel::layoutChanged, this, &ChooserModelBase::modelLayoutChanged);
-
- g_StudioApp.GetCore()->GetDispatch()->AddPresentationChangeListener(this);
-
- rebuild();
-}
-
-ChooserModelBase::~ChooserModelBase()
-{
- g_StudioApp.GetCore()->GetDispatch()->RemovePresentationChangeListener(this);
-}
-
-QHash<int, QByteArray> ChooserModelBase::roleNames() const
-{
- auto modelRoleNames = m_model->roleNames();
- modelRoleNames.insert(IsExpandableRole, "isExpandable");
- modelRoleNames.insert(DepthRole, "depth");
- modelRoleNames.insert(ExpandedRole, "expanded");
- modelRoleNames.insert(IsSelectableRole, "isSelectable");
- modelRoleNames.insert(IsCurrentFile, "isCurrentFile");
- return modelRoleNames;
-}
-
-int ChooserModelBase::rowCount(const QModelIndex &) const
-{
- return getFixedItems().count() + m_items.count();
-}
-
-QVariant ChooserModelBase::data(const QModelIndex &index, int role) const
-{
- const int row = index.row();
-
- const auto fixedItems = getFixedItems();
- const int fixedItemCount = fixedItems.count();
-
- if (row < fixedItemCount) {
- const auto &item = fixedItems.at(row);
-
- switch (role) {
- case Qt::DecorationRole:
- if (!item.iconSource.isEmpty()) {
- return StudioUtils::resourceImageUrl() + item.iconSource;
- } else {
- return StudioUtils::resourceImageUrl()
- + CStudioObjectTypes::GetNormalIconName(item.iconType);
- }
-
- case IsExpandableRole:
- return false;
-
- case DepthRole:
- return 0;
-
- case ExpandedRole:
- return false;
-
- case IsSelectableRole:
- return true;
-
- case IsCurrentFile:
- return item.name == m_currentFile;
-
- default:
- return item.name;
- }
- } else {
- const auto &item = m_items.at(row - fixedItemCount);
-
- switch (role) {
- case Qt::DecorationRole: {
- QString path = item.index.data(QFileSystemModel::FilePathRole).toString();
- return StudioUtils::resourceImageUrl() + getIconName(path);
- }
-
- case IsExpandableRole: {
- QFileInfo fileInfo(item.index.data(QFileSystemModel::FilePathRole).toString());
- return fileInfo.isDir();
- }
-
- case DepthRole:
- return item.depth;
-
- case ExpandedRole:
- return item.expanded;
-
- case IsSelectableRole: {
- QFileInfo fileInfo(item.index.data(QFileSystemModel::FilePathRole).toString());
- return fileInfo.isFile();
- }
-
- case IsCurrentFile: {
- QString path = item.index.data(QFileSystemModel::FilePathRole).toString();
- return path == m_currentFile;
- }
-
- case QFileSystemModel::FileNameRole: {
- QString displayName = specialDisplayName(item);
- if (displayName.isEmpty())
- displayName = m_model->data(item.index, QFileSystemModel::FileNameRole).toString();
- return displayName;
- }
-
- default:
- return m_model->data(item.index, role).toString();
- }
- }
-}
-
-void ChooserModelBase::setCurrentFile(const QString &path)
-{
- const auto fixedItems = getFixedItems();
- const int fixedItemCount = fixedItems.count();
- const auto getFixedItemIndex = [fixedItemCount, &fixedItems](const QString &path) -> int {
- for (int i = 0; i < fixedItemCount; ++i) {
- const auto &item = fixedItems.at(i);
- if (item.name == path)
- return i;
- }
- return -1;
- };
- int fixedItemIndex = getFixedItemIndex(path);
-
- const auto doc = g_StudioApp.GetCore()->GetDoc();
- const QDir documentDir(doc->GetDocumentDirectory());
- const QString fullPath = fixedItemIndex == -1 ? QDir::cleanPath(documentDir.filePath(path))
- : path;
-
- if (fullPath != m_currentFile) {
- const auto fileRow = [this, getFixedItemIndex, fixedItemCount](const QString &path) -> int
- {
- const int fixedItemIndex = getFixedItemIndex(path);
- if (fixedItemIndex != -1)
- return fixedItemIndex;
-
- const int itemCount = m_items.count();
-
- for (int i = 0; i < itemCount; ++i) {
- const auto &item = m_items.at(i);
-
- if (item.index.data(QFileSystemModel::FilePathRole).toString() == path)
- return fixedItemCount + i;
- }
-
- return -1;
- };
-
- int previousRow = fileRow(m_currentFile);
- int currentRow = fileRow(fullPath);
-
- m_currentFile = fullPath;
-
- if (previousRow != -1)
- Q_EMIT dataChanged(index(previousRow), index(previousRow));
-
- if (currentRow != -1)
- Q_EMIT dataChanged(index(currentRow), index(currentRow));
- }
-
- // expand parent folder if current file is hidden
- auto matched = m_model->match(m_rootIndex, QFileSystemModel::FilePathRole, path, 1,
- Qt::MatchExactly|Qt::MatchRecursive);
- if (!matched.isEmpty()) {
- auto modelIndex = matched.first();
- if (modelIndexRow(modelIndex) == -1)
- expand(m_model->parent(modelIndex));
- }
-}
-
-void ChooserModelBase::expand(const QModelIndex &modelIndex)
-{
- if (modelIndex == m_rootIndex)
- return;
-
- int row = modelIndexRow(modelIndex);
- if (row == -1) {
- QModelIndex parentIndex = m_model->parent(modelIndex);
- expand(parentIndex);
-
- row = modelIndexRow(modelIndex);
- Q_ASSERT(row != -1);
- }
-
- if (!m_items.at(row).expanded)
- expand(row + getFixedItems().count());
-}
-
-void ChooserModelBase::setRootPath(const QString &path)
-{
- // Delete the old model. If the new project is in a totally different directory tree, not
- // doing this will result in unexplicable crashes when trying to parse something that should
- // not be parsed.
- disconnect(m_model, &QAbstractItemModel::rowsInserted,
- this, &ChooserModelBase::modelRowsInserted);
- disconnect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved,
- this, &ChooserModelBase::modelRowsRemoved);
- disconnect(m_model, &QAbstractItemModel::layoutChanged,
- this, &ChooserModelBase::modelLayoutChanged);
- delete m_model;
- m_model = new QFileSystemModel(this);
- connect(m_model, &QAbstractItemModel::rowsInserted,
- this, &ChooserModelBase::modelRowsInserted);
- connect(m_model, &QAbstractItemModel::rowsAboutToBeRemoved,
- this, &ChooserModelBase::modelRowsRemoved);
- connect(m_model, &QAbstractItemModel::layoutChanged,
- this, &ChooserModelBase::modelLayoutChanged);
-
- setRootIndex(m_model->setRootPath(path));
-}
-
-void ChooserModelBase::setRootIndex(const QModelIndex &rootIndex)
-{
- if (rootIndex != m_rootIndex) {
- clearModelData();
- m_rootIndex = rootIndex;
- showModelTopLevelItems();
- }
-}
-
-void ChooserModelBase::clearModelData()
-{
- if (!m_items.isEmpty()) {
- const auto fixedItemCount = getFixedItems().count();
- beginRemoveRows({}, fixedItemCount, fixedItemCount + m_items.count() - 1);
- m_items.clear();
- endRemoveRows();
- }
-}
-
-void ChooserModelBase::showModelTopLevelItems()
-{
- int rowCount = m_model->rowCount(m_rootIndex);
-
- if (rowCount == 0) {
- if (m_model->hasChildren(m_rootIndex) && m_model->canFetchMore(m_rootIndex))
- m_model->fetchMore(m_rootIndex);
- } else {
- showModelChildItems(m_rootIndex, 0, rowCount - 1);
-
- for (int i = 0; i < rowCount; ++i) {
- const auto &childIndex = m_model->index(i, 0, m_rootIndex);
- if (m_model->hasChildren(childIndex) && m_model->canFetchMore(childIndex))
- m_model->fetchMore(childIndex);
- }
- }
-}
-
-void ChooserModelBase::showModelChildItems(const QModelIndex &parentIndex, int start, int end)
-{
- QVector<QModelIndex> rowsToInsert;
- for (int i = start; i <= end; ++i) {
- const auto &childIndex = m_model->index(i, 0, parentIndex);
- if (isVisible(childIndex))
- rowsToInsert.append(childIndex);
- }
-
- const int insertCount = rowsToInsert.count();
-
- if (insertCount != 0) {
- TreeItem *parent;
- int depth, startRow;
-
- if (parentIndex == m_rootIndex) {
- parent = nullptr;
- depth = 0;
- startRow = 0;
- } else {
- const int parentRow = modelIndexRow(parentIndex);
- Q_ASSERT(parentRow != -1 && isVisible(parentIndex));
- parent = &m_items[parentRow];
- depth = parent->depth + 1;
- startRow = parentRow + parent->childCount + 1;
- }
-
- const int fixedItemCount = getFixedItems().count();
- beginInsertRows({}, startRow + fixedItemCount, startRow + fixedItemCount + insertCount - 1);
-
- for (auto it = rowsToInsert.rbegin(); it != rowsToInsert.rend(); ++it)
- m_items.insert(startRow, { *it, depth, false, parent, 0 });
-
- for (; parent != nullptr; parent = parent->parent)
- parent->childCount += insertCount;
-
- endInsertRows();
- }
-}
-
-void ChooserModelBase::expand(int row)
-{
- const int fixedItemCount = getFixedItems().count();
- Q_ASSERT(row >= fixedItemCount && row < fixedItemCount + m_items.count());
-
- auto &item = m_items[row - fixedItemCount];
- Q_ASSERT(item.expanded == false);
-
- const auto &modelIndex = item.index;
-
- const int rowCount = m_model->rowCount(modelIndex);
- if (rowCount == 0) {
- if (m_model->hasChildren(modelIndex) && m_model->canFetchMore(modelIndex))
- m_model->fetchMore(modelIndex);
- } else {
- showModelChildItems(modelIndex, 0, rowCount - 1);
- }
-
- item.expanded = true;
- Q_EMIT dataChanged(index(row), index(row));
-}
-
-void ChooserModelBase::collapse(int row)
-{
- const int fixedItemCount = getFixedItems().count();
- Q_ASSERT(row >= fixedItemCount && row < fixedItemCount + m_items.count());
-
- auto &item = m_items[row - fixedItemCount];
- Q_ASSERT(item.expanded == true);
-
- const int childCount = item.childCount;
-
- if (childCount > 0) {
- beginRemoveRows({}, row + 1, row + childCount);
-
- auto first = std::begin(m_items) + row - fixedItemCount + 1;
- m_items.erase(first, first + childCount);
-
- for (auto parent = &item; parent != nullptr; parent = parent->parent)
- parent->childCount -= childCount;
-
- endRemoveRows();
- }
-
- item.expanded = false;
- Q_EMIT dataChanged(index(row), index(row));
-}
-
-void ChooserModelBase::OnNewPresentation()
-{
- rebuild();
-}
-
-int ChooserModelBase::modelIndexRow(const QModelIndex &modelIndex) const
-{
- auto it = std::find_if(std::begin(m_items), std::end(m_items),
- [&modelIndex](const TreeItem &item)
- {
- return item.index == modelIndex;
- });
-
- return it != std::end(m_items) ? std::distance(std::begin(m_items), it) : -1;
-}
-
-bool ChooserModelBase::isExpanded(const QModelIndex &modelIndex) const
-{
- if (modelIndex == m_rootIndex) {
- return true;
- } else {
- const int row = modelIndexRow(modelIndex);
- return row != -1 && m_items.at(row).expanded;
- }
-}
-
-EStudioObjectType ChooserModelBase::getIconType(const QString &path) const
-{
- return Q3DStudio::ImportUtils::GetObjectFileTypeForFile(path).m_IconType;
-}
-
-QString ChooserModelBase::specialDisplayName(const ChooserModelBase::TreeItem &item) const
-{
- Q_UNUSED(item)
- return {};
-}
-
-QString ChooserModelBase::getIconName(const QString &path) const
-{
- QString iconName;
-
- QFileInfo fileInfo(path);
- if (fileInfo.isFile()) {
- EStudioObjectType type = getIconType(path);
- if (type != OBJTYPE_UNKNOWN)
- iconName = CStudioObjectTypes::GetNormalIconName(type);
- else
- iconName = QStringLiteral("Objects-Layer-Normal.png");
- } else {
- iconName = QStringLiteral("Objects-Folder-Normal.png");
- }
-
- return iconName;
-}
-
-bool ChooserModelBase::isVisible(const QModelIndex &modelIndex) const
-{
- QString path = modelIndex.data(QFileSystemModel::FilePathRole).toString();
- QFileInfo fileInfo(path);
-
- if (fileInfo.isFile()) {
- return isVisible(path);
- } else {
- return hasVisibleChildren(modelIndex);
- }
-}
-
-bool ChooserModelBase::hasVisibleChildren(const QModelIndex &modelIndex) const
-{
- int rowCount = m_model->rowCount(modelIndex);
-
- for (int i = 0; i < rowCount; ++i) {
- const auto &childIndex = m_model->index(i, 0, modelIndex);
-
- if (m_model->hasChildren(childIndex)) {
- if (hasVisibleChildren(childIndex))
- return true;
- } else {
- QString path = childIndex.data(QFileSystemModel::FilePathRole).toString();
- QFileInfo fileInfo(path);
- if (fileInfo.isFile() && isVisible(path))
- return true;
- }
- }
-
- return false;
-}
-
-void ChooserModelBase::modelRowsInserted(const QModelIndex &parentIndex, int start, int end)
-{
- if (!m_rootIndex.isValid())
- return;
-
- if (isExpanded(parentIndex)) {
- showModelChildItems(parentIndex, start, end);
- } else {
- if (modelIndexRow(parentIndex) == -1) {
- // parent wasn't inserted in model yet, check if any of the new rows is visible
-
- bool visible = false;
-
- for (int i = start; i <= end; ++i) {
- const auto &childIndex = m_model->index(i, 0, parentIndex);
- QString path = childIndex.data(QFileSystemModel::FilePathRole).toString();
- QFileInfo fileInfo(path);
- if (fileInfo.isFile() && isVisible(path)) {
- visible = true;
- break;
- }
- }
-
- // if any of the new rows is visible, insert parent folder index into model
-
- if (visible) {
- QModelIndex index = parentIndex, parent = m_model->parent(parentIndex);
-
- while (parent != m_rootIndex && modelIndexRow(parent) == -1) {
- index = parent;
- parent = m_model->parent(parent);
- }
-
- if (isExpanded(parent) && modelIndexRow(index) == -1) {
- const int row = index.row();
- showModelChildItems(parent, row, row);
- }
- }
- }
-
- // if one of the new rows is the current file expand parent folder
-
- bool containsCurrent = false;
-
- for (int i = start; i <= end; ++i) {
- const auto &childIndex = m_model->index(i, 0, parentIndex);
- if (childIndex.data(QFileSystemModel::FilePathRole).toString() == m_currentFile) {
- containsCurrent = true;
- break;
- }
- }
-
- if (containsCurrent)
- expand(parentIndex);
- }
-
- // fetch children so we're notified when files are added or removed
-
- for (int i = start; i <= end; ++i) {
- const auto &childIndex = m_model->index(i, 0, parentIndex);
- if (m_model->hasChildren(childIndex) && m_model->canFetchMore(childIndex))
- m_model->fetchMore(childIndex);
- }
-}
-
-void ChooserModelBase::modelRowsRemoved(const QModelIndex &parentIndex, int start, int end)
-{
- if (!m_rootIndex.isValid())
- return;
-
- if (isExpanded(parentIndex)) {
- const auto fixedItems = getFixedItems();
-
- const auto removeRow = [this, &fixedItems](int row)
- {
- const auto &item = m_items.at(row);
-
- const int fixedItemCount = fixedItems.count();
- beginRemoveRows({}, row + fixedItemCount, row + fixedItemCount + item.childCount);
-
- for (auto parent = item.parent; parent != nullptr; parent = parent->parent)
- parent->childCount -= 1 + item.childCount;
-
- m_items.erase(std::begin(m_items) + row, std::begin(m_items) + row + item.childCount + 1);
-
- endRemoveRows();
- };
-
- // remove rows
-
- for (int i = start; i <= end; ++i) {
- const int row = modelIndexRow(m_model->index(i, 0, parentIndex));
- if (row != -1)
- removeRow(row);
- }
-
- // also remove folder row if there are no more visible children
-
- QModelIndex index = parentIndex;
-
- while (index != m_rootIndex && !hasVisibleChildren(index)) {
- const int row = modelIndexRow(index);
- Q_ASSERT(row != -1);
- removeRow(row);
- index = m_model->parent(index);
- }
- }
-}
-
-void ChooserModelBase::modelLayoutChanged()
-{
- if (!m_rootIndex.isValid())
- return;
-
- QSet<QPersistentModelIndex> expandedItems;
- for (const auto &item : m_items) {
- if (item.expanded)
- expandedItems.insert(item.index);
- }
-
- const std::function<int(const QModelIndex &, TreeItem *)> insertChildren =
- [this, &expandedItems, &insertChildren](const QModelIndex &parentIndex, TreeItem *parent)
- {
- Q_ASSERT(parentIndex == m_rootIndex || isVisible(parentIndex));
-
- const int rowCount = m_model->rowCount(parentIndex);
- const int depth = parent == nullptr ? 0 : parent->depth + 1;
-
- int childCount = 0;
-
- for (int i = 0; i < rowCount; ++i) {
- const auto &childIndex = m_model->index(i, 0, parentIndex);
- if (isVisible(childIndex)) {
- const bool expanded = expandedItems.contains(childIndex);
- m_items.append({ childIndex, depth, expanded, parent, 0 });
- auto &item = m_items.last();
- if (expanded) {
- item.childCount = insertChildren(childIndex, &item);
- childCount += item.childCount;
- }
- ++childCount;
- }
- }
-
- return childCount;
- };
-
- const int itemCount = m_items.count();
-
- m_items.clear();
- m_items.reserve(itemCount);
-
- insertChildren(m_rootIndex, nullptr);
- Q_ASSERT(m_items.count() == itemCount);
-
- const int fixedItemCount = getFixedItems().count();
- Q_EMIT dataChanged(index(fixedItemCount), index(fixedItemCount + itemCount - 1));
-}
-
-void ChooserModelBase::rebuild()
-{
- setRootPath(g_StudioApp.GetCore()->getProjectFile().getProjectPath());
-}