summaryrefslogtreecommitdiff
path: root/src/filetree.cpp
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-12-12 18:57:36 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-04 03:33:17 -0500
commitc5f98f9756ed9ba5b2241fa11215d99c8bf52461 (patch)
tree3e88b4cd79f0a7b408df2337fbaf5569b685d591 /src/filetree.cpp
parentd3e9abddaf1f927102002d9fb2721e858f6c3a3e (diff)
now prunes empty directories
handles archives and conflicts checkboxes
Diffstat (limited to 'src/filetree.cpp')
-rw-r--r--src/filetree.cpp124
1 files changed, 88 insertions, 36 deletions
diff --git a/src/filetree.cpp b/src/filetree.cpp
index f43d07a2..cf40e01c 100644
--- a/src/filetree.cpp
+++ b/src/filetree.cpp
@@ -16,17 +16,16 @@ FileTreeItem::FileTreeItem()
FileTreeItem::FileTreeItem(
FileTreeItem* parent, int originID,
- std::wstring virtualParentPath, std::wstring realPath, Flags flags,
+ std::wstring dataRelativeParentPath, std::wstring realPath, Flags flags,
std::wstring file, std::wstring mod) :
m_parent(parent), m_originID(originID),
- m_virtualParentPath(QString::fromStdWString(virtualParentPath)),
+ m_virtualParentPath(QString::fromStdWString(dataRelativeParentPath)),
m_realPath(QString::fromStdWString(realPath)),
m_flags(flags),
m_file(QString::fromStdWString(file)),
m_mod(QString::fromStdWString(mod)),
m_loaded(false)
{
- Q_ASSERT(!m_mod.isEmpty());
}
void FileTreeItem::add(std::unique_ptr<FileTreeItem> child)
@@ -56,27 +55,20 @@ const QString& FileTreeItem::virtualParentPath() const
QString FileTreeItem::virtualPath() const
{
- if (m_virtualParentPath.isEmpty()) {
- return m_file;
- } else {
- return m_virtualParentPath + "\\" + m_file;
- }
-}
+ QString s = "Data\\";
-QString FileTreeItem::dataRelativeParentPath() const
-{
- if (m_virtualParentPath == "data") {
- return "";
+ if (!m_virtualParentPath.isEmpty()) {
+ s += m_virtualParentPath + "\\";
}
- static const QString prefix = "data\\";
+ s += m_file;
- auto path = m_virtualParentPath;
- if (path.startsWith(prefix)) {
- path = path.mid(prefix.size());
- }
+ return s;
+}
- return path;
+QString FileTreeItem::dataRelativeParentPath() const
+{
+ return m_virtualParentPath;
}
QString FileTreeItem::dataRelativeFilePath() const
@@ -396,13 +388,13 @@ bool FileTreeModel::showConflicts() const
bool FileTreeModel::showArchives() const
{
- return (m_flags & Archives);
+ return (m_flags & Archives) && m_core.getArchiveParsing();
}
void FileTreeModel::refresh()
{
beginResetModel();
- m_root = {nullptr, 0, L"", L"", FileTreeItem::Directory, L"Data", L""};
+ m_root = {nullptr, 0, L"", L"", FileTreeItem::Directory, L"Data", L"<root>"};
fill(m_root, *m_core.directoryStructure(), L"");
endResetModel();
}
@@ -437,27 +429,87 @@ void FileTreeModel::fill(
FileTreeItem& parentItem, const MOShared::DirectoryEntry& parentEntry,
const std::wstring& parentPath)
{
- const std::wstring path =
- parentPath +
- (parentPath.empty() ? L"" : L"\\") +
- parentEntry.getName();
+ std::wstring path = parentPath;
+
+ if (!parentEntry.isTopLevel()) {
+ if (!path.empty()) {
+ path += L"\\";
+ }
+
+ path += parentEntry.getName();
+ }
+
+ const auto flags = FillFlag::PruneDirectories;
std::vector<DirectoryEntry*>::const_iterator begin, end;
parentEntry.getSubDirectories(begin, end);
- fillDirectories(parentItem, path, begin, end);
+ fillDirectories(parentItem, path, begin, end, flags);
- fillFiles(parentItem, path, parentEntry.getFiles());
+ fillFiles(parentItem, path, parentEntry.getFiles(), flags);
parentItem.setLoaded(true);
}
+bool FileTreeModel::shouldShowFile(const FileEntry& file) const
+{
+ if (showConflicts() && (file.getAlternatives().size() == 0)) {
+ return false;
+ }
+
+ bool isArchive = false;
+ int originID = file.getOrigin(isArchive);
+ if (!showArchives() && isArchive) {
+ return false;
+ }
+
+ return true;
+}
+
+bool FileTreeModel::hasFilesAnywhere(const DirectoryEntry& dir) const
+{
+ bool foundFile = false;
+
+ dir.forEachFile([&](auto&& f) {
+ if (shouldShowFile(f)) {
+ foundFile = true;
+
+ // stop
+ return false;
+ }
+
+ // continue
+ return true;
+ });
+
+ if (foundFile) {
+ return true;
+ }
+
+ std::vector<DirectoryEntry*>::const_iterator begin, end;
+ dir.getSubDirectories(begin, end);
+
+ for (auto itor=begin; itor!=end; ++itor) {
+ if (hasFilesAnywhere(**itor)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
void FileTreeModel::fillDirectories(
FileTreeItem& parentItem, const std::wstring& path,
- DirectoryIterator begin, DirectoryIterator end)
+ DirectoryIterator begin, DirectoryIterator end, FillFlags flags)
{
for (auto itor=begin; itor!=end; ++itor) {
const auto& dir = **itor;
+ if (flags & FillFlag::PruneDirectories) {
+ if (!hasFilesAnywhere(dir)) {
+ continue;
+ }
+ }
+
auto child = std::make_unique<FileTreeItem>(
&parentItem, 0, path, L"", FileTreeItem::Directory, dir.getName(), L"");
@@ -471,18 +523,15 @@ void FileTreeModel::fillDirectories(
void FileTreeModel::fillFiles(
FileTreeItem& parentItem, const std::wstring& path,
- const std::vector<FileEntry::Ptr>& files)
+ const std::vector<FileEntry::Ptr>& files, FillFlags)
{
for (auto&& file : files) {
- if (showConflicts() && (file->getAlternatives().size() == 0)) {
+ if (!shouldShowFile(*file)) {
continue;
}
bool isArchive = false;
int originID = file->getOrigin(isArchive);
- if (!showArchives() && isArchive) {
- continue;
- }
FileTreeItem::Flags flags = FileTreeItem::NoFlags;
@@ -549,9 +598,12 @@ QModelIndex FileTreeModel::index(
ensureLoaded(parent);
if (static_cast<std::size_t>(row) >= parent->children().size()) {
- log::error(
- "FileTreeModel::index(): row {} is out of range for {}",
- row, parent->debugName());
+ // don't warn if the tree hasn't been refreshed yet
+ if (!m_root.children().empty()) {
+ log::error(
+ "FileTreeModel::index(): row {} is out of range for {}",
+ row, parent->debugName());
+ }
return {};
}