#pragma once #include "common.h" #include #include #include #include #include namespace Arc { Q_NAMESPACE enum class Column { Size, Type, Name, }; Q_ENUM_NS(Column) enum class FileType { Label, MipTexture, Normal, Palette, Picture, Sound, Texture, }; Q_ENUM_NS(FileType) enum class ArcType { Pack, Wad2, }; Q_ENUM_NS(ArcType) class Dir; class File; class Node { public: Node() = delete; Node(Node const &) = delete; Node(Node &&) = default; virtual ~Node(); virtual Dir const *getDir() const = 0; virtual Dir *getDir() = 0; virtual File const *getFile() const = 0; virtual File *getFile() = 0; Dir *getRoot(); Node *findPath(std::string path); std::string getPath(bool fromChild = false) const; Dir *parent{nullptr}; std::string name; protected: Node(std::string name); }; class Dir : public Node { public: using DataType = std::vector>; Dir(std::string name); Dir(Dir const &) = delete; Dir(Dir &&) = default; virtual ~Dir(); Dir const *getDir() const override {return this;} Dir *getDir() override {return this;} File const *getFile() const override {return nullptr;} File *getFile() override {return nullptr;} DataType const &data() const {return m_data;} Node *at(std::size_t i) const {return &*m_data.at(i);} std::size_t size() const {return m_data.size();} UniquePtr const &emplaceBack(Node *node); Node *findNode(std::string const &name); static Dir readArchive(std::istream &st, ArcType type); private: DataType m_data; }; class File : public Node { public: using DataType = QByteArray; File(std::string name, QByteArray &&data); File(File const &) = delete; File(File &&) = default; virtual ~File(); Dir const *getDir() const override {return nullptr;} Dir *getDir() override {return nullptr;} File const *getFile() const override {return this;} File *getFile() override {return this;} DataType const &data() const {return m_data;} std::size_t size() const {return m_data.size();} FileType type{FileType::Normal}; private: DataType m_data; }; class Model : public QAbstractItemModel { Q_OBJECT public: explicit Model(QObject *parent); ~Model(); QVariant data(QModelIndex const &index, int role) const override; Qt::ItemFlags flags(QModelIndex const &index) const override; QVariant headerData(int section, Qt::Orientation ori, int role) const override; QModelIndex index(int row, int col, QModelIndex const &parent = QModelIndex()) const override; QModelIndex parent(QModelIndex const &index = QModelIndex()) const override; int rowCount(QModelIndex const &index = QModelIndex()) const override; int columnCount(QModelIndex const &index = QModelIndex()) const override; Dir *dir() const; Node *findPath(std::string path); public slots: void setDir(Dir *dir); void setDirToIndex(QModelIndex const &ind); bool goUp(); bool goPath(std::string path); signals: void dirChanged(Dir *from, Dir *to); private: Dir *m_dir; }; class ArcInfo { public: ArcInfo(ArcType arcType) noexcept; ArcType type; std::size_t pathMaxChars; QMetaObject validatorType; }; class Arc : QObject { Q_OBJECT public: explicit Arc(std::istream &st, QObject *parent = nullptr); ~Arc(); ArcInfo info; Dir root; QValidator *validator; }; Option getArchiveType(std::istream &st) noexcept; } static inline QDebug operator<<(QDebug debug, Arc::Dir const &t) { debug << t.data(); return debug; } static inline QDebug operator<<(QDebug debug, Arc::File const &t) { debug << t.data(); return debug; } static inline QDebug operator<<(QDebug debug, Arc::Node const &t) { debug << "Arc::Node(" << t.name << ", "; if(auto v = t.getDir()) { debug << *v; } else if(auto v = t.getFile()) { debug << *v; } debug << ")"; return debug; } // EOF