diff --git a/ArtModel.cpp b/ArtModel.cpp index d8aa89e..166d555 100644 --- a/ArtModel.cpp +++ b/ArtModel.cpp @@ -4,13 +4,21 @@ #include #include #include -#include -#include #include #include #include +#include ArtModel::ArtModel(const QString& definitionDirectory, const QString& assetDirectory) : QAbstractTableModel() { + piecesFuture = new QFutureWatcher(this); + connect(piecesFuture, &QFutureWatcher::resultReadyAt, this, &ArtModel::pieceFinished); + connect(piecesFuture, &QFutureWatcher::finished, this, &ArtModel::finished); + + struct PieceInformation { + QString definition; + QString asset; + }; + QVector pieceList; QDirIterator it(definitionDirectory); while (it.hasNext()) { QFileInfo info(it.next()); @@ -18,22 +26,26 @@ ArtModel::ArtModel(const QString& definitionDirectory, const QString& assetDirec continue; } + pieceList.push_back(PieceInformation{QString("%1/%2").arg(definitionDirectory).arg(info.baseName()), QString("%1/%2").arg(assetDirectory).arg(info.baseName())}); + beginInsertRows(QModelIndex(), m_artPieces.size(), m_artPieces.size() + 1); - ArtPiece p; - loadData(p, QString("%1/%2").arg(definitionDirectory).arg(info.baseName()), QString("%1/%2").arg(assetDirectory).arg(info.baseName())); - - m_artPieces.push_back(p); + m_artPieces.push_back(ArtPiece{}); endInsertRows(); } - std::sort(m_artPieces.begin(), m_artPieces.end(), [](ArtPiece& a, ArtPiece& b) - { - return a.date > b.date; - }); + std::function loadPiece = [this](const PieceInformation& info) -> ArtPiece { + ArtPiece p; + loadData(p, info.definition, info.asset); - dataChanged(index(0, 0), index(m_artPieces.size(), 0)); + p.image.load(p.filename); + p.thumbnail = QPixmap::fromImage(p.image).scaled(100, 100, Qt::AspectRatioMode::KeepAspectRatio).toImage(); + + return p; + }; + + piecesFuture->setFuture(QtConcurrent::mapped(pieceList, loadPiece)); } int ArtModel::rowCount(const QModelIndex &parent) const { @@ -65,10 +77,7 @@ QVariant ArtModel::data(const QModelIndex &index, int role) const { switch(index.column()) { case 1: { - QImage image; - image.load(m_artPieces[index.row()].filename); - - return QPixmap::fromImage(image).scaled(100, 100, Qt::AspectRatioMode::KeepAspectRatio); + return m_artPieces[index.row()].thumbnail; } break; case 3: @@ -113,7 +122,25 @@ void ArtModel::loadData(ArtPiece& piece, const QString& filename, const QString& piece.date = QDate::fromString(artJson["date"].toString(), "yyyy"); } + if (artJson.object().contains("title")) { + piece.title = artJson.object()["title"].toString(); + } + if(artJson.object().contains("alt_text")) { piece.hasAltText = true; } -} \ No newline at end of file +} +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)); +} diff --git a/ArtModel.h b/ArtModel.h index 23c85b4..477c408 100644 --- a/ArtModel.h +++ b/ArtModel.h @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include struct ArtPiece { QString filename, jsonFilename; @@ -9,6 +11,7 @@ struct ArtPiece { QJsonObject object; QDate date; + QImage image, thumbnail; bool hasAltText = false; }; @@ -26,5 +29,10 @@ public: private: void loadData(ArtPiece& piece, const QString& filename, const QString& assetFilename); + void pieceFinished(int index); + void finished(); + + QFutureWatcher* piecesFuture; + QList m_artPieces; }; diff --git a/CMakeLists.txt b/CMakeLists.txt index 92b6fcb..e8578ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ find_package(Qt5 COMPONENTS Core Gui Widgets + Concurrent REQUIRED) add_executable(Redai main.cpp MainWindow.cpp MainWindow.h ArtModel.cpp ArtModel.h ArtDetailWindow.cpp ArtDetailWindow.h imagelabel.cpp imagelabel.h) @@ -17,5 +18,6 @@ target_link_libraries(Redai Qt5::Core Qt5::Gui Qt5::Widgets + Qt5::Concurrent )