redai/src/ArtModel.cpp

150 lines
4.2 KiB
C++
Raw Normal View History

2023-08-31 09:09:52 +02:00
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
//
// SPDX-License-Identifier: GPL-3.0-or-later
2023-03-27 12:49:53 -04:00
#include "ArtModel.h"
#include <QDirIterator>
#include <QFile>
#include <QFileInfo>
#include <QIcon>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPixmap>
#include <QtConcurrent>
2023-03-27 12:49:53 -04:00
ArtModel::ArtModel(const QString& definitionDirectory, const QString& assetDirectory) : QAbstractTableModel() {
piecesFuture = new QFutureWatcher<ArtPiece>(this);
connect(piecesFuture, &QFutureWatcher<ArtPiece>::resultReadyAt, this, &ArtModel::pieceFinished);
connect(piecesFuture, &QFutureWatcher<ArtPiece>::finished, this, &ArtModel::finished);
struct PieceInformation {
QString definition;
QString asset;
};
QVector<PieceInformation> pieceList;
2023-03-27 12:49:53 -04:00
QDirIterator it(definitionDirectory);
while (it.hasNext()) {
QFileInfo info(it.next());
if(!info.isFile()) {
continue;
}
2023-08-31 09:51:57 +02:00
pieceList.push_back(PieceInformation{QStringLiteral("%1/%2").arg(definitionDirectory, info.baseName()), QStringLiteral("%1/%2").arg(assetDirectory, info.baseName())});
2023-03-27 12:49:53 -04:00
beginInsertRows(QModelIndex(), m_artPieces.size(), m_artPieces.size() + 1);
2023-03-27 12:49:53 -04:00
m_artPieces.push_back(ArtPiece{});
2023-03-27 12:49:53 -04:00
endInsertRows();
}
std::function<ArtPiece(const PieceInformation& info)> loadPiece = [this](const PieceInformation& info) -> ArtPiece {
ArtPiece p;
loadData(p, info.definition, info.asset);
p.image.load(p.filename);
p.thumbnail = QPixmap::fromImage(p.image).scaled(100, 100, Qt::AspectRatioMode::KeepAspectRatio).toImage();
2023-03-27 12:49:53 -04:00
return p;
};
piecesFuture->setFuture(QtConcurrent::mapped(pieceList, loadPiece));
2023-03-27 12:49:53 -04:00
}
int ArtModel::rowCount(const QModelIndex &parent) const {
return m_artPieces.size();
}
int ArtModel::columnCount(const QModelIndex &parent) const {
return 4;
}
QVariant ArtModel::data(const QModelIndex &index, int role) const {
if (!index.isValid())
return {};
if (role == Qt::DisplayRole) {
switch(index.column()) {
case 0:
return m_artPieces[index.row()].filename;
case 1:
return {};
case 2:
return m_artPieces[index.row()].title;
case 3:
return m_artPieces[index.row()].hasAltText;
}
} else if (role == Qt::UserRole) {
return m_artPieces[index.row()].object;
} else if (role == Qt::DecorationRole) {
switch(index.column()) {
case 1:
return m_artPieces[index.row()].thumbnail;
2023-03-27 12:49:53 -04:00
case 3:
2023-08-31 09:51:57 +02:00
return m_artPieces[index.row()].hasAltText ? QIcon::fromTheme(QStringLiteral("emblem-checked")) : QIcon::fromTheme(QStringLiteral("emblem-error"));
2023-03-27 12:49:53 -04:00
}
} else if (role == Qt::UserRole + 1) {
return m_artPieces[index.row()].jsonFilename;
}
return {};
}
QVariant ArtModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole) {
switch(section) {
case 0:
2023-08-31 09:51:57 +02:00
return QStringLiteral("Filename");
2023-03-27 12:49:53 -04:00
case 1:
2023-08-31 09:51:57 +02:00
return QStringLiteral("Image");
2023-03-27 12:49:53 -04:00
case 2:
2023-08-31 09:51:57 +02:00
return QStringLiteral("Title");
2023-03-27 12:49:53 -04:00
case 3:
2023-08-31 09:51:57 +02:00
return QStringLiteral("Has Alt Text");
default:
Q_UNREACHABLE();
2023-03-27 12:49:53 -04:00
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}
void ArtModel::loadData(ArtPiece& piece, const QString& filename, const QString& assetFilename) {
piece.jsonFilename = filename + ".json";
piece.filename = assetFilename;
QFile artFile(piece.jsonFilename);
artFile.open(QFile::ReadOnly);
QJsonDocument artJson = QJsonDocument::fromJson(artFile.readAll());
2023-08-31 09:51:57 +02:00
if(artJson[QStringLiteral("date")].toString().contains(QStringLiteral("-"))) {
piece.date = QDate::fromString(artJson[QStringLiteral("date")].toString(), QStringLiteral("yyyy-MM-dd"));
2023-03-27 12:49:53 -04:00
} else {
2023-08-31 09:51:57 +02:00
piece.date = QDate::fromString(artJson[QStringLiteral("date")].toString(), QStringLiteral("yyyy"));
2023-03-27 12:49:53 -04:00
}
2023-08-31 09:51:57 +02:00
if (artJson.object().contains(QStringLiteral("title"))) {
piece.title = artJson.object()[QStringLiteral("title")].toString();
}
2023-08-31 09:51:57 +02:00
if(artJson.object().contains(QStringLiteral("alt_text"))) {
2023-03-27 12:49:53 -04:00
piece.hasAltText = true;
}
}
void ArtModel::pieceFinished(int row) {
m_artPieces[row] = piecesFuture->resultAt(row);
Q_EMIT dataChanged(index(row, 0), index(row + 1, 0));
}
void ArtModel::finished() {
std::sort(m_artPieces.begin(), m_artPieces.end(), [](ArtPiece& a, ArtPiece& b)
{
return a.date > b.date;
});
Q_EMIT dataChanged(index(0, 0), index(m_artPieces.size(), 0));
}