diff --git a/wallpapers/image/slidefiltermodel.h b/wallpapers/image/slidefiltermodel.h --- a/wallpapers/image/slidefiltermodel.h +++ b/wallpapers/image/slidefiltermodel.h @@ -22,7 +22,7 @@ #include #include - +#include class SlideFilterModel : public QSortFilterProxyModel { @@ -34,7 +34,9 @@ SlideFilterModel(QObject* parent); bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override; bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; + void setSourceModel(QAbstractItemModel *sourceModel) override; void setSortingMode(Image::SlideshowMode mode); + void invalidate(); void invalidateFilter(); Q_INVOKABLE int indexOf(const QString& path); @@ -44,6 +46,9 @@ void usedInConfigChanged(); private: + void buildRandomOrder(); + + QVector m_randomOrder; Image::SlideshowMode m_SortingMode; bool m_usedInConfig; }; diff --git a/wallpapers/image/slidefiltermodel.cpp b/wallpapers/image/slidefiltermodel.cpp --- a/wallpapers/image/slidefiltermodel.cpp +++ b/wallpapers/image/slidefiltermodel.cpp @@ -24,6 +24,8 @@ #include #include +#include + SlideFilterModel::SlideFilterModel(QObject* parent) : QSortFilterProxyModel{parent} , m_SortingMode{Image::Random} @@ -39,11 +41,23 @@ return m_usedInConfig || index.data(BackgroundListModel::ToggleRole).toBool(); } +void SlideFilterModel::setSourceModel(QAbstractItemModel *sourceModel) +{ + if (this->sourceModel()) { + disconnect(this->sourceModel(), nullptr, this, nullptr); + } + QSortFilterProxyModel::setSourceModel(sourceModel); + if(sourceModel) { + connect(sourceModel, &QAbstractItemModel::rowsInserted, this, &SlideFilterModel::invalidate); + connect(sourceModel, &QAbstractItemModel::rowsRemoved, this, &SlideFilterModel::invalidate); + } +} + bool SlideFilterModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const { switch (m_SortingMode) { case Image::Random: - return (*QRandomGenerator::system())() % 2 == 0; + return m_randomOrder.indexOf(source_left.row()) < m_randomOrder.indexOf(source_right.row()); case Image::Alphabetical: return QSortFilterProxyModel::lessThan(source_left, source_right); case Image::AlphabeticalReversed: @@ -67,10 +81,20 @@ void SlideFilterModel::setSortingMode(Image::SlideshowMode mode) { m_SortingMode = mode; + if (mode == Image::Random) { + buildRandomOrder(); + } if (!(m_usedInConfig && mode == Image::Random)) { QSortFilterProxyModel::invalidate(); } } +void SlideFilterModel::invalidate() +{ + if (m_SortingMode == Image::Random) { + buildRandomOrder(); + } + QSortFilterProxyModel::invalidate(); +} void SlideFilterModel::invalidateFilter() { @@ -88,3 +112,13 @@ auto sourceIndex = mapToSource(index(rowIndex, 0)); static_cast(sourceModel())->openContainingFolder(sourceIndex.row()); } + +void SlideFilterModel::buildRandomOrder() +{ + if (m_SortingMode != Image::Random) { + return; + } + m_randomOrder.resize(sourceModel()->rowCount()); + std::iota(m_randomOrder.begin(), m_randomOrder.end(), 0); + std::random_shuffle(m_randomOrder.begin(), m_randomOrder.end()); +}