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