a-la-karte/src/screenshotmodel.cpp

135 lines
3.1 KiB
C++

#include "screenshotmodel.h"
#include <QDir>
#include <QFileInfo>
#include <QtConcurrent>
ScreenshotModel::ScreenshotModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&m_watcher, &QFutureWatcher<QVector<ScreenshotEntry>>::finished, this, [this]() {
const int token = m_watcher.property("refreshToken").toInt();
if (token != m_refreshToken) {
return;
}
setEntries(m_watcher.result());
});
}
ScreenshotModel::~ScreenshotModel()
{
m_refreshToken++;
m_watcher.cancel();
m_watcher.waitForFinished();
}
QString ScreenshotModel::directoryPath() const
{
return m_directoryPath;
}
void ScreenshotModel::setDirectoryPath(const QString &path)
{
if (m_directoryPath == path) {
return;
}
m_directoryPath = path;
Q_EMIT directoryPathChanged();
refresh();
}
int ScreenshotModel::count() const
{
return rowCount();
}
int ScreenshotModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid()) {
return 0;
}
return m_entries.size();
}
QVariant ScreenshotModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || index.row() >= m_entries.size()) {
return {};
}
const ScreenshotEntry &e = m_entries.at(index.row());
switch (role) {
case UrlRole:
return QUrl::fromLocalFile(e.filePath);
case FileNameRole:
return e.fileName;
case CreatedRole:
return e.created;
case SizeRole:
return e.size;
default:
return {};
}
}
QHash<int, QByteArray> ScreenshotModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[UrlRole] = "url";
roles[FileNameRole] = "fileName";
roles[CreatedRole] = "created";
roles[SizeRole] = "size";
return roles;
}
void ScreenshotModel::refresh()
{
const QString path = m_directoryPath;
const int token = ++m_refreshToken;
m_watcher.setProperty("refreshToken", token);
auto future = QtConcurrent::run([path]() -> QVector<ScreenshotEntry> {
QVector<ScreenshotEntry> result;
if (path.isEmpty()) {
return result;
}
QDir dir(path);
if (!dir.exists()) {
return result;
}
const QStringList nameFilters = {
QStringLiteral("*.png"),
QStringLiteral("*.jpg"),
QStringLiteral("*.jpeg"),
QStringLiteral("*.webp"),
};
const QFileInfoList files = dir.entryInfoList(nameFilters, QDir::Files | QDir::Readable, QDir::Time | QDir::Reversed);
result.reserve(files.size());
for (const QFileInfo &fi : files) {
ScreenshotEntry e;
e.filePath = fi.absoluteFilePath();
e.fileName = fi.fileName();
e.created = fi.lastModified();
e.size = fi.size();
result.push_back(std::move(e));
}
return result;
});
m_watcher.setFuture(future);
}
void ScreenshotModel::setEntries(QVector<ScreenshotEntry> entries)
{
beginResetModel();
m_entries = std::move(entries);
endResetModel();
Q_EMIT countChanged();
}