#include "quam/archive.h" #include "quam/pack.h" #include "quam/wad2.h" #include namespace Arc { Option getArchiveType(std::istream &st) noexcept { try { auto pos = st.tellg(); auto magic = readBytes<4>(st); st.seekg(pos); if(magic == std::array{'P', 'A', 'C', 'K'}) {return ArcType::Pack;} if(magic == std::array{'W', 'A', 'D', '2'}) {return ArcType::Wad2;} } catch(...) { } return None; } Dir readArchive(std::istream &st) { switch(auto v = getArchiveType(st); v.has_value() ? *v : throw FileFormatError("not an archive")) { case ArcType::Pack: return readPack(st); case ArcType::Wad2: return readWad2(st); } } Node *Dir::findNode(std::string const &name) { auto it = std::find_if(begin(), end(), [&name](Node &node) { return node.name == name; }); return it != end() ? &*it : nullptr; } Node::Node(Dir &&f, std::string &&n, FileType t) : superType(std::move(f)), name(std::move(n)), type(t) { } Node::Node(File &&f, std::string &&n, FileType t) : superType(std::move(f)), name(std::move(n)), type(t) { } Model::Model(QObject *parent) : QAbstractItemModel{parent}, m_dir{nullptr} { } Model::~Model() { } QVariant Model::data(QModelIndex const &index, int role) const { if(!index.isValid()) { return QVariant{}; } auto node = static_cast(index.internalPointer()); auto col = Column(index.column()); switch(role) { case Qt::DecorationRole: if(col == Column::Name) { auto icon = std::holds_alternative(*node) ? "folder" : "text-x-generic"; return QVariant{QIcon::fromTheme(icon)}; } break; case Qt::DisplayRole: switch(col) { case Column::Size: if(auto file = std::get_if(node)) { return QVariant{QString::number(file->size())}; } break; case Column::Type: return QVariant{tr(enumToString(node->type))}; case Column::Name: return QVariant{tr(node->name.data())}; } case Qt::UserRole: return QVariant::fromValue(static_cast(node)); default: break; } return QVariant{}; } Qt::ItemFlags Model::flags(QModelIndex const &index) const { if(!index.isValid()) { return Qt::NoItemFlags; } else { return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; } } QVariant Model::headerData(int section, Qt::Orientation ori, int role) const { if(ori == Qt::Horizontal && role == Qt::DisplayRole) { switch(Column(section)) { case Column::Size: return QVariant{tr("Size")}; case Column::Type: return QVariant{tr("Type")}; case Column::Name: return QVariant{tr("Name")}; } } return QVariant{}; } QModelIndex Model::index(int row, int col, QModelIndex const &parent) const { if(!m_dir || !hasIndex(row, col, parent) || row > m_dir->size()) { return QModelIndex{}; } else { return createIndex(row, col, &m_dir->at(row)); } } QModelIndex Model::parent(QModelIndex const &) const { return QModelIndex{}; } int Model::rowCount(QModelIndex const &) const { return m_dir ? m_dir->size() : 0; } int Model::columnCount(QModelIndex const &) const { return enumMax(); } Dir *Model::dir() const { return m_dir; } void Model::setDir(Dir *dir) { if(dir != m_dir) { 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; emit layoutChanged(); emit dirChanged(dir); } } } // EOF