crime spaghetti
This commit is contained in:
parent
ed5f825b5a
commit
4c118e2b63
|
@ -120,6 +120,15 @@ static inline int enumMax() {
|
||||||
return QMetaEnum::fromType<T>().keyCount();
|
return QMetaEnum::fromType<T>().keyCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static inline T orThrow(Option<T> opt, Error err) {
|
||||||
|
if(opt) {
|
||||||
|
return *opt;
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline QDebug operator<<(QDebug debug, std::string const &t) {
|
static inline QDebug operator<<(QDebug debug, std::string const &t) {
|
||||||
debug << QString::fromStdString(t);
|
debug << QString::fromStdString(t);
|
||||||
return debug;
|
return debug;
|
||||||
|
|
|
@ -18,14 +18,42 @@ namespace Arc {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dir readArchive(std::istream &st) {
|
Dir Dir::readArchive(std::istream &st, ArcType type) {
|
||||||
switch(auto v = getArchiveType(st);
|
switch(type) {
|
||||||
v.has_value() ? *v : throw FileFormatError("not an archive")) {
|
|
||||||
case ArcType::Pack: return readPack(st);
|
case ArcType::Pack: return readPack(st);
|
||||||
case ArcType::Wad2: return readWad2(st);
|
case ArcType::Wad2: return readWad2(st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArcInfo::ArcInfo(ArcType arcType) noexcept :
|
||||||
|
type{arcType}
|
||||||
|
{
|
||||||
|
switch(type) {
|
||||||
|
case ArcType::Pack:
|
||||||
|
pathMaxChars = 56;
|
||||||
|
validatorType = PackValidator::staticMetaObject;
|
||||||
|
break;
|
||||||
|
case ArcType::Wad2:
|
||||||
|
pathMaxChars = 16;
|
||||||
|
validatorType = Wad2Validator::staticMetaObject;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Arc::Arc(std::istream &st, QObject *parent) :
|
||||||
|
QObject{parent},
|
||||||
|
info{ArcInfo(orThrow(getArchiveType(st),
|
||||||
|
FileFormatError("not an archive")))},
|
||||||
|
root{Dir::readArchive(st, info.type)},
|
||||||
|
validator{qobject_cast<QValidator *>(info.validatorType
|
||||||
|
.newInstance(Q_ARG(QObject *,
|
||||||
|
this)))}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Arc::~Arc() {
|
||||||
|
}
|
||||||
|
|
||||||
Node *Dir::findNode(std::string const &name) {
|
Node *Dir::findNode(std::string const &name) {
|
||||||
auto it = std::find_if(begin(), end(), [&name](Node &node) {
|
auto it = std::find_if(begin(), end(), [&name](Node &node) {
|
||||||
return node.name == name;
|
return node.name == name;
|
||||||
|
@ -143,17 +171,25 @@ namespace Arc {
|
||||||
return m_dir;
|
return m_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::setDir(Dir *dir) {
|
void Model::setDir(Dir *to) {
|
||||||
if(dir != m_dir) {
|
auto from = m_dir;
|
||||||
|
if(to != from) {
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
for(int row = 0, rows = rowCount(); row < rows; row++) {
|
for(int row = 0, rows = rowCount(); row < rows; row++) {
|
||||||
for(int col = 0, cols = columnCount(); col < cols; col++) {
|
for(int col = 0, cols = columnCount(); col < cols; col++) {
|
||||||
changePersistentIndex(index(row, col), QModelIndex{});
|
changePersistentIndex(index(row, col), QModelIndex{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_dir = dir;
|
m_dir = to;
|
||||||
emit layoutChanged();
|
emit layoutChanged();
|
||||||
emit dirChanged(dir);
|
emit dirChanged(from, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::setDirToIndex(QModelIndex const &ind) {
|
||||||
|
auto node = static_cast<Node *>(ind.data(Qt::UserRole).value<void *>());
|
||||||
|
if(auto dir = std::get_if<Dir>(node)) {
|
||||||
|
setDir(dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,13 @@
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
#include <QMetaObject>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QValidator>
|
||||||
|
|
||||||
namespace Arc {
|
namespace Arc {
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
|
||||||
struct Node;
|
|
||||||
struct Dir;
|
|
||||||
|
|
||||||
enum class Column {
|
enum class Column {
|
||||||
Size,
|
Size,
|
||||||
Type,
|
Type,
|
||||||
|
@ -36,14 +35,14 @@ namespace Arc {
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(ArcType)
|
Q_ENUM_NS(ArcType)
|
||||||
|
|
||||||
Option<ArcType> getArchiveType(std::istream &st) noexcept;
|
struct Node;
|
||||||
|
|
||||||
Dir readArchive(std::istream &st);
|
|
||||||
|
|
||||||
struct Dir : public std::vector<Node> {
|
struct Dir : public std::vector<Node> {
|
||||||
using std::vector<Node>::vector;
|
using std::vector<Node>::vector;
|
||||||
|
|
||||||
Node *findNode(std::string const &name);
|
Node *findNode(std::string const &name);
|
||||||
|
|
||||||
|
static Dir readArchive(std::istream &st, ArcType type);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct File : public QByteArray {
|
struct File : public QByteArray {
|
||||||
|
@ -89,13 +88,36 @@ namespace Arc {
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setDir(Dir *dir);
|
void setDir(Dir *dir);
|
||||||
|
void setDirToIndex(QModelIndex const &ind);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dirChanged(Dir *dir);
|
void dirChanged(Dir *from, Dir *to);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Dir *m_dir;
|
Dir *m_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ArcInfo {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
Q_DECLARE_METATYPE(Arc::Dir)
|
Q_DECLARE_METATYPE(Arc::Dir)
|
||||||
Q_DECLARE_METATYPE(Arc::File)
|
Q_DECLARE_METATYPE(Arc::File)
|
||||||
|
|
|
@ -43,9 +43,7 @@ static int modeText(int argc, char *argv[]) {
|
||||||
auto fileName = par.value(fileNameOpt).toStdString();
|
auto fileName = par.value(fileNameOpt).toStdString();
|
||||||
|
|
||||||
auto st = openReadBin(fileName);
|
auto st = openReadBin(fileName);
|
||||||
auto arc = Arc::readArchive(st);
|
qDebug() << Arc::Arc(st).root;
|
||||||
|
|
||||||
qDebug() << arc;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,8 @@ void MainWindow::fileOpen() {
|
||||||
|
|
||||||
if(!fileName.isEmpty()) {
|
if(!fileName.isEmpty()) {
|
||||||
try {
|
try {
|
||||||
auto st = openReadBin(fileName.toStdString());
|
auto st = openReadBin(fileName.toStdString());
|
||||||
auto arc = Arc::readArchive(st);
|
new Project{st, m_errors, mdiArea};
|
||||||
new Project{std::move(arc), m_errors, mdiArea};
|
|
||||||
} catch(std::exception const &exc) {
|
} catch(std::exception const &exc) {
|
||||||
m_errors->showMessage(tr(exc.what()));
|
m_errors->showMessage(tr(exc.what()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,4 +93,13 @@ Arc::Dir readPack(std::istream &st) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PackValidator::PackValidator(QObject *parent) :
|
||||||
|
QValidator{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QValidator::State PackValidator::validate(QString &input, int &pos) const {
|
||||||
|
return QValidator::Acceptable;
|
||||||
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -4,6 +4,17 @@
|
||||||
|
|
||||||
#include "quam/archive.h"
|
#include "quam/archive.h"
|
||||||
|
|
||||||
|
#include <QValidator>
|
||||||
|
|
||||||
|
class PackValidator : public QValidator {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE explicit PackValidator(QObject *parent);
|
||||||
|
|
||||||
|
QValidator::State validate(QString &input, int &pos) const override;
|
||||||
|
};
|
||||||
|
|
||||||
Arc::Dir readPack(std::istream &st);
|
Arc::Dir readPack(std::istream &st);
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -5,15 +5,17 @@
|
||||||
#include <QMdiArea>
|
#include <QMdiArea>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
Project::Project(Arc::Dir &&arc, QErrorMessage *errors, QMdiArea *parent) :
|
Project::Project(std::istream &st, QErrorMessage *errors, QMdiArea *parent) :
|
||||||
QMdiSubWindow{parent},
|
QMdiSubWindow{parent},
|
||||||
Ui::Project{},
|
Ui::Project{},
|
||||||
m_arc{std::move(arc)},
|
m_arc{new Arc::Arc{st, this}},
|
||||||
|
m_root{&m_arc->root},
|
||||||
|
m_lastDir{nullptr},
|
||||||
m_errors{errors},
|
m_errors{errors},
|
||||||
m_model{new Arc::Model{this}},
|
m_model{new Arc::Model{this}},
|
||||||
m_sorter{new QSortFilterProxyModel{this}}
|
m_sorter{new QSortFilterProxyModel{this}}
|
||||||
{
|
{
|
||||||
auto widget = new QWidget(this);
|
auto widget = new QWidget{this};
|
||||||
setupUi(widget);
|
setupUi(widget);
|
||||||
setWidget(widget);
|
setWidget(widget);
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
@ -22,26 +24,19 @@ Project::Project(Arc::Dir &&arc, QErrorMessage *errors, QMdiArea *parent) :
|
||||||
connect(m_model, &Arc::Model::dirChanged,
|
connect(m_model, &Arc::Model::dirChanged,
|
||||||
this, &Project::dirChanged);
|
this, &Project::dirChanged);
|
||||||
connect(tableView, &QAbstractItemView::doubleClicked,
|
connect(tableView, &QAbstractItemView::doubleClicked,
|
||||||
this, &Project::viewDoubleClicked);
|
m_model, &Arc::Model::setDirToIndex);
|
||||||
|
|
||||||
m_sorter->setSourceModel(m_model);
|
m_sorter->setSourceModel(m_model);
|
||||||
tableView->setModel(m_sorter);
|
tableView->setModel(m_sorter);
|
||||||
m_model->setDir(&m_arc);
|
m_model->setDir(m_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
Project::~Project() {
|
Project::~Project() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::dirChanged(Arc::Dir *) {
|
void Project::dirChanged(Arc::Dir *from, Arc::Dir *to) {
|
||||||
|
m_lastDir = from;
|
||||||
tableView->resizeColumnsToContents();
|
tableView->resizeColumnsToContents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Project::viewDoubleClicked(QModelIndex const &index) {
|
|
||||||
auto node = static_cast<Arc::Node *>(index.data(Qt::UserRole)
|
|
||||||
.value<void *>());
|
|
||||||
if(auto dir = std::get_if<Arc::Dir>(node)) {
|
|
||||||
m_model->setDir(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -17,15 +17,15 @@ class Project : public QMdiSubWindow, private Ui::Project {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Project(Arc::Dir &&arc, QErrorMessage *errors, QMdiArea *parent);
|
explicit Project(std::istream &st, QErrorMessage *errors, QMdiArea *parent);
|
||||||
virtual ~Project();
|
virtual ~Project();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void dirChanged(Arc::Dir *dir);
|
void dirChanged(Arc::Dir *from, Arc::Dir *to);
|
||||||
void viewDoubleClicked(QModelIndex const &index);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Arc::Dir m_arc;
|
Arc::Arc *m_arc;
|
||||||
|
Arc::Dir *m_root, *m_lastDir;
|
||||||
QErrorMessage *m_errors;
|
QErrorMessage *m_errors;
|
||||||
Arc::Model *m_model;
|
Arc::Model *m_model;
|
||||||
QSortFilterProxyModel *m_sorter;
|
QSortFilterProxyModel *m_sorter;
|
||||||
|
|
|
@ -19,43 +19,66 @@
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTableView" name="tableView">
|
<widget class="QWidget" name="">
|
||||||
<property name="verticalScrollBarPolicy">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
<item>
|
||||||
</property>
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<property name="horizontalScrollBarPolicy">
|
<item>
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<widget class="QLineEdit" name="dirName"/>
|
||||||
</property>
|
</item>
|
||||||
<property name="autoScroll">
|
<item>
|
||||||
<bool>false</bool>
|
<widget class="QPushButton" name="buttonUp">
|
||||||
</property>
|
<property name="icon">
|
||||||
<property name="tabKeyNavigation">
|
<iconset theme="go-up"/>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="flat">
|
||||||
<property name="alternatingRowColors">
|
<bool>true</bool>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="selectionMode">
|
</item>
|
||||||
<enum>QAbstractItemView::SingleSelection</enum>
|
</layout>
|
||||||
</property>
|
</item>
|
||||||
<property name="selectionBehavior">
|
<item>
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
<widget class="QTableView" name="tableView">
|
||||||
</property>
|
<property name="verticalScrollBarPolicy">
|
||||||
<property name="showGrid">
|
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||||
<bool>false</bool>
|
</property>
|
||||||
</property>
|
<property name="horizontalScrollBarPolicy">
|
||||||
<property name="sortingEnabled">
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
<property name="autoScroll">
|
||||||
<attribute name="horizontalHeaderVisible">
|
<bool>false</bool>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</attribute>
|
<property name="tabKeyNavigation">
|
||||||
<attribute name="horizontalHeaderStretchLastSection">
|
<bool>true</bool>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</attribute>
|
<property name="alternatingRowColors">
|
||||||
<attribute name="verticalHeaderVisible">
|
<bool>true</bool>
|
||||||
<bool>false</bool>
|
</property>
|
||||||
</attribute>
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::SingleSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
|
<property name="showGrid">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="sortingEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<attribute name="horizontalHeaderVisible">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="horizontalHeaderStretchLastSection">
|
||||||
|
<bool>true</bool>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="verticalHeaderVisible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPlainTextEdit" name="textEdit"/>
|
<widget class="QPlainTextEdit" name="textEdit"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -88,4 +88,13 @@ Arc::Dir readWad2(std::istream &st) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wad2Validator::Wad2Validator(QObject *parent) :
|
||||||
|
QValidator{parent}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QValidator::State Wad2Validator::validate(QString &input, int &pos) const {
|
||||||
|
return QValidator::Acceptable;
|
||||||
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
|
@ -4,6 +4,17 @@
|
||||||
|
|
||||||
#include "quam/archive.h"
|
#include "quam/archive.h"
|
||||||
|
|
||||||
|
#include <QValidator>
|
||||||
|
|
||||||
|
class Wad2Validator : public QValidator {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE explicit Wad2Validator(QObject *parent);
|
||||||
|
|
||||||
|
QValidator::State validate(QString &input, int &pos) const override;
|
||||||
|
};
|
||||||
|
|
||||||
Arc::Dir readWad2(std::istream &st);
|
Arc::Dir readWad2(std::istream &st);
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
|
Loading…
Reference in New Issue
Block a user