quake-tools/source/quam/archive.h

201 lines
4.1 KiB
C++

#pragma once
#include "common.h"
#include <QAbstractItemModel>
#include <QByteArray>
#include <QMetaObject>
#include <QObject>
#include <QValidator>
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<UniquePtr<Node>>;
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<Node> 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<ArcType> 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