From d14488d2f750a52f85519ca15d087f35332a784f Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Tue, 4 Feb 2020 03:12:19 -0500 Subject: update tree items when origins change --- src/filetreeitem.cpp | 48 +++++++++++++++++++++++++------------ src/filetreeitem.h | 65 +++++++++++++++++++++++++++++++++++---------------- src/filetreemodel.cpp | 39 ++++++++++++++++++++----------- src/filetreemodel.h | 2 ++ 4 files changed, 105 insertions(+), 49 deletions(-) diff --git a/src/filetreeitem.cpp b/src/filetreeitem.cpp index da4ce701..30805d8b 100644 --- a/src/filetreeitem.cpp +++ b/src/filetreeitem.cpp @@ -39,33 +39,51 @@ const QString& directoryFileType() FileTreeItem::FileTreeItem( - FileTreeItem* parent, int originID, - std::wstring dataRelativeParentPath, std::wstring realPath, Flags flags, - std::wstring file, std::wstring mod) : + FileTreeItem* parent, + std::wstring dataRelativeParentPath, bool isDirectory, std::wstring file) : m_parent(parent), m_indexGuess(NoIndexGuess), - m_originID(originID), m_virtualParentPath(QString::fromStdWString(dataRelativeParentPath)), - m_wsRealPath(realPath), - m_realPath(QString::fromStdWString(realPath)), - m_flags(flags), m_wsFile(file), m_wsLcFile(ToLowerCopy(file)), m_key(m_wsLcFile), m_file(QString::fromStdWString(file)), - m_mod(QString::fromStdWString(mod)), + m_isDirectory(isDirectory), + m_originID(-1), + m_flags(NoFlags), m_loaded(false), m_expanded(false) { } -FileTreeItem::Ptr FileTreeItem::create( - FileTreeItem* parent, int originID, - std::wstring dataRelativeParentPath, std::wstring realPath, Flags flags, - std::wstring file, std::wstring mod) +FileTreeItem::Ptr FileTreeItem::createFile( + FileTreeItem* parent, std::wstring dataRelativeParentPath, std::wstring file) { return std::unique_ptr(new FileTreeItem( - parent, originID, std::move(dataRelativeParentPath), std::move(realPath), - flags, std::move(file), std::move(mod))); + parent, std::move(dataRelativeParentPath), false, std::move(file))); +} + +FileTreeItem::Ptr FileTreeItem::createDirectory( + FileTreeItem* parent, + std::wstring dataRelativeParentPath, std::wstring file) +{ + return std::unique_ptr(new FileTreeItem( + parent, std::move(dataRelativeParentPath), true, std::move(file))); +} + +void FileTreeItem::setOrigin( + int originID, const std::wstring& realPath, Flags flags, + const std::wstring& mod) +{ + m_originID = originID; + m_wsRealPath = realPath; + m_realPath = QString::fromStdWString(realPath); + m_flags = flags; + m_mod = QString::fromStdWString(mod); + + m_fileSize.reset(); + m_lastModified.reset(); + m_fileType.reset(); + m_compressedFileSize.reset(); } void FileTreeItem::insert(FileTreeItem::Ptr child, std::size_t at) @@ -298,7 +316,7 @@ void FileTreeItem::getFileType() const QFileIconProvider::IconType FileTreeItem::icon() const { - if (m_flags & Directory) { + if (m_isDirectory) { return QFileIconProvider::Folder; } else { return QFileIconProvider::File; diff --git a/src/filetreeitem.h b/src/filetreeitem.h index 8ef42289..0d92b3f7 100644 --- a/src/filetreeitem.h +++ b/src/filetreeitem.h @@ -15,24 +15,30 @@ public: enum Flag { NoFlags = 0x00, - Directory = 0x01, - FromArchive = 0x02, - Conflicted = 0x04 + FromArchive = 0x01, + Conflicted = 0x02 }; Q_DECLARE_FLAGS(Flags, Flag); - static Ptr create( - FileTreeItem* parent, int originID, - std::wstring dataRelativeParentPath, std::wstring realPath, Flags flags, - std::wstring file, std::wstring mod); + static Ptr createFile( + FileTreeItem* parent, + std::wstring dataRelativeParentPath, std::wstring file); + + static Ptr createDirectory( + FileTreeItem* parent, + std::wstring dataRelativeParentPath, std::wstring file); FileTreeItem(const FileTreeItem&) = delete; FileTreeItem& operator=(const FileTreeItem&) = delete; FileTreeItem(FileTreeItem&&) = default; FileTreeItem& operator=(FileTreeItem&&) = default; + void setOrigin( + int originID, const std::wstring& realPath, + Flags flags, const std::wstring& mod); + void add(Ptr child) { child->m_indexGuess = m_children.size(); @@ -136,17 +142,17 @@ public: std::optional compressedFileSize() const { - return m_compressedFileSize; + return m_compressedFileSize.value; } void setFileSize(uint64_t size) { - m_fileSize.set(size); + m_fileSize.override(size); } void setCompressedFileSize(uint64_t compressedSize) { - m_compressedFileSize = compressedSize; + m_compressedFileSize.override(compressedSize); } const QString& realPath() const @@ -165,7 +171,7 @@ public: bool isDirectory() const { - return (m_flags & Directory); + return m_isDirectory; } bool isFromArchive() const @@ -226,6 +232,7 @@ private: { std::optional value; bool failed = false; + bool overridden = false; bool empty() const { @@ -236,12 +243,29 @@ private: { value = std::move(t); failed = false; + overridden = false; + } + + void override(T t) + { + value = std::move(t); + failed = false; + overridden = true; } void fail() { value = {}; failed = true; + overridden = false; + } + + void reset() + { + if (!overridden) { + value = {}; + failed = false; + } } }; @@ -251,20 +275,22 @@ private: FileTreeItem* m_parent; mutable std::size_t m_indexGuess; - const int m_originID; const QString m_virtualParentPath; - const std::wstring m_wsRealPath; - const QString m_realPath; - const Flags m_flags; const std::wstring m_wsFile, m_wsLcFile; const MOShared::DirectoryEntry::FileKey m_key; const QString m_file; - const QString m_mod; + const bool m_isDirectory; + + int m_originID; + QString m_realPath; + std::wstring m_wsRealPath; + Flags m_flags; + QString m_mod; mutable Cached m_fileSize; mutable Cached m_lastModified; mutable Cached m_fileType; - mutable std::optional m_compressedFileSize; + mutable Cached m_compressedFileSize; bool m_loaded; bool m_expanded; @@ -272,9 +298,8 @@ private: FileTreeItem( - FileTreeItem* parent, int originID, - std::wstring dataRelativeParentPath, std::wstring realPath, Flags flags, - std::wstring file, std::wstring mod); + FileTreeItem* parent, + std::wstring dataRelativeParentPath, bool isDirectory, std::wstring file); void getFileType() const; }; diff --git a/src/filetreemodel.cpp b/src/filetreemodel.cpp index 3890ad2e..aa87edbf 100644 --- a/src/filetreemodel.cpp +++ b/src/filetreemodel.cpp @@ -137,8 +137,7 @@ void* makeInternalPointer(FileTreeItem* item) FileTreeModel::FileTreeModel(OrganizerCore& core, QObject* parent) : QAbstractItemModel(parent), m_core(core), - m_root(FileTreeItem::create( - nullptr, 0, L"", L"", FileTreeItem::Directory, L"", L"")), + m_root(FileTreeItem::createDirectory(nullptr, L"", L"")), m_flags(NoFlags) { m_root->setExpanded(true); @@ -623,6 +622,11 @@ void FileTreeModel::removeDisappearingFiles( // file is still there seen.emplace(f->getIndex()); + if (f->getOrigin() != item->originID()) { + // origin has changed + updateFileItem(*item, *f); + } + // if there were files before this row that need to be removed, // do it now itor = range.remove(); @@ -708,9 +712,8 @@ FileTreeItem::Ptr FileTreeModel::createDirectoryItem( FileTreeItem& parentItem, const std::wstring& parentPath, const DirectoryEntry& d) { - auto item = FileTreeItem::create( - &parentItem, 0, parentPath, L"", FileTreeItem::Directory, - d.getName(), L""); + auto item = FileTreeItem::createDirectory( + &parentItem, parentPath, d.getName()); if (d.isEmpty()) { // if this directory is empty, mark the item as loaded so the expand @@ -724,6 +727,19 @@ FileTreeItem::Ptr FileTreeModel::createDirectoryItem( FileTreeItem::Ptr FileTreeModel::createFileItem( FileTreeItem& parentItem, const std::wstring& parentPath, const FileEntry& file) +{ + auto item = FileTreeItem::createFile( + &parentItem, parentPath, file.getName()); + + updateFileItem(*item, file); + + item->setLoaded(true); + + return item; +} + +void FileTreeModel::updateFileItem( + FileTreeItem& item, const MOShared::FileEntry& file) { bool isArchive = false; int originID = file.getOrigin(isArchive); @@ -738,21 +754,16 @@ FileTreeItem::Ptr FileTreeModel::createFileItem( flags |= FileTreeItem::Conflicted; } - auto item = FileTreeItem::create( - &parentItem, originID, parentPath, file.getFullPath(), flags, - file.getName(), makeModName(file, originID)); + item.setOrigin( + originID, file.getFullPath(), flags, makeModName(file, originID)); if (file.getFileSize() != FileEntry::NoFileSize) { - item->setFileSize(file.getFileSize()); + item.setFileSize(file.getFileSize()); } if (file.getCompressedFileSize() != FileEntry::NoFileSize) { - item->setCompressedFileSize(file.getCompressedFileSize()); + item.setCompressedFileSize(file.getCompressedFileSize()); } - - item->setLoaded(true); - - return item; } bool FileTreeModel::shouldShowFile(const FileEntry& file) const diff --git a/src/filetreemodel.h b/src/filetreemodel.h index 03bae602..ffd46fac 100644 --- a/src/filetreemodel.h +++ b/src/filetreemodel.h @@ -125,6 +125,8 @@ private: FileTreeItem& parentItem, const std::wstring& parentPath, const MOShared::FileEntry& file); + void updateFileItem(FileTreeItem& item, const MOShared::FileEntry& file); + QVariant displayData(const FileTreeItem* item, int column) const; std::wstring makeModName(const MOShared::FileEntry& file, int originID) const; -- cgit v1.3.1