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)
|
|
|
|
|
2019-10-05 16:58:19 -07:00
|
|
|
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-05 16:58:19 -07:00
|
|
|
};
|
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;
|
2019-10-05 16:58:19 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
class Model : public QAbstractItemModel {
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit Model(QObject *parent);
|
|
|
|
~Model();
|
2019-10-03 12:17:16 -07:00
|
|
|
|
2019-10-05 16:58:19 -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)
|
2019-10-05 16:58:19 -07:00
|
|
|
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())
|
2019-10-05 16:58:19 -07:00
|
|
|
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
|
|
|
|
2019-10-05 16:58:19 -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);
|
|
|
|
|
2019-10-05 16:58:19 -07:00
|
|
|
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
|
|
|
|
2019-10-05 16:58:19 -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
|
|
|
|
2019-10-05 16:58:19 -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-05 16:58:19 -07:00
|
|
|
}
|
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
|