From f42028a37859dbda437c068632dc6ec23035d9b1 Mon Sep 17 00:00:00 2001 From: Alison Watson Date: Thu, 3 Oct 2019 15:17:16 -0400 Subject: [PATCH] piss --- CMakeLists.txt | 2 + source/quam/archive.cc | 27 +++++++++ source/quam/archive.h | 61 +++++++++++++++++++ source/quam/main_window.cc | 4 +- source/quam/main_window.h | 1 + source/quam/pak.cc | 121 +++---------------------------------- source/quam/pak.h | 81 +------------------------ source/quam/project.cc | 18 ------ source/quam/project.h | 7 +-- 9 files changed, 107 insertions(+), 215 deletions(-) create mode 100644 source/quam/archive.cc create mode 100644 source/quam/archive.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c1bae5f..c36ab52 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,8 @@ find_package( add_executable( quam WIN32 source/common.h + source/quam/archive.cc + source/quam/archive.h source/quam/main.cc source/quam/main_window.cc source/quam/main_window.h diff --git a/source/quam/archive.cc b/source/quam/archive.cc new file mode 100644 index 0000000..2ad26d3 --- /dev/null +++ b/source/quam/archive.cc @@ -0,0 +1,27 @@ +#include "quam/archive.h" + +#include + +Arc::FileType Arc::getFileType(int n) { + if(int t = QMetaEnum::fromType().value(n); n != -1) { + return Arc::FileType(t); + } else { + throw std::range_error("invalid file type"); + } +} + +ArcNode::ArcNode(ArcDir &&t, std::string &&n, Arc::FileType ty) : + super_type(std::move(t)), + name(std::move(n)), + type(ty) +{ +} + +ArcNode::ArcNode(ArcFile &&t, std::string &&n, Arc::FileType ty) : + super_type(std::move(t)), + name(std::move(n)), + type(ty) +{ +} + +// EOF diff --git a/source/quam/archive.h b/source/quam/archive.h new file mode 100644 index 0000000..8a2ba4f --- /dev/null +++ b/source/quam/archive.h @@ -0,0 +1,61 @@ +#pragma once + +#include "common.h" + +#include +#include + +namespace Arc { + Q_NAMESPACE + + enum Column { + ColumnSize, + ColumnName, + ColumnMax, + }; + Q_ENUM_NS(Column) + + enum FileType { + FileNormal, + FileLabel, + + FilePalette = 64, + FileTexture, + FilePicture, + FileSound, + FileMipTexture, + }; + Q_ENUM_NS(FileType) + + Arc::FileType getFileType(int n); +} + +struct ArcNode; + +struct ArcDir : public std::vector { + using std::vector::vector; +}; +Q_DECLARE_METATYPE(ArcDir) + +struct ArcFile : public QByteArray { + using QByteArray::QByteArray; +}; +Q_DECLARE_METATYPE(ArcFile) + +struct ArcNode : public std::variant { + using super_type = std::variant; + + ArcNode() = default; + + ArcNode(ArcDir &&t, std::string &&n, Arc::FileType ty = Arc::FileNormal); + ArcNode(ArcFile &&t, std::string &&n, Arc::FileType ty = Arc::FileNormal); + + ArcNode(ArcNode const &) = default; + ArcNode(ArcNode &&) = default; + + std::string name; + Arc::FileType type; +}; +Q_DECLARE_METATYPE(ArcNode) + +// EOF diff --git a/source/quam/main_window.cc b/source/quam/main_window.cc index b32a8e1..806c32a 100644 --- a/source/quam/main_window.cc +++ b/source/quam/main_window.cc @@ -1,4 +1,3 @@ -#include "common.h" #include "quam/main_window.h" #include "quam/project.h" @@ -34,7 +33,8 @@ void MainWindow::fileOpen() { try { auto st = openReadBin(fileName.toStdString()); auto pak = readPak(st); - new Project{std::move(pak), m_errors, mdiArea}; + Q_UNUSED(pak); + //new Project{std::move(pak), m_errors, mdiArea}; } catch(std::exception const &exc) { m_errors->showMessage(tr(exc.what())); } diff --git a/source/quam/main_window.h b/source/quam/main_window.h index 29031c4..a7347d0 100644 --- a/source/quam/main_window.h +++ b/source/quam/main_window.h @@ -1,5 +1,6 @@ #pragma once +#include "common.h" #include "quam/pak.h" #include "quam/ui_main_window.h" diff --git a/source/quam/pak.cc b/source/quam/pak.cc index 2edbc10..ec4d219 100644 --- a/source/quam/pak.cc +++ b/source/quam/pak.cc @@ -1,4 +1,3 @@ -#include "common.h" #include "quam/pak.h" #include @@ -11,7 +10,7 @@ struct PakHeader { struct PakEntry { std::string name; - PakFile file; + ArcFile file; }; static constexpr quint32 sizeOfPakEntry = 64; @@ -45,15 +44,14 @@ static PakEntry readPakEntry(std::istream &st) { st.seekg(entOffset); - PakFile file; + ArcFile file; file.resize(entSize); st.read(file.data(), entSize); st.seekg(pos); - auto zero = std::find(entName.cbegin(), entName.cend(), '\0'); - std::string name; + auto zero = std::find(entName.cbegin(), entName.cend(), '\0'); std::copy(entName.cbegin(), zero, std::back_inserter(name)); if(name.front() == '/') { @@ -66,7 +64,7 @@ static PakEntry readPakEntry(std::istream &st) { return ent; } -void insertFile(PakDir &dir, std::string name, PakFile file) { +void insertFile(ArcDir &dir, std::string name, ArcFile file) { std::optional next; if(auto slash = name.find('/'); slash != std::string::npos) { @@ -75,7 +73,7 @@ void insertFile(PakDir &dir, std::string name, PakFile file) { } auto existingNode = std::find_if(dir.begin(), dir.end(), - [&name](PakNode const &node) { + [&name](ArcNode const &node) { return node.name == name; }); @@ -83,8 +81,8 @@ void insertFile(PakDir &dir, std::string name, PakFile file) { auto ref = existingNode != dir.end() ? *existingNode - : dir.emplace_back(PakDir{}, std::move(name)); - insertFile(std::get(ref), *std::move(next), std::move(file)); + : dir.emplace_back(ArcDir{}, std::move(name)); + insertFile(std::get(ref), *std::move(next), std::move(file)); } else { if(existingNode != dir.end()) { throw std::runtime_error("duplicate file"); @@ -93,11 +91,11 @@ void insertFile(PakDir &dir, std::string name, PakFile file) { } } -PakDir readPak(std::istream &st) { +ArcDir readPak(std::istream &st) { auto hdr = readPakHeader(st); st.seekg(hdr.dirOffset); - PakDir root; + ArcDir root; for(quint32 i = 0; i < hdr.dirNum; i++) { auto ent = readPakEntry(st); @@ -107,105 +105,4 @@ PakDir readPak(std::istream &st) { return root; } -PakDirRoot::PakDirRoot(PakDir &&root, QObject *parent) : - QObject{parent}, - PakDir{std::move(root)} -{ -} - -PakDirRoot::~PakDirRoot() { -} - -PakDirModel::PakDirModel(PakDir const *root, QObject *parent) : - QAbstractItemModel{parent}, - m_root{root} -{ -} - -PakDirModel::~PakDirModel() { -} - -QVariant PakDirModel::data(QModelIndex const &index, int role) const { - if(!index.isValid()) { - return QVariant{}; - } - - auto node = static_cast(index.internalPointer()); - auto col = Pak::Column(index.column()); - - switch(role) { - case Qt::DecorationRole: - if(col == Pak::Column::Name) { - auto icon = - std::holds_alternative(*node) ? "folder" - : "text-x-generic"; - return QVariant{QIcon::fromTheme(icon)}; - } - break; - case Qt::DisplayRole: - switch(col) { - case Pak::Column::Size: - if(auto file = std::get_if(node)) { - return QVariant{QString::number(file->size())}; - } - break; - case Pak::Column::Name: - return QVariant{tr(node->name.data())}; - } - default: - break; - } - return QVariant{}; -} - -Qt::ItemFlags PakDirModel::flags(QModelIndex const &index) const { - if(!index.isValid()) { - return Qt::NoItemFlags; - } else { - return Qt::ItemIsSelectable | - Qt::ItemIsDragEnabled | - Qt::ItemIsEnabled | - Qt::ItemNeverHasChildren; - } -} - -QVariant PakDirModel::headerData(int section, - Qt::Orientation orientation, - int role) const { - if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch(Pak::Column(section)) { - case Pak::Column::Size: return QVariant{tr("Size")}; - case Pak::Column::Name: return QVariant{tr("Name")}; - } - } - return QVariant{}; -} - -QModelIndex PakDirModel::index(int row, - int col, - QModelIndex const &parent) const { - if(!hasIndex(row, col, parent) || row > m_root->size()) { - return QModelIndex{}; - } else { - // despite index data being const, this function does not take a const - // pointer, which is very annoying! - return createIndex(row, col, const_cast(&m_root->at(row))); - } -} - -QModelIndex PakDirModel::parent(QModelIndex const &) const { - return QModelIndex{}; -} - -int PakDirModel::rowCount(QModelIndex const &) const { - return m_root->size(); -} - -int PakDirModel::columnCount(QModelIndex const &) const { - return QMetaEnum::fromType().keyCount(); -} - -PakDirModelSorter::~PakDirModelSorter() { -} - // EOF diff --git a/source/quam/pak.h b/source/quam/pak.h index 42c5443..af1505a 100644 --- a/source/quam/pak.h +++ b/source/quam/pak.h @@ -1,83 +1,8 @@ #pragma once -#include -#include +#include "common.h" +#include "quam/archive.h" -namespace Pak { - Q_NAMESPACE - - enum class Column { - Size, - Name, - }; - Q_ENUM_NS(Column) -} - -struct PakNode; - -struct PakDir : public std::vector { - using std::vector::vector; -}; -Q_DECLARE_METATYPE(PakDir) - -struct PakFile : public QByteArray { - using QByteArray::QByteArray; -}; -Q_DECLARE_METATYPE(PakFile) - -struct PakNode : public std::variant { - PakNode() = default; - - template - constexpr PakNode(T &&t, std::string &&n) : - variant(std::move(t)), - name(std::move(n)) { - } - - PakNode(PakNode const &) = default; - PakNode(PakNode &&) = default; - - std::string name; -}; -Q_DECLARE_METATYPE(PakNode) - -class PakDirRoot : public QObject, public PakDir { - Q_OBJECT - -public: - explicit PakDirRoot(PakDir &&root, QObject *parent); - virtual ~PakDirRoot(); -}; - -class PakDirModel : public QAbstractItemModel { - Q_OBJECT - -public: - explicit PakDirModel(PakDir const *root, QObject *parent); - virtual ~PakDirModel(); - - QVariant data(QModelIndex const &index, int role) const override; - Qt::ItemFlags flags(QModelIndex const &index) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) - const override; - QModelIndex index(int row, int col, QModelIndex const &parent) - const override; - QModelIndex parent(QModelIndex const &index) const override; - int rowCount(QModelIndex const &parent) const override; - int columnCount(QModelIndex const &parent) const override; - -private: - PakDir const *const m_root; -}; - -class PakDirModelSorter : public QSortFilterProxyModel { - Q_OBJECT - -public: - using QSortFilterProxyModel::QSortFilterProxyModel; - virtual ~PakDirModelSorter(); -}; - -PakDir readPak(std::istream &st); +ArcDir readPak(std::istream &st); // EOF diff --git a/source/quam/project.cc b/source/quam/project.cc index 6c6c519..96e9db6 100644 --- a/source/quam/project.cc +++ b/source/quam/project.cc @@ -1,4 +1,3 @@ -#include "common.h" #include "quam/project.h" #include @@ -18,24 +17,7 @@ Project::Project(QErrorMessage *errors, QMdiArea *parent) : showMaximized(); } -Project::Project(PakDir &&dir, QErrorMessage *errors, QMdiArea *parent) : - Project{errors, parent} -{ - auto root = new PakDirRoot{std::move(dir), this}; - auto model = new PakDirModel{root, this}; - setupModel(model); -} - Project::~Project() { } -void Project::setupModel(QAbstractItemModel *model) { - m_model = model; - m_sorter = new QSortFilterProxyModel{this}; - m_sorter->setSourceModel(m_model); - tableView->setModel(m_sorter); - tableView->sortByColumn(int(Pak::Column::Name), Qt::AscendingOrder); - tableView->resizeColumnsToContents(); -} - // EOF diff --git a/source/quam/project.h b/source/quam/project.h index ec0fce5..c41c597 100644 --- a/source/quam/project.h +++ b/source/quam/project.h @@ -1,5 +1,6 @@ #pragma once +#include "common.h" #include "quam/pak.h" #include "quam/ui_project.h" @@ -15,14 +16,10 @@ class Project : public QMdiSubWindow, private Ui::Project { Q_OBJECT public: - explicit Project(PakDir &&dir, QErrorMessage *errors, QMdiArea *parent); + explicit Project(QErrorMessage *errors, QMdiArea *parent); virtual ~Project(); private: - explicit Project(QErrorMessage *errors, QMdiArea *parent); - - void setupModel(QAbstractItemModel *model); - QErrorMessage *m_errors; QAbstractItemModel *m_model; QSortFilterProxyModel *m_sorter;