LevelTreeModel.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "LevelTreeModel.h"
  10. // Editor
  11. #include "LevelFileDialog.h"
  12. // Folder in which levels are stored
  13. static const char kLevelsFolder[] = "Levels";
  14. LevelTreeModelFilter::LevelTreeModelFilter(QObject* parent)
  15. : QSortFilterProxyModel(parent)
  16. {
  17. }
  18. QVariant LevelTreeModelFilter::data(const QModelIndex& index, int role) const
  19. {
  20. if (!sourceModel())
  21. {
  22. return QVariant();
  23. }
  24. return sourceModel()->data(mapToSource(index), role);
  25. }
  26. bool LevelTreeModelFilter::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
  27. {
  28. if (m_filterText.isEmpty())
  29. {
  30. return true;
  31. }
  32. QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
  33. if (!idx.isValid())
  34. {
  35. return false;
  36. }
  37. const QString text = idx.data(Qt::DisplayRole).toString();
  38. if (text.contains(m_filterText, Qt::CaseInsensitive))
  39. {
  40. return true;
  41. }
  42. // Recurse into the children
  43. const int count = sourceModel()->rowCount(idx);
  44. for (int i = 0; i < count; ++i)
  45. {
  46. if (filterAcceptsRow(i, idx))
  47. {
  48. return true;
  49. }
  50. }
  51. return false;
  52. }
  53. void LevelTreeModelFilter::setFilterText(const QString& text)
  54. {
  55. QString lowerText = text.toLower();
  56. if (m_filterText != lowerText)
  57. {
  58. m_filterText = lowerText;
  59. invalidateFilter();
  60. }
  61. }
  62. LevelTreeModel::LevelTreeModel(QObject* parent)
  63. : QStandardItemModel(parent)
  64. {
  65. }
  66. LevelTreeModel::~LevelTreeModel()
  67. {
  68. }
  69. QVariant LevelTreeModel::data(const QModelIndex& index, int role) const
  70. {
  71. if (role == Qt::DecorationRole)
  72. {
  73. const bool isLevelFolder = index.data(LevelTreeModel::IsLevelFolderRole).toBool();
  74. if (isLevelFolder)
  75. {
  76. return QIcon(":/img/tree_view_level.png");
  77. }
  78. else
  79. {
  80. return QIcon(":/img/tree_view_folder.png");
  81. }
  82. }
  83. return QStandardItemModel::data(index, role);
  84. }
  85. void LevelTreeModel::ReloadTree(bool recurseIfNoLevels)
  86. {
  87. clear();
  88. QString levelsFolder = QString("%1/%2").arg(Path::GetEditingGameDataFolder().c_str()).arg(kLevelsFolder);
  89. QStandardItem* root = new QStandardItem(kLevelsFolder);
  90. root->setData(levelsFolder, FullPathRole);
  91. root->setEditable(false);
  92. invisibleRootItem()->appendRow(root);
  93. ReloadTree(root, recurseIfNoLevels);
  94. }
  95. void LevelTreeModel::ReloadTree(QStandardItem* root, bool recurseIfNoLevels)
  96. {
  97. QStringList levelFiles;
  98. const QString parentFullPath = root->data(FullPathRole).toString();
  99. const bool isLevelFolder = CLevelFileDialog::CheckLevelFolder(parentFullPath, &levelFiles);
  100. root->setData(isLevelFolder, IsLevelFolderRole);
  101. // Recurse to sub folders if this is not a level folder
  102. // Also recurse to sub folders if we detected a level folder
  103. // but there are no level files in it in open mode
  104. if (!isLevelFolder || (recurseIfNoLevels && levelFiles.empty()))
  105. {
  106. QDir currentDir(parentFullPath);
  107. currentDir.setFilter(QDir::NoDot | QDir::NoDotDot | QDir::Dirs);
  108. const QStringList subFolders = currentDir.entryList();
  109. foreach (const QString &subFolder, subFolders)
  110. {
  111. auto child = new QStandardItem(subFolder);
  112. child->setData(parentFullPath + "/" + subFolder, FullPathRole);
  113. child->setEditable(false);
  114. root->appendRow(child);
  115. ReloadTree(child, recurseIfNoLevels);
  116. }
  117. }
  118. else
  119. {
  120. // eTreeImage_Level
  121. // Support for legacy folder structure: Multiple cry files in level folder
  122. if (recurseIfNoLevels && levelFiles.size() > 1)
  123. {
  124. foreach (const QString &levelFile, levelFiles)
  125. {
  126. auto child = new QStandardItem(levelFile);
  127. child->setData(root->data(FullPathRole).toString() + "/" + levelFile, FullPathRole);
  128. child->setData(false, IsLevelFolderRole);
  129. child->setEditable(false);
  130. root->appendRow(child);
  131. }
  132. }
  133. }
  134. }
  135. void LevelTreeModel::AddItem(const QString& name, const QModelIndex& parent)
  136. {
  137. auto item = new QStandardItem(name);
  138. item->setData(false, IsLevelFolderRole);
  139. item->setEditable(false);
  140. QStandardItem* parentItem = itemFromIndex(parent);
  141. if (parentItem)
  142. {
  143. const QString parentPath = parent.data(FullPathRole).toString();
  144. item->setData(parentPath + "/" + name, FullPathRole);
  145. parentItem->appendRow(item);
  146. }
  147. }
  148. #include <moc_LevelTreeModel.cpp>