diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2020-02-09 08:52:03 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-09 08:52:03 -0500 |
| commit | 1f1f99f253f981ae3d11e9df177a144d00dbce0e (patch) | |
| tree | 01d38125329508f5628f9221f797e303180c8fc3 /src/filetreeitem.h | |
| parent | 718c2a56f91f824c5eab69d8cc16294f77243370 (diff) | |
| parent | 3a80685189967fbf4cfa002ac2b8a4fa421306ca (diff) | |
Merge pull request #994 from isanae/generic-file-list
New file tree
Diffstat (limited to 'src/filetreeitem.h')
| -rw-r--r-- | src/filetreeitem.h | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/src/filetreeitem.h b/src/filetreeitem.h new file mode 100644 index 00000000..390d5499 --- /dev/null +++ b/src/filetreeitem.h @@ -0,0 +1,320 @@ +#ifndef MODORGANIZER_FILETREEITEM_INCLUDED +#define MODORGANIZER_FILETREEITEM_INCLUDED + +#include "directoryentry.h" +#include <QFileIconProvider> + +class FileTreeModel; + +class FileTreeItem +{ + class Sorter; + +public: + using Ptr = std::unique_ptr<FileTreeItem>; + using Children = std::vector<Ptr>; + + enum Flag + { + NoFlags = 0x00, + FromArchive = 0x01, + Conflicted = 0x02 + }; + + + Q_DECLARE_FLAGS(Flags, Flag); + + static Ptr createFile( + FileTreeModel* model, FileTreeItem* parent, + std::wstring dataRelativeParentPath, std::wstring file); + + static Ptr createDirectory( + FileTreeModel* model, 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(); + m_children.push_back(std::move(child)); + } + + void insert(Ptr child, std::size_t at); + + template <class Itor> + void insert(Itor begin, Itor end, std::size_t at) + { + std::size_t nextRowGuess = m_children.size(); + for (auto itor=begin; itor!=end; ++itor) { + (*itor)->m_indexGuess = nextRowGuess++; + } + + m_children.insert(m_children.begin() + at, begin, end); + } + + void remove(std::size_t i); + void remove(std::size_t from, std::size_t n); + + void clear() + { + m_children.clear(); + m_loaded = false; + } + + const Children& children() const + { + return m_children; + } + + int childIndex(const FileTreeItem& item) const + { + if (item.m_indexGuess < m_children.size()) { + if (m_children[item.m_indexGuess].get() == &item) { + return static_cast<int>(item.m_indexGuess); + } + } + + for (std::size_t i=0; i<m_children.size(); ++i) { + if (m_children[i].get() == &item) { + item.m_indexGuess = i; + return static_cast<int>(i); + } + } + + return -1; + } + + void sort(int column, Qt::SortOrder order, bool force); + + FileTreeItem* parent() + { + return m_parent; + } + + int originID() const + { + return m_originID; + } + + const QString& virtualParentPath() const + { + return m_virtualParentPath; + } + + QString virtualPath() const; + + const QString& filename() const + { + return m_file; + } + + const std::wstring& filenameWs() const + { + return m_wsFile; + } + + const std::wstring& filenameWsLowerCase() const + { + return m_wsLcFile; + } + + const MOShared::DirectoryEntry::FileKey& key() const + { + return m_key; + } + + const QString& mod() const + { + return m_mod; + } + + QFont font() const; + + std::optional<uint64_t> fileSize() const; + std::optional<QDateTime> lastModified() const; + std::optional<QString> fileType() const; + + std::optional<uint64_t> compressedFileSize() const + { + return m_compressedFileSize.value; + } + + void setFileSize(uint64_t size) + { + m_fileSize.override(size); + } + + void setCompressedFileSize(uint64_t compressedSize) + { + m_compressedFileSize.override(compressedSize); + } + + const QString& realPath() const + { + return m_realPath; + } + + const QString& dataRelativeParentPath() const + { + return m_virtualParentPath; + } + + QString dataRelativeFilePath() const; + + QFileIconProvider::IconType icon() const; + + bool isDirectory() const + { + return m_isDirectory; + } + + bool isFromArchive() const + { + return (m_flags & FromArchive); + } + + bool isConflicted() const + { + return (m_flags & Conflicted); + } + + bool isHidden() const; + + bool hasChildren() const + { + if (!isDirectory()) { + return false; + } + + if (isLoaded() && m_children.empty()) { + return false; + } + + return true; + } + + + void setLoaded(bool b) + { + m_loaded = b; + } + + bool isLoaded() const + { + return m_loaded; + } + + void unload(); + + void setExpanded(bool b) + { + if (m_expanded == b) { + return; + } + + m_expanded = b; + + if (m_expanded && m_sortingStale) { + sort(); + } + } + + bool isStrictlyExpanded() const + { + return m_expanded; + } + + bool areChildrenVisible() const; + + QString debugName() const; + +private: + template <class T> + struct Cached + { + std::optional<T> value; + bool failed = false; + bool overridden = false; + + bool empty() const + { + return !failed && !value; + } + + void set(T t) + { + 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; + } + } + }; + + static constexpr std::size_t NoIndexGuess = + std::numeric_limits<std::size_t>::max(); + + FileTreeModel* m_model; + FileTreeItem* m_parent; + mutable std::size_t m_indexGuess; + + const QString m_virtualParentPath; + const std::wstring m_wsFile, m_wsLcFile; + const MOShared::DirectoryEntry::FileKey m_key; + const QString m_file; + const bool m_isDirectory; + + int m_originID; + QString m_realPath; + std::wstring m_wsRealPath; + Flags m_flags; + QString m_mod; + + mutable Cached<uint64_t> m_fileSize; + mutable Cached<QDateTime> m_lastModified; + mutable Cached<QString> m_fileType; + mutable Cached<uint64_t> m_compressedFileSize; + + bool m_loaded; + bool m_expanded; + bool m_sortingStale; + Children m_children; + + + FileTreeItem( + FileTreeModel* model, FileTreeItem* parent, + std::wstring dataRelativeParentPath, bool isDirectory, std::wstring file); + + void getFileType() const; + void sort(); +}; + +#endif // MODORGANIZER_FILETREEITEM_INCLUDED |
