diff --git a/source/quam/main_window.cc b/source/quam/main_window.cc index 5cc5c7a..9597f38 100644 --- a/source/quam/main_window.cc +++ b/source/quam/main_window.cc @@ -2,24 +2,6 @@ #include "quam/main_window.h" #include "quam/pak.h" -static void setListToDir(QListWidget &list, PakDir const &dir) { - list.clear(); - for(auto const &kv : dir) { - auto const &name = kv.first; - auto const &node = kv.second; - auto var = QVariant::fromValue(node); - auto item = new QListWidgetItem{&list}; - item->setText(QString::fromStdString(name)); - item->setData(Qt::UserRole, var); - if(std::holds_alternative(node)) { - item->setIcon(QIcon::fromTheme("folder")); - } else { - item->setIcon(QIcon::fromTheme("text-x-generic")); - } - list.addItem(item); - } -} - MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent}, Ui::MainWindow{}, @@ -27,8 +9,10 @@ MainWindow::MainWindow(QWidget *parent) : { setupUi(this); - actionOpen->setShortcut(QKeySequence(QKeySequence::Open)); - actionQuit->setShortcut(QKeySequence(QKeySequence::Quit)); + actionOpen->setShortcut(QKeySequence{QKeySequence::Open}); + actionQuit->setShortcut(QKeySequence{QKeySequence::Quit}); + + tableWidget->sortByColumn(Pak::ColumnId, Qt::AscendingOrder); } void MainWindow::fileOpen() { @@ -38,13 +22,14 @@ void MainWindow::fileOpen() { tr("Open Archive"), QString{}, tr("Quake PACK file (*.pak);;" + "Quake WAD2 file (*.wad);;" "All files (*)")); if(!fileName.isEmpty()) { try { auto st = openReadBin(fileName.toStdString()); auto pak = readPak(st); - setListToDir(*listWidget, pak); + setTableToPakDir(*tableWidget, pak); } catch(std::exception const &exc) { m_errors.showMessage(tr(exc.what())); } diff --git a/source/quam/main_window.ui b/source/quam/main_window.ui index ef5b573..f93548f 100644 --- a/source/quam/main_window.ui +++ b/source/quam/main_window.ui @@ -16,7 +16,71 @@ - + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + false + + + true + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + true + + + true + + + true + + + false + + + + ID + + + The ID of the file. This is the N-th file in the archive. + + + + + Size + + + The size of the file in bytes. + + + + + Name + + + The name of the file. + + + diff --git a/source/quam/pak.cc b/source/quam/pak.cc index c392436..33c2c4a 100644 --- a/source/quam/pak.cc +++ b/source/quam/pak.cc @@ -8,7 +8,7 @@ struct PakHeader { struct PakEntry { std::string name; - PakFile data; + PakFile file; }; static constexpr quint32 sizeOfPakEntry = 64; @@ -33,7 +33,7 @@ static PakHeader readPakHeader(std::istream &st) { return hdr; } -static PakEntry readPakEntry(std::istream &st) { +static PakEntry readPakEntry(std::istream &st, quint32 id) { auto entName = readBytes<56>(st); auto entOffset = readLE(st); auto entSize = readLE(st); @@ -42,9 +42,10 @@ static PakEntry readPakEntry(std::istream &st) { st.seekg(entOffset); - PakFile bytes; - bytes.resize(entSize); - st.read(bytes.data(), entSize); + PakFile file; + file.id = id; + file.resize(entSize); + st.read(file.data(), entSize); st.seekg(pos); @@ -59,7 +60,7 @@ static PakEntry readPakEntry(std::istream &st) { PakEntry ent; ent.name = std::move(name); - ent.data = std::move(bytes); + ent.file = std::move(file); return ent; } @@ -82,12 +83,57 @@ PakDir readPak(std::istream &st) { PakDir root; - for(quint32 i = 0; i < hdr.dirNum; i++) { - auto ent = readPakEntry(st); - insertFile(root, std::move(ent.name), std::move(ent.data)); + for(quint32 id = 0; id < hdr.dirNum; id++) { + auto ent = readPakEntry(st, id); + insertFile(root, std::move(ent.name), std::move(ent.file)); } return root; } +void setTableToPakDir(QTableWidget &table, PakDir const &dir) { + constexpr auto Flags = Qt::ItemIsSelectable | + Qt::ItemIsDragEnabled | + Qt::ItemIsEnabled | + Qt::ItemNeverHasChildren; + + auto sorted = table.isSortingEnabled(); + table.clearContents(); + table.setSortingEnabled(false); + quint32 row{0}; + for(auto const &kv : dir) { + auto const &name = kv.first; + auto const &node = kv.second; + table.setRowCount(row + 1); + { + auto item = new QTableWidgetItem; + item->setFlags(Flags); + if(auto file = std::get_if(&node)) { + item->setText(QString::number(file->id)); + } + table.setItem(row, Pak::ColumnId, item); + } + { + auto item = new QTableWidgetItem; + item->setFlags(Flags); + if(auto file = std::get_if(&node)) { + item->setText(QString::number(file->size())); + } + table.setItem(row, Pak::ColumnSize, item); + } + { + auto item = new QTableWidgetItem; + auto icon = std::holds_alternative(node) ? "folder" : + "text-x-generic"; + item->setFlags(Flags); + item->setText(QString::fromStdString(name)); + item->setIcon(QIcon::fromTheme(icon)); + table.setItem(row, Pak::ColumnName, item); + } + ++row; + } + table.setSortingEnabled(sorted); + table.resizeColumnsToContents(); +} + // EOF diff --git a/source/quam/pak.h b/source/quam/pak.h index f52fdd7..093b45b 100644 --- a/source/quam/pak.h +++ b/source/quam/pak.h @@ -1,5 +1,15 @@ #pragma once +#include + +namespace Pak { + enum PakColumn { + ColumnId, + ColumnSize, + ColumnName, + }; +} + struct PakNode; struct PakDir : public std::map { @@ -9,6 +19,8 @@ Q_DECLARE_METATYPE(PakDir) struct PakFile : public QByteArray { using QByteArray::QByteArray; + + quint32 id{0}; }; Q_DECLARE_METATYPE(PakFile) @@ -18,5 +30,6 @@ struct PakNode : public std::variant { Q_DECLARE_METATYPE(PakNode) PakDir readPak(std::istream &st); +void setTableToPakDir(QTableWidget &table, PakDir const &dir); // EOF