make opened files use a complex table view
This commit is contained in:
		
							parent
							
								
									62253abab0
								
							
						
					
					
						commit
						89414dd5ec
					
				| 
						 | 
					@ -2,24 +2,6 @@
 | 
				
			||||||
#include "quam/main_window.h"
 | 
					#include "quam/main_window.h"
 | 
				
			||||||
#include "quam/pak.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<PakDir>(node)) {
 | 
					 | 
				
			||||||
			item->setIcon(QIcon::fromTheme("folder"));
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			item->setIcon(QIcon::fromTheme("text-x-generic"));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		list.addItem(item);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MainWindow::MainWindow(QWidget *parent) :
 | 
					MainWindow::MainWindow(QWidget *parent) :
 | 
				
			||||||
	QMainWindow{parent},
 | 
						QMainWindow{parent},
 | 
				
			||||||
	Ui::MainWindow{},
 | 
						Ui::MainWindow{},
 | 
				
			||||||
| 
						 | 
					@ -27,8 +9,10 @@ MainWindow::MainWindow(QWidget *parent) :
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setupUi(this);
 | 
						setupUi(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	actionOpen->setShortcut(QKeySequence(QKeySequence::Open));
 | 
						actionOpen->setShortcut(QKeySequence{QKeySequence::Open});
 | 
				
			||||||
	actionQuit->setShortcut(QKeySequence(QKeySequence::Quit));
 | 
						actionQuit->setShortcut(QKeySequence{QKeySequence::Quit});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tableWidget->sortByColumn(Pak::ColumnId, Qt::AscendingOrder);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWindow::fileOpen() {
 | 
					void MainWindow::fileOpen() {
 | 
				
			||||||
| 
						 | 
					@ -38,13 +22,14 @@ void MainWindow::fileOpen() {
 | 
				
			||||||
			tr("Open Archive"),
 | 
								tr("Open Archive"),
 | 
				
			||||||
			QString{},
 | 
								QString{},
 | 
				
			||||||
			tr("Quake PACK file (*.pak);;"
 | 
								tr("Quake PACK file (*.pak);;"
 | 
				
			||||||
 | 
								   "Quake WAD2 file (*.wad);;"
 | 
				
			||||||
			   "All files (*)"));
 | 
								   "All files (*)"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(!fileName.isEmpty()) {
 | 
						if(!fileName.isEmpty()) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			auto st  = openReadBin(fileName.toStdString());
 | 
								auto st  = openReadBin(fileName.toStdString());
 | 
				
			||||||
			auto pak = readPak(st);
 | 
								auto pak = readPak(st);
 | 
				
			||||||
			setListToDir(*listWidget, pak);
 | 
								setTableToPakDir(*tableWidget, pak);
 | 
				
			||||||
		} catch(std::exception const &exc) {
 | 
							} catch(std::exception const &exc) {
 | 
				
			||||||
			m_errors.showMessage(tr(exc.what()));
 | 
								m_errors.showMessage(tr(exc.what()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,71 @@
 | 
				
			||||||
  <widget class="QWidget" name="centralwidget">
 | 
					  <widget class="QWidget" name="centralwidget">
 | 
				
			||||||
   <layout class="QHBoxLayout" name="horizontalLayout_2">
 | 
					   <layout class="QHBoxLayout" name="horizontalLayout_2">
 | 
				
			||||||
    <item>
 | 
					    <item>
 | 
				
			||||||
     <widget class="QListWidget" name="listWidget"/>
 | 
					     <widget class="QTableWidget" name="tableWidget">
 | 
				
			||||||
 | 
					      <property name="verticalScrollBarPolicy">
 | 
				
			||||||
 | 
					       <enum>Qt::ScrollBarAlwaysOn</enum>
 | 
				
			||||||
 | 
					      </property>
 | 
				
			||||||
 | 
					      <property name="horizontalScrollBarPolicy">
 | 
				
			||||||
 | 
					       <enum>Qt::ScrollBarAlwaysOff</enum>
 | 
				
			||||||
 | 
					      </property>
 | 
				
			||||||
 | 
					      <property name="autoScroll">
 | 
				
			||||||
 | 
					       <bool>false</bool>
 | 
				
			||||||
 | 
					      </property>
 | 
				
			||||||
 | 
					      <property name="tabKeyNavigation">
 | 
				
			||||||
 | 
					       <bool>true</bool>
 | 
				
			||||||
 | 
					      </property>
 | 
				
			||||||
 | 
					      <property name="alternatingRowColors">
 | 
				
			||||||
 | 
					       <bool>true</bool>
 | 
				
			||||||
 | 
					      </property>
 | 
				
			||||||
 | 
					      <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="horizontalHeaderShowSortIndicator" stdset="0">
 | 
				
			||||||
 | 
					       <bool>true</bool>
 | 
				
			||||||
 | 
					      </attribute>
 | 
				
			||||||
 | 
					      <attribute name="horizontalHeaderStretchLastSection">
 | 
				
			||||||
 | 
					       <bool>true</bool>
 | 
				
			||||||
 | 
					      </attribute>
 | 
				
			||||||
 | 
					      <attribute name="verticalHeaderVisible">
 | 
				
			||||||
 | 
					       <bool>false</bool>
 | 
				
			||||||
 | 
					      </attribute>
 | 
				
			||||||
 | 
					      <column>
 | 
				
			||||||
 | 
					       <property name="text">
 | 
				
			||||||
 | 
					        <string>ID</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="toolTip">
 | 
				
			||||||
 | 
					        <string>The ID of the file. This is the N-th file in the archive.</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					      </column>
 | 
				
			||||||
 | 
					      <column>
 | 
				
			||||||
 | 
					       <property name="text">
 | 
				
			||||||
 | 
					        <string>Size</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="toolTip">
 | 
				
			||||||
 | 
					        <string>The size of the file in bytes.</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					      </column>
 | 
				
			||||||
 | 
					      <column>
 | 
				
			||||||
 | 
					       <property name="text">
 | 
				
			||||||
 | 
					        <string>Name</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					       <property name="toolTip">
 | 
				
			||||||
 | 
					        <string>The name of the file.</string>
 | 
				
			||||||
 | 
					       </property>
 | 
				
			||||||
 | 
					      </column>
 | 
				
			||||||
 | 
					     </widget>
 | 
				
			||||||
    </item>
 | 
					    </item>
 | 
				
			||||||
    <item>
 | 
					    <item>
 | 
				
			||||||
     <widget class="QPlainTextEdit" name="textEdit"/>
 | 
					     <widget class="QPlainTextEdit" name="textEdit"/>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ struct PakHeader {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PakEntry {
 | 
					struct PakEntry {
 | 
				
			||||||
	std::string name;
 | 
						std::string name;
 | 
				
			||||||
	PakFile     data;
 | 
						PakFile     file;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr quint32 sizeOfPakEntry = 64;
 | 
					static constexpr quint32 sizeOfPakEntry = 64;
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ static PakHeader readPakHeader(std::istream &st) {
 | 
				
			||||||
	return hdr;
 | 
						return hdr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PakEntry readPakEntry(std::istream &st) {
 | 
					static PakEntry readPakEntry(std::istream &st, quint32 id) {
 | 
				
			||||||
	auto entName   = readBytes<56>(st);
 | 
						auto entName   = readBytes<56>(st);
 | 
				
			||||||
	auto entOffset = readLE<quint32>(st);
 | 
						auto entOffset = readLE<quint32>(st);
 | 
				
			||||||
	auto entSize   = readLE<quint32>(st);
 | 
						auto entSize   = readLE<quint32>(st);
 | 
				
			||||||
| 
						 | 
					@ -42,9 +42,10 @@ static PakEntry readPakEntry(std::istream &st) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	st.seekg(entOffset);
 | 
						st.seekg(entOffset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PakFile bytes;
 | 
						PakFile file;
 | 
				
			||||||
	bytes.resize(entSize);
 | 
						file.id = id;
 | 
				
			||||||
	st.read(bytes.data(), entSize);
 | 
						file.resize(entSize);
 | 
				
			||||||
 | 
						st.read(file.data(), entSize);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	st.seekg(pos);
 | 
						st.seekg(pos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +60,7 @@ static PakEntry readPakEntry(std::istream &st) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PakEntry ent;
 | 
						PakEntry ent;
 | 
				
			||||||
	ent.name = std::move(name);
 | 
						ent.name = std::move(name);
 | 
				
			||||||
	ent.data = std::move(bytes);
 | 
						ent.file = std::move(file);
 | 
				
			||||||
	return ent;
 | 
						return ent;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,12 +83,57 @@ PakDir readPak(std::istream &st) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PakDir root;
 | 
						PakDir root;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for(quint32 i = 0; i < hdr.dirNum; i++) {
 | 
						for(quint32 id = 0; id < hdr.dirNum; id++) {
 | 
				
			||||||
		auto ent = readPakEntry(st);
 | 
							auto ent = readPakEntry(st, id);
 | 
				
			||||||
		insertFile(root, std::move(ent.name), std::move(ent.data));
 | 
							insertFile(root, std::move(ent.name), std::move(ent.file));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return root;
 | 
						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<PakFile>(&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<PakFile>(&node)) {
 | 
				
			||||||
 | 
									item->setText(QString::number(file->size()));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								table.setItem(row, Pak::ColumnSize, item);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								auto item = new QTableWidgetItem;
 | 
				
			||||||
 | 
								auto icon = std::holds_alternative<PakDir>(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
 | 
					// EOF
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,15 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <QTableWidget>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Pak {
 | 
				
			||||||
 | 
						enum PakColumn {
 | 
				
			||||||
 | 
							ColumnId,
 | 
				
			||||||
 | 
							ColumnSize,
 | 
				
			||||||
 | 
							ColumnName,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PakNode;
 | 
					struct PakNode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PakDir : public std::map<std::string, PakNode> {
 | 
					struct PakDir : public std::map<std::string, PakNode> {
 | 
				
			||||||
| 
						 | 
					@ -9,6 +19,8 @@ Q_DECLARE_METATYPE(PakDir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct PakFile : public QByteArray {
 | 
					struct PakFile : public QByteArray {
 | 
				
			||||||
	using QByteArray::QByteArray;
 | 
						using QByteArray::QByteArray;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						quint32 id{0};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
Q_DECLARE_METATYPE(PakFile)
 | 
					Q_DECLARE_METATYPE(PakFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,5 +30,6 @@ struct PakNode : public std::variant<PakDir, PakFile> {
 | 
				
			||||||
Q_DECLARE_METATYPE(PakNode)
 | 
					Q_DECLARE_METATYPE(PakNode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PakDir readPak(std::istream &st);
 | 
					PakDir readPak(std::istream &st);
 | 
				
			||||||
 | 
					void setTableToPakDir(QTableWidget &table, PakDir const &dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// EOF
 | 
					// EOF
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user