You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.9 KiB
131 lines
3.9 KiB
/* |
|
SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com> |
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later |
|
*/ |
|
|
|
#include "abstractimagelistmodel.h" |
|
|
|
#include <QPixmap> |
|
#include <QThreadPool> |
|
|
|
#include <KFileItem> |
|
#include <KIO/PreviewJob> |
|
|
|
#include "../finder/imagesizefinder.h" |
|
|
|
AbstractImageListModel::AbstractImageListModel(const QSize &targetSize, QObject *parent) |
|
: QAbstractListModel(parent) |
|
, m_screenshotSize(targetSize / 8) |
|
, m_targetSize(targetSize) |
|
{ |
|
m_imageCache.setMaxCost(m_screenshotSize.width() * m_screenshotSize.height() * 20); |
|
m_imageSizeCache.setMaxCost(20); |
|
|
|
connect(this, &QAbstractListModel::rowsInserted, this, &AbstractImageListModel::countChanged); |
|
connect(this, &QAbstractListModel::rowsRemoved, this, &AbstractImageListModel::countChanged); |
|
connect(this, &QAbstractListModel::modelReset, this, &AbstractImageListModel::countChanged); |
|
} |
|
|
|
QHash<int, QByteArray> AbstractImageListModel::roleNames() const |
|
{ |
|
return { |
|
{Qt::DisplayRole, "display"}, |
|
{Qt::DecorationRole, "decoration"}, |
|
{AuthorRole, "author"}, |
|
{ScreenshotRole, "screenshot"}, |
|
{PathRole, "path"}, |
|
{PackageNameRole, "packageName"}, |
|
{RemovableRole, "removable"}, |
|
{PendingDeletionRole, "pendingDeletion"}, |
|
{ToggleRole, "checked"}, |
|
}; |
|
} |
|
|
|
int AbstractImageListModel::count() const |
|
{ |
|
return rowCount(); |
|
} |
|
|
|
void AbstractImageListModel::reload() |
|
{ |
|
if (m_loading || m_customPaths.empty()) { |
|
return; |
|
} |
|
|
|
load(m_customPaths); |
|
} |
|
|
|
void AbstractImageListModel::slotTargetSizeChanged(const QSize &size) |
|
{ |
|
m_targetSize = size; |
|
reload(); |
|
} |
|
|
|
void AbstractImageListModel::slotHandleImageSizeFound(const QString &path, const QSize &size) |
|
{ |
|
const QPersistentModelIndex index = m_sizeJobsUrls.take(path); |
|
|
|
if (m_imageSizeCache.insert(path, new QSize(size), 1)) { |
|
Q_EMIT dataChanged(index, index, {ResolutionRole}); |
|
} |
|
} |
|
|
|
void AbstractImageListModel::slotHandlePreview(const KFileItem &item, const QPixmap &preview) |
|
{ |
|
const QString urlString = item.url().toLocalFile(); |
|
const QPersistentModelIndex pidx = m_previewJobsUrls.take(urlString); |
|
QModelIndex idx; |
|
|
|
if (!pidx.isValid()) { |
|
if (int row = indexOf(urlString); row >= 0) { |
|
idx = index(row, 0); |
|
} else { |
|
return; |
|
} |
|
} else { |
|
idx = pidx; |
|
} |
|
|
|
const int cost = preview.width() * preview.height() * preview.depth() / 8; |
|
|
|
if (m_imageCache.insert(urlString, new QPixmap(preview), cost)) { |
|
Q_EMIT dataChanged(idx, idx, {ScreenshotRole}); |
|
} |
|
} |
|
|
|
void AbstractImageListModel::slotHandlePreviewFailed(const KFileItem &item) |
|
{ |
|
m_previewJobsUrls.remove(item.url().toLocalFile()); |
|
} |
|
|
|
void AbstractImageListModel::asyncGetPreview(const QString &path, const QPersistentModelIndex &index) const |
|
{ |
|
if (m_previewJobsUrls.contains(path) || path.isEmpty()) { |
|
return; |
|
} |
|
|
|
const QUrl url = QUrl::fromLocalFile(path); |
|
const QStringList availablePlugins = KIO::PreviewJob::availablePlugins(); |
|
|
|
KIO::PreviewJob *const job = KIO::filePreview(KFileItemList{KFileItem(url, QString(), 0)}, m_screenshotSize, &availablePlugins); |
|
job->setIgnoreMaximumSize(true); |
|
|
|
connect(job, &KIO::PreviewJob::gotPreview, this, &AbstractImageListModel::slotHandlePreview); |
|
connect(job, &KIO::PreviewJob::failed, this, &AbstractImageListModel::slotHandlePreviewFailed); |
|
|
|
m_previewJobsUrls.insert(path, index); |
|
} |
|
|
|
void AbstractImageListModel::asyncGetImageSize(const QString &path, const QPersistentModelIndex &index) const |
|
{ |
|
if (m_sizeJobsUrls.contains(path) || path.isEmpty()) { |
|
return; |
|
} |
|
|
|
ImageSizeFinder *finder = new ImageSizeFinder(path); |
|
connect(finder, &ImageSizeFinder::sizeFound, this, &AbstractImageListModel::slotHandleImageSizeFound); |
|
QThreadPool::globalInstance()->start(finder); |
|
|
|
m_sizeJobsUrls.insert(path, index); |
|
}
|
|
|