diff --git a/CMakeLists.txt b/CMakeLists.txt index 07c8ccb..c1bae5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,10 @@ add_executable( source/quam/main_window.h source/quam/main_window.ui source/quam/pak.cc - source/quam/pak.h) + source/quam/pak.h + source/quam/project.cc + source/quam/project.h + source/quam/project.ui) make_qt_project(quam) diff --git a/source/quam/main_window.cc b/source/quam/main_window.cc index 23580c0..b32a8e1 100644 --- a/source/quam/main_window.cc +++ b/source/quam/main_window.cc @@ -1,28 +1,20 @@ #include "common.h" #include "quam/main_window.h" -#include "quam/pak.h" +#include "quam/project.h" -#include #include #include -#include MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent}, Ui::MainWindow{}, - m_directory{}, - m_errors{new QErrorMessage{this}}, - m_model{nullptr}, - m_sorter{nullptr} + m_errors{new QErrorMessage{this}} { setupUi(this); actionClose->setShortcut(QKeySequence{QKeySequence::Close}); actionOpen->setShortcut(QKeySequence{QKeySequence::Open}); actionQuit->setShortcut(QKeySequence{QKeySequence::Quit}); - - tableView->sortByColumn(Pak::ColumnSize, Qt::AscendingOrder); - tableView->resizeColumnsToContents(); } MainWindow::~MainWindow() { @@ -40,12 +32,9 @@ void MainWindow::fileOpen() { if(!fileName.isEmpty()) { try { - auto st = openReadBin(fileName.toStdString()); - m_directory = readPak(st); - m_model = new PakDirModel{&m_directory, this}; - m_sorter = new PakDirModelSorter{m_model}; - m_sorter->setSourceModel(m_model); - tableView->setModel(m_sorter); + auto st = openReadBin(fileName.toStdString()); + auto pak = readPak(st); + new Project{std::move(pak), m_errors, mdiArea}; } catch(std::exception const &exc) { m_errors->showMessage(tr(exc.what())); } @@ -53,10 +42,9 @@ void MainWindow::fileOpen() { } void MainWindow::fileClose() { - tableView->setModel(nullptr); - delete m_sorter; - delete m_model; - m_directory = PakDir{}; + if(auto win = mdiArea->activeSubWindow()) { + mdiArea->removeSubWindow(win); + } } // EOF diff --git a/source/quam/main_window.h b/source/quam/main_window.h index 7c435e2..29031c4 100644 --- a/source/quam/main_window.h +++ b/source/quam/main_window.h @@ -6,9 +6,7 @@ #include #include -class QAbstractItemModel; class QErrorMessage; -class QSortFilterProxyModel; class MainWindow : public QMainWindow, private Ui::MainWindow { Q_OBJECT @@ -22,10 +20,7 @@ public slots: void fileClose(); private: - PakDir m_directory; - QErrorMessage *m_errors; - QAbstractItemModel *m_model; - QSortFilterProxyModel *m_sorter; + QErrorMessage *m_errors; }; // EOF diff --git a/source/quam/main_window.ui b/source/quam/main_window.ui index aeac4c7..1145642 100644 --- a/source/quam/main_window.ui +++ b/source/quam/main_window.ui @@ -16,46 +16,19 @@ - - - Qt::Horizontal + + + QMdiArea::TabbedView + + + true + + + true + + + true - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - - - false - - - true - - - true - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - false - - - true - - - true - - - false - - - @@ -101,7 +74,8 @@ - + + .. &Close diff --git a/source/quam/pak.cc b/source/quam/pak.cc index 7fca3db..2edbc10 100644 --- a/source/quam/pak.cc +++ b/source/quam/pak.cc @@ -2,6 +2,7 @@ #include "quam/pak.h" #include +#include struct PakHeader { quint32 dirOffset; @@ -106,6 +107,15 @@ 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} @@ -121,10 +131,11 @@ QVariant PakDirModel::data(QModelIndex const &index, int role) const { } auto node = static_cast(index.internalPointer()); + auto col = Pak::Column(index.column()); switch(role) { case Qt::DecorationRole: - if(index.column() == Pak::ColumnName) { + if(col == Pak::Column::Name) { auto icon = std::holds_alternative(*node) ? "folder" : "text-x-generic"; @@ -132,13 +143,13 @@ QVariant PakDirModel::data(QModelIndex const &index, int role) const { } break; case Qt::DisplayRole: - switch(index.column()) { - case Pak::ColumnSize: + switch(col) { + case Pak::Column::Size: if(auto file = std::get_if(node)) { return QVariant{QString::number(file->size())}; } break; - case Pak::ColumnName: + case Pak::Column::Name: return QVariant{tr(node->name.data())}; } default: @@ -162,9 +173,9 @@ QVariant PakDirModel::headerData(int section, Qt::Orientation orientation, int role) const { if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch(section) { - case Pak::ColumnSize: return QVariant{tr("Size")}; - case Pak::ColumnName: return QVariant{tr("Name")}; + switch(Pak::Column(section)) { + case Pak::Column::Size: return QVariant{tr("Size")}; + case Pak::Column::Name: return QVariant{tr("Name")}; } } return QVariant{}; @@ -191,7 +202,7 @@ int PakDirModel::rowCount(QModelIndex const &) const { } int PakDirModel::columnCount(QModelIndex const &) const { - return Pak::ColumnMax; + return QMetaEnum::fromType().keyCount(); } PakDirModelSorter::~PakDirModelSorter() { diff --git a/source/quam/pak.h b/source/quam/pak.h index 2ec9693..42c5443 100644 --- a/source/quam/pak.h +++ b/source/quam/pak.h @@ -4,11 +4,13 @@ #include namespace Pak { - enum PakColumn { - ColumnSize, - ColumnName, - ColumnMax, + Q_NAMESPACE + + enum class Column { + Size, + Name, }; + Q_ENUM_NS(Column) } struct PakNode; @@ -39,6 +41,14 @@ struct PakNode : public std::variant { }; 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 diff --git a/source/quam/project.cc b/source/quam/project.cc new file mode 100644 index 0000000..6c6c519 --- /dev/null +++ b/source/quam/project.cc @@ -0,0 +1,41 @@ +#include "common.h" +#include "quam/project.h" + +#include +#include +#include +#include + +Project::Project(QErrorMessage *errors, QMdiArea *parent) : + QMdiSubWindow{parent}, + Ui::Project{}, + m_errors{errors} +{ + auto widget = new QWidget(this); + setupUi(widget); + setWidget(widget); + setAttribute(Qt::WA_DeleteOnClose); + 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 new file mode 100644 index 0000000..ec0fce5 --- /dev/null +++ b/source/quam/project.h @@ -0,0 +1,31 @@ +#pragma once + +#include "quam/pak.h" +#include "quam/ui_project.h" + +#include +#include +#include + +class QAbstractItemModel; +class QErrorMessage; +class QSortFilterProxyModel; + +class Project : public QMdiSubWindow, private Ui::Project { + Q_OBJECT + +public: + explicit Project(PakDir &&dir, 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; +}; + +// EOF diff --git a/source/quam/project.ui b/source/quam/project.ui new file mode 100644 index 0000000..c7b429d --- /dev/null +++ b/source/quam/project.ui @@ -0,0 +1,67 @@ + + + Project + + + + 0 + 0 + 640 + 480 + + + + Project View + + + + + + Qt::Horizontal + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + false + + + true + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + true + + + true + + + false + + + + + + + + + +