Verified Commit 9fab17a6 authored by Fushan Wen's avatar Fushan Wen 💬
Browse files

wallpapers/image: Rewrite SlideModel based on QConcatenateTablesProxyModel

SlideModel is inherited from QConcatenateTablesProxyModel, and its
source model is ImageProxyModel. Each folder will create its
corresponding ImageProxyModel.
parent b1b841a2
......@@ -6,59 +6,160 @@
#include "slidemodel.h"
void SlideModel::reload(const QStringList &selected)
#include <QDir>
#include "model/imageproxymodel.h"
SlideModel::SlideModel(const QSize &targetSize, QObject *parent)
: QConcatenateTablesProxyModel(parent)
, m_targetSize(targetSize)
{
connect(this, &SlideModel::targetSizeChanged, [this](const QSize &s) {
m_targetSize = s;
});
}
QHash<int, QByteArray> SlideModel::roleNames() const
{
if (!m_packages.isEmpty()) {
beginRemoveRows(QModelIndex(), 0, m_packages.count() - 1);
m_packages.clear();
endRemoveRows();
Q_EMIT countChanged();
const auto models = sourceModels();
if (!models.empty()) {
return models.at(0)->roleNames();
}
addDirs(selected);
return QConcatenateTablesProxyModel::roleNames();
}
void SlideModel::addDirs(const QStringList &selected)
QVariant SlideModel::data(const QModelIndex &index, int role) const
{
BackgroundFinder *finder = new BackgroundFinder(m_wallpaper.data(), selected);
connect(finder, &BackgroundFinder::backgroundsFound, this, &SlideModel::backgroundsFound);
m_findToken = finder->token();
finder->start();
if (!index.isValid()) {
return QVariant();
}
if (role == ToggleRole) {
return m_checkedTable.value(index.data(PackageNameRole).toString(), true);
}
return QConcatenateTablesProxyModel::data(index, role);
}
void SlideModel::backgroundsFound(const QStringList &paths, const QString &token)
bool SlideModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (token != m_findToken) {
return;
if (!index.isValid()) {
return false;
}
processPaths(paths);
Q_EMIT done();
if (role == ToggleRole) {
m_checkedTable[index.data(PackageNameRole).toString()] = value.toBool();
Q_EMIT dataChanged(index, index, {ToggleRole});
return true;
}
return QConcatenateTablesProxyModel::setData(index, value, role);
}
void SlideModel::removeDir(const QString &path)
int SlideModel::indexOf(const QString &packagePath) const
{
BackgroundFinder *finder = new BackgroundFinder(m_wallpaper.data(), QStringList{path});
connect(finder, &BackgroundFinder::backgroundsFound, this, &SlideModel::removeBackgrounds);
finder->start();
int idx = -1;
const auto models = sourceModels();
for (const auto &m : models) {
idx = static_cast<const ImageProxyModel *>(m)->indexOf(packagePath);
if (idx >= 0) {
return mapFromSource(m->index(idx, 0)).row();
}
}
return idx;
}
void SlideModel::removeBackgrounds(const QStringList &paths, const QString &token)
QStringList SlideModel::addDirs(const QStringList &dirs)
{
for (const QString &file : paths) {
removeBackground(file);
QStringList added;
for (const QString &_d : dirs) {
if (!QFileInfo(_d).isDir()) {
continue;
}
const QString d = _d.endsWith(QDir::separator()) ? _d : _d + QDir::separator();
if (!m_models.contains(d)) {
auto m = new ImageProxyModel({d}, m_targetSize, this);
connect(m, &ImageProxyModel::loadingChanged, this, &SlideModel::slotSourceModelLoadingChanged);
m_models.insert(d, m);
added.append(d);
}
}
return added;
}
QVariant SlideModel::data(const QModelIndex &index, int role) const
QString SlideModel::removeDir(const QString &_dir)
{
if (role == ToggleRole) {
return !m_wallpaper.data()->uncheckedSlides().contains(data(index, PathRole).toString());
const QString dir = _dir.endsWith(QDir::separator()) ? _dir : _dir + QDir::separator();
if (!m_models.contains(dir)) {
return QString();
}
return BackgroundListModel::data(index, role);
auto *m = m_models.take(dir);
m_loaded--;
removeSourceModel(m);
m->deleteLater();
return dir;
}
QHash<int, QByteArray> SlideModel::roleNames() const
void SlideModel::setSlidePaths(const QStringList &slidePaths)
{
const auto models = sourceModels();
for (const auto &k : std::as_const(m_models)) {
if (models.contains(k)) {
removeSourceModel(k);
} else {
// Abort loading
disconnect(k, nullptr, this, nullptr);
}
k->deleteLater();
}
m_models.clear();
m_loaded = 0;
addDirs(slidePaths);
}
void SlideModel::setUncheckedSlides(const QStringList &uncheckedSlides)
{
QHash<int, QByteArray> roleNames = BackgroundListModel::roleNames();
roleNames.insert(ToggleRole, "checked");
return roleNames;
m_checkedTable.clear();
for (const QString &p : uncheckedSlides) {
m_checkedTable[p] = false;
}
}
void SlideModel::slotSourceModelLoadingChanged()
{
auto m = qobject_cast<ImageProxyModel *>(sender());
if (!m) {
return;
}
disconnect(m, &ImageProxyModel::loadingChanged, this, nullptr);
connect(this, &SlideModel::targetSizeChanged, m, &ImageProxyModel::targetSizeChanged);
addSourceModel(m);
if (++m_loaded == m_models.size()) {
Q_EMIT done();
}
}
......@@ -6,23 +6,50 @@
#pragma once
#include "backgroundlistmodel.h"
#include <QConcatenateTablesProxyModel>
#include <QSet>
#include <QSize>
class SlideModel : public BackgroundListModel
#include "model/imageroles.h"
class ImageProxyModel;
class SlideModel : public QConcatenateTablesProxyModel, public ImageRoles
{
Q_OBJECT
public:
using BackgroundListModel::BackgroundListModel;
void reload(const QStringList &selected);
void addDirs(const QStringList &selected);
void removeDir(const QString &selected);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
explicit SlideModel(const QSize &targetSize, QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
int indexOf(const QString &packagePath) const;
/**
* @return added directories
*/
QStringList addDirs(const QStringList &dirs);
QString removeDir(const QString &selected);
void setSlidePaths(const QStringList &slidePaths);
void setUncheckedSlides(const QStringList &uncheckedSlides);
Q_SIGNALS:
void done();
void targetSizeChanged(const QSize &size);
private Q_SLOTS:
void removeBackgrounds(const QStringList &paths, const QString &token);
void backgroundsFound(const QStringList &paths, const QString &token);
void slotSourceModelLoadingChanged();
private:
QSize m_targetSize;
QHash<QString, ImageProxyModel *> m_models;
int m_loaded = 0;
QHash<QString, bool> m_checkedTable;
friend class SlideModelTest;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment