quake-tools/source/quam/archive.h

201 lines
4.1 KiB
C
Raw Normal View History

2019-10-03 12:17:16 -07:00
#pragma once
#include "common.h"
2019-10-04 10:37:34 -07:00
#include <QAbstractItemModel>
2019-10-03 12:17:16 -07:00
#include <QByteArray>
2019-10-09 16:06:14 -07:00
#include <QMetaObject>
2019-10-04 10:37:34 -07:00
#include <QObject>
2019-10-09 16:06:14 -07:00
#include <QValidator>
2019-10-04 10:37:34 -07:00
2019-10-03 12:17:16 -07:00
namespace Arc {
Q_NAMESPACE
2019-10-08 20:43:35 -07:00
enum class Column {
Size,
Type,
Name,
2019-10-03 12:17:16 -07:00
};
Q_ENUM_NS(Column)
enum class FileType {
Label,
MipTexture,
Normal,
Palette,
Picture,
Sound,
Texture,
2019-10-03 12:17:16 -07:00
};
Q_ENUM_NS(FileType)
2019-10-08 20:43:35 -07:00
enum class ArcType {
Pack,
Wad2,
2019-10-04 10:37:34 -07:00
};
2019-10-08 20:43:35 -07:00
Q_ENUM_NS(ArcType)
2019-10-04 10:37:34 -07:00
2019-10-10 14:29:08 -07:00
class Dir;
class File;
2019-10-03 12:17:16 -07:00
2019-10-10 14:29:08 -07:00
class Node {
public:
Node() = delete;
Node(Node const &) = delete;
Node(Node &&) = default;
virtual ~Node();
2019-10-03 12:17:16 -07:00
2019-10-10 14:29:08 -07:00
virtual Dir const *getDir() const = 0;
virtual Dir *getDir() = 0;
virtual File const *getFile() const = 0;
virtual File *getFile() = 0;
2019-10-09 16:06:14 -07:00
2019-11-06 22:42:59 -08:00
Dir *getRoot();
Node *findPath(std::string path);
std::string getPath(bool fromChild = false) const;
2019-10-10 14:29:08 -07:00
Dir *parent{nullptr};
std::string name;
2019-10-03 14:06:05 -07:00
2019-10-10 14:29:08 -07:00
protected:
2019-11-06 22:42:59 -08:00
Node(std::string name);
};
2019-10-03 12:17:16 -07:00
2019-11-06 22:42:59 -08:00
class Dir : public Node {
2019-10-10 14:29:08 -07:00
public:
2019-11-06 22:42:59 -08:00
using DataType = std::vector<UniquePtr<Node>>;
2019-10-03 12:17:16 -07:00
2019-11-06 22:42:59 -08:00
Dir(std::string name);
2019-10-10 14:29:08 -07:00
Dir(Dir const &) = delete;
Dir(Dir &&) = default;
virtual ~Dir();
2019-10-03 12:17:16 -07:00
2019-10-10 14:29:08 -07:00
Dir const *getDir() const override {return this;}
Dir *getDir() override {return this;}
File const *getFile() const override {return nullptr;}
File *getFile() override {return nullptr;}
2019-10-03 12:17:16 -07:00
2019-11-06 22:42:59 -08:00
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);
2019-10-10 14:29:08 -07:00
Node *findNode(std::string const &name);
2019-10-03 12:17:16 -07:00
2019-10-10 14:29:08 -07:00
static Dir readArchive(std::istream &st, ArcType type);
2019-11-06 22:42:59 -08:00
private:
DataType m_data;
2019-10-10 14:29:08 -07:00
};
2019-11-06 22:42:59 -08:00
class File : public Node {
2019-10-10 14:29:08 -07:00
public:
2019-11-06 22:42:59 -08:00
using DataType = QByteArray;
2019-10-10 14:29:08 -07:00
2019-11-06 22:42:59 -08:00
File(std::string name, QByteArray &&data);
2019-10-10 14:29:08 -07:00
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;}
2019-11-06 22:42:59 -08:00
DataType const &data() const {return m_data;}
std::size_t size() const {return m_data.size();}
2019-10-10 14:29:08 -07:00
FileType type{FileType::Normal};
2019-11-06 22:42:59 -08:00
private:
DataType m_data;
};
class Model : public QAbstractItemModel {
Q_OBJECT
public:
explicit Model(QObject *parent);
~Model();
2019-10-03 12:17:16 -07:00
QVariant data(QModelIndex const &index, int role) const override;
Qt::ItemFlags flags(QModelIndex const &index) const override;
2019-10-08 20:43:35 -07:00
QVariant headerData(int section, Qt::Orientation ori, int role)
const override;
QModelIndex index(int row,
2019-10-08 20:43:35 -07:00
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;
2019-10-03 12:17:16 -07:00
Dir *dir() const;
2019-10-04 10:37:34 -07:00
2019-11-06 22:42:59 -08:00
Node *findPath(std::string path);
public slots:
void setDir(Dir *dir);
2019-10-09 16:06:14 -07:00
void setDirToIndex(QModelIndex const &ind);
2019-11-06 22:42:59 -08:00
bool goUp();
bool goPath(std::string path);
2019-10-04 10:37:34 -07:00
signals:
2019-10-09 16:06:14 -07:00
void dirChanged(Dir *from, Dir *to);
2019-10-04 10:37:34 -07:00
private:
Dir *m_dir;
};
2019-10-09 16:06:14 -07:00
2019-10-10 14:29:08 -07:00
class ArcInfo {
public:
2019-10-09 16:06:14 -07:00
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;
}
2019-10-10 14:29:08 -07:00
static inline QDebug operator<<(QDebug debug, Arc::Dir const &t) {
2019-11-06 22:42:59 -08:00
debug << t.data();
2019-10-10 14:29:08 -07:00
return debug;
}
static inline QDebug operator<<(QDebug debug, Arc::File const &t) {
2019-11-06 22:42:59 -08:00
debug << t.data();
2019-10-10 14:29:08 -07:00
return debug;
}
2019-10-04 10:37:34 -07:00
2019-10-08 20:43:35 -07:00
static inline QDebug operator<<(QDebug debug, Arc::Node const &t) {
debug << "Arc::Node(" << t.name << ", ";
2019-10-10 14:29:08 -07:00
if(auto v = t.getDir()) {
debug << *v;
} else if(auto v = t.getFile()) {
debug << *v;
}
2019-10-08 20:43:35 -07:00
debug << ")";
return debug;
}
2019-10-03 12:17:16 -07:00
// EOF